§8 — Concepts transverses¶
Les concepts qui s'appliquent de manière cohérente sur l'ensemble du code base — ni purement frontend ni purement backend. Chaque concept renvoie à son ADR ou à sa sous-page quand le détail l'exige.
8.1 Design system — Atomic Design + ABEM¶
Le design system est spécifié par ADR-002 (ABEM) et ADR-009 (Storybook scope). Il est catalogué et naviguable sur storybook.alpimonitor.fr — 15 composants présentationnels, 46 stories, 5 pages MDX design system.
Détail tokens, composants et règles éditoriales : design-system.md.
8.2 Conventions Git, code et commits¶
- Commits atomiques + conventional commits en anglais (règle d'engagement 6 de
CLAUDE.md). - ABEM strictement appliqué sur 100 % des composants Vue (ADR-002).
- Règle façade enforced côté web : aucun consumer prod n'importe
useStationsStoredirectement (ADR-010). - Gate
pnpm typecheckfonctionnel depuis le fix C1 (scriptvue-tsc --noEmit --project tsconfig.app.json, voir passe-c-findings §C1). - Push feature branches régulièrement pour déclencher la CI en avance, éviter la flakiness cross-env exposée au merge (mémoire projet
feedback_ci_feedback_loop).
Détail par domaine : conventions.md.
8.3 Observabilité¶
- Logs structurés Pino JSON stdout sur l'API, captés par Coolify. Pas de PII, pas d'IP en clair en base.
/api/v1/health— liveness probe minimaliste avec probe DB (SELECT 1). Consommé par Coolify/Traefik./api/v1/status— exposeIngestionRun.lastRun,lastSuccessAt,healthyThresholdMinutes, compteurs journée. Lu parMStatusBadgedans le hero UI (polling 60 s).- Pas d'APM, pas de tracing distribué — hors scope v1, cf. §10 non-scope.
8.4 Sécurité¶
- 6 headers nginx côté SPA : HSTS (
max-age=31536000; includeSubDomains), CSP, X-Frame-OptionsDENY, X-Content-Type-Optionsnosniff, Referrer-Policystrict-origin-when-cross-origin, Cross-Origin-Opener-Policysame-origin. - CORS allowlist côté API — aucune étoile,
CORS_ORIGINSenv. Origines dev + prod whitelistées explicitement. - Container non-root (
USER app) + volume pre-créé + chowné dans le Dockerfile avantUSER(lesson post-mortem EACCES). - Zod systématique — validation runtime sur tous les endpoints. Payload malformé → 400
VALIDATION_ERROR, pas de crash. - Helmet + rate-limit API reportés post-candidature (read-only public acceptable pour démo).
8.5 Internationalisation¶
vue-i18nFR uniquement en v1. Clésfr.jsonservies viauseI18n().t(key)etuseI18nList<T>(key)(composable dédié pour les arrays).- Multi-langue = backlog v2. Le public cible CREALP est francophone. Ajouter
en/deimpliquerait deux locales à maintenir sans gain immédiat. - Labels UI en français, code / commits / ADR en anglais pour le premier, français pour les autres (§2.2 contraintes).
8.6 Gestion d'erreurs¶
ApiErrorunion discriminée côté web —network | http | parse. Chaque consumer nomme sa branche via le compilateur TS.apiErrorMessage(error)centralise le rendu texte pour les logs / fallbacks (ADR-010 §1.3).- Ingestion LINDAS non-fatal — un échec d'archive disque logue
warnmais ne fait pas échouer l'upsert mesures. L'API reste up même si LINDAS est down (fallback seed + badge "données indisponibles"). entrypoint.shtolérant au seed échoué —prisma migrate deployfatal,prisma db seednon-fatal (warn + continue). Une seed cassée ne met pas l'API offline (post-mortem 2026-04-21).
8.7 Tests — pyramide¶
- Fonctions pures (
lib/charts/chart-model,lib/map/station-map-mapping,lib/hydrodaten) — tests unitaires Vitest, pas de mount, pas de Pinia. - Composables (
useStationDrawer,useStationsList,useStationSelection,useStationMeasurements,useEscapeClose,useScrollLock,usePolling) — tests via composant probe +effectScope. - Intégration composants (
OHydroChart,OStationMap,OStationDrawer,OKeyMetricsSection,MStationCard,ASourcingBadge) —@vue/test-utils+ mount + assertions DOM. - API — 71 tests sur routes (
health,status,stations,station-measurements,station-status,cors) + ingestion (lindas-parser,lindas-ingestion). - Total : 173 tests verts. Pas de E2E Playwright en v1 (reporté backlog).
8.8 Gestion de la documentation¶
- Source de vérité — ce dossier
docs/(arc42, ce site) + les ADR dansdocs/architecture/adr/(sources migrées ici §9). - Règle de dépendance — un changement de décision = mise à jour du doc concerné + ADR si structurant. Un ADR obsolète passe à
Statut: Superseded by ADR-XXX, jamais supprimé. - README racine court — pointe vers
docs.alpimonitor.fr(cette doc) etstorybook.alpimonitor.frpour les détails.