Skip to content

Promo Manager, Announcements, Content‑Drops, and admin UX refactor; SSHV/health improvements; add smoke checks - #86

Merged
gamblecodezcom merged 2 commits into
mainfrom
codex/add-new-admin-promo-manager
Feb 25, 2026
Merged

Promo Manager, Announcements, Content‑Drops, and admin UX refactor; SSHV/health improvements; add smoke checks#86
gamblecodezcom merged 2 commits into
mainfrom
codex/add-new-admin-promo-manager

Conversation

@gamblecodezcom

@gamblecodezcom gamblecodezcom commented Feb 25, 2026

Copy link
Copy Markdown
Owner

User description

Motivation

  • Replace brittle single promo/code model with a DB-backed Promo Manager to support multiple promos, claims, approvals, cooldowns and richer eligibility rules.
  • Modernize admin UX for broadcasts/announcements and content drops (formerly "tips") and make group/channel targets more robust.
  • Harden SSHV console, health checks (optionally TLS), and add safer file/save behavior and diagnostic hints for sandbox restrictions.
  • Add static runtime/smoke checks to catch syntax issues and orphaned callback buttons early.

Description

  • Introduces a Promo Manager (promoManagerStore) persisted to data/promo-manager-db.json, with new types/fields (PROMO_STATUS, PROMO_REQUIREMENT) and functions for listing, loading, saving, eligibility evaluation, claim creation, and admin approval/denial (/pmapprove, /pmdeny).
  • Replaces legacy single promoStore/promoCodeStore flows with DB-backed promos and updates the user-facing /promo and claim flows to use the new promo manager, including admin UI changes (🎛 Promo Manager) and many callback/action renames/aliases for backward compatibility.
  • Implements a new announcement builder flow with toggleable targets and modes (announceBuilderKeyboard, sendAnnouncementTargets) and maps legacy broadcast actions to the new flow.
  • Renames and reworks the tips system into a Content Drops subsystem: improved scheduling, target resolution, postTipToConfiguredTarget, better failure handling, /register_chat to capture group/channel targets, and UI/strings updated accordingly.
  • SSHV and health improvements: add isHealthTlsEnabled, sandbox restriction hint for exec errors, safer editor save with error logging, more admin logs for ctrl actions, GC timers unref() calls, and support for TLS local health checks when keys/certs configured.
  • Miscellaneous: .env.example comment for WEBAPP_HMAC_KEY, updated .gitignore to allow example env files and persist data backups, migration additions to createDefaultUser (new flags), many keyboard/menu text refinements and backward-compatible aliases across the bot.
  • Adds a smoke test test/smoke.test.js that syntactically checks index.js and performs a static scan to ensure inline callback button IDs map to bot.action handlers or regex patterns.

Testing

  • Ran the new smoke checks which include node --check index.js and the static callback-to-handler coverage test from test/smoke.test.js, and both passed locally.
  • Manually exercised key admin flows in a dev environment: Promo Manager creation/claim/auto-approve and pending queue notification paths, and the Announcement builder send path (DM/channel/group toggles); these worked as expected in the test instance.
  • Tips/Content Drops scheduler and /register_chat flow were tested with tiptest to confirm messages are attempted to the configured group and failures produce helpful guidance.

Codex Task


CodeAnt-AI Description

Scan all JavaScript files for menu callbacks and action handlers in smoke checks

What Changed

  • The smoke test now scans all .js files (skipping .git, node_modules, data, logs) instead of only index.js when validating that menu callback IDs have matching action handlers.
  • Callback IDs are detected from literal button callbacks and action handlers are detected from both literal strings and regular-expression actions; malformed regex patterns are ignored instead of failing the static check.
  • Test output lists any uncovered callback IDs across the codebase rather than only within a single file.

Impact

✅ Fewer CI false positives from single-file scans
✅ Fewer missed handler mismatches across files
✅ Shorter debugging when callbacks lack handlers

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

@codeant-ai

codeant-ai Bot commented Feb 25, 2026

Copy link
Copy Markdown

CodeAnt AI is reviewing your PR.


Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@gamblecodezcom
gamblecodezcom merged commit b4bec40 into main Feb 25, 2026
1 check passed
@gamblecodezcom
gamblecodezcom deleted the codex/add-new-admin-promo-manager branch February 25, 2026 09:59
@codeant-ai

codeant-ai Bot commented Feb 25, 2026

Copy link
Copy Markdown

Sequence Diagram

The PR enhances the smoke test to scan all .js files, extract callback button IDs and bot.action handlers (including regex patterns), and verify every callback has a matching handler (literal or pattern). This diagram shows the core successful path of that static verification.

sequenceDiagram
    participant TestRunner
    participant FileSystem
    participant SmokeCheck
    participant BotSource

    TestRunner->>FileSystem: Collect all .js files under repo
    SmokeCheck->>BotSource: Read and concatenate JS sources
    SmokeCheck->>BotSource: Extract callback button IDs
    SmokeCheck->>BotSource: Extract literal action handlers and regex action patterns
    SmokeCheck->>SmokeCheck: Match callbacks against literals or regex patterns
    SmokeCheck-->>TestRunner: Pass if all callbacks covered (else fail)
Loading

Generated by CodeAnt AI

@codeant-ai codeant-ai Bot added the size:M This PR changes 30-99 lines, ignoring generated files label Feb 25, 2026
@codeant-ai

codeant-ai Bot commented Feb 25, 2026

Copy link
Copy Markdown

Nitpicks 🔍

🔒 No security issues identified
⚡ Recommended areas for review

  • Directory traversal errors
    collectJsFiles walks directories synchronously without handling symlinks, permission errors or removed directories. This can throw (failing the smoke test) or enter symlink loops on some environments. Consider defensive handling and avoiding following symlinks.

  • Fragile regex-based pattern extraction
    extractActionRegexPatterns builds RegExp objects from source substrings and silently skips malformed patterns. It can be fooled by escaped slashes, comments, or non-standard flags and may miss valid handlers or silently ignore important patterns. A parser-based approach would be more robust.

Comment thread test/smoke.test.js

function extractLiteralIds(source, kind) {
const regex = kind === 'callback'
? /Markup\.button\.callback\([^,]+,\s*(["'`])((?:\\.|(?!\1).)*)\1\)/g

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggestion: The smoke test currently treats callback IDs built with template literals (e.g., containing ${...}) as literal IDs and then tries to match them against regex-based handlers, which will always fail, causing valid dynamically-generated callback buttons like pamenu_gw_end_${gw.id} or help_page_${page - 1} to be reported as "uncovered" even though matching bot.action(/.../) handlers exist; restricting the callback scan to only single/double-quoted literals avoids these false positives while still checking all statically-known IDs. [logic error]

Severity Level: Major ⚠️
- ❌ Smoke test fails despite valid dynamic callback handlers.
- ⚠️ CI/test pipeline may be blocked by false alarms.
- ⚠️ Reduces trust in static callback-to-handler coverage check.
Suggested change
? /Markup\.button\.callback\([^,]+,\s*(["'`])((?:\\.|(?!\1).)*)\1\)/g
? /Markup\.button\.callback\([^,]+,\s*(["'])((?:\\.|(?!\1).)*)\1\)/g
Steps of Reproduction ✅
1. Run the smoke tests, e.g. `node test/smoke.test.js` or the project's test script, which
executes `test('menu callback buttons map to handlers (literal or dynamic patterns)',
...)` in `test/smoke.test.js:50-65`.

2. That test reads all JS sources via `collectJsFiles('.')` and concatenates them into
`combinedSource`, then calls `extractLiteralIds(combinedSource, 'callback')` at
`test/smoke.test.js:56`, using the current regex that matches Markup.button.callback IDs
quoted with single, double, or backtick literals.

3. In `index.js:2293-2294`, callback buttons are defined with template literals for their
callback data, e.g. `Markup.button.callback(#${gw.id} End Early, pamenu_gw_end_${gw.id})`
and similarly for extend/cancel/participants, and in `index.js:3046-3048` help pagination
buttons are defined as `help_page_${page - 1}` / `help_page_${page + 1}`.

4. `extractLiteralIds` currently treats those backtick template literals as literal IDs
(e.g. the string `pamenu_gw_end_${gw.id}`), but when the test compares them against
handlers, the corresponding regex handlers like `bot.action(/^pamenu_gw_end_(\d+)$/, ...)`
at `index.js:4839` and `bot.action(/^help_page_(\d+)$/, ...)` at `index.js:4483` do not
match those literal template strings, so they appear in `uncovered` and cause the
assertion at `test/smoke.test.js:64` to fail with "Uncovered callback handlers:
pamenu_gw_end_${gw.id}, help_page_${page - 1}, ...".
Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** test/smoke.test.js
**Line:** 27:27
**Comment:**
	*Logic Error: The smoke test currently treats callback IDs built with template literals (e.g., containing `${...}`) as literal IDs and then tries to match them against regex-based handlers, which will always fail, causing valid dynamically-generated callback buttons like `pamenu_gw_end_${gw.id}` or `help_page_${page - 1}` to be reported as "uncovered" even though matching `bot.action(/.../)` handlers exist; restricting the callback scan to only single/double-quoted literals avoids these false positives while still checking all statically-known IDs.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
👍 | 👎

@codeant-ai

codeant-ai Bot commented Feb 25, 2026

Copy link
Copy Markdown

CodeAnt AI finished reviewing your PR.

@coderabbitai

coderabbitai Bot commented Feb 25, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@gamblecodezcom has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 18 minutes and 39 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between fa22618 and d7a3e2a.

📒 Files selected for processing (2)
  • .gitignore
  • test/smoke.test.js
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch codex/add-new-admin-promo-manager

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

codex size:M This PR changes 30-99 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant