Review: T5: data-driven page.server.ts + merge logic

review-776-2026-04-03 Doc

review ready

Verdict: READY

Template Completeness

  • [x] Type — Feature
  • [x] Lineage — sub-ticket of westside-contracts#34, wave 2
  • [x] Repo — forgejo_admin/westside-contracts
  • [x] User Story — clear "contract page loads structured config and merges team defaults with player overrides"
  • [x] Context — thorough, includes all 7 merge rules
  • [x] File Targets — 2 modify targets + explicit exclusion list
  • [x] Acceptance Criteria — 8 testable criteria
  • [x] Test Expectations — 5 unit tests + run command
  • [x] Constraints — pure function extraction, backwards compat, type alignment
  • [x] Checklist — present
  • [x] Related — parent issue + basketball-api dependencies listed

Traceability

  • [x] story:WS-S23 — "As an admin, I want to configure custom contract terms per player (different fee, tournaments, practice schedule) so that custom deals render correctly without code changes"
  • [x] story note verified — found in project-westside-basketball user-stories section under Admin (Marcus)
  • [x] arch:contracts — contracts architecture component
  • [x] arch note verified — arch-contracts-westside-basketball exists in pal-e-docs (has Config Merge Logic, Custom Deals, Data Model, Contract Variants sections)
  • [x] Forgejo issue — westside-contracts#36, open

File Targets

  • [x] src/routes/contract/[token]/+page.server.ts — verified: exists (47 lines), currently does simple JOIN query with isLocal/isGirls derivation from team_name. No contract_config or contract_overrides columns yet. Ticket accurately describes current state.
  • [x] src/lib/types.ts — verified: exists (27 lines), has Player and SignRequest interfaces. No ContractConfig types yet. Ticket correctly identifies this as target for new interfaces.
  • [x] src/lib/contract-config.ts — does not exist yet (new file per Constraints section for pure merge function). Parent directory src/lib/ exists. Correct create target.

Repo Placement

OK. Issue filed on westside-contracts, all file targets are in westside-contracts. The basketball-api migration dependencies (#319, #321) are correctly filed as separate issues on that repo. No cross-repo work in this ticket.

Dependencies

  • [x] basketball-api #319 (contract_config JSONB on teams) — board item #772, currently in qa. Must be merged and migration applied before this ticket's SQL can reference the column. Pending.
  • [x] basketball-api #321 (contract_overrides JSONB on players) — board item #773, currently in qa. Same dependency. Pending.
  • [x] #774 (T3: seed team configs + audit player overrides) — wave 2 peer, in backlog. Provides test data but not a code dependency.
  • [x] #775 (T4: extract Svelte components) — wave 1, in qa. Not a direct dependency (this ticket is server-side only).
Wave 1 dependencies (#772, #773) are in qa — not yet merged. Execution should wait until both migrations land, but the ticket scope itself is correct and reviewable now.

Acceptance Criteria

All 8 criteria are verifiable by an agent:
  • SQL column presence — grep-checkable after implementation
  • Merge function behavior (5 criteria) — unit-testable via the 5 specified test cases
  • NULL fallback — unit-testable
  • TypeScript check — npm run check
Run command specified: npm test && npm run check. Adequate and executable.

Blast Radius

  • isLocal/isGirls are consumed by +page.svelte (rendering) and sign/+server.ts (contract_version derivation). This ticket only changes +page.server.ts load function — the page still receives isLocal/isGirls. Additive change (new config field).
  • The sign endpoint (explicitly excluded) has its own isLocal/isGirls derivation — updating it is ticket #778 (wave 3).
  • Component wire-up to consume config instead of hardcoded HTML is ticket #777 (wave 3).
  • No blast radius concerns. Change is additive and backwards compatible.

Decomposition Assessment

Apply three-thing limit and five-minute rule:
  • File targets: 2 modify + 1 create = 3 files, 1 repo. At the limit but cohesive.
  • Acceptance criteria: 8 AC — above the 5 guideline, but 5 of them are unit test variations of the same merge function. Logically 3 discrete changes: (1) update SQL query, (2) write merge function + types, (3) wire merge into load return.
  • Estimated agent time: ~4 minutes. Query change is small, merge function is well-specified with clear rules, types follow from the merge rules.
  • Independent subtasks: No — the merge function, types, and query update are tightly coupled.
No decomposition needed.

Recommendation

No action needed. Ticket is ready for execution once wave 1 dependencies (#772, #773) clear qa.