# Admin CLI & REPL — spotlight.cam Administrative console for maintenance tasks inside the backend container. Provides both one‑shot commands and an interactive REPL with app context. --- ## Quick Start - Development REPL: `docker compose exec backend npm run cli` - Production REPL: `docker compose exec backend-prod npm run cli` - One-shot examples: - `docker compose exec backend npm run cli -- users:list --limit 20` - `docker compose exec backend npm run cli -- events:checkin --username john_doe --slug warsaw-dance-2025` With Makefile shortcuts: - `make dev-cli` / `make prod-cli` - `make dev-up`, `make dev-down`, `make prod-up`, `make prod-down`, rebuild variants also available --- ## REPL Features - Default entry: running `npm run cli` starts a Node.js REPL with: - `prisma` client and `bcrypt` in context - Aliases: `u = prisma.user`, `e = prisma.event`, `m = prisma.match`, `ep = prisma.eventParticipant`, `r = prisma.rating` - Top‑level await: `await u.findMany({ take: 5 })` - Autocomplete (TAB) from Node REPL - Persistent history in `.repl_history` (best‑effort) - Run CLI subcommands from inside REPL: - `.cli users:list --limit 20` - `run('events:checkin --username john_doe --slug warsaw-dance-2025')` - Error handling: CLI errors (e.g., missing flags) do not exit the REPL; the error is printed and you can correct the command and retry. --- ## Commands ### Cheatsheet - `repl` - `users:list [--limit ]` - `users:create --email --username --password

[--first ] [--last ]` - `users:verify --email ` - `events:list [--limit ]` - `events:details --slug ` - `events:participants --slug [--limit ] [--csv]` - `events:import:wsdc [--dry-run] [--since YYYY-MM-DD] [--until YYYY-MM-DD] [--limit ]` - `matches:list [--limit ] [--status pending|accepted|completed]` - `events:checkin --username --slug ` - `logs:app [--lines ]` - `logs:messages [--limit ]` ### users:list - Description: List users - Options: - `--limit `: number of rows (default: 50) - Examples: - CLI: `npm run cli -- users:list --limit 20` - REPL: `.cli users:list --limit 20` ### users:create - Description: Create a user - Required: - `--email ` - `--username ` - `--password ` (hashed with bcrypt) - Optional: - `--first ` - `--last ` - Examples: - CLI: `npm run cli -- users:create --email admin@example.com --username admin --password 'Secret123!'` - REPL: `run("users:create --email a@b.c --username admin --password 'Secret123!'")` ### users:verify - Description: Mark user email as verified and clear verification fields - Required: - `--email ` - Example: `npm run cli -- users:verify --email admin@example.com` ### events:list - Description: List events - Options: - `--limit ` (default: 50) - Example: `npm run cli -- events:list --limit 10` ### events:details - Description: Show details for a specific event by slug - Required: - `--slug ` - Options: - `--participants `: number of recent participants to show (default: 10) - Output: basic fields (id, slug, name, start/end, location, worldsdcId), participantsCount, optional check-in token, relation counts, event chat room id and message count, and up to N recent participants - Examples: - `npm run cli -- events:details --slug warsaw-dance-2025` - `npm run cli -- events:details --slug warsaw-dance-2025 --participants 25` ### matches:list - Description: List matches - Options: - `--limit ` (default: 50) - `--status ` filter - Example: `npm run cli -- matches:list --status accepted --limit 20` ### events:checkin - Description: Attach user to event by username and event slug (simulate QR check-in) - Required: - `--username ` - `--slug ` - Behavior: Upserts into `event_participants` (idempotent) - Example: `npm run cli -- events:checkin --username john_doe --slug warsaw-dance-2025` ### events:participants - Description: List participants for an event by slug - Required: - `--slug ` - Options: - `--limit `: number of rows (default: 100) - `--csv`: output as CSV (stdout) - Output: eventId, slug, userId, username, email, firstName, lastName, country, city, joinedAt - Examples: - `npm run cli -- events:participants --slug warsaw-dance-2025 --limit 50` - `npm run cli -- events:participants --slug warsaw-dance-2025 --limit 200 --csv > participants.csv` ### events:import:wsdc - Description: Import events from worldsdc.com. - Sources: - `--source list`: parse Event List page (includes Event Location + Country) - `--source calendar`: parse Events Calendar page (title/start/end/url) - `--source auto` (default): try calendar first, then list if calendar parsing yields no events - Options: - `--dry-run`: show what would be created without writing to DB - `--since YYYY-MM-DD`: only events on/after date - `--until YYYY-MM-DD`: only events on/before date - `--limit `: limit considered items after filtering - `--update-missing-location`: when an event already exists and its `location` is empty/"Unknown", update it from the imported source (list recommended) - Examples: - `npm run cli -- events:import:wsdc --dry-run --since 2024-01-01 --until 2024-12-31` - `npm run cli -- events:import:wsdc --source list --limit 50` - `npm run cli -- events:import:wsdc --source list --update-missing-location` - Field mapping: `name`, `startDate`, `endDate`, `sourceUrl`, `location` (from list) or `Unknown` (from calendar). No updates to `participantsCount`. - Dedup strategy: skip when `(name, startDate)` already exists. - Alias: `events:import:worldsdc` (kept for backwards compatibility). ### logs:app - Description: Tail application log file (if configured) - Options: - `--lines ` number of lines from end (default: 200) - Env: - `LOG_FILE` — absolute/relative path inside backend container (default: `./app.log` in working dir) - Note: For container logs prefer `docker compose logs -f backend` ### logs:messages - Description: Recent chat messages from DB - Options: - `--limit ` (default: 50) - Output: message id, time, user, room (event/private), type, first 100 chars --- ## Troubleshooting - REPL not interactive: ensure TTY: `docker compose exec -it backend npm run cli` - DB access errors: verify backend container env and DB service are running - `events:checkin` says not found: confirm `username` and `slug` exist in DB - Autocomplete: works with Node REPL; press TAB after `prisma.` to see model methods --- ## Security Notes - CLI has full DB access; restrict usage to SSH + container exec - Do not expose CLI via HTTP endpoints - Consider audit logs for sensitive actions if needed --- ## Domain Notes - In spotlight.cam, `participantsCount` reflects local check‑ins (EventParticipants), not official WSDC participant metrics. - The WSDC calendar source does not provide reliable location or participant counts; importer intentionally does not set `worldsdcId` or `participantsCount`.