|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Project overview |
| 6 | + |
| 7 | +Frosting is a Vue 3/Nuxt frontend (SPA mode, no SSR) for the [Cupcake](https://github.com/javaBin/cupcake) backend. It lets javaBin heroes (`helter` group) browse JavaZone conferences and sessions to find potential speakers for local events. |
| 8 | + |
| 9 | +## Commands |
| 10 | + |
| 11 | +```bash |
| 12 | +pnpm install # Install dependencies |
| 13 | +pnpm dev # Start dev server on :3000 (proxies /api/* to :8080) |
| 14 | +pnpm build # Production build (outputs to .output/) |
| 15 | +pnpm preview # Preview production build |
| 16 | +pnpm lint # ESLint check |
| 17 | +pnpm lint:fix # ESLint auto-fix |
| 18 | +pnpm format # Prettier format |
| 19 | +``` |
| 20 | + |
| 21 | +There are no unit tests in this project. |
| 22 | + |
| 23 | +## Architecture |
| 24 | + |
| 25 | +### Authentication |
| 26 | +- OIDC Authorization Code flow via `oidc-client-ts` |
| 27 | +- Tokens in browser `sessionStorage`; cleared on browser close |
| 28 | +- Global auth middleware in `app/plugins/auth.client.ts` protects all routes |
| 29 | +- `helter` group required for access; home page warns if user is not a member |
| 30 | +- Logic lives in `app/composables/useAuth.ts` |
| 31 | + |
| 32 | +### API layer |
| 33 | +- `app/composables/useApiFetch.ts` — wraps `$fetch` with Bearer token injection; on 401, silently refreshes token and retries |
| 34 | +- `server/middleware/proxy.ts` — Nitro/h3 server middleware that transparently proxies `/api/*`, `/login`, and `/refresh` to the Cupcake backend, keeping everything same-origin to avoid CORS |
| 35 | + |
| 36 | +### State management |
| 37 | +- No Pinia — uses Nuxt `useState()` composables |
| 38 | +- `app/composables/conferences.ts` — conference list |
| 39 | +- `app/composables/sessions.ts` — sessions per conference |
| 40 | +- `app/composables/useSessionData.ts` — single session detail |
| 41 | +- `app/composables/useUser.ts` — current user from `/api/me` |
| 42 | +- Each composable uses `Pending`/`Loaded` flags to prevent duplicate API calls |
| 43 | + |
| 44 | +### Pages |
| 45 | +| Route | File | Purpose | |
| 46 | +|-------|------|---------| |
| 47 | +| `/` | `app/pages/index.vue` | Auth check, user info, role warning | |
| 48 | +| `/conference/[conferenceId]` | `app/pages/conference/[conferenceId]/index.vue` | Session browser with format/language/status filters | |
| 49 | +| `/conference/[conferenceId]/session/[sessionId]` | `app/pages/conference/[conferenceId]/session/[sessionId]/index.vue` | Session detail with full speaker info | |
| 50 | + |
| 51 | +## Key environment variables |
| 52 | + |
| 53 | +| Variable | Default | Description | |
| 54 | +|----------|---------|-------------| |
| 55 | +| `CUPCAKE_BACKEND` | `http://127.0.0.1:8080` (dev) / `https://cupcake-backend.java.no` (prod) | Backend URL for server-side proxy | |
| 56 | +| `CUPCAKE_FRONTEND` | `localhost` | Hostname for Vite `allowedHosts` | |
| 57 | +| `NUXT_PUBLIC_OIDC_AUTHORITY` | `https://auth.home.chrissearle.org/realms/HA12` | Keycloak realm URL | |
| 58 | +| `NUXT_PUBLIC_OIDC_CLIENT_ID` | `cupcake-client` | OIDC client ID | |
| 59 | + |
| 60 | +For local dev against the Cupcake backend with `JWT_ENABLED=false`, no OIDC config overrides are needed. |
| 61 | + |
| 62 | +## Code style |
| 63 | + |
| 64 | +- TypeScript throughout; `any` is not acceptable |
| 65 | +- No semicolons (Prettier config) |
| 66 | +- ESLint + Prettier enforced via pre-commit hooks (lint-staged + husky) |
| 67 | +- All changes must pass `pnpm lint` before merging (enforced in `pr.yaml`) |
| 68 | +- Use exact versions for dependencies |
0 commit comments