SF

AI StateFlow

Admin Studio

Menu

Knowledge

Project Memory

Persistent notes Claude keeps about this project. Stored locally in /home/ubuntu/gametext/.claude/memory

Memory Files

10

Index

MEMORY.md

Total Size

19.3 KB

Index — MEMORY.md

- [Database is PostgreSQL](database-is-postgres.md) — gamebot app was migrated from MongoDB to Postgres; how to run it.
- [v2 FSM engine](v2-fsm-engine.md) — conversation logic rewritten as data-driven FSM under src/domain/ (old messageProcessor/rules.json unused).
- [Memory location & dashboard](memory-location-and-dashboard.md) — auto-memory stored project-local (.claude/memory) and viewable at /admin/memory.
- [Data editor dashboard](data-editor-dashboard.md) — /admin/data tab views & edits live Postgres rows (deposits/users/etc) via /api/data.
- [Human Task & Payments](human-task-and-payments.md) — game pick & payments are human-gated (/admin/human-task); payment methods editable (/admin/payments).
- [Logic editor & knowledge](logic-editor-and-knowledge.md) — messages/keywords editable at /admin/logic; intents+cashout expanded from 5k real chats; legacy rules/prompt removed.
- [Flow Builder](flow-builder.md) — flow is now a declarative state machine editable from a drag-and-drop flowchart at /admin/flow; conditions are serializable JSON.
- [Overrides shadow code](overrides-shadow-code.md) — DB overrides (flow_definition/response_overrides) win over code; clear them in app_settings if a code change to flow/messages doesn't appear.
md

data-editor-dashboard.md

1.3 KB · updated 6/13/2026, 11:18:42 PM
---
name: data-editor-dashboard
description: The admin dashboard has a "Data" tab to view AND edit live Postgres rows (esp. deposits/payments).
metadata:
  type: project
---

The user needed to view/edit Postgres data live from the UI because payment data changes constantly (stale views are useless).

**Data tab:** nav → `GET /admin/data?table=<key>` (`dataController.renderData`, view `view/data.ejs`). Tabs for whitelisted tables: deposits, user_states, game_accounts, games (editable) + messages (read-only). Always fresh — `Cache-Control: no-store`, reads straight from DB (not via gameService cache).

**Editing:** inline inputs per editable column; Save → `POST /api/data/:table/:id` `{updates:{...}}`; Delete → `DELETE /api/data/:table/:id`. Endpoints live under `/api` (not `/admin`) so the errorHandler returns JSON, not an HTML error page.

**Safety (`src/modules/data/data.service.js`):** a `TABLES` whitelist defines per-table idColumn/idType/orderBy and per-column {type, editable, options}. Only whitelisted column names are interpolated into SQL; values are parameterized; types coerced (number/boolean/json/text); JSON validated before save; read-only tables and unknown tables rejected with AppError.

See also [[v2-fsm-engine]], [[memory-location-and-dashboard]].
md

database-is-postgres.md

1.7 KB · updated 6/13/2026, 11:18:42 PM
---
name: database-is-postgres
description: "This project (gamebot/stateflow-engine2) uses PostgreSQL, not MongoDB — user requested the switch."
metadata: 
  node_type: memory
  type: project
  originSessionId: e817bff4-cb97-429e-a96e-737070c537f0
---

The user asked to migrate this Express "gamebot" app from MongoDB/Mongoose to PostgreSQL.

**Why:** User preference ("instead of mongodb use postgres"). PostgreSQL 16 is installed and running locally as Windows service `postgresql-x64-16` (user `postgres`, password `postgres`, port 5432). MongoDB was not installed.

**How to apply:**
- DB access goes through `src/config/db.js` (a `pg` Pool exposing `query`, `getPool`, `disconnect`; `connectDB` default export auto-creates the `gamebot` DB + tables on boot).
- Tables: `user_states`, `rules`, `system_prompts` (states/payload are JSONB; per-key state merge done via `states || $patch::jsonb`).
- The Mongoose models `rule.model.js` / `prompt.model.js` were deleted; `user.model.js` is now just a `mapUserRow` row mapper.
- Config via `.env` (PGHOST/PGPORT/PGUSER/PGPASSWORD/PGDATABASE or DATABASE_URL). `PORT=3005` because 3000 was taken by another app.
- Seed with `npm run seed`; start with `npm start` / `npm run dev`.
- AI bot is **Claude Code Router (CCR)**, NOT Ollama (user switched it). `src/aiService.js` POSTs to CCR's Anthropic-compatible endpoint `http://127.0.0.1:3456/v1/messages` (env `CCR_URL`/`CCR_MODEL`/`CCR_MAX_TOKENS`). CCR is managed by a separate dashboard project at `D:\2026\Ai\Claudeui` (UI on http://localhost:5174, edits `~/.claude-code-router/config.json`). Default route/model: `openrouter,openai/gpt-oss-120b:free`. App boots without CCR; `/api/message` uses it, `/api/bot` is rules-only. Check with `ccr status`.
md

everything-in-flowchart.md

1.4 KB · updated 6/13/2026, 11:18:42 PM
---
name: everything-in-flowchart
description: "STANDING INSTRUCTION — every bot process/feature must be represented in the Flow page flowchart (nodes + edges), not only in code. Always wire new flows as editable edges."
metadata: 
  node_type: memory
  type: feedback
  originSessionId: 520c0af0-e263-43ae-b35b-5433c05bc5e7
---

The user repeatedly insists: **every process must also be connected to the flowchart.** When adding ANY new conversation behavior (cashout, payments, follow-ups, new client paths, etc.), it must show up on the `/admin/flow` drag-and-drop flowchart as real nodes/edges and in the Logic message tabs — never code-only.

**Why:** the user manages and understands the whole system through the visual flowchart + logic tabs; logic that isn't visible there is invisible to them.

**How to apply:** for each new feature — (1) add any new stages as nodes in `DEFAULT_NODES` (with x/y so they're visible), (2) express the decision logic as `edges` with clear labels in `DEFAULT_FLOW`, (3) add the messages to `responses.js` and the right client-type group in `STEP_CATEGORIES` so they appear as editable textboxes. Mechanical/handler-only steps (e.g. human approvals) should still have their messages in the Logic tabs. After building, clear stale `flow_definition`/`response_overrides` so the new code shows (see [[overrides-shadow-code]]). See also [[flow-builder]].
md

flow-builder.md

3.0 KB · updated 6/13/2026, 11:18:42 PM
---
name: flow-builder
description: "The bot flow is a declarative state machine (nodes+edges) editable from a drag-and-drop flowchart at /admin/flow; conditions are serializable JSON, not JS closures."
metadata: 
  node_type: memory
  type: project
  originSessionId: 520c0af0-e263-43ae-b35b-5433c05bc5e7
---

The conversation flow was converted from JS-closure guards into a **declarative, serializable state machine** so it can be edited live from a drag-and-drop flowchart.

**Pieces:**
- `src/domain/conditions.js` — safe (no-`eval`) condition evaluator. `FACTS` whitelist (each `{key,label,type,values}`), `OPS`, `evalCondition(cond,ctx)`, `sanitizeCondition`. Conditions are JSON: leaf `{fact,op,value}` combined with `all`/`any`/`not`. Derived `choice` fact encapsulates the old `choseFreePlay`/`choseDeposit` regex helpers.
- `src/domain/flow.js` — rewritten as `DEFAULT_FLOW = {version, nodes, edges}`. **Nodes = stages, edges = transition rules** (`from` stage or `"*"` global; `to` stage or null=stay; `priority`; `when:{intent,cond}`; `set`; `action`; `step`; `silent`; `aiRephrase`; `followup`). `matchTransition(ctx)` filters candidates (`from===stage || "*"`), sorts by priority, first match wins — **byte-for-byte parity with the old TRANSITIONS table** (every old row ported 1:1, priority=original index; verified by a 16-case parity test). `applyFlowOverride`/`activeFlow`/`definition`.
- DB override `flow_definition` in `app_settings` (via `settings.service.getFlowDefinition/saveFlowDefinition`) wins over code defaults — same pattern as response/keyword overrides; `engine.process()` applies it before classify (cached 15s).
- UI: **`/admin/flow`** (`adminController.renderFlow/saveFlow/resetFlow`, view `flow-builder.ejs`) — Drawflow canvas (vendored at `public/vendor/drawflow.*`, served by `express.static`). Boxes=stages (draggable, positions saved), red "★ Any state" box = global edges. Side panel = guided editor (trigger/conditions/outcome/message/follow-up). Saves nodes+edges to `POST /api/flow` (server-side whitelist validation) and message text via the existing `/api/logic/responses`. `POST /api/flow/reset` clears the override.

**Follow-ups:** edges can carry `{delaySeconds, step}`. `engine.finalize` inserts a `flow_followups` row (auto-migrated table); a new inbound cancels pending rows. `followup.worker.js` (started in `app.js`, 30s `setInterval`) renders+logs due rows; `GET /api/followups/due` lets the chat integration actually deliver them (the server has no outbound push channel of its own).

**One-time policies:** state flags `welcome_sent` (set by welcome edges, guards them) and `free_play_used` (set in `approveTasks`, guards free-task edges) enforce "welcome once / free task once / no re-onboarding for returning paid clients".

Stripe = the existing "Card" method (`T_DEP_CARD` → `DEPOSIT_CARD`). Added `SIGNUP_BONUS` response step.

The old read-only Flow tab in `/admin/logic` was removed (it now links to `/admin/flow`). See also [[v2-fsm-engine]], [[logic-editor-and-knowledge]].
md

human-task-and-payments.md

3.3 KB · updated 6/13/2026, 11:18:42 PM
---
name: human-task-and-payments
description: Game pick & payments are manual human-gated; Human Task tab confirms them; payment methods are editable in a Payments tab.
metadata:
  type: project
---

Per user request, account creation is no longer automatic and payment methods are UI-managed.

**Account gate:** picking a game (intent GAME_PICK) NO LONGER auto-creates credentials. Transition `T_GAME_PICK` → stage `ACCOUNT_REVIEW`, sets `account_pending_review`, sends a holding message (`ACCOUNT_REQUEST_RECEIVED`). While in ACCOUNT_REVIEW the bot HOLDS (`T_STATUS_ACCOUNT`) — no progression until a human approves.

**Human Task tab:** `/admin/human-task` (`renderHumanTask`, view `human-task.ejs`) lists users with `account_pending_review` / `tasks_pending_review` / `payment_pending_review` (from `userService.getPendingReviews()`). Each card has Game + Username + Password + Score fields → **Approve & Send** or **Reject**.

**Unified approval:** `POST /api/admin/state {action:"approve", username, password, score, gameKey}` → `engine.approveHumanTask()`. If username given → creates account (with those exact creds via `accountService.getOrCreateAccount` override) and sends login details. If score given (or payment pending) → credits deposit (deposit_count++) and sends scores message. Both can fire in one submit (so payment approval can also send user/pass). `approveTasks` (free-play) and `rejectReview` are separate.

**Payment methods:** stored in `app_settings` (key `payment_methods`) via `settings.service.js`; editable at `/admin/payments` (view `payments.ejs`, save `POST /api/payments`). Four methods: cashapp(link), chime(tag), card(info), btc(address), each with enabled toggle. Classifier detects all four; flow has `T_DEP_CASHAPP/CHIME/CARD/BTC`; responses fill `{{cashapp_link}}/{{chime_tag}}/{{card_info}}/{{btc_address}}/{{methods}}` from the live settings (engine injects `renderCtx.payment`).

**Pause while pending (silent):** while a user is in a *_REVIEW stage the bot acknowledges ONCE, then sends NOTHING on further messages until a human approves. Implemented via `silent: true` on transitions T_STATUS_PAY/TASK/ACCOUNT; engine returns `{silent:true, message:null}` (messageController returns `silent:true, message:null` so the integration sends nothing). Controlled by `settings.getBehavior().pauseWhilePending` (default true), toggled from a switch on the Human Task page (`POST /api/behavior`). After approval the message IS sent.

**Human Task sub-tabs:** the page has two client-side tabs — "Pending" (the approval queue) and "All Users & Payments" (`userService.getAllWithPayments` → every user joined with their `deposits` ledger). In the All tab each user's fields (name/stage/deposit_count/total) and each payment row (amount/method/status/score) are inline-editable and Save via the existing `POST /api/data/<table>/<id>` endpoint.

**Resend & tester live view:** after approve, the Human Task card shows the sent message(s) in editable boxes with a Resend button → `POST /api/admin/send {userId,text}` (logs an outgoing MANUAL message). The Tester page (`view/tester.ejs`) renders the whole thread from `GET /api/users/:id/messages` and polls every 3s, so agent sends/resends appear there without a reload.

See also [[v2-fsm-engine]], [[data-editor-dashboard]].
md

logic-editor-and-knowledge.md

2.4 KB · updated 6/13/2026, 11:18:42 PM
---
name: logic-editor-and-knowledge
description: "Bot messages & keywords are editable from a web \"Logic\" tab (DB overrides); intents/flow expanded from 5k real conversations."
metadata: 
  node_type: memory
  type: project
  originSessionId: 520c0af0-e263-43ae-b35b-5433c05bc5e7
---

**Logic tab** (`/admin/logic`, `adminController.renderLogic`, view `logic.ejs`) — three sub-tabs:
- **Messages**: edit `responses.js` STEP variations live. Saved to `app_settings` key `response_overrides` via `POST /api/logic/responses`. `responses.applyOverrides()` makes DB overrides win over code defaults (variations separated by a line `---`).
- **Keywords**: edit `classifier.js` keyword groups live. Saved to key `keyword_overrides` via `POST /api/logic/keywords`. `classifier.applyKeywordOverrides()` replaces a group when provided. Groups: cashapp/chime/card/btc/deposit/freePlay/proof/login/cashout/missing/status/gamesList/bonus/account/smalltalk.
- **Flow**: the old read-only table was removed — the flow is now fully editable at `/admin/flow` (see [[flow-builder]]); the Logic page links out to it.

`engine.process()` loads both overrides (cached 15s in settings.service) and applies them before classify/render, so edits take effect within seconds. Empty overrides `{}` = restore defaults.

**Knowledge from the 5,131-conversation export** (`Messagefolder/1/...`) folded in:
- New intents: BONUS (offer inquiry), MISSING ("didn't get my scores/where's my money"), ACCOUNT (asking for account w/o naming a game → shows game list). Big keyword expansion with real phrasings (load/redeem/cash tag/etc).
- Payment methods now: Cash App, Chime, Card (→ easygamecredits link, covers Apple Pay/Venmo/PayPal/Google Pay), Crypto. Editable in Payments tab.
- **Cashout/redeem is human-gated**: intent CASHOUT → `CASHOUT_DETAILS` (ask Chime tag/game id/amount, $25–$300) → stage `CASHOUT_REVIEW` + `cashout_pending_review` → appears in Human Task ("💸 Cashout") → agent approves with amount → `CASHOUT_PAID`. `approveHumanTask` handles account creds, payment score credit, AND cashout payout (the "Score/Cashout $" field) in one submit.

**Cleanup done earlier**: legacy Rules Lab + System Prompt pages/routes removed; `messageProcessor.js`, `rule.service.js`, `prompt.service.js`, `systemPrompt.js` deleted; `rules` + `system_prompts` tables dropped. `aiService` now only exports `rephrase`.

See also [[v2-fsm-engine]], [[human-task-and-payments]].
md

memory-location-and-dashboard.md

1.1 KB · updated 6/13/2026, 11:18:42 PM
---
name: memory-location-and-dashboard
description: Claude auto-memory for this project is stored project-locally and is viewable in the admin dashboard.
metadata:
  type: project
---

The user wanted Claude's auto-memory kept inside the project (not the global `~/.claude/projects/...`) and viewable from the app dashboard.

**Storage:** `autoMemoryDirectory` is set to `D:/2026/Ai/stateflow-engine2/stateflow-engine2/.claude/memory` in `.claude/settings.local.json` (NOT in `.claude/settings.json` — that key is ignored from the checked-in project settings for security; it must live in user settings or settings.local.json). Memory `*.md` files + `MEMORY.md` index live there.

**Dashboard view:** A "Memory" tab in the admin nav → `GET /admin/memory` (`adminController.renderMemory`, view `view/memory.ejs`) reads and displays every `.md` file from that directory (read-only). Constant `MEMORY_DIR = path.join(rootDir, ".claude", "memory")`.

Note: the old global memory copy at `~/.claude/projects/D--2026-.../memory/` is now stale; the project-local dir is canonical.

See also [[v2-fsm-engine]], [[database-is-postgres]].
md

overrides-shadow-code.md

1.8 KB · updated 6/13/2026, 11:18:42 PM
---
name: overrides-shadow-code
description: "DB overrides (flow_definition, response_overrides, keyword_overrides) WIN over code defaults — if a code change to flow.js/responses.js/classifier.js doesn't show up, a stale saved snapshot in app_settings is the cause."
metadata: 
  node_type: memory
  type: project
  originSessionId: 520c0af0-e263-43ae-b35b-5433c05bc5e7
---

The bot has a layered config: code defaults in `src/domain/{flow,responses,classifier}.js`, overridden by rows in the `app_settings` table (`flow_definition`, `response_overrides`, `keyword_overrides`). **The DB override always wins** (`applyFlowOverride`/`applyOverrides`/`applyKeywordOverrides` run in `engine.process()` each message).

**The trap:** clicking **Save Flow** (Flow page) or **Save Messages** (Logic page) persists a *full snapshot* of the current state into `app_settings`. After that, any later change made in CODE is invisible — the frozen snapshot shadows it. This caused repeated "my edit isn't showing" confusion.

**When a code change to flow/messages doesn't appear at runtime, check + clear the override:**
```js
// inspect
SELECT key, jsonb_typeof(value) FROM app_settings WHERE key IN ('flow_definition','response_overrides','keyword_overrides');
// clear (code defaults take over)
DELETE FROM app_settings WHERE key='flow_definition';
DELETE FROM app_settings WHERE key='response_overrides';
```
Overrides are cached ~15s (`settings.service`), so wait/restart after clearing.

**Mitigation added:** `saveLogicResponses` now drops any message equal to its code default, so saving messages only persists genuine edits (no more freezing every message). The flow save has no such guard yet — the whole flow is the override — so clearing `flow_definition` is the way to re-sync to code during active code-side development.

See also [[flow-builder]].
md

user-prefers-simple-direct.md

0.9 KB · updated 6/13/2026, 11:18:42 PM
---
name: user-prefers-simple-direct
description: "User wants simple, easy-to-manage non-technical UIs and prefers I act directly rather than ask multiple-choice clarifying questions."
metadata: 
  node_type: memory
  type: feedback
  originSessionId: 520c0af0-e263-43ae-b35b-5433c05bc5e7
---

The user rejected an AskUserQuestion menu and said "need this flow very easy to manage. write easy my flowchart view" — i.e. just build the simpler thing.

**Why:** They are non-technical (communicates in mixed Bengali/English, thinks in flowchart terms) and value ease-of-use and momentum over being presented options.

**How to apply:** For this user, when intent is reasonably clear, implement the simplest, most manageable version directly instead of asking clarifying questions. Favor plain-language labels, fit-everything-in-view, minimal clicks, and hide advanced/technical fields. Reserve questions for genuinely irreversible or high-ambiguity decisions.
md

v2-fsm-engine.md

2.4 KB · updated 6/13/2026, 11:18:42 PM
---
name: v2-fsm-engine
description: The conversation engine was rewritten as a data-driven FSM under src/domain/ (replaces the old hardcoded messageProcessor logic).
metadata: 
  node_type: memory
  type: project
  originSessionId: e817bff4-cb97-429e-a96e-737070c537f0
---

The gamebot conversation logic was re-architected (user said "tume sob kore daw") into a clean, data-driven engine under `src/domain/`. The OLD `src/messageProcessor.js` + `rules.json` (hardcoded `if (ruleId===...)` branches + ~10 overlapping booleans) is **no longer used by the API**.

**New pieces:**
- `domain/flow.js` — explicit `STAGES` enum (NEW→WELCOMED→FREEPLAY_TASKS→TASKS_REVIEW→GAME_SELECT→ACCOUNT_READY→DEPOSIT_INFO→PAYMENT_REVIEW→ACTIVE). **UPDATE:** the ordered `TRANSITIONS` table was converted into a declarative `nodes+edges` state machine with serializable JSON conditions, now editable from a drag-and-drop flowchart at `/admin/flow` — see [[flow-builder]]. Code defaults still live here.
- `domain/classifier.js` — local-first intent+entity detection (game/method/amount/media), multilingual-ish; AI hints optional.
- `domain/responses.js` — variation bank per step with `{{slots}}` + **anti-repeat** (avoids recently-sent texts). Slots filled from DB/businessConfig, NEVER from AI.
- `domain/engine.js` — `process(msg,userId,opts)` ties it together; plus manual-review handlers `approveTasks/approvePayment/approveFreePlay/rejectReview`.
- `domain/businessConfig.js` — real facts: CASHAPP_LINK, CHIME_TAG (`$Denise-Ray-31`), bonus tiers, cashout limits, GAMES catalog.

**New tables** (auto-migrated in `config/db.js` initSchema): `games`, `game_accounts` (auto username like `April100vb`), `deposits` (ledger → drives `user_states.deposit_count`/`total_deposit_amount`), `messages` (full history). `user_states` extended with `stage`, `current_game`, counters, `display_name`.

**AI usage:** `aiService.rephrase()` (CCR) humanizes ONLY smalltalk/fallback steps (transitions with `aiRephrase:true`) — never touches links/credentials/amounts. `/api/message` = AI path, `/api/bot` = deterministic rules-only.

**Admin approval:** `POST /api/admin/state` with `{userId, action:"approve_tasks|approve_payment|approve_freeplay|reject", score, amount}` → engine advances stage + sends resume message.

Design doc: `docs/requirements-draft.md`. Note: the old admin "Rules" page edits `rules.json` which no longer drives behavior (future cleanup).