Skip to content
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
151 changes: 151 additions & 0 deletions .github/workflows/metabase-events.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
name: Metabase events

# Deux jobs :
# - drift-check (PR) : fail si docs/events.md est desynchronise avec le code.
# - wiki-sync (push sur dev/master) : regenere docs/events.md et pousse le
# glossaire sur le wiki GitHub (pages: Matomo-Events, Metabase-Materialized-Views,
# Metabase-Dashboards, Metabase-Schema, Metabase-Models).
#
# Pour la sync wiki : le wiki doit avoir ete initialise au moins une fois
# manuellement (creer la premiere page via l'UI GitHub). Ensuite tout est auto.
#
# Secrets requis : aucun - utilise secrets.GITHUB_TOKEN par defaut.
# Si ce token ne peut pas pousser sur le wiki (selon la config du repo),
# definir WIKI_TOKEN (PAT avec scope `repo`) dans les secrets.

on:
push:
branches:
- dev
- master
paths:
- "packages/metabase/events/**"
- "packages/metabase/docs/**"
- "packages/code-du-travail-frontend/src/modules/**/*.ts"
- "packages/code-du-travail-frontend/src/modules/**/*.tsx"
- ".github/workflows/metabase-events.yml"
pull_request:
paths:
- "packages/metabase/**"
- "packages/code-du-travail-frontend/src/modules/**/*.ts"
- "packages/code-du-travail-frontend/src/modules/**/*.tsx"
- ".github/workflows/metabase-events.yml"
workflow_dispatch:

concurrency:
group: metabase-events-${{ github.ref }}
cancel-in-progress: true

jobs:
drift-check:
name: Drift check (docs/events.md synchronise)
if: github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Node
uses: actions/setup-node@v4
with:
node-version-file: .node-version
- name: Install pnpm
uses: pnpm/action-setup@v4
with:
run_install: false
- name: Install metabase deps
run: pnpm install --filter @cdt/metabase --frozen-lockfile
- name: Verify events.md is up-to-date
run: pnpm -F @cdt/metabase events:check

wiki-sync:

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
name: Sync glossaire events vers le wiki
if: github.event_name == 'push'
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Node
uses: actions/setup-node@v4
with:
node-version-file: .node-version

- name: Install pnpm
uses: pnpm/action-setup@v4
with:
run_install: false

- name: Install metabase deps
run: pnpm install --filter @cdt/metabase --frozen-lockfile

- name: Regenerate events docs
run: pnpm -F @cdt/metabase events:docs

- name: Determine wiki auth token
id: wiki-token
env:
WIKI_TOKEN: ${{ secrets.WIKI_TOKEN }}
run: |
if [ -n "${WIKI_TOKEN}" ]; then
echo "Using secrets.WIKI_TOKEN"
echo "token=${WIKI_TOKEN}" >> "$GITHUB_OUTPUT"
else
echo "Using secrets.GITHUB_TOKEN (fallback)"
echo "token=${{ secrets.GITHUB_TOKEN }}" >> "$GITHUB_OUTPUT"
fi

- name: Clone wiki repo
env:
WIKI_URL: https://x-access-token:${{ steps.wiki-token.outputs.token }}@github.com/${{ github.repository }}.wiki.git
run: |
if ! git clone "$WIKI_URL" wiki 2>clone-err.log; then
echo "::warning::Impossible de cloner le wiki. Verifie que le wiki est initialise (creer manuellement une premiere page via l'UI GitHub) et que le token a les droits d'ecriture."
cat clone-err.log
exit 1
fi

- name: Copy docs to wiki pages
run: |
# Noms de pages du wiki GitHub (les espaces deviennent des "-").
cp packages/metabase/docs/events.md wiki/Matomo-Events.md
cp packages/metabase/docs/materialized-views.md wiki/Metabase-Materialized-Views.md
cp packages/metabase/docs/dashboards.md wiki/Metabase-Dashboards.md
cp packages/metabase/docs/schema.md wiki/Metabase-Schema.md
cp packages/metabase/docs/models.md wiki/Metabase-Models.md
# Page d'index du wiki (Home.md) avec liens croises.
cat <<'EOF' > wiki/Home.md
# Metabase & Events Matomo — CDTN

Ce wiki est **auto-genere** depuis `packages/metabase/` a chaque push sur `dev` / `master`.
Ne pas editer directement : modifier les fichiers source dans le repo et la sync
s'occupera du reste.

## Pages disponibles

- [Matomo-Events](./Matomo-Events) — glossaire exhaustif des events emis par le frontend, avec declencheur metier, KPI, dashboards et cartes lies.
- [Metabase-Dashboards](./Metabase-Dashboards) — reference des dashboards et cartes maintenus.
- [Metabase-Materialized-Views](./Metabase-Materialized-Views) — definitions et patterns d'usage des vues materialisees.
- [Metabase-Models](./Metabase-Models) — modeles Metabase et patterns SQL optimises.
- [Metabase-Schema](./Metabase-Schema) — schema de la DB OVH PG CDTN.

## Sources

Code : [`packages/metabase/`](https://github.com/${{ github.repository }}/tree/dev/packages/metabase)
Pipeline events : [`packages/metabase/events/`](https://github.com/${{ github.repository }}/tree/dev/packages/metabase/events)
Workflow de sync : [`.github/workflows/metabase-events.yml`](https://github.com/${{ github.repository }}/blob/dev/.github/workflows/metabase-events.yml)
EOF

- name: Commit and push to wiki
working-directory: wiki
run: |
git config user.name "cdtn-events-bot"
git config user.email "cdtn-events-bot@users.noreply.github.com"
git add -A
if git diff --cached --quiet; then
echo "Aucun changement a pousser sur le wiki."
exit 0
fi
git commit -m "chore(events): sync depuis ${{ github.sha }} (workflow ${{ github.run_id }})"
git push
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ lerna-debug.log
packages/code-du-travail-modeles/bin
packages/code-du-travail-modeles/lib
token
.lighthouseci
.lighthouseci
.mcp.json
13 changes: 13 additions & 0 deletions .mcp.example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"$schema": "https://modelcontextprotocol.io/schema/mcp.json",
"mcpServers": {
"metabase": {
"command": "npx",
"args": ["@easecloudio/mcp-metabase-server"],
"env": {
"METABASE_URL": "https://metabase-cdtn.fabrique.social.gouv.fr",
"METABASE_API_KEY": "your_api_key_here"
}
}
}
}
57 changes: 57 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# CLAUDE.md — Code du Travail Numerique

Monorepo pnpm + lerna du projet Code du travail numerique (CDTN). Ce fichier est le point d'entree pour les IA agents (Claude Code, Cursor, etc.). Pour chaque dossier, un `CLAUDE.md` local precise les regles specifiques.

## Stack

- **Node 24** (`.node-version`), **pnpm 10** (`packageManager`), **lerna 9** pour l'orchestration monorepo.
- 4 packages dans `packages/*` :
- `@cdt/frontend` (`code-du-travail-frontend`) — app Next.js principale ([CLAUDE.md](packages/code-du-travail-frontend/CLAUDE.md))
- `@socialgouv/modeles-social` (`code-du-travail-modeles`) — regles publicodes et modeles de calcul (simulateurs)
- `@socialgouv/cdtn-utils` (`code-du-travail-utils`) — utilitaires partages
- `@cdt/metabase` (`metabase`) — dashboards Metabase + pipeline events Matomo ([CLAUDE.md](packages/metabase/CLAUDE.md))

## Regles globales

1. **Conventions de code** : voir [`BEST_PRACTICE.md`](BEST_PRACTICE.md) (nommage `kebab-case` / `PascalCase`, regle de l'`index.ts`, conventions de test).
2. **Commits / PR** : messages conventionnels (`feat:`, `fix:`, `chore:`, `docs:`). Les PR sont squashees sur `dev`, promues vers `master` pour release.
3. **Branch de travail** : forker depuis `dev` (branche integration). `master` = production.
4. **Precommit** : `husky` + `lint-staged` (config dans chaque package). Inclut les drift checks du pipeline events Metabase (`@cdt/metabase precommit`).
5. **CI** : voir `.github/workflows/` (build, lint, format, type-check, tests, e2e, lighthouse, wiki sync events).

## Commandes racine

```bash
pnpm install # install toutes les deps du monorepo
pnpm dev:frontend # dev frontend + modeles en parallele
pnpm build # build utils + modeles + frontend
pnpm test # frontend + modeles + utils
pnpm lint # lint tous les packages
pnpm format # prettier sur tous les packages
pnpm type-check # tsc sur tous les packages
```

## Ou trouver quoi

| Besoin | Ou |
| --- | --- |
| Ajouter un event Matomo | [`packages/metabase/events/CLAUDE.md`](packages/metabase/events/CLAUDE.md) |
| Modifier un simulateur | [`packages/code-du-travail-frontend/src/modules/outils/`](packages/code-du-travail-frontend/src/modules/outils/) + `packages/code-du-travail-modeles/src/modeles/` |
| Creer une carte Metabase | [`packages/metabase/CLAUDE.md`](packages/metabase/CLAUDE.md) (§Process avant TOUTE modification) |
| Ajouter une regle publicodes | `packages/code-du-travail-modeles/BEST_PRACTICE.md` |
| Comprendre le KPI d'un dashboard | [Wiki Metabase-Dashboards](https://github.com/SocialGouv/code-du-travail-numerique/wiki/Metabase-Dashboards) (auto-sync depuis `packages/metabase/docs/dashboards.md`) |
| Ajouter une contribution / CC traitee | `packages/code-du-travail-frontend/src/modules/contributions/` + modeles publicodes |
| Ajouter / modifier une variable d'env | Chercher dans `packages/code-du-travail-frontend/src/config.ts` |

## Priorites strictes

- **Toujours** mettre a jour la doc `docs/` du package touche en meme temps que le code (regle recursive : chaque package/sous-dossier precise ce qui doit etre sync).
- **Ne jamais** editer `packages/metabase/docs/events.md` a la main (auto-genere ; voir son CLAUDE.md).
- **Ne jamais** commiter `.mcp.json`, `.env`, cles API (gitignore defaillant = a corriger immediatement).
- **Pour tout event trace** : valider que le trio `(category, action, name)` matche bien ce qu'attend Metabase avant merge. Le pipeline `@cdt/metabase events:check` bloque la PR en cas de drift.

## Ressources externes

- Site prod : <https://code-du-travail.beta.gouv.fr/>
- Metabase : <https://metabase-cdtn.fabrique.social.gouv.fr>
- Issues GitHub : <https://github.com/SocialGouv/code-du-travail-numerique/issues>
110 changes: 110 additions & 0 deletions packages/code-du-travail-frontend/CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# @cdt/frontend — consignes Claude

App Next.js (App Router) du CDTN. Stack principale :

| Techno | Role | Ou |
| --- | --- | --- |
| **Next.js 14+** (App Router) | Framework web, SSR + SSG | `app/`, `next.config.mjs` |
| **React 18+** | UI | composants fonctionnels + hooks |
| **TypeScript strict** | Typage | `tsconfig.json` |
| **@codegouvfr/react-dsfr** | Design System de l'Etat (DSFR) | composants `Button`, `Input`, `fr.cx()` pour les classes |
| **Panda CSS** | CSS-in-JS atomique | `panda.config.ts`, `@styled-system/css` |
| **Zustand + Immer** | State management (simulateurs) | `modules/outils/*/store/` |
| **Elasticsearch 8** | Moteur de recherche | `src/api/modules/search/` |
| **@socialgouv/matomo-next** | Tracking Matomo | voir §Tracking ci-dessous |
| **Sentry + OpenTelemetry** | Monitoring + traces | `sentry.*.config.ts`, `instrumentation*.ts` |
| **Jest + Testing Library** | Tests unitaires | `*.test.{ts,tsx}` colocalises |
| **Playwright** | Tests e2e | `test-results/`, `playwright.config.ts` |
| **Publicodes (via `@socialgouv/modeles-social`)** | Moteur de regles des simulateurs | `modules/outils/indemnite-*` |

## Architecture des modules

`src/modules/<feature>/` est le decoupage principal. Conventions par dossier :

- `tracking.ts` / `tracking.tsx` → hook `useXxxTracking()` qui expose des `emitXxx()` wrappant `sendEvent` ou `push` de matomo-next.
- `events/` → emitters specifiques aux simulateurs (ex: `useIndemniteLicenciementEventEmitter`).
- `store/` (zustand) → slice par etape de simulateur.
- `components/` → composants React colocalises.
- `__tests__/` → tests Jest colocalises (exclus du scan events).

Voir [`BEST_PRACTICE.md`](../../BEST_PRACTICE.md) pour les regles de nommage (`kebab-case` / `PascalCase`) et la convention `index.ts`.

## Tracking Matomo

**Toute modification d'event doit etre accompagnee d'une mise a jour de `@cdt/metabase`.**

### Ajouter un event custom (cas standard)

```typescript
// modules/ma-feature/tracking.ts
import { sendEvent } from "@socialgouv/matomo-next";

enum MyCategory {
MY_CATEGORY = "ma_category",
}

enum MyAction {
MY_ACTION = "mon_action",
}

export const useMyFeatureTracking = () => {
const emitMyEvent = (idcc: number) => {
sendEvent({
category: MyCategory.MY_CATEGORY,
action: MyAction.MY_ACTION,
name: idcc.toString(),
});
};
return { emitMyEvent };
};
```

Puis :
1. `pnpm -F @cdt/metabase events:docs` → l'event apparait dans `packages/metabase/docs/events.md` (section "Orphelins" au premier run).
2. Documenter dans `packages/metabase/events/events.metadata.yaml` (cle `"ma_category:mon_action"`, champs `label_fr`, `trigger`, `feature_group`, optionnellement `kpi`, `dashboards`, `cards`, `mv_source`).
3. Relancer `pnpm -F @cdt/metabase events:docs`. L'event passe dans sa section metier.
4. Commit tout ensemble : `tracking.ts` + `events.metadata.yaml` + `events.extracted.json` + `docs/events.md`.

Le precommit husky lance `events:check` qui bloque le commit si ces fichiers sont desync.

### Autres patterns Matomo

- `push(["trackSiteSearch", query])` → event natif Matomo site search (cf. `modules/recherche/tracking.ts:194`).
- `push(["trackEvent", cat, action, name])` → alternative a `sendEvent` (meme semantique, moins prefere).
- `_paq.push([cmd, ...])` → commandes de configuration (consent, heatmap, A/B test, etc.). Non-events ; listees en section "Commandes Matomo de configuration" du glossaire.

Tous ces patterns sont detectes par `@cdt/metabase events:extract` (AST scan).

## Ajouter un simulateur

1. Creer `modules/outils/<nom-simulateur>/` avec sous-dossiers : `steps/`, `store/`, `components/`, `events/`.
2. Implementer les etapes via Zustand + Immer (voir `indemnite-licenciement` comme reference).
3. Brancher `useXxxEventEmitter` pour fire `view_step_*`, `click_previous_*`, `results_ineligible`.
4. Ajouter la regle de calcul dans `@socialgouv/modeles-social` (publicodes).
5. Exposer la route dans `app/outils/<slug>/`.
6. Tester : Jest pour la logique, Playwright pour le parcours complet.
7. **Documenter les events** : editer `packages/metabase/events/events.metadata.yaml` (cf. §Tracking).

## Tests

- **Unit / integration** : `pnpm test:frontend` (Jest + Testing Library). Snapshot dans `__snapshots__/`, update avec `--updateSnapshot`.
- **API** : `pnpm test:api` (Elasticsearch en docker).
- **E2E** : `pnpm test:e2e` ou `pnpm test:e2e:ui` (Playwright).
- **RGAA** : `playwright.rgaa.config.ts` — tests d'accessibilite automatiques.

## Commandes courantes

```bash
pnpm dev # serveur Next.js en dev
pnpm build # prebuild (tsup) + panda + dsfr + next build
pnpm lint # eslint
pnpm format # prettier
pnpm type-check # tsc --noEmit
```

## Ne pas faire

- **Ne jamais** mettre une cle API Matomo / Sentry / Elasticsearch dans le code source ; toutes les variables sensibles passent par `.env` (gitignore).
- **Ne jamais** appeler `sendEvent` / `push` depuis un composant directement — toujours passer par un hook `useXxxTracking()`. Facilite le mock en test et l'extraction AST.
- **Ne jamais** dupliquer un `enum` d'event : si `analytics/types.ts` contient deja l'enum, l'importer plutot que redeclarer localement (evite le drift).
- **Ne jamais** editer `packages/metabase/docs/events.md` a la main — c'est l'output auto-genere du pipeline. La source technique est le code TS de ce package ; la source metier est `packages/metabase/events/events.metadata.yaml`.
45 changes: 45 additions & 0 deletions packages/code-du-travail-modeles/CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# @socialgouv/modeles-social — consignes Claude

Moteur de **regles publicodes** pour les simulateurs CDTN (Indemnite de licenciement, IRC, Preavis retraite, Preavis demission, Heures recherche emploi, etc.).

## Stack

| Techno | Role |
| --- | --- |
| **Publicodes** | Langage de regles declaratif (fichiers `.yaml` dans `src/modeles/` et `src/publicodes/`) |
| **TypeScript** | API programmatique exposant les engines publicodes |
| **Jest** | Tests unitaires (un `*.spec.ts` par regle / CC) |
| **tsup** | Bundler pour l'export npm |

## Organisation du code

```
src/
├── __test__/ tests publicodes par theme (legal + CC specifiques) — voir BEST_PRACTICE.md
├── internal/ wrappers TS autour des engines publicodes
├── modeles/ regles publicodes par simulateur (packages de regles)
├── publicodes/ wrappers haut niveau par simulateur
└── index.ts exports publics consommes par @cdt/frontend
```

Voir **[`BEST_PRACTICE.md`](BEST_PRACTICE.md)** pour la structure des tests (dossier `legal/` pour le code du travail, dossier par CC + simulateur, granularite des specs selon la complexite).

## Regles

1. **Toute modification d'une regle publicodes doit etre couverte par un test** dans `src/__test__/`.
2. **Les changements qui modifient le resultat d'un simulateur** doivent etre signales dans `CHANGELOG.md` et peuvent necessiter un rebuild du site (dependance directe de `@cdt/frontend`).
3. **Les references legales** (code du travail, CC) sont obligatoires dans chaque regle — voir les `references.spec.ts` qui les valident.
4. **Pas d'event Matomo ici** : le package est 100% moteur de regles, sans side-effects. Le tracking des simulateurs se fait dans `@cdt/frontend/src/modules/outils/**`.

## Commandes

```bash
pnpm -F @socialgouv/modeles-social test # jest
pnpm -F @socialgouv/modeles-social build # tsup
```

## Ne pas faire

- Ne jamais introduire un `import` vers `@cdt/frontend` (cycle) : ce package est consomme en aval, pas l'inverse.
- Ne jamais importer `matomo-next` ou `sendEvent` ici — le tracking est une responsabilite exclusive du frontend.
- Ne pas faire d'appel reseau / side-effect dans les wrappers publicodes — ils doivent rester purs.
Loading
Loading