AGENT SKILL

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
所属仓库
Volontariapp/meta
最近更新
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

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 entre ms-<domaine>, outbox-<domaine>, worker-<domaine> et post-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 :

  1. Tu vérifies localement la compilation : yarn build (et yarn test).
  2. Tu crées le changeset puis tu appliques le bump : yarn changeset add puis yarn changeset version (une seule fois par branche).
  3. TU T'ARRÊTES IMMÉDIATEMENT. Tu ne touches à AUCUN autre fichier ou repository.
  4. INTERDICTION FORMELLE d'aller modifier, tester ou compiler les microservices consommateurs (ms-*, api-gateway, runners) en avance.
  5. INTERDICTION FORMELLE de bricoler des types, d'utiliser du casting as unknown as Type, ou de poser du any pour faire semblant que le code compile sans le paquet publié.
  6. ACTION EXIGÉE : Tu passes la main au Lead Dev. Tu lui indiques que les modifications dans npm-packages sont prêtes et tu ATTENDS qu'il pousse sur une PR.
  7. 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-tag next et listée en commentaire de la PR (ex: @volontariapp/messaging@2.17.1-snap-a1b2c3d) ou définitive sur main.
  8. 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 :

  1. Mesurer le rayon d'impact : Utilise l'outil MCP find_dependents pour 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" })
    
  2. Pour les flux asynchrones : Si tu modifies un événement ou un job dans messaging, utilise l'outil MCP analyze_impact pour 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"]
  1. Édition locale : Modifications ciblées dans npm-packages/packages/<package>.
  2. Build & Tests : Vérifier que yarn build passe sans aucune erreur.
  3. Changeset :
    • Exécuter yarn changeset add et sélectionner les packages modifiés, puis yarn changeset version pour écrire la version et le CHANGELOG.md que 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, comparer package.json à origin/main : s'il est déjà différent, le bump a eu lieu.
    • yarn changeset add est interactif. Sans TTY, écrire .changeset/<nom>.md (en-tête '@volontariapp/<pkg>': minor|patch, puis une phrase), puis yarn changeset version.
    • version propage un bump patch aux dépendants internes (updateInternalDependencies: patch) : relire le diff des package.json et CHANGELOG.md générés (ex. un changement dans database touche domain-*, outbox, workers, post-processors). yarn check-changelogs compare à origin/main sur des commits : il répond « No packages were modified » tant que rien n'est commité.
  4. 🛑 STOP TOTAL : Arrêt de toute exécution. Informer le Lead Dev que le package est prêt pour la PR.
  5. Attente de publication : Attendre le retour de la CI avec la version snapshot ou définitive.
  6. 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_request de ce ci.yml inclut labeled : poser un label (même notify-discord) relance tout le pipeline, snapshot compris. C'est pourquoi notify-ready ne reçoit pas ORG_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 : le GITHUB_TOKEN y est en lecture seule, le job notify-ready échouerait au lieu de notifier.
  • Le bump se fait dans la PR : yarn changeset add puis yarn changeset version, une seule fois par branche (deux version sur 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 shared reconstruit 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. outbox qui importe un nouvel export de database) : le consommateur lit le dist du 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 est null alors que le type dit string | undefined. Normaliser à la frontière (pushers, sérialisation) pour qu'aucun null ne 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 de ms-<d>/src/migrations/ qui dérive (migration manquante, fichier renommé). Symptôme constaté : passer un événement à FINISHED échouait avec invalid input value for enum events_state_enum: "4" parce que 1781400000000-AddFinishedAndCancelledToEventStateEnum n'était pas copiée. Avant d'écrire un test d'intégration, comparer ls des 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 sur 127.0.0.1:5433 avec testuser/testpassword, base volontariapp_test, et Redis 6379 mot de passe password. ci-tools/docker-compose.yml mappe 5433 sur postgres-post avec 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 (dans proto-registry), la chaîne est asynchrone :
    1. Modification dans proto-registry.
    2. Merge sur main dans proto-registry.
    3. La CI de proto-registry ouvre/met à jour automatiquement une PR dans npm-packages pour régénérer @volontariapp/contracts et @volontariapp/contracts-nest.
    4. Cette PR dans npm-packages doit être mergée et publiée par la CI.
    5. Tu ne dois JAMAIS tenter de toucher aux microservices avant que toute cette boucle ne soit terminée !

[^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
Volontariapp/meta

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.

★ 0
Volontariapp
Volontariapp/meta

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.

律师与法务
★ 0
Volontariapp
Volontariapp/meta

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.

Skill与智能体开发
★ 0
Volontariapp
Volontariapp/meta

volontariapp-implement-async-event-flow

Guide pas-à-pas pour concevoir et implémenter un flux asynchrone complet (messaging -> outbox -> post-processors -> ws-service -> client).

前端开发
★ 0
Volontariapp
Volontariapp/meta

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.

资料检索与研究
★ 0
Volontariapp
Volontariapp/meta

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.

设计师
★ 0