P4-1: read-only Projects + Tasks SPA pages + dev-port pins #1153

Merged
jason.woltje merged 2 commits from feat/webui-p4-1 into next 2026-08-11 04:00:37 +00:00
Owner

P4-1 — Read-only Projects + Tasks SPA pages (list/detail) + dev-port pins

First slice of Phase-P increment 4/6. Ports the existing Next (dashboard) read-only Projects/Tasks
pages into the Vite SPA on react-router, and pins the canonical dev topology. View-only — edit UX is
deliberately split to a later increment (P4-1b).

Traceability: Phase P RFC §6.4 (authenticated data surfaces) + §2.4 (same-origin invariant). In-repo
anchors: apps/web/src/spa/routes.spec.tsx (v1-parity route set) + the Next (dashboard) reference pages.

Scope (IN)

  • /projects list, /projects/:id detail, /tasks list — new SPA pages under apps/web/src/spa/pages/,
    page-local (no nav shell), reusing existing components/projects/* + components/tasks/*, @/lib/api
    (relative /api/...), @/lib/types.
  • routes.tsx: three <Placeholder> replaced with the real pages, each with an errorElement boundary.
  • Dev-topology port pins: vite.config.ts strictPort: true; Next dev/start scripts → -p 3101
    (canonical: SPA=3100 · gateway=14242 · Next=3101).
  • Tests: per-page render/data/error tests + routes.spec.tsx assertions that the routes resolve to real
    elements. Detail page follows the reference graceful-degradation contract — a missions/tasks fetch failure
    renders the project with an empty tab; only a project-fetch failure drives the error state.

Scope (OUT)

No mutation/edit (P4-1b), no nav shell, no gateway/packages/** changes, no new deps (lockfile unchanged),
no WS/Origin changes, /chat untouched, Settings/Admin still Placeholder.

Independent gates (author self-reports discarded; re-derived on the pushed commit)

  • Integrator-verify (clean detached checkout): scope CONFINED to the allowed path set; tree clean;
    typecheck/lint/test/build/frozen-lock/format-check all rc=0; lockfile unchanged; no new absolute origin;
    154 tests pass (19 files).
  • Independent code+security review: APPROVE-WITH-NITS. One MEDIUM (detail-page Promise.all dropped the
    reference's per-request .catch(() => [])) remediated in commit 29db2421 — restored graceful degradation
    and corrected the test that had enshrined the regression; re-verified (delta = exactly 2 files, guard shape
    correct, all gates rc=0). Two LOW/INFO findings accepted (React-escaped error text mirroring the reference;
    sound PRD escaping in a pre-existing component).

Author: pi (gpt-5.6-sol:max). Integrator-verify + review + merge-gate: independent (author≠reviewer≠merge-gate).

## P4-1 — Read-only Projects + Tasks SPA pages (list/detail) + dev-port pins First slice of Phase-P increment 4/6. Ports the existing Next `(dashboard)` **read-only** Projects/Tasks pages into the Vite SPA on react-router, and pins the canonical dev topology. **View-only** — edit UX is deliberately split to a later increment (P4-1b). Traceability: Phase P RFC §6.4 (authenticated data surfaces) + §2.4 (same-origin invariant). In-repo anchors: `apps/web/src/spa/routes.spec.tsx` (v1-parity route set) + the Next `(dashboard)` reference pages. ### Scope (IN) - `/projects` list, `/projects/:id` detail, `/tasks` list — new SPA pages under `apps/web/src/spa/pages/`, page-local (no nav shell), reusing existing `components/projects/*` + `components/tasks/*`, `@/lib/api` (relative `/api/...`), `@/lib/types`. - `routes.tsx`: three `<Placeholder>` replaced with the real pages, each with an `errorElement` boundary. - Dev-topology port pins: `vite.config.ts` `strictPort: true`; Next `dev`/`start` scripts → `-p 3101` (canonical: SPA=3100 · gateway=14242 · Next=3101). - Tests: per-page render/data/error tests + `routes.spec.tsx` assertions that the routes resolve to real elements. Detail page follows the reference graceful-degradation contract — a missions/tasks fetch failure renders the project with an empty tab; only a project-fetch failure drives the error state. ### Scope (OUT) No mutation/edit (P4-1b), no nav shell, no gateway/`packages/**` changes, no new deps (lockfile unchanged), no WS/Origin changes, `/chat` untouched, Settings/Admin still Placeholder. ### Independent gates (author self-reports discarded; re-derived on the pushed commit) - Integrator-verify (clean detached checkout): scope CONFINED to the allowed path set; tree clean; typecheck/lint/test/build/frozen-lock/format-check all rc=0; lockfile unchanged; no new absolute origin; **154 tests pass** (19 files). - Independent code+security review: APPROVE-WITH-NITS. One MEDIUM (detail-page `Promise.all` dropped the reference's per-request `.catch(() => [])`) remediated in commit `29db2421` — restored graceful degradation and corrected the test that had enshrined the regression; re-verified (delta = exactly 2 files, guard shape correct, all gates rc=0). Two LOW/INFO findings accepted (React-escaped error text mirroring the reference; sound PRD escaping in a pre-existing component). Author: pi (gpt-5.6-sol:max). Integrator-verify + review + merge-gate: independent (author≠reviewer≠merge-gate).
jason.woltje added 2 commits 2026-08-11 03:48:26 +00:00
jason.woltje merged commit 20718b5a27 into next 2026-08-11 04:00:37 +00:00
Sign in to join this conversation.