Files
2026-07-12 10:17:17 -04:00

3.6 KiB

Mass Port via Delegation

Pattern used on 2026-06-26 to port 6 pages from vanilla JS v1 to React v2 in one session.

Approach: Parallel Fan-Out

  1. Infrastructure first — update types, routes, navigation yourself (quick edits, no delegation needed)
  2. Dispatch all pages in parallel — 2 batches of 3 delegate_task calls
  3. Each subagent gets: target file path, original source file paths, project context (types, existing patterns, PB collections), feature checklist
  4. Subagents write the complete .tsx file — no partial work, no test cycle (speed over perfect TDD for bulk codegen)

Batch Structure

Wave 1 (dispatch together): Customers, RepairOrders, Appointments
Wave 2 (dispatch together): FinancialDashboard, Invoices, Settings

Per-Task Context Template

TASK: Build <file path>

ORIGINAL SOURCE: <v1 file paths with sizes>

PROJECT CONTEXT:
- React 19 + TypeScript + Vite + Tailwind CSS
- PocketBase backend at pb (import from '../lib/pocketbase')
- Types defined in ../types.ts — see <interfaces>
- Uses lucide-react for icons
- Existing pages for reference: Dashboard.tsx, QuoteGenerator.tsx

FEATURES TO IMPLEMENT:
1. Feature with specific behavior
2. ...

POCKETBASE COLLECTIONS:
- '<name>' collection with fields: <schema>

CODE PATTERNS TO FOLLOW:
- Import pb from '../lib/pocketbase'
- LoadingSpinner for loading state
- Error state with retry button
- Empty state with create CTA
- Modals for create/edit
- Tailwind dark mode patterns

Post-Dispatch

  1. Build: npx vite build
  2. Fix import errors — subagents may use wrong paths or import components that need providers (e.g. useToast needs ToastProvider wrapper)
  3. Add ToastProvider — lazy-loaded pages that use useToast crash silently if ToastProvider isn't wrapping <Routes>
  4. Lazy loading: use React.lazy() + <Suspense> to isolate page errors and enable code splitting
  5. PB collections: subagents can't create collections without admin access. Create missing ones or handle gracefully with error states.

Pitfalls

  • useToast crash: New pages using toast without ToastProvider → white screen with no error message. Always wrap <Routes> in <ToastProvider>.
  • Broken sort field: Legacy PocketBase collections may lack created/updated system fields. Dashboard sort=-created returns 400. Patch built JS to use sort=-id.
  • Double /api prefix: PocketBase SDK's buildURL adds /api/ to the path. Proxy must NOT blindly prepend another /api/.
  • Refreshed browser snapshots: After navigation, refs change. Always re-snapshot before clicking nav links.
  • Missing onClick handlers: Subagents frequently create buttons with text but no onClick — verify every button in generated code has an attached handler.
  • AI function signature mismatches: Subagents may write UI code calling AI functions with different signatures than the actual ai.ts module. Always cross-check the handleAiWrite/handleGeneratePriorities/handleAiSuggest call signatures against the exports in src/lib/ai.ts.
  • Wrong PB collection names: Original v1 code uses underscore names (repair_orders) but the PocketBase instance uses camelCase (repairOrders). Subagents copy the v1 name verbatim → query fails. Always verify collection names against the actual PB instance before dispatching.
  • Lazy-loaded pages and providers: Pages wrapped in React.lazy() don't get providers from parent context if the provider is mounted after the lazy boundary. Mount <ToastProvider> and other context providers ABOVE <Suspense> in App.tsx.