SvelteKit public site — layout shell + all 8 pages from playground #98

Closed
opened 2026-03-27 03:12:55 +00:00 by forgejo_admin · 7 comments

Type

Feature

Lineage

Ports westside-playground HTML to production SvelteKit. Depends on public API endpoints in basketball-api.

Repo

forgejo_admin/westside-app

User Story

As a visitor, I want to browse the Westside Kings and Queens website with real team data and coach bios so that the site feels professional and up-to-date.

story:WS-S26

Context

The westside-playground has 8 annotated public pages with @svelte-notes translation guides. westside-app already has adapter-static configured with 13+ existing authenticated routes using Keycloak. The convention-sveltekit-spa defines the full architecture.

No auth needed for public pages. Public and authenticated routes coexist via SvelteKit route groups.

Architecture: Route Groups

SvelteKit route groups isolate layouts. Public pages get their own layout (no Keycloak). Authenticated pages keep their existing layout (Keycloak init + auth guards). The group name does not appear in the URL.

src/routes/
  +layout.svelte          ← ROOT: minimal, just imports app.css
  +layout.js              ← export const ssr = false
  (public)/               ← new group, NO keycloak
    +layout.svelte        ← public nav/footer/toggle state
    +page.svelte          ← home (/)
    about/+page.svelte
    staff/+page.svelte
    teams/+page.svelte
    schedule/+page.svelte
    tryouts/+page.svelte
    gear/+page.svelte
    sponsors/+page.svelte
  (app)/                  ← existing auth routes, moved here
    +layout.svelte        ← keycloak init, auth guards (existing code)
    admin/...
    coach/...
    my-players/...
    signin/...
    register/...
    forgot-password/...
    reset-password/...
    checkout/...
    jersey/...
    players/...
    teams/...
    # tryouts/ deleted — replaced by (public) version
    teams/[id]/...       ← auth detail page (no collision with public /teams list)
    coaches/[id]/...     ← auth detail page (no collision with public /staff list)

Scope

1. Route group restructuring:

  • Create src/routes/(public)/ directory
  • Create src/routes/(app)/ directory
  • Move ALL existing authenticated routes into (app)/
  • Move existing +layout.svelte (with Keycloak) to (app)/+layout.svelte
  • Create new minimal root +layout.svelte (just CSS import)
  • Delete existing src/routes/+page.svelte (auth redirect). Migrate redirect logic into (app)/+layout.svelte auth guard
  • Routes with public AND auth versions: public wins at the base URL. Delete tryouts/ from auth routes (replaced by public). Keep teams/[id] and coaches/[id] under (app) — these are auth detail pages, no collision with public list pages
  • Verify all remaining authenticated routes still work after move

2. Public layout shell ((public)/+layout.svelte):

  • Nav component (logo-only brand, 8 links, hamburger toggle)
  • Footer component
  • Kings/Queens toggle as shared $state rune with localStorage $effect
  • queens-active body class via <svelte:body>
  • NO keycloak, NO auth

3. CSS (src/app.css):

  • Copy from playground shared/style.css
  • Import in root +layout.svelte
  • No Tailwind

4. Public fetch helper (src/lib/public-api.js):

const API = import.meta.env.VITE_API_URL;
export async function publicFetch(path) {
  const res = await fetch(`${API}${path}`);
  if (!res.ok) return null;
  return res.json();
}

Separate from existing apiFetch (which requires Keycloak tokens). Public pages MUST use publicFetch, NOT apiFetch.

5. Static pages (copy-paste from playground + layout):

  • (public)/+page.svelte — home (hero, value props, Marcus quote, explore cards)
  • (public)/about/+page.svelte — program info, divisions, recruitment, philosophy
  • (public)/sponsors/+page.svelte — Snoopy, NanoReleaf, Coach West, FAQ
  • (public)/schedule/+page.svelte — tournaments, practice grid (hardcoded)
  • (public)/tryouts/+page.svelte — past history, upcoming (hardcoded)
  • (public)/gear/+page.svelte — jersey photos from MinIO, KQ toggle

6. Dynamic pages (fetch from basketball-api public endpoints):

  • (public)/teams/+page.sveltepublicFetch('/public/teams'), roster cards, coach anchor links
  • (public)/staff/+page.svelte — static coach cards (bios hardcoded from playground, no API)

7. Inline nav cleanup:

  • Strip inline nav from (app)/tryouts/+page.svelte (lines 9-15)
  • Strip inline nav from (app)/register/+page.svelte (line 182)
  • Any other routes with duplicate nav markup

Translation Reference

Read @svelte-notes in each playground HTML file before coding. Key patterns:

  • data-program-content{#if program === 'kings'} blocks
  • initKQToggle() → gone, Svelte reactivity replaces it
  • Nav/footer duplication → (public)/+layout.svelte (render once)
  • .queens-active<svelte:body class:queens-active={program === 'queens'}>
  • Hardcoded mock data stays hardcoded for static pages
  • Dynamic pages use onMount + publicFetch

File Targets

  • src/routes/+layout.svelte — ROOT: minimal, just import '../app.css'
  • src/routes/+layout.jsexport const ssr = false
  • src/routes/(public)/+layout.svelte — public nav/footer/toggle
  • src/routes/(public)/+page.svelte — home
  • src/routes/(public)/about/+page.svelte
  • src/routes/(public)/staff/+page.svelte
  • src/routes/(public)/teams/+page.svelte
  • src/routes/(public)/schedule/+page.svelte
  • src/routes/(public)/tryouts/+page.svelte
  • src/routes/(public)/gear/+page.svelte
  • src/routes/(public)/sponsors/+page.svelte
  • src/routes/(app)/+layout.svelte — existing Keycloak layout, moved
  • src/routes/(app)/ — all existing auth routes moved here
  • src/lib/public-api.js — unauthenticated fetch helper
  • src/app.css — from playground shared/style.css
  • DELETE: src/routes/+page.svelte (old auth redirect — replaced by (public)/+page.svelte)
  • DELETE: (app)/tryouts/ — replaced by (public)/tryouts
  • Cleanup: (app)/register/+page.svelte — strip inline nav

Acceptance Criteria

  • All 8 public pages render and match playground visual design
  • Kings/Queens toggle persists across pages via localStorage
  • Queens pink color scheme swaps on toggle
  • Teams page fetches real roster data from /public/teams via publicFetch
  • Staff page fetches real coach data from /public/coaches via publicFetch
  • Coach names on teams page link to staff page anchors
  • Nav consistent across all public pages
  • Mobile hamburger menu works
  • All existing authenticated routes (/admin, /coach, /my-players, etc.) still work after restructuring
  • Keycloak auth flow unbroken for authenticated routes
  • No double-rendered nav on any page
  • Dynamic pages degrade gracefully if API unreachable (empty state, not crash)

Test Expectations

  • npm run build succeeds with adapter-static
  • All public routes accessible without auth
  • All auth routes still require login
  • Toggle state persists on page navigation

Constraints

  • Follow convention-sveltekit-spa exactly
  • No Tailwind — pure CSS vars from playground
  • No +page.server.ts — all client-side
  • Public pages use publicFetch, NOT apiFetch — no Keycloak dependency
  • Existing auth routes must survive the restructuring unchanged
  • Test locally before pushing

Checklist

  • Route groups created: (public) and (app)
  • All existing routes moved to (app) without breakage
  • Public layout shell with nav/footer/css/toggle
  • All 8 public page routes created
  • Dynamic pages wired to public endpoints via publicFetch
  • Inline nav stripped from auth routes
  • Build succeeds
  • Auth flow verified
  • Mobile tested
  • Lucas review

Depends On

  • basketball-api#176: public teams endpoint
  • convention-sveltekit-spa — architecture reference
  • westside-playground PR #45 — all page annotations
  • westside-app #96 — Svelte promotion prep
### Type Feature ### Lineage Ports westside-playground HTML to production SvelteKit. Depends on public API endpoints in basketball-api. ### Repo `forgejo_admin/westside-app` ### User Story As a visitor, I want to browse the Westside Kings and Queens website with real team data and coach bios so that the site feels professional and up-to-date. story:WS-S26 ### Context The westside-playground has 8 annotated public pages with `@svelte-notes` translation guides. westside-app already has `adapter-static` configured with 13+ existing authenticated routes using Keycloak. The `convention-sveltekit-spa` defines the full architecture. No auth needed for public pages. Public and authenticated routes coexist via SvelteKit **route groups**. ### Architecture: Route Groups SvelteKit route groups isolate layouts. Public pages get their own layout (no Keycloak). Authenticated pages keep their existing layout (Keycloak init + auth guards). The group name does not appear in the URL. ``` src/routes/ +layout.svelte ← ROOT: minimal, just imports app.css +layout.js ← export const ssr = false (public)/ ← new group, NO keycloak +layout.svelte ← public nav/footer/toggle state +page.svelte ← home (/) about/+page.svelte staff/+page.svelte teams/+page.svelte schedule/+page.svelte tryouts/+page.svelte gear/+page.svelte sponsors/+page.svelte (app)/ ← existing auth routes, moved here +layout.svelte ← keycloak init, auth guards (existing code) admin/... coach/... my-players/... signin/... register/... forgot-password/... reset-password/... checkout/... jersey/... players/... teams/... # tryouts/ deleted — replaced by (public) version teams/[id]/... ← auth detail page (no collision with public /teams list) coaches/[id]/... ← auth detail page (no collision with public /staff list) ``` ### Scope **1. Route group restructuring:** - Create `src/routes/(public)/` directory - Create `src/routes/(app)/` directory - Move ALL existing authenticated routes into `(app)/` - Move existing `+layout.svelte` (with Keycloak) to `(app)/+layout.svelte` - Create new minimal root `+layout.svelte` (just CSS import) - Delete existing `src/routes/+page.svelte` (auth redirect). Migrate redirect logic into `(app)/+layout.svelte` auth guard - Routes with public AND auth versions: public wins at the base URL. Delete `tryouts/` from auth routes (replaced by public). Keep `teams/[id]` and `coaches/[id]` under (app) — these are auth detail pages, no collision with public list pages - Verify all remaining authenticated routes still work after move **2. Public layout shell (`(public)/+layout.svelte`):** - Nav component (logo-only brand, 8 links, hamburger toggle) - Footer component - Kings/Queens toggle as shared `$state` rune with localStorage `$effect` - `queens-active` body class via `<svelte:body>` - NO keycloak, NO auth **3. CSS (`src/app.css`):** - Copy from playground `shared/style.css` - Import in root `+layout.svelte` - No Tailwind **4. Public fetch helper (`src/lib/public-api.js`):** ```js const API = import.meta.env.VITE_API_URL; export async function publicFetch(path) { const res = await fetch(`${API}${path}`); if (!res.ok) return null; return res.json(); } ``` Separate from existing `apiFetch` (which requires Keycloak tokens). Public pages MUST use `publicFetch`, NOT `apiFetch`. **5. Static pages (copy-paste from playground + layout):** - `(public)/+page.svelte` — home (hero, value props, Marcus quote, explore cards) - `(public)/about/+page.svelte` — program info, divisions, recruitment, philosophy - `(public)/sponsors/+page.svelte` — Snoopy, NanoReleaf, Coach West, FAQ - `(public)/schedule/+page.svelte` — tournaments, practice grid (hardcoded) - `(public)/tryouts/+page.svelte` — past history, upcoming (hardcoded) - `(public)/gear/+page.svelte` — jersey photos from MinIO, KQ toggle **6. Dynamic pages (fetch from basketball-api public endpoints):** - `(public)/teams/+page.svelte` — `publicFetch('/public/teams')`, roster cards, coach anchor links - `(public)/staff/+page.svelte` — static coach cards (bios hardcoded from playground, no API) **7. Inline nav cleanup:** - Strip inline nav from `(app)/tryouts/+page.svelte` (lines 9-15) - Strip inline nav from `(app)/register/+page.svelte` (line 182) - Any other routes with duplicate nav markup ### Translation Reference Read `@svelte-notes` in each playground HTML file before coding. Key patterns: - `data-program-content` → `{#if program === 'kings'}` blocks - `initKQToggle()` → gone, Svelte reactivity replaces it - Nav/footer duplication → `(public)/+layout.svelte` (render once) - `.queens-active` → `<svelte:body class:queens-active={program === 'queens'}>` - Hardcoded mock data stays hardcoded for static pages - Dynamic pages use `onMount` + `publicFetch` ### File Targets - `src/routes/+layout.svelte` — ROOT: minimal, just `import '../app.css'` - `src/routes/+layout.js` — `export const ssr = false` - `src/routes/(public)/+layout.svelte` — public nav/footer/toggle - `src/routes/(public)/+page.svelte` — home - `src/routes/(public)/about/+page.svelte` - `src/routes/(public)/staff/+page.svelte` - `src/routes/(public)/teams/+page.svelte` - `src/routes/(public)/schedule/+page.svelte` - `src/routes/(public)/tryouts/+page.svelte` - `src/routes/(public)/gear/+page.svelte` - `src/routes/(public)/sponsors/+page.svelte` - `src/routes/(app)/+layout.svelte` — existing Keycloak layout, moved - `src/routes/(app)/` — all existing auth routes moved here - `src/lib/public-api.js` — unauthenticated fetch helper - `src/app.css` — from playground `shared/style.css` - DELETE: `src/routes/+page.svelte` (old auth redirect — replaced by (public)/+page.svelte) - DELETE: `(app)/tryouts/` — replaced by (public)/tryouts - Cleanup: `(app)/register/+page.svelte` — strip inline nav ### Acceptance Criteria - [ ] All 8 public pages render and match playground visual design - [ ] Kings/Queens toggle persists across pages via localStorage - [ ] Queens pink color scheme swaps on toggle - [ ] Teams page fetches real roster data from /public/teams via publicFetch - [ ] Staff page fetches real coach data from /public/coaches via publicFetch - [ ] Coach names on teams page link to staff page anchors - [ ] Nav consistent across all public pages - [ ] Mobile hamburger menu works - [ ] All existing authenticated routes (/admin, /coach, /my-players, etc.) still work after restructuring - [ ] Keycloak auth flow unbroken for authenticated routes - [ ] No double-rendered nav on any page - [ ] Dynamic pages degrade gracefully if API unreachable (empty state, not crash) ### Test Expectations - [ ] `npm run build` succeeds with adapter-static - [ ] All public routes accessible without auth - [ ] All auth routes still require login - [ ] Toggle state persists on page navigation ### Constraints - Follow `convention-sveltekit-spa` exactly - No Tailwind — pure CSS vars from playground - No `+page.server.ts` — all client-side - Public pages use `publicFetch`, NOT `apiFetch` — no Keycloak dependency - Existing auth routes must survive the restructuring unchanged - Test locally before pushing ### Checklist - [ ] Route groups created: (public) and (app) - [ ] All existing routes moved to (app) without breakage - [ ] Public layout shell with nav/footer/css/toggle - [ ] All 8 public page routes created - [ ] Dynamic pages wired to public endpoints via publicFetch - [ ] Inline nav stripped from auth routes - [ ] Build succeeds - [ ] Auth flow verified - [ ] Mobile tested - [ ] Lucas review ### Depends On - basketball-api#176: public teams endpoint ### Related - `convention-sveltekit-spa` — architecture reference - westside-playground PR #45 — all page annotations - westside-app #96 — Svelte promotion prep
Author
Owner

Scope Review: NEEDS_REFINEMENT

Review note: review-431-2026-03-26
Template complete, traceability triangle intact, playground sources verified. Three issues found:

  • Auth coexistence strategy missing. Current +layout.svelte initializes Keycloak and guards all protected routes. Issue says "no keycloak, no auth" but doesn't describe how authenticated routes (/admin, /coach, /my-players, etc.) survive the layout replacement. Must add a Layout Strategy section (route groups, conditional rendering, or layout reset).
  • Inline nav cleanup needed. /tryouts/+page.svelte (lines 9-15) has its own nav that will double-render with the new layout shell. Add to file targets.
  • Public fetch pattern unspecified. $lib/api.js requires Keycloak tokens. Dynamic pages need raw fetch() or a public API utility. One line in Constraints prevents the most likely agent mistake.
## Scope Review: NEEDS_REFINEMENT Review note: `review-431-2026-03-26` Template complete, traceability triangle intact, playground sources verified. Three issues found: - **Auth coexistence strategy missing.** Current `+layout.svelte` initializes Keycloak and guards all protected routes. Issue says "no keycloak, no auth" but doesn't describe how authenticated routes (`/admin`, `/coach`, `/my-players`, etc.) survive the layout replacement. Must add a Layout Strategy section (route groups, conditional rendering, or layout reset). - **Inline nav cleanup needed.** `/tryouts/+page.svelte` (lines 9-15) has its own nav that will double-render with the new layout shell. Add to file targets. - **Public fetch pattern unspecified.** `$lib/api.js` requires Keycloak tokens. Dynamic pages need raw `fetch()` or a public API utility. One line in Constraints prevents the most likely agent mistake.
Author
Owner

Review Response

1. Auth coexistence strategy

The existing +layout.svelte with Keycloak stays intact for authenticated routes. The public pages use a route group layout:

src/routes/
  (public)/          ← new layout group, NO keycloak
    +layout.svelte   ← public nav/footer/css/toggle only
    +page.svelte     ← home
    about/+page.svelte
    staff/+page.svelte
    teams/+page.svelte
    schedule/+page.svelte
    tryouts/+page.svelte
    gear/+page.svelte
    sponsors/+page.svelte
  (app)/             ← existing auth layout group
    +layout.svelte   ← keycloak init, auth guards
    admin/...
    coach/...
    my-players/...

SvelteKit route groups ((public) vs (app)) get different layouts. No conflict. The root +layout.svelte becomes minimal (just shared CSS import), each group has its own layout.

2. Duplicate nav cleanup

Added to scope: strip inline nav from existing route files (/tryouts/+page.svelte lines 9-15, and any other routes that duplicate nav). File targets updated to include cleanup of existing routes that will live under the (public) group.

3. Public fetch pattern

Public pages use plain fetch() — no auth wrapper needed:

// src/lib/public-api.js
const API = import.meta.env.VITE_API_URL;
export async function publicFetch(path) {
  const res = await fetch(`${API}${path}`);
  if (!res.ok) return null; // graceful degradation
  return res.json();
}

This is separate from the existing apiFetch (which requires Keycloak tokens). Constraint added: "Dynamic pages use publicFetch, NOT apiFetch. No Keycloak dependency."

## Review Response ### 1. Auth coexistence strategy The existing `+layout.svelte` with Keycloak stays intact for authenticated routes. The public pages use a **route group layout**: ``` src/routes/ (public)/ ← new layout group, NO keycloak +layout.svelte ← public nav/footer/css/toggle only +page.svelte ← home about/+page.svelte staff/+page.svelte teams/+page.svelte schedule/+page.svelte tryouts/+page.svelte gear/+page.svelte sponsors/+page.svelte (app)/ ← existing auth layout group +layout.svelte ← keycloak init, auth guards admin/... coach/... my-players/... ``` SvelteKit route groups (`(public)` vs `(app)`) get different layouts. No conflict. The root `+layout.svelte` becomes minimal (just shared CSS import), each group has its own layout. ### 2. Duplicate nav cleanup Added to scope: strip inline nav from existing route files (`/tryouts/+page.svelte` lines 9-15, and any other routes that duplicate nav). File targets updated to include cleanup of existing routes that will live under the `(public)` group. ### 3. Public fetch pattern Public pages use plain `fetch()` — no auth wrapper needed: ```js // src/lib/public-api.js const API = import.meta.env.VITE_API_URL; export async function publicFetch(path) { const res = await fetch(`${API}${path}`); if (!res.ok) return null; // graceful degradation return res.json(); } ``` This is separate from the existing `apiFetch` (which requires Keycloak tokens). Constraint added: "Dynamic pages use `publicFetch`, NOT `apiFetch`. No Keycloak dependency."
Author
Owner

Scope Review (Re-review): NEEDS_REFINEMENT

Review note: review-431-2026-03-26 (updated)

Previous 3 issues all have correct solutions in comment #8102, but the issue body has not been updated — agents execute against the body, not comments. Five issues found:

  • Issue body is stale. Route group strategy, publicFetch, and nav cleanup exist only in comment. The spec agents will read has none of these.
  • Route group restructuring scope missing. Moving 13 existing route dirs under (app)/ is not in Scope, File Targets, or Checklist. This is a major structural change the agent won't know to do.
  • File target paths wrong for route groups. All 11 paths say src/routes/... but should be src/routes/(public)/.... Also missing src/routes/(app)/+layout.svelte and src/lib/public-api.js.
  • Missing acceptance criteria for auth route survival after restructuring.
  • Register page inline nav (/register/+page.svelte line 182) has same double-render problem as tryouts. Placement decision needed: (public) or (app)?
## Scope Review (Re-review): NEEDS_REFINEMENT Review note: `review-431-2026-03-26` (updated) Previous 3 issues all have correct solutions in comment #8102, but the **issue body has not been updated** — agents execute against the body, not comments. Five issues found: - **Issue body is stale.** Route group strategy, publicFetch, and nav cleanup exist only in comment. The spec agents will read has none of these. - **Route group restructuring scope missing.** Moving 13 existing route dirs under `(app)/` is not in Scope, File Targets, or Checklist. This is a major structural change the agent won't know to do. - **File target paths wrong for route groups.** All 11 paths say `src/routes/...` but should be `src/routes/(public)/...`. Also missing `src/routes/(app)/+layout.svelte` and `src/lib/public-api.js`. - **Missing acceptance criteria** for auth route survival after restructuring. - **Register page inline nav** (`/register/+page.svelte` line 182) has same double-render problem as tryouts. Placement decision needed: `(public)` or `(app)`?
Author
Owner

Scope Review (3rd review): NEEDS_REFINEMENT

Review note: review-431-2026-03-26-r3

Issue body rewrite is excellent — route groups, publicFetch, nav cleanup, file targets all verified against codebase. Two remaining gaps:

  • Root +page.svelte disposition. Existing src/routes/+page.svelte has auth redirect logic (lines 6-11). The new (public)/+page.svelte takes over /, but the issue doesn't say to delete the existing root page or where the redirect logic migrates (likely (app)/+layout.svelte).
  • Route collision at /tryouts. Both (app)/tryouts/+page.svelte (moved) and (public)/tryouts/+page.svelte (new) resolve to /tryouts. SvelteKit will error. Must clarify: existing tryouts page is replaced (not moved to (app)), or relocated to a different URL.
## Scope Review (3rd review): NEEDS_REFINEMENT Review note: `review-431-2026-03-26-r3` Issue body rewrite is excellent — route groups, publicFetch, nav cleanup, file targets all verified against codebase. Two remaining gaps: - **Root +page.svelte disposition.** Existing `src/routes/+page.svelte` has auth redirect logic (lines 6-11). The new `(public)/+page.svelte` takes over `/`, but the issue doesn't say to delete the existing root page or where the redirect logic migrates (likely `(app)/+layout.svelte`). - **Route collision at /tryouts.** Both `(app)/tryouts/+page.svelte` (moved) and `(public)/tryouts/+page.svelte` (new) resolve to `/tryouts`. SvelteKit will error. Must clarify: existing tryouts page is replaced (not moved to (app)), or relocated to a different URL.
Author
Owner

Review Response v3

Finding 1: Root +page.svelte disposition

The existing src/routes/+page.svelte (auth redirect logic) gets deleted. The (public)/+page.svelte takes over / as the home page. The auth redirect logic (if authenticated → role dashboard) moves to (app)/+layout.svelte as part of its auth guard.

Adding to Scope section 1: "Delete existing src/routes/+page.svelte (auth redirect). Migrate its redirect logic into (app)/+layout.svelte auth guard."

Finding 2: Route collision at /tryouts

Routes that exist in BOTH (app)/ and (public)/ are not moved to (app)/. They are replaced by the public version. Affected routes:

  • /tryouts — public version replaces authenticated version
  • /teams — public version replaces authenticated version
  • /coaches/staff — different URL, no collision

The existing (app)/tryouts/ and (app)/teams/ authenticated pages are deleted. If authenticated team/tryout views are needed later, they get different URLs (e.g. /admin/tryouts, /my-team).

Adding to Scope section 1: "Routes with both public and auth versions: public wins at the base URL. Delete tryouts/, teams/, coaches/ from (app)/ — these are replaced by (public)/ versions."

## Review Response v3 ### Finding 1: Root +page.svelte disposition The existing `src/routes/+page.svelte` (auth redirect logic) gets **deleted**. The `(public)/+page.svelte` takes over `/` as the home page. The auth redirect logic (if authenticated → role dashboard) moves to `(app)/+layout.svelte` as part of its auth guard. Adding to Scope section 1: "Delete existing `src/routes/+page.svelte` (auth redirect). Migrate its redirect logic into `(app)/+layout.svelte` auth guard." ### Finding 2: Route collision at /tryouts Routes that exist in BOTH `(app)/` and `(public)/` are **not moved to (app)/**. They are **replaced** by the public version. Affected routes: - `/tryouts` — public version replaces authenticated version - `/teams` — public version replaces authenticated version - `/coaches` → `/staff` — different URL, no collision The existing `(app)/tryouts/` and `(app)/teams/` authenticated pages are deleted. If authenticated team/tryout views are needed later, they get different URLs (e.g. `/admin/tryouts`, `/my-team`). Adding to Scope section 1: "Routes with both public and auth versions: public wins at the base URL. Delete `tryouts/`, `teams/`, `coaches/` from `(app)/` — these are replaced by `(public)/` versions."
Author
Owner

Scope Review v4: NEEDS_REFINEMENT

Review note: review-431-2026-03-26

All 5 v3 issues are resolved in the updated issue body. One new critical issue found:

  • DELETE (app)/teams/ and (app)/coaches/ would break authenticated detail routes. Current teams/[id]/+page.svelte and coaches/[id]/+page.svelte are authenticated detail views (fetch by ID via apiFetch). They are NOT duplicates of the public list pages ((public)/teams and (public)/staff). No route collision exists -- /coaches/123 and /staff are different URLs. Deleting these directories breaks links from admin dashboard, player profiles, and coach profiles (5+ cross-page links). These routes should be KEPT under (app)/, not deleted.

Fix needed: Remove DELETE lines for (app)/teams/ and (app)/coaches/. Update architecture tree to show (app)/teams/[id]/... and (app)/coaches/[id]/... as retained routes. Clarify in Scope section 1 that teams/[id] and coaches/[id] are auth detail routes that coexist alongside the new public list pages.

Once corrected, this ticket is READY.

## Scope Review v4: NEEDS_REFINEMENT Review note: `review-431-2026-03-26` All 5 v3 issues are resolved in the updated issue body. One new critical issue found: - **DELETE (app)/teams/ and (app)/coaches/ would break authenticated detail routes.** Current `teams/[id]/+page.svelte` and `coaches/[id]/+page.svelte` are authenticated detail views (fetch by ID via `apiFetch`). They are NOT duplicates of the public list pages (`(public)/teams` and `(public)/staff`). No route collision exists -- `/coaches/123` and `/staff` are different URLs. Deleting these directories breaks links from admin dashboard, player profiles, and coach profiles (5+ cross-page links). These routes should be KEPT under `(app)/`, not deleted. **Fix needed:** Remove DELETE lines for `(app)/teams/` and `(app)/coaches/`. Update architecture tree to show `(app)/teams/[id]/...` and `(app)/coaches/[id]/...` as retained routes. Clarify in Scope section 1 that `teams/[id]` and `coaches/[id]` are auth detail routes that coexist alongside the new public list pages. Once corrected, this ticket is READY.
Author
Owner

Scope Review v5: READY

Review note: review-431-2026-03-26

v4 fix verified — DELETE lines for (app)/teams/ and (app)/coaches/ removed, architecture tree shows them as retained auth detail routes, Scope section 1 explicitly keeps teams/[id] and coaches/[id] under (app). All 17 file targets verified against codebase. Traceability triangle complete. Template fully populated.

This ticket is approved to move from todo to next_up.

## Scope Review v5: READY Review note: `review-431-2026-03-26` v4 fix verified — DELETE lines for `(app)/teams/` and `(app)/coaches/` removed, architecture tree shows them as retained auth detail routes, Scope section 1 explicitly keeps `teams/[id]` and `coaches/[id]` under `(app)`. All 17 file targets verified against codebase. Traceability triangle complete. Template fully populated. This ticket is approved to move from `todo` to `next_up`.
Sign in to join this conversation.
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
forgejo_admin/westside-app#98
No description provided.