# SPQ v1 → v2 Porting Patterns ## Architecture - **v2**: React 19 + TypeScript + Vite + Tailwind CSS 4. Lives at `/mnt/seagate8tb/Websites/ShopProQuote.backup-20260626-2058/spq-v2/` - **Backend**: Same PocketBase at 127.0.0.1:8091, proxied through `/pb` → served by a Python proxy script - **Build**: `npx vite build` → `dist/` (code-split with React.lazy, ~38 chunks) - **Serve**: `/tmp/spq-backup-server.py` — static files from dist/ + PB proxy on port 4173 ## Common Pitfalls ### PocketBase collection field mismatches SPQ's PocketBase collections often lack `created`/`updated` system fields because they were created via the API rather than the admin UI. Any query using `sort: '-created'` or `fields: '...,created'` will fail with 400. Replace with `sort: '-id'` (PB IDs are roughly chronological). ### Collection naming conventions The same collection may be named `repairOrders` (camelCase) or `repair_orders` (snake_case) depending on how it was created. Always verify the exact name via `GET /api/collections` before writing queries. The error is a 404 with "The requested resource wasn't found" — identical to a missing collection. ### Existing collections vs expected collections Collections that exist: `users`, `quotes`, `customers`, `appointments`, `services`, `settings`, `repairOrders` Collections that may be missing: `invoices`, `service_advisors`, `vehicles` ### Page states when collections are missing Pages should detect 404 responses and show a `SetupBanner` component with the collection name, required fields, and a link to `http://192.168.50.98:8091/_/` (PB admin). See `src/components/SetupBanner.tsx`. ### Build vs TypeScript `npx tsc --noEmit` passing does NOT guarantee `npx vite build` success. Rolldown (Vite's bundler) enforces stricter module resolution. Always run the build after changes. ### React patterns from subagents Subagents frequently produce: - Buttons without `onClick` handlers (appear in DOM but do nothing) - Nested components inside parent functions → input focus loss on every keystroke - AI function modules with hardcoded fallbacks instead of real API calls - Function signature drift between `ai.ts` exports and `QuoteGenerator.tsx` imports ### Test credentials ``` Email: demo@shop.com Password: test1234 ``` The demo user has no data — all pages show empty states.