Files
Kordant/tasks/shieldai-unified-restructure/23-frontend-api-integration.md
2026-05-25 12:23:23 -04:00

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 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:
    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.