# P2HS HTML App — Cursor Rules

## Platform-First Development
- Use P2HS platform ports for database, auth, storage, functions, bookings, jobs, and AI — never build replacements
- Every capability is an installed Cloudflare Pages Function under functions/api/... — call it with a relative fetch('/api/...'), same pattern as every other framework
- Read .cursor/instructions.md for the complete platform API reference

## Security
- CLOUD_SERVICE_TOKEN DOES exist here — inside the installed functions/api/... files only, as a CF Pages env binding. Never add it to js/ or any browser-loaded file.
- Auth tokens (user JWT from signin) go in localStorage — never expose service tokens
- Staff-gated installed routes check the caller's role and add the service token themselves — you only ever forward the caller's own bearer token

## API Calls
- Call installed routes with a relative fetch('/api/...') — no project ID or gateway URL needed for these
- js/p2hs-api.js (window.p2hsApi.coreFetch/cloudFetch) is a legacy escape hatch for a genuine capability with no installed port — check api_surface in the manifest first
- Always check res.ok before calling .json()
- Always handle 401 by redirecting to login

## File Conventions
- Pages: {name}.html in root (e.g. products.html, dashboard.html)
- Scripts: js/{name}.js (ES modules)
- Auth helper: js/auth.js (create this if it doesn't exist)
- DO NOT MODIFY js/p2hs-api.js
- DO NOT edit anything under functions/api/... listed in p2hs/platform-ports.lock.json, or functions/_lib/p2hs-ports.mjs / p2hs-port-contract.mjs

## Provisioning
- p2hs/provision.json — new entities/storage buckets (additive only)
- p2hs/feature-packs.json — install a whole-workflow feature pack
- p2hs/functions.json — deploy a standalone library function
- p2hs/required-user-inputs.json — public URL/embed key/ID only, never a secret

## Code Rules
- Vanilla ES modules (type="module" on script tags)
- async/await for all fetch calls — no .then() chains
- Tailwind CSS via CDN for styling — no separate build step
- Always handle loading states (disable buttons, show spinners)
- Always handle error states (show user-friendly messages, not raw error strings)
- No external JS frameworks — keep it vanilla
