Files
spotlightcam/docs/ADMIN_CLI.md

180 lines
6.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Admin CLI & REPL — spotlight.cam
Administrative console for maintenance tasks inside the backend container. Provides both oneshot 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`
- Toplevel await: `await u.findMany({ take: 5 })`
- Autocomplete (TAB) from Node REPL
- Persistent history in `.repl_history` (besteffort)
- 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 <n>]`
- `users:create --email <e> --username <u> --password <p> [--first <f>] [--last <l>]`
- `users:verify --email <e>`
- `events:list [--limit <n>]`
- `events:details --slug <slug>`
- `events:participants --slug <slug> [--limit <n>] [--csv]`
- `events:import:wsdc [--dry-run] [--since YYYY-MM-DD] [--until YYYY-MM-DD] [--limit <n>]`
- `matches:list [--limit <n>] [--status pending|accepted|completed]`
- `events:checkin --username <u> --slug <s>`
- `logs:app [--lines <n>]`
- `logs:messages [--limit <n>]`
### users:list
- Description: List users
- Options:
- `--limit <n>`: 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 <email>`
- `--username <username>`
- `--password <password>` (hashed with bcrypt)
- Optional:
- `--first <firstName>`
- `--last <lastName>`
- 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 <email>`
- Example: `npm run cli -- users:verify --email admin@example.com`
### events:list
- Description: List events
- Options:
- `--limit <n>` (default: 50)
- Example: `npm run cli -- events:list --limit 10`
### events:details
- Description: Show details for a specific event by slug
- Required:
- `--slug <event-slug>`
- Options:
- `--participants <n>`: 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 <n>` (default: 50)
- `--status <pending|accepted|completed>` 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 <username>`
- `--slug <event-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 <event-slug>`
- Options:
- `--limit <n>`: 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 <n>`: 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 <n>` 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 <n>` (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 checkins (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`.