---
phase: 16-frontend-scaffold
plan: 04
subsystem: ui
tags: [tanstack-router, file-based-routing, shadcn-ui, react, vite]

# Dependency graph
requires:
  - phase: 16-03
    provides: tRPC React Query client with provider stack
  - phase: 16-01
    provides: Vite + React + Tailwind + shadcn/ui config
provides:
  - TanStack Router with file-based route generation
  - App shell layout with persistent nav header
  - Page stubs for Dashboard, Initiative Detail, and Inbox
  - shadcn/ui button, badge, card, dropdown-menu components
  - Type-safe route params on /initiatives/$id
affects: [17-initiative-dashboard, 18-initiative-detail, 19-agent-inbox]

# Tech tracking
tech-stack:
  added: ["@tanstack/react-router", "@tanstack/router-plugin", "@radix-ui/react-dropdown-menu", "@radix-ui/react-slot"]
  patterns: ["file-based routing with TanStack Router Vite plugin", "root route wraps AppLayout shell", "activeProps for nav highlighting"]

key-files:
  created: ["packages/web/src/routes/__root.tsx", "packages/web/src/routes/index.tsx", "packages/web/src/routes/initiatives/index.tsx", "packages/web/src/routes/initiatives/$id.tsx", "packages/web/src/routes/inbox.tsx", "packages/web/src/layouts/AppLayout.tsx", "packages/web/src/router.tsx", "packages/web/src/routeTree.gen.ts", "packages/web/src/components/ui/button.tsx", "packages/web/src/components/ui/badge.tsx", "packages/web/src/components/ui/card.tsx", "packages/web/src/components/ui/dropdown-menu.tsx"]
  modified: ["packages/web/vite.config.ts", "packages/web/package.json", "packages/web/src/App.tsx"]

key-decisions:
  - "TanStackRouterVite plugin must come BEFORE react plugin in Vite config"
  - "Root route wraps all pages with AppLayout via Outlet"
  - "/ redirects to /initiatives via beforeLoad + throw redirect"
  - "Agents, Tasks, Settings nav items rendered as disabled spans (out of Phase 16-19 scope)"
  - "shadcn CLI creates files in literal @/ dir - manually moved to src/components/ui/"

patterns-established:
  - "File-based routing: src/routes/ directory maps to URL paths"
  - "Root layout: __root.tsx wraps all pages with AppLayout shell"
  - "Type-safe params: Route.useParams() for $id segments"
  - "Nav highlighting: activeProps on Link components"
  - "Router registration: declare module for type-safe router"

# Metrics
duration: 3min
completed: 2026-02-04
---

# Phase 16 Plan 04: Router & App Shell Summary

**TanStack Router with file-based routes, persistent nav header, and page stubs for Dashboard/Detail/Inbox**

## Performance

- **Duration:** 3 min
- **Started:** 2026-02-04
- **Completed:** 2026-02-04
- **Tasks:** 2
- **Files modified:** 15

## Accomplishments
- TanStack Router configured with Vite plugin for automatic route tree generation
- App shell layout with header (title + New Initiative button) and navigation tabs matching wireframe
- Four file-based routes: / (redirect), /initiatives (dashboard), /initiatives/$id (detail), /inbox
- Type-safe route params on initiative detail page
- Four foundational shadcn/ui components installed: button, badge, card, dropdown-menu
- Active nav item highlighting via TanStack Router activeProps

## Task Commits

Each task was committed atomically:

1. **Task 1: Install TanStack Router and add shadcn/ui base components** - `64d751d` (feat)
2. **Task 2: Create file-based routes, app shell layout, and page stubs** - `6d2920d` (feat)

## Files Created/Modified
- `packages/web/vite.config.ts` - Added TanStackRouterVite plugin before react plugin
- `packages/web/package.json` - Added @tanstack/react-router, router-plugin, Radix UI deps
- `packages/web/src/components/ui/button.tsx` - shadcn/ui Button component
- `packages/web/src/components/ui/badge.tsx` - shadcn/ui Badge component
- `packages/web/src/components/ui/card.tsx` - shadcn/ui Card component
- `packages/web/src/components/ui/dropdown-menu.tsx` - shadcn/ui DropdownMenu component
- `packages/web/src/routes/__root.tsx` - Root layout wrapping AppLayout with Outlet
- `packages/web/src/routes/index.tsx` - Redirect / to /initiatives
- `packages/web/src/routes/initiatives/index.tsx` - Dashboard stub with tRPC health check
- `packages/web/src/routes/initiatives/$id.tsx` - Detail stub with type-safe $id param
- `packages/web/src/routes/inbox.tsx` - Inbox page stub
- `packages/web/src/layouts/AppLayout.tsx` - Persistent nav header with title, button, tabs
- `packages/web/src/router.tsx` - Router creation with type registration
- `packages/web/src/routeTree.gen.ts` - Auto-generated route tree manifest
- `packages/web/src/App.tsx` - Replaced health check with RouterProvider

## Decisions Made
- TanStackRouterVite plugin placed before react plugin in Vite config (required by TanStack docs)
- Root route uses AppLayout wrapper with Outlet for persistent shell across all pages
- Index route redirects to /initiatives via beforeLoad + throw redirect pattern
- Agents, Tasks, Settings nav items disabled (greyed out spans) since they are out of Phase 16-19 scope
- shadcn CLI put files in literal `@/` directory instead of resolving the alias; manually moved to `src/components/ui/`

## Deviations from Plan

### Auto-fixed Issues

**1. [Rule 3 - Blocking] shadcn CLI output directory mismatch**
- **Found during:** Task 1 (shadcn/ui component installation)
- **Issue:** `npx shadcn@latest add` created files in a literal `@/components/ui/` directory instead of resolving the `@/` path alias to `src/`
- **Fix:** Moved files from `packages/web/@/components/ui/` to `packages/web/src/components/ui/` and removed the erroneous `@/` directory
- **Files modified:** Component files relocated to correct path
- **Verification:** Vite build passes, imports resolve correctly
- **Committed in:** `64d751d` (Task 1 commit)

---

**Total deviations:** 1 auto-fixed (1 blocking)
**Impact on plan:** Trivial path fix, no scope creep.

## Issues Encountered
None

## User Setup Required
None - no external service configuration required.

## Next Phase Readiness
- Navigation skeleton complete with all route stubs in place
- Phase 17 can implement DashboardPage content inside initiatives/index.tsx
- Phase 18 can implement InitiativeDetailPage content inside initiatives/$id.tsx
- Phase 19 can implement InboxPage content inside inbox.tsx
- shadcn/ui base components (button, badge, card, dropdown-menu) ready for use

---
*Phase: 16-frontend-scaffold*
*Completed: 2026-02-04*
