Rework backend #1
@@ -12,3 +12,4 @@ data/*.sqlite-*
|
|||||||
server/data/*.sqlite
|
server/data/*.sqlite
|
||||||
server/data/*.sqlite-*
|
server/data/*.sqlite-*
|
||||||
/data
|
/data
|
||||||
|
/scratch
|
||||||
|
|||||||
+31
-18
@@ -24,10 +24,13 @@ TTRPG Initiative Tracker — fork with self-hosted backend. Monorepo via npm wor
|
|||||||
shared/ # Pure logic, no I/O (client + server + tests import)
|
shared/ # Pure logic, no I/O (client + server + tests import)
|
||||||
turn.js # turn-order state machine
|
turn.js # turn-order state machine
|
||||||
tests/ # turn logic tests
|
tests/ # turn logic tests
|
||||||
scripts/ # manual demo/audit tools (NOT unit tests)
|
scripts/ # manual demo tool (NOT test)
|
||||||
replay-combat.js # live backend demo
|
replay-combat.js # live backend demo
|
||||||
audit-rotation.js # exploratory rotation bug-finder
|
tests/
|
||||||
audit-state.js # exploratory invariant bug-finder (9 classes)
|
audit/ # exploratory bug-finders (manual, Math.random)
|
||||||
|
audit-rotation.js # rotation invariant
|
||||||
|
audit-state.js # 9 invariant classes
|
||||||
|
scratch/ # gitignored: throwaway repro/exploration
|
||||||
docs/
|
docs/
|
||||||
REWORK_PLAN.md
|
REWORK_PLAN.md
|
||||||
DEVELOPMENT.md # this file
|
DEVELOPMENT.md # this file
|
||||||
@@ -119,33 +122,38 @@ CI=true npx react-scripts test --watchAll=false src/tests/App.characterization.t
|
|||||||
CI=true npx react-scripts test --watchAll=false --testPathIgnorePatterns="Combat.scenario"
|
CI=true npx react-scripts test --watchAll=false --testPathIgnorePatterns="Combat.scenario"
|
||||||
```
|
```
|
||||||
|
|
||||||
## Manual tools (NOT tests)
|
## Demo tool (NOT test)
|
||||||
|
|
||||||
`scripts/` = exploratory. Math.random, non-deterministic. Used to find bugs, unit tests lock them.
|
`scripts/replay-combat.js` = live backend demo. Watch UI react to state changes.
|
||||||
|
|
||||||
### replay-combat.js — live demo
|
|
||||||
|
|
||||||
Drives full combat through real backend via ws adapter (same contract as App). Player display live-updates.
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# start backend + frontend first (see Run)
|
# start backend + frontend first
|
||||||
node scripts/replay-combat.js [rounds] [delayMs]
|
node scripts/replay-combat.js [rounds] [delayMs]
|
||||||
# defaults: 100 rounds, 200ms/step
|
# defaults: 100 rounds, 200ms/step
|
||||||
```
|
```
|
||||||
|
|
||||||
Coverage per round: damage, heal, all 22 conditions, toggleActive (mark inactive/reactivate), removeParticipant, addParticipant (reinforcements), updateParticipant (edit), pause/resume, reorderParticipants, endEncounter. Revives dead each round to sustain 100 rounds.
|
Coverage per round: damage, heal, all 22 conditions, toggleActive,
|
||||||
|
removeParticipant, addParticipant (reinforcements), updateParticipant,
|
||||||
|
pause/resume, reorderParticipants, endEncounter. Revives dead each round
|
||||||
|
to sustain full round count.
|
||||||
|
|
||||||
### audit-rotation.js — rotation bug-finder
|
## Audit tools (NOT unit tests)
|
||||||
|
|
||||||
Pure turn.js simulation of replay op sequence. Detects rotation violations (skip/dupe per round). Pinpointed BUG-1 (addParticipant + pause corrupts rotation).
|
`tests/audit/` = exploratory, Math.random, non-deterministic. Manual run.
|
||||||
|
Unit tests (`{shared,server,src}/tests/`) lock known bugs deterministically.
|
||||||
|
|
||||||
|
### audit-rotation.js
|
||||||
|
|
||||||
|
Pure turn.js simulation of replay op sequence. Detects rotation violations
|
||||||
|
(skip/dupe per round). Found BUG-1 (addParticipant + pause corrupts rotation).
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
node scripts/audit-rotation.js
|
node tests/audit/audit-rotation.js
|
||||||
```
|
```
|
||||||
|
|
||||||
Bisect mode: comment/uncomment op blocks to isolate which combo triggers.
|
Bisect: comment/uncomment op blocks to isolate triggering combo.
|
||||||
|
|
||||||
### audit-state.js — expanded invariant bug-finder
|
### audit-state.js
|
||||||
|
|
||||||
Runs pure turn.js combat, audits 9 invariant classes per round:
|
Runs pure turn.js combat, audits 9 invariant classes per round:
|
||||||
|
|
||||||
@@ -160,13 +168,18 @@ Runs pure turn.js combat, audits 9 invariant classes per round:
|
|||||||
9. undo support
|
9. undo support
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
node scripts/audit-state.js [rounds]
|
node tests/audit/audit-state.js [rounds] # default 100
|
||||||
```
|
```
|
||||||
|
|
||||||
100-round run: 128 violations, all BUG-1/BUG-2 family (4 symptom faces). Clean: HP, isActive, deathSave, conditions, removal.
|
Current state (post BUG-1/2 fix): 0 violations / 100 rounds.
|
||||||
|
|
||||||
See `TODO.md` for known bugs.
|
See `TODO.md` for known bugs.
|
||||||
|
|
||||||
|
## Scratch
|
||||||
|
|
||||||
|
`scratch/` = gitignored throwaway. Repro scripts, exploration, debug.
|
||||||
|
Not committed. Use freely, delete anytime.
|
||||||
|
|
||||||
## Build
|
## Build
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
+7
-34
@@ -1,13 +1,11 @@
|
|||||||
# scripts/
|
# scripts/
|
||||||
|
|
||||||
Manual tools. NOT unit tests. Math.random, non-deterministic.
|
Manual demo tool. NOT test.
|
||||||
|
|
||||||
Used to FIND bugs. Unit tests (in `*/tests/`) LOCK them.
|
|
||||||
|
|
||||||
## replay-combat.js
|
## replay-combat.js
|
||||||
|
|
||||||
Drives full combat through live backend via ws adapter (same contract as App).
|
Live backend demo. Drives full combat via ws adapter (same contract as App).
|
||||||
Player display live-updates. Use to watch UI react to state changes.
|
Player display live-updates. Watch UI react to state changes.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# start backend + frontend first (see docs/DEVELOPMENT.md)
|
# start backend + frontend first (see docs/DEVELOPMENT.md)
|
||||||
@@ -20,33 +18,8 @@ removeParticipant, addParticipant (reinforcements), updateParticipant,
|
|||||||
pause/resume, reorderParticipants, endEncounter. Revives dead each round
|
pause/resume, reorderParticipants, endEncounter. Revives dead each round
|
||||||
to sustain full round count.
|
to sustain full round count.
|
||||||
|
|
||||||
## audit-rotation.js
|
## See also
|
||||||
|
|
||||||
Pure turn.js simulation of replay op sequence. Detects rotation violations
|
- `tests/audit/` — exploratory bug-finders (manual run, non-deterministic)
|
||||||
(skip/dupe per round). Pinpointed BUG-1 (addParticipant + pause corrupts).
|
- `{shared,server,src}/tests/` — jest unit/integration/characterization
|
||||||
|
- `scratch/` — gitignored throwaway
|
||||||
```bash
|
|
||||||
node scripts/audit-rotation.js
|
|
||||||
```
|
|
||||||
|
|
||||||
Bisect: comment/uncomment op blocks to isolate triggering combo.
|
|
||||||
|
|
||||||
## audit-state.js
|
|
||||||
|
|
||||||
Expanded invariant bug-finder. 9 check classes per round:
|
|
||||||
|
|
||||||
1. rotation integrity
|
|
||||||
2. HP bounds
|
|
||||||
3. isActive consistency
|
|
||||||
4. turnOrder no dup ids
|
|
||||||
5. turnOrder ids all active
|
|
||||||
6. currentTurn valid + active
|
|
||||||
7. deathSave range + reset on revive
|
|
||||||
8. removeParticipant orphans
|
|
||||||
9. undo support
|
|
||||||
|
|
||||||
```bash
|
|
||||||
node scripts/audit-state.js [rounds] # default 100
|
|
||||||
```
|
|
||||||
|
|
||||||
See TODO.md for bugs found.
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
// rotation breaks (skip or dupe). Prints minimal repro + preceding ops.
|
// rotation breaks (skip or dupe). Prints minimal repro + preceding ops.
|
||||||
// No backend, no WS, no sleep. Fast.
|
// No backend, no WS, no sleep. Fast.
|
||||||
|
|
||||||
const shared = require('../shared');
|
const shared = require('../../shared');
|
||||||
const {
|
const {
|
||||||
buildCharacterParticipant, buildMonsterParticipant,
|
buildCharacterParticipant, buildMonsterParticipant,
|
||||||
startEncounter, nextTurn, togglePause,
|
startEncounter, nextTurn, togglePause,
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
// Run: node scripts/audit-state.js [rounds]
|
// Run: node scripts/audit-state.js [rounds]
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
const shared = require('../shared');
|
const shared = require('../../shared');
|
||||||
const {
|
const {
|
||||||
makeParticipant, startEncounter, nextTurn, togglePause,
|
makeParticipant, startEncounter, nextTurn, togglePause,
|
||||||
addParticipant, updateParticipant, removeParticipant,
|
addParticipant, updateParticipant, removeParticipant,
|
||||||
Reference in New Issue
Block a user