feat: wire content components to render from merged contract data #37

Closed
opened 2026-04-03 23:51:40 +00:00 by forgejo_admin · 3 comments
Contributor

Type

Feature

Lineage

Sub-ticket of forgejo_admin/westside-contracts#34 — data-driven contract rendering system. Wave 3 (depends on T4 + T5). Board note: board-34-data-driven-contracts.

Repo

forgejo_admin/westside-contracts

User Story

As a parent viewing a contract, I see tournaments, practices, payments, and sections rendered from structured data so that my contract reflects my child's actual deal.

Context

After T4 (component extraction) and T5 (data-driven loading + merge), the 6 content components exist but still receive hardcoded props from three {#if} branches. This ticket collapses the three branches into ONE data-driven flow:

<!-- Before (3 branches, hardcoded): -->
{#if !isLocal && !isGirls}
  <FeeSection monthlyFee={monthlyFee} practiceDescription="..." />
  <TournamentCard name="Utah State Invitational" ... />
  <!-- 170 more lines of hardcoded props -->
{:else if isGirls}
  <!-- 180 lines -->
{:else}
  <!-- 55 lines -->
{/if}

<!-- After (1 flow, data-driven): -->
<FeeSection monthlyFee={config.monthly_fee} practiceDescription={config.practice_description} />
{#each config.tournaments as t}
  {#if t.local}<TournamentCard {...t} />{:else}<TournamentTrip {...t} />{/if}
{/each}
<PracticeSchedule practices={config.practices} />
<!-- etc -->

Fallback: if config is null (team has no contract_config), render using the old hardcoded branches. This preserves backwards compatibility during rollout.

File Targets

  • src/routes/contract/[token]/+page.svelte — replace three {#if} branches with single data-driven flow + null config fallback
  • src/lib/components/*.svelte — update component props to accept merged config data shapes (may need minor prop adjustments from T4's initial extraction)

Do NOT touch:

  • Script block state/logic (signing, effects)
  • Signing section, footer, success overlay
  • src/lib/db.ts, src/lib/minio.ts, src/lib/validation.ts
  • src/app.css

Acceptance Criteria

  • When config is present: page renders from data (one flow, no branches)
  • When config is null: page falls back to hardcoded rendering (old branches preserved)
  • TournamentCard renders local tournaments, TournamentTrip renders travel tournaments with cost tables
  • PracticeSchedule renders from config.practices array
  • PaymentSchedule renders from config.payments array
  • StaticSection shows/hides based on config.sections flags
  • Queens pink branding applies when config.variant is "girls-travel"
  • Kiana's contract: $100/month, 2 tournaments (Mesa + Nike Vegas), 1 practice, custom note
  • Kelsie's contract: $200/month, local variant, local tournament info, practice schedule
  • All standard contracts render identically to current (no regression)
  • Signing flow works end-to-end

Test Expectations

  • npm test && npm run check passes
  • Manual: compare every team variant side-by-side with current output
  • Manual: test Kiana and Kelsie contracts with overrides
  • Run command: npm test && npm run check

Constraints

  • Fallback path must preserve 100% visual parity with current hardcoded rendering
  • Components use Svelte 5 runes ($props)
  • No scoped styles — use existing app.css classes
  • The variant field drives branding (queens-active class), not team name

Checklist

  • PR opened
  • Tests pass
  • No unrelated changes
  • No visual regression for standard contracts
  • Custom contracts render correctly
  • westside-basketball — parent project
  • forgejo_admin/westside-contracts#34 — parent issue
  • Board note: board-34-data-driven-contracts
  • Depends on: westside-contracts #35 (T4), westside-contracts #36 (T5)
### Type Feature ### Lineage Sub-ticket of `forgejo_admin/westside-contracts#34` — data-driven contract rendering system. Wave 3 (depends on T4 + T5). Board note: `board-34-data-driven-contracts`. ### Repo `forgejo_admin/westside-contracts` ### User Story As a parent viewing a contract, I see tournaments, practices, payments, and sections rendered from structured data so that my contract reflects my child's actual deal. ### Context After T4 (component extraction) and T5 (data-driven loading + merge), the 6 content components exist but still receive hardcoded props from three `{#if}` branches. This ticket collapses the three branches into ONE data-driven flow: ```svelte <!-- Before (3 branches, hardcoded): --> {#if !isLocal && !isGirls} <FeeSection monthlyFee={monthlyFee} practiceDescription="..." /> <TournamentCard name="Utah State Invitational" ... /> <!-- 170 more lines of hardcoded props --> {:else if isGirls} <!-- 180 lines --> {:else} <!-- 55 lines --> {/if} <!-- After (1 flow, data-driven): --> <FeeSection monthlyFee={config.monthly_fee} practiceDescription={config.practice_description} /> {#each config.tournaments as t} {#if t.local}<TournamentCard {...t} />{:else}<TournamentTrip {...t} />{/if} {/each} <PracticeSchedule practices={config.practices} /> <!-- etc --> ``` Fallback: if `config` is null (team has no contract_config), render using the old hardcoded branches. This preserves backwards compatibility during rollout. ### File Targets - `src/routes/contract/[token]/+page.svelte` — replace three `{#if}` branches with single data-driven flow + null config fallback - `src/lib/components/*.svelte` — update component props to accept merged config data shapes (may need minor prop adjustments from T4's initial extraction) Do NOT touch: - Script block state/logic (signing, effects) - Signing section, footer, success overlay - `src/lib/db.ts`, `src/lib/minio.ts`, `src/lib/validation.ts` - `src/app.css` ### Acceptance Criteria - [ ] When config is present: page renders from data (one flow, no branches) - [ ] When config is null: page falls back to hardcoded rendering (old branches preserved) - [ ] TournamentCard renders local tournaments, TournamentTrip renders travel tournaments with cost tables - [ ] PracticeSchedule renders from config.practices array - [ ] PaymentSchedule renders from config.payments array - [ ] StaticSection shows/hides based on config.sections flags - [ ] Queens pink branding applies when config.variant is "girls-travel" - [ ] Kiana's contract: $100/month, 2 tournaments (Mesa + Nike Vegas), 1 practice, custom note - [ ] Kelsie's contract: $200/month, local variant, local tournament info, practice schedule - [ ] All standard contracts render identically to current (no regression) - [ ] Signing flow works end-to-end ### Test Expectations - [ ] `npm test && npm run check` passes - [ ] Manual: compare every team variant side-by-side with current output - [ ] Manual: test Kiana and Kelsie contracts with overrides - Run command: `npm test && npm run check` ### Constraints - Fallback path must preserve 100% visual parity with current hardcoded rendering - Components use Svelte 5 runes ($props) - No scoped styles — use existing app.css classes - The variant field drives branding (queens-active class), not team name ### Checklist - [ ] PR opened - [ ] Tests pass - [ ] No unrelated changes - [ ] No visual regression for standard contracts - [ ] Custom contracts render correctly ### Related - `westside-basketball` — parent project - `forgejo_admin/westside-contracts#34` — parent issue - Board note: `board-34-data-driven-contracts` - Depends on: westside-contracts #35 (T4), westside-contracts #36 (T5)
forgejo_admin changed title from feat: wire components to render from merged contract data to feat: wire content components to render from merged contract data 2026-04-04 21:36:26 +00:00
Author
Contributor

Scope Review: READY

Review note: review-777-2026-04-03
Scope is solid — all template sections present, traceability complete (story:WS-S20 verified, arch-contracts-westside-basketball exists), file targets confirmed. Dependencies on T4 (#35) and T5 (#36) are correctly documented; both are in QA and must merge before dispatch.

## Scope Review: READY Review note: `review-777-2026-04-03` Scope is solid — all template sections present, traceability complete (story:WS-S20 verified, arch-contracts-westside-basketball exists), file targets confirmed. Dependencies on T4 (#35) and T5 (#36) are correctly documented; both are in QA and must merge before dispatch.
Author
Contributor

Agent picked up this ticket.

Agent picked up this ticket.
Author
Contributor

Agent picked up this ticket (retry).

Agent picked up this ticket (retry).
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ldraney/westside-contracts#37
No description provided.