44 lines
1.8 KiB
Markdown
44 lines
1.8 KiB
Markdown
---
|
|
inclusion: fileMatch
|
|
fileMatchPattern: "frontend/**"
|
|
---
|
|
# Frontend Conventions
|
|
|
|
## Stack
|
|
- React 19, TypeScript strict mode, Vite 8
|
|
- Tailwind CSS with custom dark theme (surface-*, brand-* colors)
|
|
- TanStack Router (file-based routes in `routes.tsx`)
|
|
- TanStack Query for data fetching (hooks in `api/hooks.ts`)
|
|
- Recharts for charts, Monaco Editor for SQL, Lucide for icons
|
|
|
|
## API Client
|
|
- `api/client.ts` — shared fetch wrapper with `apiGet`, `apiPost`, `apiPut`, `apiDelete`
|
|
- Three API bases: `query` (→ `/api/`), `registry` (→ `/registry/`), `risk` (→ `/risk/`)
|
|
- Base URLs use `||` fallback (not `??`) because Vite inlines empty string for undefined env vars
|
|
- All hooks in `api/hooks.ts` — typed with TanStack Query
|
|
|
|
## Testing
|
|
- Vitest + MSW (Mock Service Worker) for deterministic tests
|
|
- Test setup: `src/test/setup.ts` starts MSW server
|
|
- Mock handlers: `src/test/mocks/handlers.ts`
|
|
- Test helper: `src/test/render.tsx` provides `renderRoute(path)` with QueryClient + Router
|
|
- Run: `npx vitest --run`
|
|
|
|
## Components
|
|
- Shared UI in `components/ui.tsx`: StatusBadge, ConfidenceBar, TrendArrow, DateRangeSelector, TickerFilter, LoadingSpinner, ErrorBoundary, Card
|
|
- DataTable in `components/DataTable.tsx`: generic sortable/filterable/paginated table
|
|
- AppLayout in `components/AppLayout.tsx`: sidebar nav + main content area
|
|
|
|
## Docker
|
|
- `frontend/Dockerfile`: multi-stage node:24-alpine → nginxinc/nginx-unprivileged:alpine
|
|
- Listens on port 8080 (not 80) for K8s security context compatibility
|
|
- `frontend/nginx.conf`: SPA fallback + `/api/`, `/registry/`, `/risk/` reverse proxies
|
|
|
|
## Adding a New Page
|
|
1. Create `src/pages/MyPage.tsx`
|
|
2. Add route in `src/routes.tsx`
|
|
3. Add nav item in `components/AppLayout.tsx` navItems array
|
|
4. Add API hooks in `api/hooks.ts` if needed
|
|
5. Add MSW handler in `test/mocks/handlers.ts`
|
|
6. Add test in `test/pages.test.tsx`
|