# CLAUDE.md — frontend (UI Nuxt)

> **frontend** : UI clients & dashboard agences (Nuxt 4 / Vue 3 / Vuetify-Vuexy / Pinia /
> CASL / Keycloak OIDC), port local **3000**.
> Gouvernance globale : `../estair-connect-docs/CLAUDE.md` + `../estair-connect-docs/registry/CLAUDE.md`.

## Rôle

Rendu 100 % piloté par les métadonnées CHAPS (colonnes, champs, CTAs, KPI) et les données
ESTAIR. Composables clés : `useEstair`, `useMetadata`, `useFilterCards`, `useCtaExecutor`.

## Règles non-négociables

- 🔒 **FND-007** : le frontend n'accède à AUCUNE base de données — tout passe par les
  proxys HTTP `server/api/proxy/estair/[...].ts` et `server/api/proxy/chaps/[...].ts`
  (jamais d'appel direct navigateur → backend).
- **Rien de hardcodé côté front** : les boutons métier (CTAs avec `endpoint`/`method`),
  les indicateurs KPI et les cartes de filtrage viennent de CHAPS. Ajouter un `case` en
  dur dans un switch d'action est un anti-pattern — utiliser les CTAs auto-descriptives
  (`useCtaExecutor`).
- ⚠️🔒 Multi-tenant : jamais d'`account_uuid` en query param ; abilities CASL via
  `stores/auth.ts`.
- Appels métier : jamais de frontend → messager, estair est l'orchestrateur.
  Exception : les pages de monitoring (`pages/monitoring/*`) consomment l'API
  messager V2 (lecture/replay messages, DLQ) via le proxy serveur
  `server/api/proxy/messager/` (clé API côté Nitro, jamais côté navigateur).

## Repères

- `utils/api.ts` (`$api`) déballe l'enveloppe `{success, data, indicators, pagination}`.
- npm (pas pnpm) ; `npm run dev` / `npm test` / `npm run lint`.
