Skip to content

Introduce DB-backed Promo Manager, Announcements, Content Drops, and admin UX improvements - #87

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

Introduce DB-backed Promo Manager, Announcements, Content Drops, and admin UX improvements#87
gamblecodezcom merged 4 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 the legacy single-code promo system with a flexible DB-backed promo manager to support multiple promos, claims, cooldowns and admin approval workflows.
  • Improve broadcast/announcement capabilities with a safer builder UI and targeted DM/channel/group delivery options.
  • Rename and harden the rotating "tips" system into a Content Drops feature with better target resolution and resilient posting logic.
  • Harden admin tooling and runtime robustness (SSHV editor/commands, health TLS handling, GC timers) and provide clearer environment/gitignore guidance.

Description

  • Added a new promo manager (promoManagerStore) persisted to data/promo-manager-db.json with normalization, eligibility checks, claim recording, listing, and helper functions, and migrated user promo flows to use it instead of the legacy promo store.
  • Implemented admin promo-manager UI and flows including create/edit/pause/delete/preview, claim queue processing and admin commands (/pmapprove, /pmdeny), plus user-facing claim handlers and auto-approve support.
  • Reworked announcement flow with an interactive builder (announceBuilderKeyboard, sendAnnouncementTargets) supporting DM/channel/group toggles, parse mode, and a single "Send Broadcast Now" action.
  • Elevated Tips into "Content Drops" with improved posting (postTipToConfiguredTarget), automatic target discovery/registration (/register_chat), scheduler robustness, and renamed commands/labels throughout UI and help text.
  • Numerous admin and UX tweaks: persistent menu label updates, legacy callback aliases, help/booklet pagination fixes, isHealthTlsEnabled and TLS-aware health checks, SSHV improvements (sandbox hint, editor save error handling, admin logging), GC timers unref'd, and various smaller compatibility/migration fields for users.
  • Project housekeeping: update .env.example with guidance for WEBAPP_HMAC_KEY, add exceptions and data backup patterns to .gitignore, and add a static smoke test (test/smoke.test.js) that verifies JS syntax and that callback buttons have handlers (literal or regex).

Testing

  • Verified JavaScript syntax with node --check index.js and the check completed successfully.
  • Ran the repository smoke test suite (npm test / Node node:test runner which executes test/smoke.test.js) and the smoke checks passed with no uncovered callback handlers.
  • Exercise-tested key admin flows locally (promo create/claim, announce builder, content drop test) during development and observed expected behavior (claims created, broadcasts simulated, drops posted to configured target).

Codex Task


CodeAnt-AI Description

Update admin panels to replace messages, enhance giveaway view, add version info, and strengthen smoke test

What Changed

  • Admin menus now update in-place (panels are replaced) instead of sending new chat messages, and the "back" action removes the persistent admin menu message to avoid leftover messages.
  • Active giveaways view now shows human-readable remaining time, includes direct "Join" and "Details" buttons for recent giveaways, and always offers a clear "Return to Admin Menu" button.
  • Version/info command now displays version, commit hash, deploy time, Node runtime and uptime in the admin panel instead of a plain reply.
  • Static smoke test expanded to scan all .js files and validate that inline callback buttons have corresponding handlers (literal or regex patterns), improving test coverage for menu/button wiring.
  • .env.example now documents how to generate and use the WEBAPP_HMAC_KEY.

Impact

✅ Fewer leftover admin messages
✅ Clearer giveaway status and faster actions
✅ Fewer unhandled menu buttons caught by tests

💡 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.

Summary by CodeRabbit

Release Notes

  • New Features

    • Tests & Bugs panel now available in Admin Dashboard with diagnostic tools and testing options
    • Forwarded chats automatically register as targets for content drops and group broadcasts
  • Improvements

    • Admin Dashboard reorganized with enhanced navigation structure
    • Announcement flow improved with new inline navigation options and updated messaging
    • Admin help documentation updated to reflect new menu organization

@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

@codeant-ai codeant-ai Bot added the size:L This PR changes 100-499 lines, ignoring generated files label Feb 25, 2026
Comment thread test/smoke.test.js Outdated
const regex = kind === 'callback'
? /Markup\.button\.callback\([^,]+,\s*(["'`])((?:\\.|(?!\1).)*)\1\)/g
: /bot\.action\(\s*(["'`])((?:\\.|(?!\1).)*)\1/g;
return new Set(Array.from(source.matchAll(regex), (m) => m[2]));

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., with ${...}) as fixed literal IDs, so they cannot be matched by the corresponding dynamic regex handlers and will always show up as "uncovered" even though handlers exist, causing the test to fail incorrectly; filtering out template-literal IDs from the static literal check fixes this logic error. [logic error]

Severity Level: Major ⚠️
- ❌ Smoke test fails despite valid dynamic callback handlers.
- ⚠️ CI or pre-commit test runs can be blocked.
Suggested change
return new Set(Array.from(source.matchAll(regex), (m) => m[2]));
const ids = Array.from(source.matchAll(regex), (m) => m[2]);
const literalIds = ids.filter((id) => !id.includes('${'));
return new Set(literalIds);
Steps of Reproduction ✅
1. Run the smoke tests (e.g. `node --test test/smoke.test.js`), which executes the "menu
callback buttons map to handlers (literal or dynamic patterns)" test defined in
`test/smoke.test.js:50-65`.

2. That test calls `collectJsFiles('.')` and concatenates all JS sources, then invokes
`extractLiteralIds(combinedSource, 'callback')` from `test/smoke.test.js:25-29` to collect
callback IDs from `Markup.button.callback(...)` usages.

3. In `index.js`, there are callback buttons whose callback data is built with template
literals, for example `Markup.button.callback('Next ▶️', \`help_page_${page + 1}\`)` at
`index.js:3048` and giveaway admin buttons like `Markup.button.callback(\`#${gw.id} End
Early\`, \`pamenu_gw_end_${gw.id}\`)` at `index.js:2293-2298`; `extractLiteralIds`
currently treats the literal source text `help_page_${page + 1}` /
`pamenu_gw_end_${gw.id}` as fixed IDs and adds them to `callbackButtons`.

4. The corresponding handlers are registered as dynamic regex actions, e.g.
`bot.action(/^help_page_(\d+)$/, ...)` at `index.js:4483` and
`bot.action(/^pamenu_gw_end_(\d+)$/, ...)` at `index.js:4844`, which are collected into
`dynamicActionPatterns` by `extractActionRegexPatterns` at `test/smoke.test.js:32-42`, but
when the smoke test checks `pattern.test(id)` in `test/smoke.test.js:60-62`, the regex
`/^help_page_(\d+)$/` does not match the static string `help_page_${page + 1}`, so these
entries remain in `uncovered` and cause the assertion `assert.deepEqual(uncovered, [],
...)` at `test/smoke.test.js:64` to fail even though runtime handlers exist.
Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** test/smoke.test.js
**Line:** 29:29
**Comment:**
	*Logic Error: The smoke test currently treats callback IDs built with template literals (e.g., with `${...}`) as fixed literal IDs, so they cannot be matched by the corresponding dynamic regex handlers and will always show up as "uncovered" even though handlers exist, causing the test to fail incorrectly; filtering out template-literal IDs from the static literal check fixes this logic error.

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.

@gamblecodezcom
gamblecodezcom merged commit cf2990b into main Feb 25, 2026
3 checks passed
@gamblecodezcom
gamblecodezcom deleted the codex/add-new-admin-promo-manager branch February 25, 2026 10:56
@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 21 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 86637da and b847f8a.

📒 Files selected for processing (2)
  • index.js
  • test/smoke.test.js
📝 Walkthrough

Walkthrough

Reworks Admin UI to add a Tests & Bugs panel and related keyboards, adds auto-registration for forwarded chats into content-drop/group targets, updates admin help/promos and panel rendering, and refines callback-ID extraction in tests.

Changes

Cohort / File(s) Summary
Admin UI & Tools
index.js
Replaced Admin Help with Tests & Bugs panel; added adminTestsToolsKeyboard(), admin_cat_tests, admin_pm_help; rewired admin dashboard/menu buttons to route through new panels and use replaceCallbackPanel for rendering.
Forwarded-chat Auto-registration
index.js
Added extractForwardedChat(msg) and autoRegisterForwardedChatIfPresent(ctx, user); integrated check into main text handling to auto-register forwarded chats as tipsStore.targetGroup/approvedGroupsStore and persist via broadcastConfigStore.
Announcement & Help Flows
index.js
Updated announcement handling to include inline return/cancel options; revised help/promo texts and labels to reference “BUGS + TESTS + SYSTEM COMMANDS” and Tests & Bugs navigation.
Tests — Callback ID Extraction
test/smoke.test.js
Adjusted extractLiteralIds() to skip dynamic template-literal callback IDs (backtick with ${...}) when extracting literal callback IDs; replaced direct Set construction with an explicit filtering loop.

Sequence Diagram

sequenceDiagram
    actor Admin
    participant MessageHandler as MessageHandler
    participant Extractor as extractForwardedChat()
    participant AutoReg as autoRegisterForwardedChatIfPresent()
    participant Store as StateStores

    Admin->>MessageHandler: Send message (may be forwarded)
    MessageHandler->>Extractor: extractForwardedChat(msg)
    Extractor-->>MessageHandler: forwardedChat metadata
    MessageHandler->>AutoReg: autoRegisterForwardedChatIfPresent(ctx, user)
    AutoReg->>Store: update approvedGroupsStore / tipsStore.targetGroup / broadcastConfigStore
    Store-->>AutoReg: persist confirmation
    AutoReg-->>MessageHandler: registration result
    MessageHandler-->>Admin: confirm content-drop target registered
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐰 In burrows of code I hop and test,
Built panels where the bugs can rest,
Forwarded friends now find a nest,
Keys and toggles pass the quest,
A tiny rabbit sings: well-done, progress! ✨

✨ 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:L This PR changes 100-499 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant