Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,3 +140,14 @@ You are the Runewager Bot Ops Commander. You manage the full lifecycle of the Ru
- Bonus state machine with transition guards is solid
- Structured JSON logging throughout
- Graceful SIGTERM/SIGINT with state persist before exit

---

## AI Coder Contract Requirements (Mandatory)

Before writing or modifying any code, the AI must always read and familiarize itself with `RUNEWAGER_FUNCTIONALITY_MAP.md`. This file is the authoritative source of truth for all bot functionality. The AI must keep this file updated with full, easy-to-understand descriptions whenever functionality is added, changed, or removed. Updating this file is a required step at the end of every coding session.

After generating or modifying any functionality, the AI must run a follow-up audit to ensure the `RUNEWAGER_FUNCTIONALITY_MAP.md` file is fully updated and accurate. No coding session is complete until the map is updated and verified.


Every coding session must end with a verification pass to detect and upgrade any missing functionality, followed by an update to RUNEWAGER_FUNCTIONALITY_MAP.md. No work is considered complete until the map is fully updated and verified.
327 changes: 327 additions & 0 deletions RUNEWAGER_FUNCTIONALITY_MAP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,327 @@
# RUNEWAGER_FUNCTIONALITY_MAP.md

_Last audited: 2026-02-26_
_Source of truth files: `index.js`, `test/*.test.js`, scripts under `scripts/`, deployment/runtime docs in repo root._

---

## 1. High‑Level Overview

Runewager is a Telegraf-based Telegram bot that provides:
- User onboarding (age gate, account/Discord guidance, username linking).
- Promo flows (DB-backed promo manager + eligibility + claim lifecycle).
- Giveaway flows (creation, join, eligibility checks, auto finalization, admin controls).
- Content Drops (scheduled/random posts to configured target chat).
- Admin operations (broadcasts, diagnostics, SSHV console, bug triage, backups).
- Runtime health and deploy tooling (`/health`, scripts, systemd template).

Navigation is driven by inline menus plus command aliases. Persistent user/admin menu headers are used in DMs for fast access.

## 2. System Architecture Summary

### Core runtime
- Single runtime app in `index.js`.
- Telegraf command handlers + callback handlers.
- Per-user mutable state stored in memory and persisted to JSON runtime snapshots.

### State/storage layers
- In-memory stores: users, giveaway state, analytics, promo manager store, content drops store, broadcast config, SSHV sessions.
- File persistence under `data/` (runtime snapshots + promo DB + optional backups).
- Periodic persistence timer + startup restore.

### Routing model
- `bot.command(...)` for slash commands.
- `bot.action(...)` for inline button callbacks (literal + regex handlers).
- `bot.on('text')` for pending “await input” state machine.

### Utility subsystems
- Eligibility checks, validation helpers, markdown escaping, analytics/event logging.
- Admin audit logging (`adminLog` and NDJSON appends).
- SSHV command execution safety checks and state restoration.

## 3. Global Bot Behaviors

- Unknown command handling routes to a structured error block with guidance.
- `requireAdmin(ctx)` enforces admin-only access without implicitly toggling admin mode.
- `sendCommandError(...)` standardizes command failure messaging.
- Menus use callback “back” paths (`to_main_menu`, `open_admin_dashboard`, `pamenu_back_*`).
- Many menu-style responses use `replaceCallbackPanel(...)` to avoid stale stacked cards.

## 4. User Menu Tree

### Main User Menu
- Core entry via `/start`, `/menu`, or persistent header.
- Includes onboarding/account actions, promo/bonus entry points, community links, giveaways, help, settings.

### Key user branches
- **Profile & status**: `/profile`, quick status callbacks.
- **Promo**: `menu_claim_bonus` → filtered eligible promos only.
- **Giveaways**: `menu_giveaways` and `/mygiveaways` for active and personalized entries.
- **Walkthrough/help**: paginated booklet (`help_page_N`) and walkthrough steps (`walk_next/back/done`).
- **Settings**: play mode + quick commands + tooltip toggles.

### Expected input & fallback
- Non-command text when no pending state is mostly ignored except smart username detect.
- Invalid/unknown commands get standard help guidance.

## 5. Admin Menu Tree

### Persistent Admin Main Menu
- User Ops & Stats
- Giveaway Ops
- Promo Manager
- Broadcasts & Drops
- System & Health
- Tests & Bugs
- VPS Console (/sshv)
- Content Drops manager shortcut

### Admin category menus
- `admin_cat_giveaway`: start/test/status.
- `admin_cat_promo`: full promo manager actions + guide.
- `admin_cat_system`: health/version/verify/setup/backup/admin mode/testall/sshv.
- `admin_cat_tests`: bug tools + test tools + sshv shortcut.
- `admin_cat_support`: bug report management shortcuts.

### Restrictions
- All above require `requireAdmin(ctx)`.
- Many actions also require pending state sequencing and validation checks.

## 6. Button‑to‑Action Map

### Dynamic callback families (regex handlers)
- `help_page_<n>`
- `page_giveaways_<n>`
- `promo_open_<id>`, `promo_claim_<id>`
- `gw_join_<id>`, `gw_details_<id>`, `gw_elig_<id>` and giveaway admin variants
- `pamenu_gw_end_<id>`, `pamenu_gw_extend_<id>`, `pamenu_gw_cancel_<id>`, `pamenu_gw_participants_<id>`
- `tip_edit_select_<id>`, `tip_remove_<id>`, `tip_toggle_<id>`

### Representative literal callbacks
- Menu routing: `to_main_menu`, `open_admin_dashboard`, `pamenu_back_admin`, `pamenu_back_user`
- Announce builder: `announce_toggle_dm/channel/group/mode`, `announce_send_now`, `announce_edit`
- Promo manager: `admin_pm_create/edit/pause_toggle/delete/stats/preview/queue/help`
- Content drops: `tips_cmd_add/edit/remove/toggle/list/test/settings/import_batch`
- SSHV: `sshv_open`, `sshv_run_prompt`, `sshv_ctrl_c`, `sshv_ctrl_z`, `sshv_editor_save`, `sshv_editor_cancel`

## 7. Wait‑For‑Input States (with timeouts)

The bot uses `user.pendingAction.type` as its input state machine. Key families:

- **Onboarding/account**: `await_runewager_username`, `await_username_confirm`.
- **Announcements**: `await_announcement_text`, `await_announcement_action`.
- **Promo manager wizard**:
- `admin_pm_create_name` → `..._code` → `..._domain` → `..._description` → `..._image` → `..._requirement` → optional wager substeps → claim/cooldown/approval.
- **Giveaway creation/edit**: `gwiz_*`, legacy `gw_*` chains, edit/extend states.
- **Content drops**: `await_tip_add_text`, `await_tip_edit_text`, `await_tip_settings_interval`.
- **Admin utility prompts**: whois/refresh/resolve bug/bonus prompts.
- **SSHV**: `await_sshv_command`, `await_sshv_editor_content`, `await_sshv_danger_confirm`.
- **Forward registration**: `await_register_chat_forward`.

### Timeouts
- No global pendingAction auto-timeout was found for most flows.
- SSHV sessions have TTL-based GC (`SSHV_SESSION_TTL_MS`), with stale-state normalization and recovery.

## 8. Fallback Logic & Error Handling

- Permission failures: `requireAdmin` + `sendCommandError`.
- Invalid pending input: explicit prompts to retry (numeric checks, yes/no checks, IDs).
- Missing entities (promo/giveaway not found): user-visible explanatory replies.
- Announce/test flows return actionable follow-up messages.
- SSHV errors include sandbox hints for EROFS/EACCES/privilege constraints.

## 9. Onboarding Flow (full step map)

1. `/start` intro + age confirmation gate.
2. Account setup guidance (Runewager + Discord verification steps).
3. Username linking via `/link` or text detect + confirm callbacks.
4. Promo and bonus prompts depending on linked state and eligibility.
5. Community join prompts (channel/group flags).
6. Walkthrough progression tracking (`user.walkthrough`, onboarding milestones).

Recovery:
- `confirm_no_username` returns to username entry.
- `/stuck` and `/fixaccount` provide guided recovery paths.

## 10. Group Commands

Group-aware commands include giveaway interaction and linking shortcuts:
- `/giveaway` (admin wizard in group context).
- `/join` and `gw_join_<id>` for participant entry.
- `/eligible [id]` checks eligibility.
- `/link <username>` from group attempts DM handoff for confirmation.

Restrictions:
- Admin-only commands require admin identity even in groups.
- Join surface checks enforce giveaway surface constraints (group vs DM).

## 11. User Help Booklet

- Multi-page booklet with pagination callbacks.
- Covers: overview, account setup, promo/bonus usage, giveaways/community, support.
- Back/menu buttons included on each page.

## 12. Admin Help Booklet

- Admin page includes admin command references and points operators to dashboard categories.
- Bugs/tests/system-heavy workflows are now surfaced in dashboard menus (Tests & Bugs / System Tools) to reduce command overload.

## 13. Full Command Index (User + Admin)

### User-facing commands (also includes aliases)
_Note: unknown-command guard uses `REGISTERED_COMMANDS`; parity is now validated by smoke test to prevent silent command breakage._
`affiliate, bonus, bugreport, cancel, checkin, claim_history, commands, discord, discord_confirm, eligible, fixaccount, giveaway, gwhistory, health, help, join, leaderboard, leaderboard_weekly, link, linkaccount, linkrunewager, menu, mygiveaways, play, profile, promo, promocheck, referral, settings, signup, startapp, status, stuck, support, top, walkthrough`

### Admin commands
`A, a, announce, admin, admin_backup, admin_log, admin_notify, approve_group, bonusstatus, boost_referrals, boostmeter, broadcast_failed, broadcast_retry, deploy, deploy_status, exportbugs, gw_graphic, gw_pause, gw_resume, list_groups, logs, off, on, pick_winner, pmapprove, pmdeny, promo_cooldown, refreshuser, register_chat, resolvebug, scan_eligibility, setpromo, sshv, start_giveaway, testall, testgiveaway, tipadd, tipedit, tiplist, tipremove, tips, tipsettings, tiptest, tiptoggle, t, tp, unapprove_group, verify_bot_setup, version, wager30_admin, whois`

Notes:
- Several commands are dual-purpose aliases.
- Many admin buttons call the same underlying command logic.

## 14. Permissions & Access Control

- Admin identity is based on `ADMIN_IDS` env list.
- `requireAdmin(ctx)` gates command/callback execution.
- Admin mode UI toggle changes visibility of admin UI, not true authorization.
- Group approvals list controls where certain broadcast/group operations target.

## 15. State Machine & Session Logic

Primary per-user state fields:
- `pendingAction` (typed-input router)
- onboarding/walkthrough progress
- promo/giveaway participation flags
- settings (play mode, quick commands, tooltips)
- admin mode display preference

SSHV session state:
- cwd, output buffer, lock, running process refs, editor mode draft, last activity timestamps.

## 16. Timeout & Auto‑Cancel Rules

Configured/observed time behaviors:
- Smart button dedupe TTL: ~2 minutes.
- SSHV session TTL GC: 10 minutes (`SSHV_SESSION_TTL_MS`).
- Periodic persistence intervals and scheduler timers (content drops, maintenance timers).
- Giveaway timers drive auto finalization and countdown behavior.

No universal pendingAction timeout/auto-cancel was detected for all user/admin input flows.

## 17. Validation Rules (username, discord, etc.)

- Username normalization + format checks for Runewager username linking.
- Numeric validations for wager/giveaway/promo fields.
- Yes/no parsing for legacy wizard decisions.
- Promo creation expects base-domain style input for casino field.
- Forward registration validates forwarded chat presence and chat id.

## 18. Rate Limits & Cooldowns

### Verification controls
- Smoke test now enforces `REGISTERED_COMMANDS` parity with `bot.command(...)` handlers (except `start`, handled by `bot.start`).


- Promo-level cooldown and claim-limit checks in eligibility evaluation.
- Bonus request lifecycle enforces transition constraints and attempt limits.
- Smart button anti-duplicate TTL reduces repeated callback abuse.
- Broadcast failure tracking caps and log caps exist to bound memory growth.

## 19. Safety & Abuse Prevention Logic

- Admin gating via `requireAdmin` on sensitive flows.
- SSHV command blocking/confirmation for dangerous shell patterns.
- SSHV sandbox error hinting to clarify denied operations.
- Markdown escaping utilities for user/path/output interpolation.
- Command error wrappers to reduce undefined behavior on invalid usage.

## 20. Edge Cases & Special Conditions

- Empty states (no giveaways/promos/bugs) return explicit panels.
- Missing/expired SSHV editor sessions recover to command mode.
- Missing pending context for confirm callbacks returns “Nothing to confirm.”
- Group DM-handoff fallback for `/link` when private DM unavailable.
- Auto-registration accepts forwarded-origin/sender chat variants when available.

## 21. External Integrations (if any)

- Telegram Bot API via Telegraf.
- Optional Runewager-related URLs for mini app/profile/promo entry.
- Optional health HTTP/HTTPS server (TLS cert paths env-driven).
- OS/system interactions for logs/deploy/health and SSHV command execution.

## 22. Internal Utilities & Shared Modules

Repo modules:
- `index.js` main app.
- `promo-message.js` promo copy helper.
- `scripts/*.sh` deployment/runtime ops (backup, restore, smoke, rollback, diagnostics).
- `test/*.test.js` smoke/unit/runtime tests.

Key shared helper families in `index.js`:
- Markdown escape helpers.
- command error helper.
- persistence load/save utilities.
- eligibility evaluators (promo/giveaway).
- menu/panel replacement helpers.

## 23. Feature‑Level Flowcharts

### Promo claim flow
```
/promo or menu_claim_bonus
-> load active promos
-> evaluate eligibility per promo
-> eligible list shown
-> user taps promo_open_<id>
-> details + eligibility result
-> promo_claim_<id>
-> auto_approve? yes => claimed
-> no => pending_approval queue
```

### Announcement flow
```
admin_cmd_announce_start or /announce
-> await_announcement_text
-> preview + toggles (DM/Channel/Group + parse mode)
-> announce_send_now
-> sendAnnouncementTargets
-> summary result
```

### Content drop target registration
```
Admin forwards message from channel/group
-> autoRegisterForwardedChatIfPresent
-> approvedGroupsStore add(chatId)
-> tipsStore.targetGroup = chatId
-> broadcastConfigStore.targetGroup = chatId
```

### Giveaway start/join
```
Admin starts wizard (gwiz)
-> collect config steps
-> createGiveaway + announceGiveaway
-> users click gw_join_<id>
-> evaluateEligibility
-> join accepted/rejected
-> timer expires -> finalizeGiveaway
```

## 24. Future Updates Log

- 2026-02-26: Created initial comprehensive functionality map and synchronized with current menu/state architecture.
- 2026-02-26: Added explicit note that template-literal callback IDs are excluded from literal smoke checks.
- 2026-02-26: Documented Tests & Bugs admin category, promo step guide, and forwarded-chat auto-registration behavior.
- 2026-02-26: Added command-registry verification notes and synchronized missing admin commands (`/pmapprove`, `/pmdeny`, `/register_chat`, `/verify_bot_setup`) plus `/language` handler implementation.

## 25. AI Coder Contract Requirements

Mandatory rules for any AI agent touching this repo:

1. **Before writing or modifying any code, the AI must always read and familiarize itself with `RUNEWAGER_FUNCTIONALITY_MAP.md`. This file is the authoritative source of truth for all bot functionality. The AI must keep this file updated with full, easy‑to‑understand descriptions whenever functionality is added, changed, or removed. Updating this file is a required step at the end of every coding session.**

2. **After generating or modifying any functionality, the AI must run a follow-up audit to ensure the `RUNEWAGER_FUNCTIONALITY_MAP.md` file is fully updated and accurate. No coding session is complete until the map is updated and verified.**

16 changes: 10 additions & 6 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,10 @@ const REGISTERED_COMMANDS = new Set([
'wager30_admin',
'walkthrough',
'whois',
'pmapprove',
'pmdeny',
'register_chat',
'verify_bot_setup',
]);

const WAGER_BONUS_RULES_TEXT =
Expand Down Expand Up @@ -3037,6 +3041,12 @@ bot.command('settings', async (ctx) => {
await sendSettingsMenu(ctx, user);
});

bot.command('language', async (ctx) => {
const user = getUser(ctx);
const lang = user.language || (ctx.from && ctx.from.language_code) || 'unknown';
await ctx.reply(`🌐 Detected language: ${lang}`);
});

/**
* Build help booklet pages array. Pages are 1-indexed.
* Returns array of { text, buttons } objects.
Expand Down Expand Up @@ -5523,12 +5533,6 @@ bot.action('admin_cmd_verify_setup', async (ctx) => {
await ctx.reply('Use /verify_bot_setup to validate BotFather setup, permissions, and targets.');
});

bot.action('admin_cmd_verify_setup', async (ctx) => {
if (!requireAdmin(ctx)) return;
await ctx.answerCbQuery();
await ctx.reply('Use /verify_bot_setup to validate BotFather setup, permissions, and targets.');
});

bot.action('admin_backup_action', async (ctx) => {
if (!requireAdmin(ctx)) return;
await ctx.answerCbQuery('Creating backup...');
Expand Down
Loading