122 lines
6.6 KiB
Markdown
122 lines
6.6 KiB
Markdown
# 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`.
|