Phase 21: Polish & Integration - 6 plans in 3 waves - 3 parallel (Wave 1), 2 parallel (Wave 2), 1 sequential (Wave 3) - Ready for execution
4.7 KiB
phase, plan, type, wave, depends_on, files_modified, autonomous
| phase | plan | type | wave | depends_on | files_modified | autonomous | ||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 21-polish-integration | 05 | execute | 2 |
|
|
true |
Purpose: The production bundle is 544 KB (a single chunk) — everything loads upfront. Route-based code splitting reduces initial load. The InitiativeCard N+1 query pattern (fetching phases per card) is acceptable for v1 but should be acknowledged with a note for future batching. Output: Lazy-loaded routes and reduced bundle size warning.
<execution_context>
@/.claude/get-shit-done/workflows/execute-plan.md
@/.claude/get-shit-done/templates/summary.md
</execution_context>
@packages/web/vite.config.ts @packages/web/src/routes/__root.tsx @packages/web/src/routes/initiatives/index.tsx @packages/web/src/routes/initiatives/$id.tsx @packages/web/src/routes/inbox.tsx @packages/web/src/components/InitiativeCard.tsx
Task 1: Add route-based code splitting via TanStack Router lazy routes packages/web/src/routes/initiatives/index.tsx, packages/web/src/routes/initiatives/$id.tsx, packages/web/src/routes/inbox.tsx TanStack Router file-based routing with the Vite plugin already supports automatic code splitting. The plugin generates lazy routes for files in the routes/ directory.Check if the TanStack Router Vite plugin is configured with autoCodeSplitting: true in packages/web/vite.config.ts. If not, add it to the TanStackRouterVite plugin options.
If autoCodeSplitting is already enabled or the plugin handles it by default, verify by building and checking if the output has multiple chunks instead of one monolithic JS file.
If the plugin does NOT support autoCodeSplitting in this version, manually split using TanStack Router's .lazy.tsx file convention:
- Create
packages/web/src/routes/initiatives/index.lazy.tsx— move the DashboardPage component there, export viacreateLazyFileRoute('/initiatives/')({ component: DashboardPage }) - Create
packages/web/src/routes/initiatives/$id.lazy.tsx— move InitiativeDetailPage and all helper components there - Create
packages/web/src/routes/inbox.lazy.tsx— move InboxPage there - Keep the original files with just the route definition (params, loaders) and remove the component export
The goal: separate chunks for dashboard, detail, and inbox routes.
npm run --workspace=packages/web buildsucceeds- Build output shows multiple JS chunks (not just one index-*.js file)
- No chunk exceeds 500 KB warning, or the warning is reduced Routes are code-split into separate chunks. Initial load only fetches the active route's code.
Fix:
- Move the
onTaskscall into auseEffectwith[tasksQuery.data, planId, onTasks]as dependencies. - Inside the useEffect, only call
onTaskswhentasksQuery.datais defined. - This prevents the setState-during-render issue and aligns with React best practices.
The pattern should be:
useEffect(() => {
if (tasksQuery.data) {
onTasks(planId, tasksQuery.data as unknown as SerializedTask[]);
}
}, [tasksQuery.data, planId, onTasks]);
<success_criteria>
- All tasks completed
- All verification checks pass
- Bundle split into route-level chunks
- No setState-during-render warnings in PlanTasksFetcher </success_criteria>