# P2HS Nuxt 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 + SSR consumer plus thin, per-port BFF routes
- Read .cursor/instructions.md for the complete platform API reference

## Security — Non-Negotiable
- NEVER expose CLOUD_SERVICE_TOKEN or CLOUD_GATEWAY_URL in browser-accessible code
- Server-side runtimeConfig (cloudGatewayUrl, cloudServiceToken, projectId) is only for server/ files
- runtimeConfig.public values are exposed to the browser — only put non-secrets there (projectId, appName, gatewayPublicUrl)
- Generated apps have no direct relationship with P2HS Core — never call Core API endpoints

## BFF Pattern (Always)
- Every Cloud capability is its own installed route under server/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/useFetch, 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 itself checks the caller's role and swaps in the service token — just forward the caller's own token, never CLOUD_SERVICE_TOKEN from client code
- Add new server logic as a new, distinctly-named route in server/api/; never modify an installed path

## Environment Variables
- Client-safe (runtimeConfig.public): projectId, appName, gatewayPublicUrl
- Server-only (runtimeConfig): cloudGatewayUrl, cloudServiceToken, projectId
- CF Pages env var names: CLOUD_GATEWAY_URL, CLOUD_SERVICE_TOKEN, PROJECT_ID, NITRO_PRESET
- Dev proxy target: NUXT_P2HS_GATEWAY_PROXY_TARGET (defaults to http://127.0.0.1:8787)

## 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
- Never build a second login form, users table, or hardcoded admin password

## File Conventions
- Pages: pages/{name}.vue (file-based routing, kebab-case)
- Components: components/Feature/ComponentName.vue
- Composables: composables/useName.ts
- Stores: stores/name.ts
- Server routes: server/api/{feature}/{action}.{method}.ts
- Types: types/domain.ts
- DO NOT MODIFY composables/useP2hsApi.ts — legacy gatewayFetch escape hatch for the rare Cloud capability with no installed port
- DO NOT edit anything under an installed path in p2hs/platform-ports.lock.json, or server/utils/p2hs-ports.mjs / p2hs-port-contract.mjs

## Code Rules
- Vue 3 Composition API with <script setup lang="ts"> always
- Auto-imports active — do not import Vue, Nuxt, or composable functions manually
- useFetch for SSR-compatible data fetching; $fetch for imperative/mutation calls
- Pinia for shared/cross-component state; composables for reusable logic
- TypeScript throughout; no implicit any
- Tailwind CSS for styling
- definePageMeta({ middleware: 'auth' }) on protected pages
