feat(career): gigs backend — propose a setlist, log the completed set#954
Conversation
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (5)
📝 WalkthroughWalkthroughAdds configurable career gig proposals, completed-gig logging with encore scoring, venue selection, and recent gig history in passport responses. ChangesCareer Gigs
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant Client
participant CareerRoutes
participant MetadataDB
participant CareerState
Client->>CareerRoutes: Propose a career gig
CareerRoutes->>MetadataDB: Read genre songs and accuracy
MetadataDB-->>CareerRoutes: Return song data
CareerRoutes-->>Client: Return setlist and venue
Client->>CareerRoutes: Log completed gig
CareerRoutes->>MetadataDB: Read newest accuracy and titles
MetadataDB-->>CareerRoutes: Return song metadata
CareerRoutes->>CareerState: Store completed gig
CareerRoutes-->>Client: Return stored gig
Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
plugins/career/routes.py (1)
691-694: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueMinor: chain the original exception for clearer tracebacks.
Ruff (B904) flags the bare
raiseinside theexceptclause.♻️ Proposed fix
try: size = int((body or {}).get("size") or 4) - except (TypeError, ValueError): - raise HTTPException(400, "size must be a number.") + except (TypeError, ValueError) as err: + raise HTTPException(400, "size must be a number.") from err🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@plugins/career/routes.py` around lines 691 - 694, Update the exception handling around the size parsing in the route to explicitly chain the caught TypeError or ValueError when raising HTTPException, preserving the existing status code and message while satisfying Ruff B904.Source: Linters/SAST tools
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@plugins/career/routes.py`:
- Around line 696-722: Fix the surplus-qualifying backfill in the gig song
selection flow by tracking the number of qualifying songs initially added,
rather than using len(picks) after rest songs may have been appended. Update the
logic around _played_by_instrument_genre and qualifying so it iterates only over
unused qualifying entries, preserving the existing size limit and fallback
behavior.
---
Nitpick comments:
In `@plugins/career/routes.py`:
- Around line 691-694: Update the exception handling around the size parsing in
the route to explicitly chain the caught TypeError or ValueError when raising
HTTPException, preserving the existing status code and message while satisfying
Ruff B904.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: eb48f0ad-e2c2-4303-a8dd-5309b47b3afe
📒 Files selected for processing (5)
CHANGELOG.mdplugins/career/passports.jsonplugins/career/routes.pytests/plugins/career/conftest.pytests/plugins/career/test_passports.py
CodeRabbit on #954: after the stakes loop appends near-bar songs, qualifying[len(picks):] overshoots and skips eligible qualifying songs — a stocked passport could still get a short set. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Career v3, WS3 (backend half). A gig is career's verb:
- POST /gigs/propose {instrument, genre, size}: setlist from the
passport's own stubs — qualifying songs (per the genre's badge bar,
family-aware) shuffled for a free re-roll, topped with the
highest-accuracy near-bar songs as stakes, and filled from UNPLAYED
genre songs when the passport is young (the first gig is how stubs
start). Names the highest venue the current stars can book.
- POST /gigs: logs a COMPLETED set only (abandoned sets never log — no
fail state). Per-song accuracy = MAX(last_accuracy) from song_stats,
freshly written by the set's own plays; encore = avg ≥ the data-driven
bar (passports.json gig.encore_accuracy, 0.75). Appends to the career
state file (same atomic _save_json pattern).
- Passports view: per-passport gigs (newest first, capped 20) and
per-instrument gig_count — the profile wall's gig line lights up.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
CodeRabbit on #954: after the stakes loop appends near-bar songs, qualifying[len(picks):] overshoots and skips eligible qualifying songs — a stocked passport could still get a short set. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
34447de to
72212e7
Compare
Career v3, workstream 3 (backend half). A gig is career's verb:
POST /gigs/propose— setlist from the passport's stubs: qualifying songs (family-aware badge bar) shuffled per call (free re-roll), topped with the highest-accuracy near-bar songs as stakes, surplus-qualifying backfill so a mature passport always fills the bill, and unplayed genre songs for a young passport (the first gig is how stubs start). Names the highest venue the current stars can book.POST /gigs— logs a completed set only (abandoned sets never log — no fail state). Per-song accuracy reads the newestsong_statsrow (the set's own play — aMAX(last_accuracy)would happily log a stale higher score from another instrument's old session); encore requires the whole set scored at the data-driven bar (one scored song must not earn an encore for a set that was 4/5 unheard). Log capped at 500 entries.gig_count(lights up the profile wall's line).passports.jsongig block falls back instead of 500ing; a legitimatestakes_songs: 0is respected.Review notes
Internal review pass (Codex quota-locked) caught: cross-arrangement stale accuracy, the partial-scoring encore vector, surplus-qualifying starvation, config 500s on junk, and the unbounded log — all fixed with regression tests.
Testing
34 career pytest green (propose mix/stakes/backfill/young-passport, newest-row accuracy, full-set encore rule, validation, no-fail-state).
🤖 Generated with Claude Code
Summary by CodeRabbit
POST /api/plugins/career/gigs/propose, using current career progression and instrument/genre matching.POST /api/plugins/career/gigs, including persisted gig history and computed encore status.