ci: add GitHub Actions workflow + dev docs + test:all script
- .github/workflows/ci.yml: runs shared + server tests on push/PR - docs/DEVELOPMENT.md: setup, run, test, architecture, status - package.json: test:all script (shared + server suites)
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, rework-backend]
|
||||
pull_request:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '22'
|
||||
cache: 'npm'
|
||||
- run: npm ci
|
||||
- name: shared tests
|
||||
run: npm test --workspace shared
|
||||
- name: server tests
|
||||
run: npm test --workspace server
|
||||
@@ -0,0 +1,155 @@
|
||||
# Development
|
||||
|
||||
TTRPG Initiative Tracker — fork with self-hosted backend. Monorepo via npm workspaces.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Node.js 22+
|
||||
- npm 10+
|
||||
|
||||
## Layout
|
||||
|
||||
```
|
||||
/
|
||||
package.json # workspaces root
|
||||
src/ # React frontend (CRA, existing)
|
||||
App.js # ~2935 lines, Firebase direct (M2 abstracts this)
|
||||
server/ # Backend: Express + ws + better-sqlite3
|
||||
index.js # REST + WS bootstrap
|
||||
db.js # SQLite schema, row mappers
|
||||
handlers.js # action -> shared turn fn -> tx persist -> broadcast
|
||||
server.test.js # integration tests
|
||||
shared/ # Pure logic, no I/O (client + server + tests import)
|
||||
turn.js # turn-order state machine
|
||||
turn.characterization.test.js
|
||||
docs/
|
||||
REWORK_PLAN.md # milestone plan
|
||||
DEVELOPMENT.md # this file
|
||||
```
|
||||
|
||||
## Setup
|
||||
|
||||
```bash
|
||||
git clone git@github.com:keen99/ttrpg-initiative-tracker.git
|
||||
cd ttrpg-initiative-tracker
|
||||
npm install
|
||||
```
|
||||
|
||||
## Run
|
||||
|
||||
### Frontend (dev server)
|
||||
|
||||
```bash
|
||||
npm start # http://localhost:3000
|
||||
```
|
||||
|
||||
Still uses Firebase by default. Set `REACT_APP_FIREBASE_*` in `.env.local` (copy `env.example`).
|
||||
|
||||
### Backend (dev)
|
||||
|
||||
```bash
|
||||
npm run server:dev # :4001, db: server/data/tracker.sqlite
|
||||
# or direct with env:
|
||||
DB_PATH=/tmp/tracker.sqlite PORT=4001 node server/index.js
|
||||
```
|
||||
|
||||
Smoke check:
|
||||
```bash
|
||||
curl http://127.0.0.1:4001/health # -> {"ok":true}
|
||||
```
|
||||
|
||||
Frontend not yet wired to backend — that is M2 (storage adapter + WS client).
|
||||
|
||||
## Test
|
||||
|
||||
Three commands:
|
||||
|
||||
```bash
|
||||
npm run test:all # runs shared/ + server/ suites in sequence
|
||||
npm run shared:test # turn logic only (shared/ folder)
|
||||
npm run server:test # backend REST + combat flow (server/ folder)
|
||||
```
|
||||
|
||||
What each runs:
|
||||
|
||||
| Suite | What | Count |
|
||||
|---|---|---|
|
||||
| `shared/*.test.js` | turn FSM, pure functions | 39 |
|
||||
| `server/*.test.js` | REST + combat flow, in-memory db | 7 |
|
||||
|
||||
Server tests use `--forceExit` (open WS handles). Tests spin server on random port, in-memory sqlite, tear down per test.
|
||||
|
||||
### CI
|
||||
|
||||
`.github/workflows/ci.yml` runs on push/PR to `main` + `rework-backend`:
|
||||
- `npm ci`
|
||||
- `shared` tests
|
||||
- `server` tests
|
||||
|
||||
## Build
|
||||
|
||||
```bash
|
||||
npm run build # CRA production build -> build/
|
||||
```
|
||||
|
||||
Docker build (existing, frontend-only):
|
||||
```bash
|
||||
docker build -t ttrpg-initiative-tracker .
|
||||
docker run -p 8080:80 --rm ttrpg-initiative-tracker
|
||||
```
|
||||
|
||||
Full-stack docker-compose arrives in M5.
|
||||
|
||||
## Backend architecture
|
||||
|
||||
Server-authoritative. Kills client-side last-write-wins races (root cause of skip bug).
|
||||
|
||||
```
|
||||
Client (browser) Server
|
||||
| |
|
||||
|-- POST /api/.../nextTurn ----->| action
|
||||
| | store.nextTurn():
|
||||
| | shared.nextTurn(enc) -> patch
|
||||
| | db tx: apply patch
|
||||
| | addLog
|
||||
| | broadcast(change)
|
||||
|<---- WS {change} --------------| push to all subscribers
|
||||
| |
|
||||
Display / tablet |
|
||||
|<---- WS {change} --------------| same push
|
||||
```
|
||||
|
||||
- **SQLite** owns truth. Single writer (server). WAL mode.
|
||||
- **shared/turn.js** = pure logic, ported verbatim from `App.js`. Bugs preserved for M3 characterization, fixed in M4.
|
||||
- **WS** = real-time push (replaces Firebase `onSnapshot`). Client subscribes to a key (`'campaigns'`, `'encounter:id'`, `'activeDisplay'`...), server pushes on change.
|
||||
- **Actions not results.** Client sends "do X", server computes X, persists, broadcasts. No client-side state mutation.
|
||||
|
||||
## Storage backend choice
|
||||
|
||||
Browser sandbox cannot touch filesystem. Cross-device (DM + tablet + player view) requires a real backend owning the DB file. SQLite = single file, docker volume, trivial backup. Postgres deferred until public multiuser exposure.
|
||||
|
||||
## Status
|
||||
|
||||
| Milestone | State |
|
||||
|---|---|
|
||||
| 0 repo/branch | ✅ done |
|
||||
| 1 backend + tests | ✅ done |
|
||||
| 2 frontend WS adapter | ⬜ next |
|
||||
| 3 characterization tests | ⬜ |
|
||||
| 4 skip fix + manual override | ⬜ |
|
||||
| 5 docker compose | ⬜ |
|
||||
| 6 undo rework | ⬜ |
|
||||
| 7 playwright e2e | ⬜ deferred |
|
||||
|
||||
See `docs/REWORK_PLAN.md` for full plan.
|
||||
|
||||
## Git
|
||||
|
||||
- `origin` = `github.com:keen99/ttrpg-initiative-tracker` (this fork)
|
||||
- `upstream` = `code.draft13.com/robert/ttrpg-initiative-tracker` (friend's Gitea, read-only)
|
||||
- work branch: `rework-backend` (off `main`)
|
||||
|
||||
```bash
|
||||
git fetch upstream # pull friend's changes
|
||||
git merge upstream/main # rebase our branch onto his
|
||||
```
|
||||
+2
-1
@@ -27,7 +27,8 @@
|
||||
"eject": "react-scripts eject",
|
||||
"server:dev": "npm run dev --workspace server",
|
||||
"server:test": "npm test --workspace server",
|
||||
"shared:test": "npm test --workspace shared"
|
||||
"shared:test": "npm test --workspace shared",
|
||||
"test:all": "npm run shared:test && npm run server:test"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
|
||||
Reference in New Issue
Block a user