# 23. Frontend Integration — Wire All Pages to tRPC APIs meta: id: shieldai-unified-restructure-23 feature: shieldai-unified-restructure priority: P1 depends_on: [shieldai-unified-restructure-11, shieldai-unified-restructure-12, shieldai-unified-restructure-13, shieldai-unified-restructure-14, shieldai-unified-restructure-15, shieldai-unified-restructure-16, shieldai-unified-restructure-17, shieldai-unified-restructure-18, shieldai-unified-restructure-19, shieldai-unified-restructure-20, shieldai-unified-restructure-21, shieldai-unified-restructure-22] tags: [frontend, integration, trpc, solidjs] objective: - Wire all frontend pages and components to the tRPC backend, replacing stub data and mock functions with real API calls. Ensure type safety end-to-end from UI to database. deliverables: - `web/src/lib/api.ts` — Updated tRPC client with auth token injection and error handling - `web/src/hooks/useAuth.ts` — Auth hook: - Uses `api.user.me` to get current user - Exposes `isAuthenticated`, `user`, `isLoading`, `logout` function - Handles 401 by redirecting to `/login` - `web/src/hooks/useSubscription.ts` — Subscription hook: - Uses `api.billing.getSubscription` to get tier - Exposes `tier`, `isLoading`, `hasFeature(feature)` helper - `web/src/hooks/useNotifications.ts` — Notification hook: - Uses `api.correlation.getAlerts` for unread count - Exposes `unreadCount`, `alerts`, `markRead(alertId)` - Updated pages with real data: - `routes/index.tsx` — Landing page (no API needed, keep static) - `routes/(auth)/login.tsx` — Call auth API (task 11) - `routes/(auth)/signup.tsx` — Call user creation API - `routes/(auth)/onboarding.tsx` — Call user update + watchlist add APIs - `routes/blog.tsx` — Call `api.reports.getReports` or dedicated blog router - `routes/blog/[slug].tsx` — Call blog post API - `routes/(webapp)/dashboard.tsx` — Call correlation, user, subscription APIs - `routes/(webapp)/darkwatch.tsx` — Call darkwatch APIs - `routes/(webapp)/voiceprint.tsx` — Call voiceprint APIs - `routes/(webapp)/spamshield.tsx` — Call spamshield APIs - `routes/(webapp)/hometitle.tsx` — Call hometitle APIs - `routes/(webapp)/removebrokers.tsx` — Call removebrokers APIs - `routes/(webapp)/settings.tsx` — Call user update, notification preference APIs - `web/src/components/dashboard/` — Updated widgets with real data: - `StatCard` displays real metrics from API - `ActivityFeed` shows real alerts from correlation API - `QuickActions` triggers real tRPC mutations steps: 1. Update `web/src/lib/api.ts`: - Ensure `AppRouter` type is imported from `~/server/api/root` - Add `headers` function that reads auth token from `document.cookie` or `localStorage` - Add `unauthorizedLink` that redirects to `/login` on 401 2. Create `web/src/hooks/useAuth.ts`: - Use `createAsync` or `createResource` to call `api.user.me` - Return `{ user, isLoading, isAuthenticated: !!user, logout }` - `logout` clears cookie/localStorage and refreshes page 3. Create `web/src/hooks/useSubscription.ts`: - Call `api.billing.getSubscription` - `hasFeature(feature)` maps feature to required tier (e.g., `darkwatch_realtime` requires Premium) 4. Create `web/src/hooks/useNotifications.ts`: - Call `api.correlation.getAlerts` with `isRead: false` filter - Poll every 60 seconds for new alerts - `markRead` calls `api.correlation.resolveAlert` with `RESOLVED` 5. Update auth pages: - Login: call auth mutation, set token/cookie on success, redirect to `/dashboard` - Signup: call user creation mutation, then login - Onboarding: collect data in signals, submit via tRPC mutations at each step 6. Update dashboard: - Replace mock data in `StatCard` with real API calls - `ActivityFeed` uses `useNotifications` hook - `QuickActions` link to service pages or trigger mutations 7. Create service pages: - Each page is a SolidStart route under `(webapp)/` - Uses `createResource` to fetch data on mount - Displays loading states and error boundaries - Uses `hasFeature` to gate premium functionality 8. Update Navbar: - Show user avatar and name from `useAuth` - Show unread notification badge from `useNotifications` - Show/hide Dashboard link based on auth state 9. Add error handling: - Create `ErrorBoundary` component for tRPC errors - Show toast notifications for mutations (success/error) 10. Test all pages end-to-end. steps: - E2E: Login flow creates session and redirects to dashboard - E2E: Dashboard displays real user data, subscription tier, and alerts - E2E: Each service page loads and displays real data - E2E: CRUD operations on watchlist, rules, properties work end-to-end - E2E: Logout clears session and redirects to landing page acceptance_criteria: - [ ] All auth pages (login, signup, onboarding) use real tRPC mutations - [ ] Dashboard displays real user profile, subscription, and alert data - [ ] Each service page (DarkWatch, VoicePrint, SpamShield, HomeTitle, RemoveBrokers) loads real data - [ ] Navbar shows authenticated user info and unread alert count - [ ] CRUD operations work end-to-end (create watchlist item, run scan, view results) - [ ] Error states are handled gracefully with toasts and error boundaries - [ ] Unauthenticated users are redirected to login when accessing protected routes - [ ] TypeScript compiles without errors (full end-to-end type safety) validation: - Complete full user journey: signup → onboarding → dashboard → add watchlist item → run scan → view alerts → logout - Verify data persists across page refreshes - Test with different subscription tiers and verify feature gating - Run `cd web && pnpm test` for frontend integration tests - Run `cd web && pnpm build` and verify no TypeScript errors notes: - This is the "glue" task that makes the app functional. It depends on all backend routers being complete. - Use SolidJS `createResource` for data fetching — it handles loading, error, and refresh states automatically. - For mutations, use `createMutation` pattern (or manual `api.xxx.mutate()` with signals for loading/error). - Consider creating a `useTRPC` hook wrapper that handles common patterns (loading, error, retry). - The `hasFeature` helper should be driven by a config map, not hardcoded in components: ```ts const FEATURE_TIERS = { darkwatch_realtime: 'premium', voiceprint_batch: 'plus', hometitle_scan: 'plus', removebrokers_unlimited: 'premium', }; ``` - For pages that don't need tRPC (landing page), keep them static for performance. - Ensure all API calls are batched where possible using tRPC's `httpBatchLink`.