Rework backend #1

Merged
robert merged 86 commits from rework-backend into main 2026-07-01 19:29:34 -04:00
Showing only changes of commit 54e8df9ffa - Show all commits
+126
View File
@@ -0,0 +1,126 @@
---
name: dev-serve
description: |
Boots the TTRPG Initiative Tracker dev stack (Node backend + CRA frontend) for
hands-on human testing, then opens a headed browser window the user can see and
click. Use when user says "let me test", "open it for me", "give me a browser",
"run it locally", "boot the app", or wants to manually use the app. Handles
STORAGE mode selection (ws vs firebase), port collision cleanup, background
process management, and headed agent_browser launch in one shot.
---
# dev-serve
Run the full app stack for human testing, then open a headed browser window the
user can see and drive.
## Prerequisites
- Repo root has `server/`, `shared/`, `src/` (npm workspaces).
- Node 18+.
- Ports 4001 (backend) and 3999 (frontend) free, or let this skill kill stale procs.
## Defaults
- Backend: `DB_PATH=/tmp/tracker-dev.sqlite PORT=4001`
- Frontend: `REACT_APP_STORAGE=ws` (self-hosted backend) unless user asks for firebase.
Override: user says "firebase mode" → `REACT_APP_STORAGE=firebase` + requires
`.env.local` with `REACT_APP_FIREBASE_*`.
- Frontend port: `3999`. Backend: `4001`.
## Steps
### 1. Kill stale procs (idempotent)
```bash
pkill -f "node server/index.js" 2>/dev/null
pkill -f "react-scripts start" 2>/dev/null
sleep 2
```
Do not error if pkill finds nothing.
### 2. Boot backend (background, log to /tmp)
```bash
rm -f /tmp/tracker-dev.sqlite*
DB_PATH=/tmp/tracker-dev.sqlite PORT=4001 nohup node server/index.js > /tmp/tracker-backend.log 2>&1 &
sleep 2
curl -s http://127.0.0.1:4001/health # must return {"ok":true}
```
If health fails, tail `/tmp/tracker-backend.log`, diagnose, fix. Do not proceed.
### 3. Boot frontend (background, log to /tmp)
```bash
REACT_APP_STORAGE=ws \
REACT_APP_BACKEND_URL=http://127.0.0.1:4001 \
REACT_APP_BACKEND_WS=ws://127.0.0.1:4001/ws \
BROWSER=none PORT=3999 nohup npm start > /tmp/tracker-frontend.log 2>&1 &
```
Wait ~10s, then confirm compile:
```bash
grep -E "Compiled successfully|Failed to compile" /tmp/tracker-frontend.log | tail -1
```
`BROWSER=none` stops CRA from stealing focus; we open our own headed window.
### 4. Open headed browser window for user
Use `agent_browser` tool, fresh session (headed flag is launch-scoped):
```json
{
"agent_browser": {
"args": ["open", "http://127.0.0.1:3999", "--headed"],
"sessionMode": "fresh",
"timeoutMs": 20000
}
}
```
Then snapshot to confirm UI rendered (look for "TTRPG Initiative Tracker" heading +
"Create Campaign" button, NOT "Loading campaigns..." after 2-3s).
### 5. Tell user the URL
```
App: http://127.0.0.1:3999 (browser window open)
Backend: http://127.0.0.1:4001
Logs: /tmp/tracker-frontend.log, /tmp/tracker-backend.log
```
User can also navigate to that URL in their own browser if they closed the
agent_browser window.
## Troubleshooting
| Symptom | Cause | Fix |
|---------|-------|-----|
| "Loading campaigns..." stuck | WS subscribe silent fail | Check `/tmp/tracker-backend.log` for WS connection; check ws.js `ensureWs` uses `.onopen/.onmessage` not `.on('open')` |
| "Configuration Error" screen | firebase mode without `.env.local`, OR init not gated on STORAGE_MODE | Confirm `STORAGE=ws`; confirm `initializeStorage()` gates firebase |
| Port 4001/3999 EADDRINUSE | stale proc | Rerun step 1 |
| Campaign created but not visible | WS broadcast not wired, or path prefix not normalized | Check ws.js `norm()` strips `artifacts/.../public/data/` |
| Headed window not on screen | remote/VM/headless env | `--headed` only guarantees browser context, not OS visibility; tell user env limitation |
## Teardown
When user done testing, kill both:
```bash
pkill -f "node server/index.js"
pkill -f "react-scripts start"
```
Or leave running if user continuing dev. Ask which.
## Storage mode notes
- `ws` (default here): self-hosted backend. Cross-device via backend WS. No Firebase creds needed.
- `firebase`: original upstream. Needs `.env.local`. Behavior identical per characterization tests.
- `memory`: in-process, tests only. Resets on reload.
Switching modes mid-session: kill procs, re-export `REACT_APP_STORAGE`, reboot.