6.6 KiB
6.6 KiB
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 handlingweb/src/hooks/useAuth.ts— Auth hook:- Uses
api.user.meto get current user - Exposes
isAuthenticated,user,isLoading,logoutfunction - Handles 401 by redirecting to
/login
- Uses
web/src/hooks/useSubscription.ts— Subscription hook:- Uses
api.billing.getSubscriptionto get tier - Exposes
tier,isLoading,hasFeature(feature)helper
- Uses
web/src/hooks/useNotifications.ts— Notification hook:- Uses
api.correlation.getAlertsfor unread count - Exposes
unreadCount,alerts,markRead(alertId)
- Uses
- 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 APIroutes/(auth)/onboarding.tsx— Call user update + watchlist add APIsroutes/blog.tsx— Callapi.reports.getReportsor dedicated blog routerroutes/blog/[slug].tsx— Call blog post APIroutes/(webapp)/dashboard.tsx— Call correlation, user, subscription APIsroutes/(webapp)/darkwatch.tsx— Call darkwatch APIsroutes/(webapp)/voiceprint.tsx— Call voiceprint APIsroutes/(webapp)/spamshield.tsx— Call spamshield APIsroutes/(webapp)/hometitle.tsx— Call hometitle APIsroutes/(webapp)/removebrokers.tsx— Call removebrokers APIsroutes/(webapp)/settings.tsx— Call user update, notification preference APIs
web/src/components/dashboard/— Updated widgets with real data:StatCarddisplays real metrics from APIActivityFeedshows real alerts from correlation APIQuickActionstriggers real tRPC mutations
steps:
- Update
web/src/lib/api.ts:- Ensure
AppRoutertype is imported from~/server/api/root - Add
headersfunction that reads auth token fromdocument.cookieorlocalStorage - Add
unauthorizedLinkthat redirects to/loginon 401
- Ensure
- Create
web/src/hooks/useAuth.ts:- Use
createAsyncorcreateResourceto callapi.user.me - Return
{ user, isLoading, isAuthenticated: !!user, logout } logoutclears cookie/localStorage and refreshes page
- Use
- Create
web/src/hooks/useSubscription.ts:- Call
api.billing.getSubscription hasFeature(feature)maps feature to required tier (e.g.,darkwatch_realtimerequires Premium)
- Call
- Create
web/src/hooks/useNotifications.ts:- Call
api.correlation.getAlertswithisRead: falsefilter - Poll every 60 seconds for new alerts
markReadcallsapi.correlation.resolveAlertwithRESOLVED
- Call
- 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
- Login: call auth mutation, set token/cookie on success, redirect to
- Update dashboard:
- Replace mock data in
StatCardwith real API calls ActivityFeedusesuseNotificationshookQuickActionslink to service pages or trigger mutations
- Replace mock data in
- Create service pages:
- Each page is a SolidStart route under
(webapp)/ - Uses
createResourceto fetch data on mount - Displays loading states and error boundaries
- Uses
hasFeatureto gate premium functionality
- Each page is a SolidStart route under
- Update Navbar:
- Show user avatar and name from
useAuth - Show unread notification badge from
useNotifications - Show/hide Dashboard link based on auth state
- Show user avatar and name from
- Add error handling:
- Create
ErrorBoundarycomponent for tRPC errors - Show toast notifications for mutations (success/error)
- Create
- 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 testfor frontend integration tests - Run
cd web && pnpm buildand 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
createResourcefor data fetching — it handles loading, error, and refresh states automatically. - For mutations, use
createMutationpattern (or manualapi.xxx.mutate()with signals for loading/error). - Consider creating a
useTRPChook wrapper that handles common patterns (loading, error, retry). - The
hasFeaturehelper should be driven by a config map, not hardcoded in components: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.