Instruction file imported from thearnavrustagi/marketmenow (
.cursor/rules/web.mdc). Copyright stays with the author.
Web Dashboard Rules
Architecture
The web app spawns mmn CLI commands as subprocesses — it does not call the
Python pipeline directly. cli_runner.py handles subprocess execution and
progress parsing. Real-time updates flow through EventHub → WebSocket.
Adapter CLIs are mounted as hidden groups in marketmenow/cli.py
(hidden=True). They don't appear in mmn --help but remain callable by the
web frontend. New workflows (like reddit-launch) use mmn run <name> directly.
Key Modules
app.py— FastAPI app with lifespan (DB pool + queue worker), WebSocket at/ws/content/{item_id}, route registration, static/output mounts.cli_runner.py—run_cli()andrun_cli_streaming(). DefinesPLATFORM_META(JSON params) andBUILDERS(command constructors). Progress parsed via regex.queue_worker.py—run_queue_loop()background task. Polls DB queue, checks per-platform rate limits, callsrun_cli_streamingfor each job.events.py—EventHubpub/sub per content-item UUID.ProgressEventtypes:phase,progress,wait,log,stderr,done,error.db.py— asyncpg pool, all DB operations (content, queue, rate limits, post log).
Patterns
- Routes live in
routes/as separateAPIRouterinstances. - Templates are Jinja2 in
templates/. - Static assets in
static/(CSS, JS). - Generated output mounted at
/outputfromsettings.output_dir.
Adding a Platform to the Dashboard
- Add an entry to
PLATFORM_METAincli_runner.py(label, modality, params). - Write generate and publish
CommandBuilderfunctions. - Register them in the
BUILDERSdict. - No route changes needed — the generate page auto-discovers from
PLATFORM_META.
Database
PostgreSQL via asyncpg. Pool initialized in lifespan, closed on shutdown.
MMN_WEB_DATABASE_URL env var required.