# P2HS React App — Cursor Rules

## Platform-First Development
- Use P2HS platform ports for database, auth, storage, functions, bookings, jobs, and AI — never build replacements
- All backend data lives in P2HS Cloud; this app is a frontend consumer plus thin, per-port BFF routes
- Read .cursor/instructions.md for the complete platform API reference

## Security — Non-Negotiable
- NEVER put CLOUD_SERVICE_TOKEN, CLOUD_GATEWAY_URL, or PROJECT_ID in client-side code (VITE_ prefix = exposed to browser)
- NEVER call Cloud Gateway with the service token from the browser
- CLOUD_SERVICE_TOKEN is only used inside installed functions/api/... files (CF Pages Functions)

## BFF Pattern (Always)
- Every Cloud capability is its own installed route under functions/api/... — auth, records, storage, bookings, jobs, ai, fn, imports. There is no single /api/cloud catch-all.
- Installed routes are pinned in p2hs/platform-ports.lock.json and enforced by a pre-push guard — never edit an installed file or add a route that shadows one
- Public/session ports: call directly with fetch, forwarding the signed-in user's own Authorization header for session-gated ports (RLS-aware)
- Staff ports (base records CRUD, admin/users, jobs): the installed route checks the caller's role and swaps in the service token — forward the caller's own token, never CLOUD_SERVICE_TOKEN from client code
- Realtime (SSE) is the one exception — it's a direct browser-to-Cloud EventSource using the user's own token, not an installed port
- Add new server logic as a new, distinctly-named route in functions/api/; never modify an installed path

## Environment Variables
- Client-safe: VITE_PROJECT_ID, VITE_P2HS_CLOUD_PUBLIC_URL (realtime SSE + legacy escape hatch)
- Server-only (CF Pages): CLOUD_GATEWAY_URL, CLOUD_SERVICE_TOKEN, PROJECT_ID

## Provisioning
- p2hs/provision.json — new entities/storage buckets (additive only, never rename/drop/re-seed a live one)
- p2hs/feature-packs.json — install a whole-workflow feature pack (check feature_packs.catalog first)
- p2hs/functions.json — deploy a standalone library function
- p2hs/required-user-inputs.json — ask the owner for a public URL/embed key/ID only, never a secret

## Staff / Admin
- Three fixed role tiers: super_admin > admin > member — do not redesign per project
- Default routes: /login (customer), /admin (staff, role-gated inside) — unless the user names different paths

## File Conventions
- Pages: src/pages/PageName.tsx
- Components: src/components/Feature/ComponentName.tsx
- Hooks: src/hooks/useName.ts
- Types: src/types/domain.ts
- DO NOT MODIFY src/lib/p2hs/ files — legacy escape hatch for a capability with no installed port
- DO NOT edit anything under an installed path in p2hs/platform-ports.lock.json, or functions/_lib/p2hs-ports.mjs / p2hs-port-contract.mjs

## Code Rules
- TypeScript strict mode; no `any` types
- Functional components only — no class components
- Named exports preferred over default exports
- async/await over .then() chains
- Every data-fetching component must handle loading and error states
- Tailwind CSS for all styling
- TanStack Query for server state (cache, invalidate after mutations)
- React Router v7 for routing and navigation
