volontariapp-shared-npm-package-change
Modifier un package partagé de npm-packages (messaging, shared, database, domain-*, auth...) et propager la nouvelle version aux consommateurs : rayon d'impact, build, changeset, STOP, snapshot CI, yarn up. À utiliser avant toute édition sous npm-packages/packages/.
- License 许可
- MIT
- 最近更新
- 2026-11-10
- Stars
- ★ 0
- Forks
- 0
01 前言 Front Matter
- name
- volontariapp-shared-npm-package-change
- tags
- [ "npm-packages", "changesets", "stop-rule" ]
- type
- Agent Skill
- paths
- [ "npm-packages/package.json", "npm-packages/packages/*/package.json", "npm-packages/packages/*/CHANGELOG.md", "npm-packages/yarn.lock", "npm-packages/.changeset/config.json", "npm-packages/.github/workflows/**" ]
- title
- Shared NPM Package Change
- status
- stable
- sources
- [ { "id": "changeset", "title": "Configuration changesets", "resource": "npm-packages/.changeset/config.json" }, { "id": "npm-ci", "title": "CI de publication npm-packages", "resource": "npm-packages/.github/workflows" }, { "id": "orchestrate", "title": "ci-orchestrate.py (plan, version snapshot)", "resource": "npm-packages/scripts/ci-orchestrate.py" }, { "id": "snap", "title": "ci-snap-publish.sh (dist-tag next)", "resource": "npm-packages/scripts/ci-snap-publish.sh" }, { "id": "pipeline", "title": "Pipeline réutilisable npm-packages (ci-tools)", "resource": "ci-tools/.github/workflows/npm-packages-pipeline.yml" } ]
- verified
- [ { "at": "2026-11-02T11:07:22Z", "by": "claude-code/agent", "digest": "a449048c4609013e" }, { "at": "2026-11-04T21:25:07Z", "by": "claude-code/agent", "digest": "84e8022a76347fbe" }, { "at": "2026-11-08T11:53:22Z", "by": "claude-code/agent", "digest": "292021b063207bff" }, { "at": "2026-11-08T12:07:09Z", "by": "claude-code/agent", "digest": "94f91136a88eb724" }, { "at": "2026-11-08T22:50:47Z", "by": "claude-code/agent", "digest": "94f91136a88eb724" } ]
- generated
- { "at": "2026-10-06T08:22:12Z", "by": "claude-code/claude-opus-5-5" }
- mesh_keys
- [ "npm-packages", "@volontariapp/" ]
- description
- Modifier un package partagé de npm-packages (messaging, shared, database, domain-*, auth...) et propager la nouvelle version aux consommateurs : rayon d'impact, build, changeset, STOP, snapshot CI, yarn up. À utiliser avant toute édition sous npm-packages/packages/.
02 资源文件 5
- 参考文档index.md1.1 KB
- 参考文档log.md12.8 KB
- 参考文档references/lessons.md30.5 KB
- 参考文档references/package-catalogue.md7.4 KB
- 脚本scripts/consumers.py2.2 KB
03 SKILL.md 正文
Shared NPM Package Change & Règle d'Or du Stop Immédiat
Le répertoire npm-packages/packages/ contient l'ensemble du code partagé entre microservices et leurs processus satellites :
- Packages de domaine (
domain-<domaine>) : partagés entrems-<domaine>,outbox-<domaine>,worker-<domaine>etpost-processors-runner. - Packages transverses (
messaging,contracts,database,auth,logger,errors,monitoring) : consommés par l'ensemble des 17 dépôts.
🛑 RÈGLE D'OR ABSOLUE : LE STOP IMMÉDIAT
[!CAUTION] DÈS QUE TU AS TERMINÉ DE MODIFIER QUOI QUE CE SOIT DANS
npm-packages:
- Tu vérifies localement la compilation :
yarn build(etyarn test).- Tu crées le changeset puis tu appliques le bump :
yarn changeset addpuisyarn changeset version(une seule fois par branche).- TU T'ARRÊTES IMMÉDIATEMENT. Tu ne touches à AUCUN autre fichier ou repository.
- INTERDICTION FORMELLE d'aller modifier, tester ou compiler les microservices consommateurs (
ms-*,api-gateway, runners) en avance.- INTERDICTION FORMELLE de bricoler des types, d'utiliser du casting
as unknown as Type, ou de poser duanypour faire semblant que le code compile sans le paquet publié.- ACTION EXIGÉE : Tu passes la main au Lead Dev. Tu lui indiques que les modifications dans
npm-packagessont prêtes et tu ATTENDS qu'il pousse sur une PR.- La CI GitHub Actions s'exécute sur la PR et génère une version snapshot
<version>-snap-<sha court>, publiée sous le dist-tagnextet listée en commentaire de la PR (ex:@volontariapp/messaging@2.17.1-snap-a1b2c3d) ou définitive surmain.- Ce n'est qu'APRÈS la publication effective par la CI que tu pourras mettre à jour les dépendances dans les microservices consommateurs (
yarn up @volontariapp/<pkg>@<version>).
1. Avant de modifier un package partagé (Impact Analysis)
Ne jamais modifier un package à l'aveugle :
- Mesurer le rayon d'impact : Utilise l'outil MCP
find_dependentspour identifier en $O(1)$ tous les fichiers et services qui importent le package ou symbole modifié :find_dependents({ "target": "@volontariapp/messaging" }) find_dependents({ "target": "SignUpCommand" }) - Pour les flux asynchrones : Si tu modifies un événement ou un job dans
messaging, utilise l'outil MCPanalyze_impactpour visualiser les producteurs, consommateurs et sagas impactés :analyze_impact({ "target": "USER_CREATED" })
2. Déroulement du Workflow Pas-à-Pas
flowchart TD
A["1. Édition du code dans npm-packages/"] --> B["2. Validation locale (yarn build & yarn test)"]
B --> C["3. Changeset et bump (yarn changeset add puis version)"]
C --> D["🛑 4. STOP IMMÉDIAT (Passage de main au Lead Dev)"]
D --> E["5. Le Lead Dev push sur PR GitHub"]
E --> F["6. La CI publie la version Snapshot / Release"]
F --> G["7. Reprise : yarn up dans les microservices consommateurs"]
- Édition locale : Modifications ciblées dans
npm-packages/packages/<package>. - Build & Tests : Vérifier que
yarn buildpasse sans aucune erreur. - Changeset :
- Exécuter
yarn changeset addet sélectionner les packages modifiés, puisyarn changeset versionpour écrire la version et leCHANGELOG.mdque la CI vérifie. - Ne JAMAIS bumper deux fois le même package sur la même branche (ex: pas de 3.1 -> 3.3). Avant
version, comparerpackage.jsonàorigin/main: s'il est déjà différent, le bump a eu lieu. yarn changeset addest interactif. Sans TTY, écrire.changeset/<nom>.md(en-tête'@volontariapp/<pkg>': minor|patch, puis une phrase), puisyarn changeset version.versionpropage un bump patch aux dépendants internes (updateInternalDependencies: patch) : relire le diff despackage.jsonetCHANGELOG.mdgénérés (ex. un changement dansdatabasetouchedomain-*,outbox,workers,post-processors).yarn check-changelogscompare àorigin/mainsur des commits : il répond « No packages were modified » tant que rien n'est commité.
- Exécuter
- 🛑 STOP TOTAL : Arrêt de toute exécution. Informer le Lead Dev que le package est prêt pour la PR.
- Attente de publication : Attendre le retour de la CI avec la version snapshot ou définitive.
- Consommation : Reprendre dans les microservices concernés via
yarn up @volontariapp/<package>@<version-snapshot>et adapter le code consommateur.
2 bis. Ce que fait réellement la CI
npm-packages/.github/workflows/ci.yml appelle le pipeline réutilisable de ci-tools[^pipeline] :
| Étape | Déclencheur | Effet |
|---|---|---|
check-changelogs |
PR et main |
Pour chaque package modifié, vérifie que CHANGELOG.md contient la version de package.json (yarn check-changelogs) : sans yarn changeset version, la PR est rouge |
| Orchestration | PR et main |
Calcule les packages à construire : ceux modifiés et leurs dépendants internes, par couches topologiques[^orchestrate] |
| Build et tests | PR et main |
Matrice parallèle sur ces packages |
| Snapshot | PR uniquement | Publie <version>-snap-<sha court> sous le dist-tag next, et liste les versions en commentaire de la PR[^snap] |
| Release | push sur main |
Publie la version déjà écrite dans package.json (ignorée si elle existe déjà sur le registre), puis met à jour le sous-module npm-packages du repo deploy |
| Secours | workflow_dispatch |
job-emergency-release.yml (option dry_run) |
| Notification | PR uniquement | Job notify-ready du ci.yml (needs: [run-pipeline]) : un seul message Discord (canal backend) quand la PR est prête, pour une PR Dependabot ou une PR portant le label notify-discord. Détail et limites dans volontariapp-ci-tools |
Conséquences pratiques :
- Le déclencheur
pull_requestde ceci.ymlinclutlabeled: poser un label (mêmenotify-discord) relance tout le pipeline, snapshot compris. C'est pourquoinotify-readyne reçoit pasORG_REPO_TOKEN: un label posé avec un jeton personnel relancerait un run de plus à chaque notification. Conséquence non vérifiée sur une vraie PR Dependabot : leGITHUB_TOKENy est en lecture seule, le jobnotify-readyéchouerait au lieu de notifier. - Le bump se fait dans la PR :
yarn changeset addpuisyarn changeset version, une seule fois par branche (deuxversionsur la même branche font sauter une version, 3.1 vers 3.3). - La version à mettre dans un consommateur pendant la PR est celle du commentaire de la CI, par exemple
yarn up @volontariapp/messaging@2.17.1-snap-a1b2c3d. Elle change à chaque push sur la PR. - Modifier
sharedreconstruit aussi tout ce qui en dépend dans le monorepo : le build de la PR est le premier test d'impact. - Les versions déclarées par les consommateurs dérivent : les runners épinglent souvent une version exacte ancienne. Vérifier avec
scripts/consumers.py <package>avant de supposer qu'un consommateur suit la dernière version.
2 ter. Avant d'écrire du code avec un package
Les README de plusieurs packages décrivent des API qui n'existent pas (BaseJobHandler, JwtVerifier, table event_outbox). La table des API réelles et des écarts est dans Catalogue des packages. En cas de doute : smart_search({ query, scope: "npm-packages/packages/<package>" }).
2 quater. Pièges de développement local dans le monorepo
- Erreurs ESLint « error typed value » / « Unsafe call of an error type » dans un package consommateur (ex.
outboxqui importe un nouvel export dedatabase) : le consommateur lit ledistdu package amont, périmé. Reconstruire dans l'ordre (yarn --cwd packages/<amont> build, puis le consommateur) avant de relancer ESLint ; ce n'est pas un vrai défaut de typage. - Colonne nullable :
nullà la lecture,undefinedà la création. Une valeur relue depuis Postgres estnullalors que le type ditstring | undefined. Normaliser à la frontière (pushers, sérialisation) pour qu'aucunnullne parte dans un stream Redis ou un job BullMQ ; seuls les tests d'intégration avec une vraie base le révèlent. - Migrations de test périmées dans
domain-*:packages/domain-<d>/src/test/migrations/est une copie dems-<d>/src/migrations/qui dérive (migration manquante, fichier renommé). Symptôme constaté : passer un événement àFINISHEDéchouait avecinvalid input value for enum events_state_enum: "4"parce que1781400000000-AddFinishedAndCancelledToEventStateEnumn'était pas copiée. Avant d'écrire un test d'intégration, comparerlsdes deux dossiers et copier la migration manquante à l'identique (md5). Ce n'est pas un bug de production. - Tests d'intégration (
database,outbox) : Postgres sur127.0.0.1:5433avectestuser/testpassword, basevolontariapp_test, et Redis6379mot de passepassword.ci-tools/docker-compose.ymlmappe 5433 surpostgres-postavec d'autres identifiants : créer le rôle et la base dedans, et ne pas les supprimer s'ils existaient déjà.
3. Lien avec proto-registry
- Si ta modification de contrat prend sa source dans des fichiers
.proto(dansproto-registry), la chaîne est asynchrone :- Modification dans
proto-registry. - Merge sur
maindansproto-registry. - La CI de
proto-registryouvre/met à jour automatiquement une PR dansnpm-packagespour régénérer@volontariapp/contractset@volontariapp/contracts-nest. - Cette PR dans
npm-packagesdoit être mergée et publiée par la CI. - Tu ne dois JAMAIS tenter de toucher aux microservices avant que toute cette boucle ne soit terminée !
- Modification dans
[^pipeline]: Pipeline réutilisable npm-packages (ci-tools) [^orchestrate]: ci-orchestrate.py (plan, version snapshot) [^snap]: ci-snap-publish.sh (dist-tag next)
04 同仓库更多 Skills
volontariapp-user-account-deletion
Suppression de compte en deux temps (PENDING_DELETION): requestDeletionWithUserDeleted, finalizeDeletion, fan-out de user.deleted vers les domaines et gather ws. A utiliser pour tout changement de domain-user touchant la suppression, le statut ou le cycle de vie d'un user.
volontariapp-proto-contract-evolution
Modifier un contrat Protobuf de proto-registry (champ, message, enum, RPC) sans casser la compatibilité wire, puis suivre la cascade proto-registry, PR automatique dans npm-packages, publication, consommateurs. À utiliser avant toute édition d'un .proto.
volontariapp-meta-scripts
Utiliser et faire evoluer la CLI Node de meta (setup, doctor, migrate, certs, repos, bump) et le manifeste repos.json, source unique des repos et unites du workspace.
volontariapp-implement-async-event-flow
Guide pas-à-pas pour concevoir et implémenter un flux asynchrone complet (messaging -> outbox -> post-processors -> ws-service -> client).
research
Investigate a question against high-trust primary sources and capture the findings as a Markdown file in the repo. Use when the user wants a topic researched, docs or API facts gathered, or reading legwork delegated to a background agent.
prototype
Build a throwaway prototype to answer a design question. Use when the user wants to sanity-check whether a state model or logic feels right, or explore what a UI should look like.