Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: notify admin to update solvers in the community #618

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

Anyitechs
Copy link

@Anyitechs Anyitechs commented Dec 20, 2024

This PR schedules a daily job at midnight to notify the admin of a community that there are no solvers in the community. The maximum number of notification messages right now is set to 5, afterwards the community is disabled.

Fixes #314

Summary by CodeRabbit

  • New Features

    • Introduced a more frequent automated check that monitors community setups and notifies administrators when communities lack required solvers.
    • Added a configuration for managing the maximum number of notifications sent to administrators.
    • Implemented multilingual alerts to provide clear guidance to users regarding community management and solver requirements.
  • Bug Fixes

    • Enhanced error handling for community notifications to ensure proper logging and user guidance.
  • Documentation

    • Updated locale files to include new messages for users about community solver requirements in multiple languages.

Copy link
Member

@Catrya Catrya left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello, did you tested it locally? It's not working properly:

  • This message is not being displayed: Your community ${community.name} doesn't have any solvers. Please add at least one solver to avoid being disabled.
  • Even though the logs say: Community: ${community.name} has been disabled due to lack of solvers. the community is not being disabled. You can continue using it normally.
  • I recommend putting the warning messages to the administrators in the language they have the bot set in, in the yaml of ./locales. You can see as an example at Add cronjob to notify admin about missing solvers (#314) #563

@Anyitechs
Copy link
Author

Hello, did you tested it locally? It's not working properly:

  • This message is not being displayed: Your community ${community.name} doesn't have any solvers. Please add at least one solver to avoid being disabled.
  • Even though the logs say: Community: ${community.name} has been disabled due to lack of solvers. the community is not being disabled. You can continue using it normally.
  • I recommend putting the warning messages to the administrators in the language they have the bot set in, in the yaml of ./locales. You can see as an example at Add cronjob to notify admin about missing solvers (#314) #563

Thank you for the review. I'll work on these feedbacks.

@Anyitechs
Copy link
Author

Anyitechs commented Jan 3, 2025

Hi @Catrya, I've addressed all the feedbacks here. Please have a look and let me know if there're other changes.

Hello, did you tested it locally? It's not working properly:

  • This message is not being displayed: Your community ${community.name} doesn't have any solvers. Please add at least one solver to avoid being disabled.
  • Even though the logs say: Community: ${community.name} has been disabled due to lack of solvers. the community is not being disabled. You can continue using it normally.
  • I recommend putting the warning messages to the administrators in the language they have the bot set in, in the yaml of ./locales. You can see as an example at Add cronjob to notify admin about missing solvers (#314) #563

Copy link
Member

@Catrya Catrya left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @Anyitechs , much better, it already sends messages to the admins and disables the community. However, I think the message for the admins could be improved so that they know how much time they have to put a new admin.
I think it could be something like this:

Your community ${communityName} does not have any solvers. Please add at least one within X days to prevent the community from being disabled.

Actually the number of notifications that the solver receives before disabling the community is MAX_MESSAGES -1 because it disables it in MAX_MESSAGES, I suggest that it shows that number of notifications before disabling it

I will continue testing and I will tell you if I find any bug, good job!

@Anyitechs
Copy link
Author

Hi @Anyitechs , much better, it already sends messages to the admins and disables the community. However, I think the message for the admins could be improved so that they know how much time they have to put a new admin. I think it could be something like this:

Your community ${communityName} does not have any solvers. Please add at least one within X days to prevent the community from being disabled.

Actually the number of notifications that the solver receives before disabling the community is MAX_MESSAGES -1 because it disables it in MAX_MESSAGES, I suggest that it shows that number of notifications before disabling it

I will continue testing and I will tell you if I find any bug, good job!

Thank you for the feedback @Catrya. I just pushed a new commit with the changes requested here. Please take a look and let me know your thoughts. Thank you.

Copy link
Member

@Catrya Catrya left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK. Thanks @Anyitechs !

Copy link
Member

@Catrya Catrya left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @Anyitechs, sorry but I remembered that when a community is disabled it should also be deleted from the database, see deleteCommunity
This PR does not delete the community from the database, and I think that is necessary.
Anyway, let's see what @grunch thinks, sorry

@Anyitechs
Copy link
Author

Hi @Anyitechs, sorry but I remembered that when a community is disabled it should also be deleted from the database, see deleteCommunity This PR does not delete the community from the database, and I think that is necessary. Anyway, let's see what @grunch thinks, sorry

Thank you @Catrya. I was thinking we needed a soft delete and that was why I added the is_disabled flag to the community model. But why do we need to disable a community first and also delete it from the database. Why don't we go ahead and delete the community rather than having to disable it first?

Any thoughts? @grunch

@Catrya
Copy link
Member

Catrya commented Jan 20, 2025

Thank you @Catrya. I was thinking we needed a soft delete and that was why I added the is_disabled flag to the community model. But why do we need to disable a community first and also delete it from the database. Why don't we go ahead and delete the community rather than having to disable it first?

Any thoughts? @grunch

Hi @Anyitechs , I don't mean to disable it first and then delete it, but to delete it.
Send messages to users as you already do, but if admin doesn't add a solver, just delete it from the database (we already called that disabling)

@Anyitechs
Copy link
Author

Thank you @Catrya. I was thinking we needed a soft delete and that was why I added the is_disabled flag to the community model. But why do we need to disable a community first and also delete it from the database. Why don't we go ahead and delete the community rather than having to disable it first?
Any thoughts? @grunch

Hi @Anyitechs , I don't mean to disable it first and then delete it, but to delete it. Send messages to users as you already do, but if admin doesn't add a solver, just delete it from the database (we already called that disabling)

That makes sense. Thank you for the clarification. I'll work on that and update the branch.

@Anyitechs
Copy link
Author

@Catrya I just pushed an update to the branch now. Please do take a look and let me know your thoughts. Thank you.

Copy link
Member

@Catrya Catrya left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks @Anyitechs I already tested it and it works well to me! Let's see @grunch review

@Anyitechs
Copy link
Author

Anyitechs commented Jan 21, 2025

thanks @Anyitechs I already tested it and it works well to me! Let's see @grunch review

Thank you @Catrya. @grunch let me know if there're any changes. Thank you.

@@ -143,7 +143,7 @@ exports.updateCommunity = async (ctx, id, field, bot) => {
if (!(await validateObjectId(ctx, id))) return;
const community = await Community.findOne({
_id: id,
creator_id: user._id,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as you can read in our contribution section, we are using the airbnb javascript guide style, please don't remove the comma

https://github.com/airbnb/javascript?tab=readme-ov-file#commas--dangling

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding them back now.

@@ -211,7 +211,7 @@ exports.deleteCommunity = async ctx => {
if (!(await validateObjectId(ctx, id))) return;
const community = await Community.findOne({
_id: id,
creator_id: ctx.user._id,
creator_id: ctx.user._id
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -233,7 +233,7 @@ exports.changeVisibility = async ctx => {
if (!(await validateObjectId(ctx, id))) return;
const community = await Community.findOne({
_id: id,
creator_id: ctx.user._id,
creator_id: ctx.user._id
Copy link
Member

@grunch grunch Jan 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


await bot.telegram.sendMessage(
admin.tg_id,
message
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@knocte
Copy link
Contributor

knocte commented Jan 23, 2025

as you can read in our contribution section, we are using the airbnb javascript guide style, please don't remove the comma

How about moving to a style that can be checked at CI time? e.g. with prettier

@knocte
Copy link
Contributor

knocte commented Jan 23, 2025

@webwarrior-ws hey, please check CI, it is red.

@knocte
Copy link
Contributor

knocte commented Jan 23, 2025

@webwarrior-ws hey, please check CI, it is red.

Oops wrong contributor!

@grunch
Copy link
Member

grunch commented Jan 23, 2025

as you can read in our contribution section, we are using the airbnb javascript guide style, please don't remove the comma

How about moving to a style that can be checked at CI time? e.g. with prettier

yes I have it locally but we need it at CI level

@Anyitechs
Copy link
Author

Thank you for the review @grunch. I just addressed the feedbacks, rebased and updated the branch.

@Anyitechs Anyitechs requested a review from grunch February 2, 2025 20:15
@grunch grunch requested a review from Catrya February 21, 2025 20:45
@grunch
Copy link
Member

grunch commented Feb 21, 2025

Hi @Anyitechs, sorry but I remembered that when a community is disabled it should also be deleted from the database, see deleteCommunity This PR does not delete the community from the database, and I think that is necessary. Anyway, let's see what @grunch thinks, sorry

Thank you @Catrya. I was thinking we needed a soft delete and that was why I added the is_disabled flag to the community model. But why do we need to disable a community first and also delete it from the database. Why don't we go ahead and delete the community rather than having to disable it first?

Any thoughts? @grunch

I agree on this, we allow users to disable a community for a while, maybe they need to stop it and want to go back later, but we already have a cronjob that deletes a community after N days without a successful order, disabled or not, so I think there is no harm if someone disable a community and forget about it, it will be deleted at some point

@Catrya
Copy link
Member

Catrya commented Feb 21, 2025

Hi @Anyitechs, sorry but I remembered that when a community is disabled it should also be deleted from the database, see deleteCommunity This PR does not delete the community from the database, and I think that is necessary. Anyway, let's see what @grunch thinks, sorry

Thank you @Catrya. I was thinking we needed a soft delete and that was why I added the is_disabled flag to the community model. But why do we need to disable a community first and also delete it from the database. Why don't we go ahead and delete the community rather than having to disable it first?
Any thoughts? @grunch

I agree on this, we allow users to disable a community for a while, maybe they need to stop it and want to go back later, but we already have a cronjob that deletes a community after N days without a successful order, disabled or not, so I think there is no harm if someone disable a community and forget about it, it will be deleted at some point

Anyway, @Anyitechs then got the community deleted, which is better IMHO
I'm going to retest everything asap

@grunch
Copy link
Member

grunch commented Feb 21, 2025

Hi @Anyitechs, sorry but I remembered that when a community is disabled it should also be deleted from the database, see deleteCommunity This PR does not delete the community from the database, and I think that is necessary. Anyway, let's see what @grunch thinks, sorry

Thank you @Catrya. I was thinking we needed a soft delete and that was why I added the is_disabled flag to the community model. But why do we need to disable a community first and also delete it from the database. Why don't we go ahead and delete the community rather than having to disable it first?
Any thoughts? @grunch

I agree on this, we allow users to disable a community for a while, maybe they need to stop it and want to go back later, but we already have a cronjob that deletes a community after N days without a successful order, disabled or not, so I think there is no harm if someone disable a community and forget about it, it will be deleted at some point

Anyway, @Anyitechs then got the community deleted, which is better IMHO
I'm going to retest everything asap

I'm sorry I was thinking you were talking about adding a new way of just disable a community from the same user creator

I agree on, if the creator execute the command to delete the community it should delete the community immediately

.env-sample Outdated
DISPUTE_START_WINDOW=600

# Number of notification messages sent to the admin, informing them of lack of solvers before disabling the community
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The admin is being sent MAX_MESSAGES -1 notifications, if it says 10 here, the admin will see 9 notifications.
I think that either this description, or MAX_MESSAGES needs to be adjusted to make it clearer for whoever is going to configuring it.

For the rest, everything seems fine to me.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @Catrya. What do you recommend?

Adjusting the description to include that the admin receives MAX_MESSAGES -1 notifications seems ok to me.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's fine by me too, go ahead. Thanks @Anyitechs

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just updated the description and rebased.

Copy link

coderabbitai bot commented Feb 25, 2025

Walkthrough

The changes introduce a new scheduling mechanism that runs the checkSolvers function every minute instead of daily. A new file check_solvers.ts implements logic to check for communities without solvers and notify the admin, with a count of notifications tracked in the community model. Additionally, a new configuration variable MAX_ADMIN_WARNINGS_BEFORE_DEACTIVATION is added to control the limit of notifications before community deactivation. Localized warning messages are also introduced across multiple languages.

Changes

File Path Change Summary
.env-sample Added new variable MAX_ADMIN_WARNINGS_BEFORE_DEACTIVATION=10 for admin notifications; retained existing DISPUTE_START_WINDOW setting.
bot/start.ts Updated scheduling for checkSolvers to run every minute instead of daily; commented out the previous job.
jobs/check_solvers.ts, jobs/index.ts Created checkSolvers functionality with error handling and notification logic; updated export in index file.
locales/{de,en,es,fa,fr,it,ko,pt,ru,uk}.yaml Introduced new internationalized entries (check_solvers and check_solvers_last_warning) for community solver warnings across multiple locales.
models/community.ts Added warning_messages_count property (default 0) to the community schema and interface to track admin notification counts.
tests/bot/bot.spec.ts Updated test case to expect an increased call count for scheduled jobs from 7 to 8.

Poem

I'm Bunny, hopping through the code at night,
Checking for solvers with all my might.
A cron job every minute makes my heart race,
Sending alerts in every language—what a chase!
With warnings counted, I leap through change with glee,
Celebrating updates as sweet as a carrot spree!
Hoppy coding to all from my bunny burrow! 🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🔭 Outside diff range comments (2)
locales/it.yaml (1)

635-636: 🛠️ Refactor suggestion

Review Italian Localization for Solver Terminology and Placeholders

The newly added keys for “check_solvers” and “check_solvers_last_warning” include dynamic placeholders (${communityName} and ${remainingDays}). Please verify that the translation aligns with the project’s terminology. In Italian it might be more appropriate to use a term like “risolutori” instead of “solver” if that is consistent with the rest of the localization strings. For example:

- check_solvers: La tua community ${communityName} non ha solver. Aggiungine almeno uno entro ${remainingDays} giorni per evitare che la community venga disabilitata.
+ check_solvers: La tua community ${communityName} non ha risolutori. Aggiungine almeno uno entro ${remainingDays} giorni per evitare che la community venga disabilitata.

Please ensure consistency with other keys and verify that the placeholders match the backend expectations.

jobs/check_solvers.ts (1)

1-57: 💡 Verification agent

🧩 Analysis chain

Verify if the MAX_MESSAGES environment variable has appropriate fallback.

The code references process.env.MAX_MESSAGES without providing a fallback value if this environment variable is not set. Consider adding a fallback value.


🏁 Script executed:

#!/bin/bash
# Check if MAX_MESSAGES is defined in any environment files
grep -r "MAX_MESSAGES" --include="*.env*" .

Length of output: 267


Action: Add a Fallback for MAX_MESSAGES

After confirming that MAX_MESSAGES is defined in the sample environment file (with a value of 10), please ensure that the production code gracefully handles cases where this variable might not be set. Currently, process.env.MAX_MESSAGES is used directly. If this environment variable is missing, using Number(process.env.MAX_MESSAGES) will yield NaN, which can lead to unexpected behavior.

Suggested changes:

  • Use a fallback value when converting process.env.MAX_MESSAGES to a number. For example:
    const maxMessages = Number(process.env.MAX_MESSAGES ?? 10);
  • Replace occurrences of Number(process.env.MAX_MESSAGES) with the new maxMessages variable in both the condition that deletes the community and when calculating remainingDays.

Next step: Update the code in jobs/check_solvers.ts (lines 1-57) accordingly.

🧰 Tools
🪛 Biome (1.9.4)

[error] 17-17: Unnecessary continue statement

Unsafe fix: Delete the unnecessary continue statement

(lint/correctness/noUnnecessaryContinue)

🧹 Nitpick comments (9)
locales/de.yaml (1)

637-638: Ensure Consistent Terminology for Solvers in German Localization

The two new keys use “Solver” (e.g. “Ihre Community ${communityName} hat keine Solver…”), but elsewhere in this file (and likely across the project) the term “Streitschlichter” is used for this role. To maintain consistency, please consider aligning the terminology in these messages. For example:

-check_solvers: Ihre Community ${communityName} hat keine Solver. Bitte fügen Sie innerhalb von ${remainingDays} Tagen mindestens einen hinzu, um zu verhindern, dass die Community deaktiviert wird.
+check_solvers: Ihre Community ${communityName} hat keine Streitschlichter. Bitte fügen Sie innerhalb von ${remainingDays} Tagen mindestens einen hinzu, um zu verhindern, dass die Community deaktiviert wird.

Similarly, update “check_solvers_last_warning” if needed.

locales/ko.yaml (1)

632-633: Verify Terminology and Placeholder Consistency in Korean Localization

The new entries:

check_solvers: ${communityName} 커뮤니티에 해결사가 없습니다. 커뮤니티가 비활성화되는 것을 방지하려면 ${remainingDays}일 이내에 하나 이상 추가하세요.
check_solvers_last_warning: ${communityName} 커뮤니티에 해결사가 없습니다. 커뮤니티가 비활성화되는 것을 방지하려면 오늘 하나 이상 추가하세요.

correctly use the dynamic placeholders (${communityName} and ${remainingDays}). Please ensure that the term “해결사” is the chosen and consistent translation for “solver” as used in other parts of the localization (or adjust it if another term is preferred).

locales/ru.yaml (1)

637-638: Verify translation accuracy and add a newline at end of file.

The new localization entries for notifying admins about missing solvers look good. The message content aligns with the feature described in the PR objectives.

As flagged by YAMLlint, there is no newline at the end of the file. While this is not a functional issue, it's a good practice to include one:

check_solvers_last_warning: В вашем сообществе ${communityName} нет решателей. Пожалуйста, добавьте хотя бы один сегодня, чтобы предотвратить отключение сообщества.
+
locales/es.yaml (1)

637-638: Verify translation accuracy and add a newline at end of file.

The new localization entries for notifying admins about missing solvers have been properly added to the Spanish locale file. The messages align with the feature described in the PR objectives.

As flagged by YAMLlint, there is no newline at the end of the file. While this is not a functional issue, it's a good practice to include one:

check_solvers_last_warning: Tu comunidad ${communityName} no tiene ningún solucionador. Agregue al menos uno hoy para evitar que la comunidad quede inhabilitada.
+
🧰 Tools
🪛 YAMLlint (1.35.1)

[error] 638-638: no new line character at the end of file

(new-line-at-end-of-file)

jobs/check_solvers.ts (5)

16-20: Simplify the conditional logic by using early continue.

The current if-else structure with an unnecessary continue statement can be simplified.

-    for (const community of communities) {
-        if (community.solvers.length > 0) {
-            continue;
-        } else {
-            await notifyAdmin(community, bot);
-        }
-    }
+    for (const community of communities) {
+        if (community.solvers.length === 0) {
+            await notifyAdmin(community, bot);
+        }
+    }
🧰 Tools
🪛 Biome (1.9.4)

[error] 17-17: Unnecessary continue statement

Unsafe fix: Delete the unnecessary continue statement

(lint/correctness/noUnnecessaryContinue)


40-42: Add error handling for community save operation.

The community save operation might fail but there's no error handling. Consider wrapping it in a try-catch block.

-  await community.save();
-  const admin = await User.findById(community.creator_id);
+  try {
+    await community.save();
+    const admin = await User.findById(community.creator_id);
+  } catch (error) {
+    logger.error(`Failed to save community ${community.name}: ${String(error)}`);
+    return;
+  }

43-45: Add logging when admin is not found.

If the admin is not found, the function silently returns without any notification. Consider adding a log message for this case.

  if (admin) {
    const i18nCtx: I18nContext = await getUserI18nContext(admin);
    const remainingDays: number = (Number(process.env.MAX_MESSAGES) - 1) - community.messages_sent_count;
+  } else {
+    logger.warn(`Admin not found for community: ${community.name} (ID: ${community.creator_id})`);
+    return;
  }

47-47: Improve message selection logic readability.

The ternary expression for message selection is a bit hard to read. Consider extracting it to a separate variable or function.

-    const message = remainingDays === 0 ? i18nCtx.t('check_solvers_last_warning', { communityName: community.name }) : i18nCtx.t('check_solvers', { communityName: community.name, remainingDays: remainingDays });
+    const messageKey = remainingDays === 0 ? 'check_solvers_last_warning' : 'check_solvers';
+    const messageParams = remainingDays === 0 
+      ? { communityName: community.name } 
+      : { communityName: community.name, remainingDays };
+    const message = i18nCtx.t(messageKey, messageParams);

49-53: Add error handling for Telegram message sending.

The bot.telegram.sendMessage operation might fail, but there's no error handling. Consider wrapping it in a try-catch block.

-    await bot.telegram.sendMessage(
-      admin.tg_id,
-      message,
-    );
+    try {
+      await bot.telegram.sendMessage(
+        admin.tg_id,
+        message,
+      );
+      logger.info(`Notification sent to admin of community ${community.name}, messages sent: ${community.messages_sent_count}`);
+    } catch (error) {
+      logger.error(`Failed to send notification to admin of community ${community.name}: ${String(error)}`);
+    }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 22a0ec9 and 76e2ba8.

📒 Files selected for processing (15)
  • .env-sample (1 hunks)
  • bot/start.ts (2 hunks)
  • jobs/check_solvers.ts (1 hunks)
  • jobs/index.ts (2 hunks)
  • locales/de.yaml (1 hunks)
  • locales/en.yaml (1 hunks)
  • locales/es.yaml (1 hunks)
  • locales/fa.yaml (1 hunks)
  • locales/fr.yaml (1 hunks)
  • locales/it.yaml (1 hunks)
  • locales/ko.yaml (1 hunks)
  • locales/pt.yaml (1 hunks)
  • locales/ru.yaml (1 hunks)
  • locales/uk.yaml (1 hunks)
  • models/community.ts (2 hunks)
🧰 Additional context used
🪛 YAMLlint (1.35.1)
locales/es.yaml

[error] 638-638: no new line character at the end of file

(new-line-at-end-of-file)

🪛 Biome (1.9.4)
jobs/check_solvers.ts

[error] 17-17: Unnecessary continue statement

Unsafe fix: Delete the unnecessary continue statement

(lint/correctness/noUnnecessaryContinue)

🔇 Additional comments (12)
jobs/index.ts (1)

10-10: Implementation looks good!

The import and export of the new checkSolvers function is clean and consistent with the existing codebase structure.

Also applies to: 20-20

.env-sample (1)

85-86: Clear configuration description that addresses previous feedback.

The comment clearly explains that admins receive MAX_MESSAGES - 1 notifications before the community is disabled, addressing the previous feedback from the PR discussion.

models/community.ts (1)

52-52: Good implementation of the message count tracking.

The addition of messages_sent_count to both the interface and schema with appropriate typing and default value is well-implemented. This will correctly track notification messages sent to community administrators.

Also applies to: 85-85

locales/fr.yaml (2)

636-636: Ensure message contains time frame as mentioned in PR comments.

Per the PR comments, Catrya suggested that the notification message should include a timeframe for when a solver should be added. This implementation correctly includes the ${remainingDays} variable to provide this information.


636-637:

✅ Verification successful

Verify translations exist in all language files.

The localized warning messages have been added to the French locale file, but similar messages should also exist in other language files (en.yaml, de.yaml, etc.) to ensure consistent multilingual support.


🏁 Script executed:

#!/bin/bash
# Check if the warning messages exist in all language files
echo "Checking for warning messages in all language files..."

# Find all locale files
locale_files=$(fd -e yaml -e yml . locales)

# Check each file for the presence of the warning messages
for file in $locale_files; do
  echo "Checking $file..."
  
  has_check_solvers=$(grep -l "check_solvers:" "$file" || echo "")
  has_last_warning=$(grep -l "check_solvers_last_warning:" "$file" || echo "")
  
  if [ -z "$has_check_solvers" ] || [ -z "$has_last_warning" ]; then
    echo "⚠️ WARNING: Missing translation in $file"
    if [ -z "$has_check_solvers" ]; then
      echo "  - Missing: check_solvers"
    fi
    if [ -z "$has_last_warning" ]; then
      echo "  - Missing: check_solvers_last_warning"
    fi
  else
    echo "$file has both warning messages"
  fi
done

Length of output: 4486


All locale files confirmed for warning message translations

I verified that both translation keys (check_solvers and check_solvers_last_warning) exist in every locale file (de.yaml, en.yaml, es.yaml, fa.yaml, fr.yaml, it.yaml, ko.yaml, pt.yaml, ru.yaml, uk.yaml). No further changes are required.

bot/start.ts (1)

203-205: Scheduled job for daily solver verification looks good.

The implementation correctly schedules the checkSolvers function to run at midnight daily using the cron syntax 0 0 * * *, which aligns with the PR objectives.

locales/uk.yaml (1)

633-634: New Ukrainian Solver Notification Messages Added
The new localization keys check_solvers and check_solvers_last_warning have been added with proper placeholders (${communityName} and ${remainingDays}). The language is clear and directs the user to add at least one solver to prevent community disablement. Make sure that these placeholders match exactly with what the backend expects.

locales/fa.yaml (1)

636-637: New Persian Solver Notification Messages Added
The additions for check_solvers and check_solvers_last_warning in Persian are well formatted and use the necessary placeholders (${communityName} and ${remainingDays}). The messages clearly instruct users to add a solver and are consistent with the tone used in other locale files. Ensure that the dynamic values render correctly in production.

locales/en.yaml (1)

638-639: New English Solver Notification Messages Added
The new entries for check_solvers and check_solvers_last_warning in English are clear and concise. They correctly include the placeholders (${communityName} and ${remainingDays}) and deliver a precise call-to-action. Verify that these keys are used consistently in the notification logic (such as in the checkSolvers function) and that the placeholders align with the data provided by the service.

locales/pt.yaml (1)

634-635: Good addition of localized warning messages for the solver notification system.

The new entries for check_solvers and check_solvers_last_warning look good, providing clear and informative messages to community admins about missing solvers and the consequences of not adding them.

jobs/check_solvers.ts (2)

4-4: Remove the trailing comma in the import statement.

There's an unnecessary trailing comma after User in the import statement.

-import { Community, User, } from '../models';
+import { Community, User } from '../models';

33-38: Verify community deletion behavior matches requirements.

According to the PR objective, communities should be disabled after the fifth notification, but here they're being deleted immediately. Confirm if this is the intended behavior based on the discussion between Anyitechs, Catrya, and Grunch mentioned in the PR comments.

Are you sure you want to delete the community directly instead of first disabling it? The PR comments indicate there was a discussion about this, with Grunch and Catrya supporting immediate deletion, but it's worth confirming this is the final agreed approach.

Comment on lines 30 to 33
/**
* The community is disabled if the admin has received the maximum notification message (MAX_MESSAGES - 1) to add a solver.
*/
if (community.messages_sent_count >= Number(process.env.MAX_MESSAGES)) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Fix comment to accurately reflect code behavior.

The comment indicates the community is disabled after receiving MAX_MESSAGES - 1 notifications, but the code actually deletes the community when the count reaches MAX_MESSAGES.

  /**
-  * The community is disabled if the admin has received the maximum notification message (MAX_MESSAGES - 1) to add a solver.
+  * The community is deleted if the admin has received the maximum number of notification messages (MAX_MESSAGES) to add a solver.
   */
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/**
* The community is disabled if the admin has received the maximum notification message (MAX_MESSAGES - 1) to add a solver.
*/
if (community.messages_sent_count >= Number(process.env.MAX_MESSAGES)) {
/**
* The community is deleted if the admin has received the maximum number of notification messages (MAX_MESSAGES) to add a solver.
*/
if (community.messages_sent_count >= Number(process.env.MAX_MESSAGES)) {

@Catrya
Copy link
Member

Catrya commented Feb 28, 2025

Hi @Anyitechs Have you tested it? It doesn't work for me with the latest commit

@Anyitechs
Copy link
Author

Hi @Anyitechs Have you tested it? It doesn't work for me with the latest commit

Hi @Catrya, what issue did you notice? I tested and it works. The latest commit is on documentation, but I tested again and it works. Let me know what issue you noticed so I can try to reproduce it here.

Copy link
Member

@Catrya Catrya left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tACK

@Catrya
Copy link
Member

Catrya commented Mar 4, 2025

Hi @Catrya, what issue did you notice? I tested and it works. The latest commit is on documentation, but I tested again and it works. Let me know what issue you noticed so I can try to reproduce it here.

Hi @Anyitechs sorry, that was a mistake on my part. I tested again and I already approved it, it works fine. Good job. Congratulations

@Catrya
Copy link
Member

Catrya commented Mar 4, 2025

@Anyitechs before merging, it is necessary that no test fails, could you please check that 1 test is failing and fix it? Thanks
should schedule recurring jobs

@Anyitechs
Copy link
Author

@Anyitechs before merging, it is necessary that no test fails, could you please check that 1 test is failing and fix it? Thanks should schedule recurring jobs

Will check it out and fix it.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
tests/bot/bot.spec.ts (1)

456-456: Correct test update for the new scheduled job

The updated test correctly verifies that 8 scheduled jobs are now expected instead of 7, which aligns with the addition of the new daily scheduled job for checking communities without solvers.

While this test verifies that the job is scheduled, consider adding specific tests for the checkSolvers functionality to ensure it:

  1. Correctly identifies communities without solvers
  2. Sends appropriate notifications to admins
  3. Properly tracks the number of notifications sent
  4. Deletes communities after reaching the MAX_MESSAGES threshold (10)
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 76e2ba8 and 319f630.

📒 Files selected for processing (1)
  • tests/bot/bot.spec.ts (1 hunks)

@Anyitechs
Copy link
Author

@Anyitechs before merging, it is necessary that no test fails, could you please check that 1 test is failing and fix it? Thanks should schedule recurring jobs

Will check it out and fix it.

@Catrya I just fixed the failing test on CI. It was failing because the PR introduced a new recurring job but the scheduleJob count on the test was still pointing to 7 rather than 8.

Copy link
Member

@Catrya Catrya left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tACK thsnks @Anyitechs. Good job!
just wait for @grunch

@knocte
Copy link
Contributor

knocte commented Mar 6, 2025

Hey! I have couple of suggestions:

.env-sample Outdated

# Number of notification messages sent to the admin, informing them of lack of solvers before disabling the community. The admin receives `MAX_MESSAGES - 1` notification messages.
MAX_MESSAGES=10
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Anyitechs I would recommend renaming this to have a much clearer name; right now "messages" sounds too generic, how about MAX_WARNINGS_TO_ADMIN_BEFORE_COMMUNITY_DEACTIVATION

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @knocte, I think the comment here already explains what "messages" represent in this context. MAX_WARNINGS_TO_ADMIN_BEFORE_COMMUNITY_DEACTIVATION is too long to have as a variable name IMO.

@@ -81,6 +82,7 @@ const CommunitySchema = new Schema<ICommunity>({
},
created_at: { type: Date, default: Date.now },
nostr_public_key: { type: String },
messages_sent_count: { type: Number, default: 0 },
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Anyitechs I'd suggest renaming this to warning_messages_count

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (6)
jobs/check_solvers.ts (6)

4-4: Remove trailing comma from import statement.

The import statement has a trailing comma after User, which is inconsistent with the Airbnb JavaScript Style Guide referenced in previous comments.

-import { Community, User, } from '../models';
+import { Community, User } from '../models';

15-21: Simplify conditional logic and fix inconsistent indentation.

The current code has two issues:

  1. Unnecessary else block with inconsistent indentation (8 spaces instead of 4)
  2. Unnecessary continue statement flagged by static analysis
    for (const community of communities) {
-        if (community.solvers.length > 0) {
-            continue;
-        } else {
-            await notifyAdmin(community, bot);
-        }
+      if (community.solvers.length === 0) {
+        await notifyAdmin(community, bot);
+      }
    }
🧰 Tools
🪛 Biome (1.9.4)

[error] 17-17: Unnecessary continue statement

Unsafe fix: Delete the unnecessary continue statement

(lint/correctness/noUnnecessaryContinue)


33-38: Improve environment variable handling with default fallback.

The code directly uses process.env.MAX_ADMIN_WARNINGS_BEFORE_DEACTIVATION without checking if it exists or has a valid value. This could lead to unexpected behavior if the environment variable is not set.

-  if (community.warning_messages_count >= Number(process.env.MAX_ADMIN_WARNINGS_BEFORE_DEACTIVATION)) {
+  const maxWarnings = Number(process.env.MAX_ADMIN_WARNINGS_BEFORE_DEACTIVATION) || 5; // Default to 5 if not set
+  if (community.warning_messages_count >= maxWarnings) {

45-45: Simplify remaining days calculation for better readability.

The current calculation of remaining days is unnecessarily complex and could be simplified.

-    const remainingDays: number = (Number(process.env.MAX_ADMIN_WARNINGS_BEFORE_DEACTIVATION) - 1) - community.warning_messages_count;
+    const maxWarnings = Number(process.env.MAX_ADMIN_WARNINGS_BEFORE_DEACTIVATION) || 5; // Default to 5 if not set
+    const remainingDays: number = maxWarnings - community.warning_messages_count;

47-47: Break down complex ternary expression for better readability.

The long ternary expression makes the code harder to read and understand.

-    const message = remainingDays === 0 ? i18nCtx.t('check_solvers_last_warning', { communityName: community.name }) : i18nCtx.t('check_solvers', { communityName: community.name, remainingDays: remainingDays });
+    let message;
+    if (remainingDays === 0) {
+      message = i18nCtx.t('check_solvers_last_warning', { communityName: community.name });
+    } else {
+      message = i18nCtx.t('check_solvers', { communityName: community.name, remainingDays });
+    }

11-26: Add logging for better observability of the job execution.

The current implementation doesn't log when it starts checking communities or how many communities it processed. Adding this information would make it easier to monitor and debug the job.

const checkSolvers = async (bot: Telegraf<MainContext>) => {
  try {
+    logger.info('Starting to check communities for missing solvers');
    const communities = await Community.find();
+    logger.info(`Found ${communities.length} communities to check`);

    for (const community of communities) {
      if (community.solvers.length === 0) {
        await notifyAdmin(community, bot);
      }
    }
+    logger.info('Finished checking communities for missing solvers');
  } catch (error) {
    const message = String(error);
    logger.error(`checkSolvers catch error: ${message}`);
  }
};
🧰 Tools
🪛 Biome (1.9.4)

[error] 17-17: Unnecessary continue statement

Unsafe fix: Delete the unnecessary continue statement

(lint/correctness/noUnnecessaryContinue)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 319f630 and 0e9b4cb.

📒 Files selected for processing (4)
  • .env-sample (1 hunks)
  • bot/start.ts (2 hunks)
  • jobs/check_solvers.ts (1 hunks)
  • models/community.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • .env-sample
  • models/community.ts
  • bot/start.ts
🧰 Additional context used
🪛 Biome (1.9.4)
jobs/check_solvers.ts

[error] 17-17: Unnecessary continue statement

Unsafe fix: Delete the unnecessary continue statement

(lint/correctness/noUnnecessaryContinue)

🔇 Additional comments (1)
jobs/check_solvers.ts (1)

30-32: Fix comment to accurately reflect code behavior.

The comment indicates the community is disabled after receiving MAX_ADMIN_WARNINGS_BEFORE_DEACTIVATION - 1 notifications, but the code actually deletes the community when the count reaches MAX_ADMIN_WARNINGS_BEFORE_DEACTIVATION.

  /**
-  * The community is disabled if the admin has received the maximum notification message (MAX_ADMIN_WARNINGS_BEFORE_DEACTIVATION - 1) to add a solver.
+  * The community is deleted if the admin has received the maximum number of notification messages (MAX_ADMIN_WARNINGS_BEFORE_DEACTIVATION) to add a solver.
   */

Comment on lines +49 to +53
await bot.telegram.sendMessage(
admin.tg_id,
message,
);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add error handling for Telegram message sending.

The current implementation doesn't handle potential errors when sending messages via Telegram. This could lead to unhandled exceptions.

-    await bot.telegram.sendMessage(
-      admin.tg_id,
-      message,
-    );
+    try {
+      await bot.telegram.sendMessage(
+        admin.tg_id,
+        message,
+      );
+      logger.info(`Notification sent to admin of community: ${community.name}`);
+    } catch (error) {
+      logger.error(`Failed to send notification to admin of community ${community.name}: ${error}`);
+    }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
await bot.telegram.sendMessage(
admin.tg_id,
message,
);
}
try {
await bot.telegram.sendMessage(
admin.tg_id,
message,
);
logger.info(`Notification sent to admin of community: ${community.name}`);
} catch (error) {
logger.error(`Failed to send notification to admin of community ${community.name}: ${error}`);
}
}

@Anyitechs
Copy link
Author

Hey! I have couple of suggestions:

Thank you for the suggestions @knocte. I've effected them. Let me know if everything looks good.

CC: @Catrya @grunch

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Bot message to community admin to update solvers
4 participants