- 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>
146 lines
5.9 KiB
Markdown
146 lines
5.9 KiB
Markdown
---
|
|
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*
|