docs(01-07): complete Player Management plan

- SUMMARY.md with frontmatter, decisions, deviations, self-check
- STATE.md updated: plan 11/14, 71% progress, 5 decisions added
- ROADMAP.md updated: 10/14 summaries for phase 01
- REQUIREMENTS.md: PLYR-02, PLYR-03, PLYR-04, PLYR-05 marked complete

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Mikkel Georgsen 2026-03-01 04:37:27 +01:00
parent 8b4b131371
commit ba7bd90399
3 changed files with 169 additions and 18 deletions

View file

@ -77,10 +77,10 @@ Requirements for Phase 1 (Development Focus: Live Tournament Management). Each m
### Player Management
- [x] **PLYR-01**: Player database persistent on Leaf (LibSQL), synced to Core (PostgreSQL)
- [ ] **PLYR-02**: Search with typeahead, merge duplicates, import from CSV
- [ ] **PLYR-03**: QR code generation per player for self-check-in
- [ ] **PLYR-04**: Buy-in flow: search/select player → confirm → optional auto-seat → receipt → displays update
- [ ] **PLYR-05**: Bust-out flow: select player → select hitman → bounty transfer → auto-rank → rebalance trigger → displays update
- [x] **PLYR-02**: Search with typeahead, merge duplicates, import from CSV
- [x] **PLYR-03**: QR code generation per player for self-check-in
- [x] **PLYR-04**: Buy-in flow: search/select player → confirm → optional auto-seat → receipt → displays update
- [x] **PLYR-05**: Bust-out flow: select player → select hitman → bounty transfer → auto-rank → rebalance trigger → displays update
- [x] **PLYR-06**: Undo capability for bust-out, rebuy, add-on, buy-in with full re-ranking
- [x] **PLYR-07**: Per-player tracking: chip count, playing time, seat, moves, rebuys, add-ons, bounties, prize, points, net take, full action history
@ -350,10 +350,10 @@ Which phases cover which requirements. Updated during roadmap reorganization.
| FIN-13 | Phase 1 | Complete |
| FIN-14 | Phase 1 | Complete |
| PLYR-01 | Phase 1 | Complete |
| PLYR-02 | Phase 1 | Pending |
| PLYR-03 | Phase 1 | Pending |
| PLYR-04 | Phase 1 | Pending |
| PLYR-05 | Phase 1 | Pending |
| PLYR-02 | Phase 1 | Complete |
| PLYR-03 | Phase 1 | Complete |
| PLYR-04 | Phase 1 | Complete |
| PLYR-05 | Phase 1 | Complete |
| PLYR-06 | Phase 1 | Complete |
| PLYR-07 | Phase 1 | Complete |
| SEAT-01 | Phase 1 | Complete |

View file

@ -3,12 +3,12 @@ gsd_state_version: 1.0
milestone: v1.0
milestone_name: milestone
status: unknown
last_updated: "2026-03-01T03:03:22.000Z"
last_updated: "2026-03-01T03:35:13.000Z"
progress:
total_phases: 1
completed_phases: 0
total_plans: 14
completed_plans: 9
completed_plans: 10
---
# Project State
@ -23,27 +23,27 @@ See: .planning/PROJECT.md (updated 2026-02-28)
## Current Position
Phase: 1 of 7 (Tournament Engine)
Plan: 10 of 14 in current phase
Plan: 11 of 14 in current phase
Status: Executing Phase 1
Last activity: 2026-03-01 — Completed Plan H (Table & Seating Engine)
Last activity: 2026-03-01 — Completed Plan G (Player Management)
Progress: [██████░░░░] 64%
Progress: [███████░░░] 71%
## Performance Metrics
**Velocity:**
- Total plans completed: 9
- Total plans completed: 10
- Average duration: 8min
- Total execution time: 1.22 hours
- Total execution time: 1.33 hours
**By Phase:**
| Phase | Plans | Total | Avg/Plan |
|-------|-------|-------|----------|
| 01-tournament-engine | 9 | 73min | 8min |
| 01-tournament-engine | 10 | 80min | 8min |
**Recent Trend:**
- Last 5 plans: 01-05 (10min), 01-03 (5min), 01-13 (5min), 01-06 (9min), 01-08 (6min)
- Last 5 plans: 01-03 (5min), 01-13 (5min), 01-06 (9min), 01-08 (6min), 01-07 (7min)
- Trend: steady
*Updated after each plan completion*
@ -95,6 +95,11 @@ Recent decisions affecting current work:
- [01-08]: Stale suggestion re-validation requires fromCount - toCount >= 2 before accepting
- [01-08]: Break table is fully automatic (applies immediately, result is informational per CONTEXT.md)
- [01-08]: Blueprint routes are venue-level (not tournament-scoped); admin role required for mutations
- [01-07]: Rankings derived from bust_out_at timestamps via RecalculateAllRankings (never stored independently)
- [01-07]: FTS5 queries use quoted terms with * suffix for prefix matching
- [01-07]: CSV formula injection neutralized with tab prefix on =, +, -, @ characters
- [01-07]: Buy-in flow auto-registers player in tournament_players if not already present
- [01-07]: QR code URL format: felt://player/{uuid} for future PWA self-check-in
### Pending Todos
@ -112,5 +117,5 @@ None yet.
## Session Continuity
Last session: 2026-03-01
Stopped at: Completed 01-08-PLAN.md (Table & Seating Engine)
Stopped at: Completed 01-07-PLAN.md (Player Management)
Resume file: None

View file

@ -0,0 +1,146 @@
---
phase: 01-tournament-engine
plan: "07"
subsystem: api, database
tags: [player, fts5, qrcode, csv-import, ranking, bounty, pko, undo]
requires:
- phase: 01-tournament-engine
provides: "audit trail + undo engine (Plan C), financial engine (Plan F), seating engine (Plan H), schema with FTS5 (Plan B)"
provides:
- "PlayerService with CRUD, FTS5 typeahead search, merge, CSV import"
- "QR code generation per player (felt://player/{uuid})"
- "Tournament player operations: register, bust, undo bust"
- "RankingEngine deriving positions from bust-out order"
- "Player API routes for venue-level and tournament-scoped operations"
- "Buy-in flow: register + financial + auto-seat"
- "Bust flow: hitman + bounty + rank + balance check"
- "CSV export safety: formula injection neutralization"
affects: [09-tournament-lifecycle, 11-tournament-ui, 14-integration]
tech-stack:
added: [skip2/go-qrcode]
patterns: [derived-rankings, csv-formula-injection-safety, fts5-prefix-matching]
key-files:
created:
- internal/player/player.go
- internal/player/ranking.go
- internal/player/qrcode.go
- internal/player/export.go
- internal/server/routes/players.go
- internal/player/ranking_test.go
- internal/player/player_test.go
modified:
- go.mod
- go.sum
key-decisions:
- "Rankings derived from bust_out_at timestamps, never stored independently (Pitfall 6)"
- "RecalculateAllRankings rebuilds all bust_out_order values from timestamps for undo consistency"
- "FTS5 query terms wrapped in quotes with * suffix for prefix matching"
- "CSV formula injection neutralized with tab prefix on =, +, -, @ characters"
- "Buy-in flow auto-registers player if not yet in tournament"
- "QR code URL format: felt://player/{uuid} for future PWA self-check-in"
patterns-established:
- "Derived rankings: always compute from bust-out list, never store"
- "CSV export safety: SanitizeCSVField for any user data in CSV output"
- "Player API pattern: venue-level CRUD + tournament-scoped actions"
requirements-completed: [PLYR-02, PLYR-03, PLYR-04, PLYR-05, PLYR-06, PLYR-07]
duration: 7min
completed: 2026-03-01
---
# Plan 07: Player Management Summary
**Player CRUD with FTS5 typeahead, CSV import, QR codes, bust/undo flows with derived rankings from bust-out order**
## Performance
- **Duration:** 7 min
- **Started:** 2026-03-01T03:27:50Z
- **Completed:** 2026-03-01T03:35:13Z
- **Tasks:** 2
- **Files modified:** 9
## Accomplishments
- Full player service with CRUD, FTS5 prefix-matching search, merge, CSV import with safety limits
- QR code generation per player using skip2/go-qrcode (felt://player/{uuid})
- Tournament player operations: register, bust (with PKO bounty), undo bust with re-ranking
- RankingEngine that derives all positions from ordered bust-out list (never stored)
- Complete player API routes: venue-level CRUD + tournament-scoped actions + rankings
- CSV export formula injection neutralization (tab-prefix on =, +, -, @)
- 12 passing tests covering ranking derivation, undo re-ranking, re-entry, deals, concurrency
## Task Commits
Each task was committed atomically:
1. **Task G1: Player CRUD, search, merge, import, QR codes** - `9373628` (feat)
2. **Task G2: Ranking engine and player API routes** - `8b4b131` (feat)
## Files Created/Modified
- `internal/player/player.go` - PlayerService with CRUD, search, merge, import, bust, undo
- `internal/player/ranking.go` - RankingEngine deriving positions from bust-out order
- `internal/player/qrcode.go` - QR code generation using skip2/go-qrcode
- `internal/player/export.go` - CSV export safety: formula injection neutralization
- `internal/server/routes/players.go` - PlayerHandler with venue-level and tournament-scoped routes
- `internal/player/ranking_test.go` - 7 ranking tests (bust order, undo, re-entry, deals, concurrency)
- `internal/player/player_test.go` - 5 tests (CSV safety, import limits, UUID)
- `go.mod` - Added skip2/go-qrcode dependency
- `go.sum` - Updated checksums
## Decisions Made
- Rankings derived from bust_out_at timestamps via RecalculateAllRankings (not stored independently per Pitfall 6)
- FTS5 queries use quoted terms with * suffix for prefix matching
- CSV formula injection neutralized with tab prefix on =, +, -, @ characters
- Buy-in flow auto-registers player in tournament_players if not already present
- QR code URL format: felt://player/{uuid} for future PWA self-check-in
## Deviations from Plan
### Auto-fixed Issues
**1. [Rule 3 - Blocking] Installed skip2/go-qrcode dependency**
- **Found during:** Task G1 (QR code generation)
- **Issue:** No QR code library in go.mod
- **Fix:** Ran `go get github.com/skip2/go-qrcode`
- **Files modified:** go.mod, go.sum
- **Verification:** QR code generation compiles and encodes valid PNG
- **Committed in:** 9373628 (Task G1 commit)
**2. [Rule 3 - Blocking] Created RankingEngine in Task G1 (planned for G2)**
- **Found during:** Task G1 (UndoBust implementation)
- **Issue:** UndoBust calls RecalculateAllRankings which requires the RankingEngine
- **Fix:** Implemented RankingEngine in ranking.go as part of Task G1
- **Files modified:** internal/player/ranking.go
- **Verification:** Package compiles, tests pass
- **Committed in:** 9373628 (Task G1 commit)
---
**Total deviations:** 2 auto-fixed (2 blocking)
**Impact on plan:** Both auto-fixes necessary for compilation and correctness. No scope creep.
## Issues Encountered
None
## User Setup Required
None - no external service configuration required.
## Next Phase Readiness
- Player management API is complete and ready for tournament lifecycle integration (Plan I)
- Ranking engine provides derived rankings for the clock/tournament UI
- Buy-in and bust flows integrate with financial engine and seating engine
- CSV import and merge provide player database management for TDs
## Self-Check: PASSED
All 7 created files verified on disk. Both task commits (9373628, 8b4b131) verified in git log.
---
*Phase: 01-tournament-engine*
*Completed: 2026-03-01*