[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6CSW3Y5ZHVBF5BX7S5BAVS0":3,"skill-same:01M6CSW3Y5ZHVBF5BX7S5BAVS0":113},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":38,"linkOnly":39,"markdownContent":40,"markdownBody":41,"frontMatter":42,"refName":78,"commitSha":79,"skillDirectory":80,"forksCount":14,"repositoryHtmlUrl":81,"repositoryHomepageUrl":6,"ownerHtmlUrl":82,"ownerBlogUrl":6,"ownerDescription":83,"updatedAt":84,"install":85,"resources":98},"01M6CSW3Y5ZHVBF5BX7S5BAVS0","volontariapp-user-account-deletion",null,"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\u002Fmeta","Volontariapp","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F263673138?v=4","01M6CSQNQ3J4SKRWA512JQF5K7","VolontariApp","01M6CSQNV8T2M4PR5A22DKHY5T",0,"MIT","https:\u002F\u002Fgithub.com\u002FVolontariapp\u002Fmeta\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Fvolontariapp-user-account-deletion\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"user","volontariapp user account deletion","deletion","account deletion","gather","sonnet","pending","de","code","claude-code","reference","npm","user-account-deletion","src","en","cycle","domain","npm-packages","packages","2026-11-10 10:12:30",false,"---\nname: volontariapp-user-account-deletion\ndescription: \"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.\"\ntype: Domain Reference\ntitle: User Account Deletion\ntags: [user-account-deletion]\nstatus: stable\npaths:\n  - \"npm-packages\u002Fpackages\u002Fdomain-user\u002Fsrc\u002F**\"\nmesh_keys:\n  - PENDING_DELETION\n  - requestDeletionWithUserDeleted\n  - finalizeDeletion\n  - USER_DELETED\ngenerated:\n  by: claude-code\u002Fagent\n  at: \"2026-10-11T16:59:33Z\"\nverified:\n  - by: claude-code\u002Fagent\n    at: \"2026-10-17T12:32:08Z\"\n    digest: f72b7f94d3a033ce\n  - by: claude-code\u002Fagent\n    at: \"2026-10-23T14:44:32Z\"\n    digest: 42ff7c20c027a49a\n  - by: claude-code\u002Fagent\n    at: \"2026-10-30T10:54:45Z\"\n    digest: b63f31dbf26972ff\n  - by: claude-code\u002Fagent\n    at: \"2026-11-04T20:26:39Z\"\n    digest: 9ff504371c918857\n  - by: claude-code\u002Fagent\n    at: \"2026-11-08T12:02:24Z\"\n    digest: 478b23700fbfdb45\nsources:\n  - id: badge-points-migration\n    resource: ms-user\u002Fsrc\u002Fmigrations\u002Fdomain\u002F1793970000000-AddBadgePointsAndProgressDedup.ts\n    title: Migration des points de badges et de la deduplication de progression\n---\n\n# User Account Deletion\n\n## Quand utiliser cette skill\n\nCe document spécifie les **invariants de domaine et règles d'architecture** pour la suppression de compte utilisateur en deux temps (`PENDING_DELETION`). \n\n> [!NOTE]\n> Cette fiche est une référence d'invariants de domaine (`Domain Reference`). Pour exécuter, implémenter ou modifier le pipeline technique asynchrone de bout en bout (émission outbox, stream fan-out, gather WebSocket et compensation), utilise le playbook opérationnel déterministe [`volontariapp-implement-async-event-flow`](\u002Fvolontariapp-implement-async-event-flow\u002FSKILL.md).\n\n## Règles\n\n- `UserService.requestDeletion` appelle `PostgresUserRepository.requestDeletionWithUserDeleted` : dans une seule transaction, le user passe `PENDING_DELETION` (`deletion_requested_at` renseigné) et `user.deleted` est écrit dans `event_queue`. Il n'y a aucun `DELETE` à ce stade.\n- `targetServices` de `user.deleted` : `USER_DELETED` (ws-service, créateur du gather), `SOCIAL_USER`, `USER_DELETED_POST`, `USER_DELETED_EVENT`, `USER_DELETED_STORAGE`, `USER_DELETED_RANKING` (ajouté par npm-packages@91040d72, `postgres-user.repository.ts:116`; le test d'intégration `user-deletion.int.spec.ts` liste les mêmes streams). Le pusher fait un `XADD` par stream, donc un stream par consommateur.\n- `UserService.finalizeDeletion` ne supprime que les users encore `PENDING_DELETION` (idempotent) et n'est appelé qu'après le succès du gather `user.deleted` côté ws-service.\n- Ne jamais supprimer un compte avec `IUserRepository.delete` (hérité de `BaseRepository`, `DELETE` physique sans événement).\n- Un user `PENDING_DELETION` doit être refusé au login et au refresh (côté `ms-user`, via `UserEntity.status`).\n- La migration réelle de `status` et `deletion_requested_at` vit dans `ms-user`; `domain-user\u002Fsrc\u002Ftest\u002Fmigrations` ne sert qu'aux tests d'intégration.\n- Les lignes de `impact_score_credits` (`ImpactScoreCreditModel`, dédup du crédit de score par `(event_id, user_id)`) ont une FK `ON DELETE CASCADE` sur `users` : `finalizeDeletion` les supprime avec le user, sans purge dédiée. La migration de la table vit dans `ms-user`. Il en va de même pour `badge_point_credits` (points crédités par badge, FK `ON DELETE CASCADE` sur `users` et sur `badges`) et `badge_progress_dedup` (déduplication de la progression, FK `ON DELETE CASCADE` sur `users`)[^badge-points-migration].\n- Voir la skill `volontariapp-implement-async-event-flow` pour le gather et les pièges des post-processors de purge.\n\n## Références\n\n- [Leçons apprises](\u002Fvolontariapp-user-account-deletion\u002Freferences\u002Flessons.md)\n\n## Scripts\n\n- Aucun script pour l'instant. Tests: `yarn test` (unitaires) et `yarn test:integration` (Postgres `ms_user` requis) dans `npm-packages\u002Fpackages\u002Fdomain-user`.\n\n[^badge-points-migration]: Migration des points de badges et de la deduplication de progression\n","# User Account Deletion\n\n## Quand utiliser cette skill\n\nCe document spécifie les **invariants de domaine et règles d'architecture** pour la suppression de compte utilisateur en deux temps (`PENDING_DELETION`). \n\n> [!NOTE]\n> Cette fiche est une référence d'invariants de domaine (`Domain Reference`). Pour exécuter, implémenter ou modifier le pipeline technique asynchrone de bout en bout (émission outbox, stream fan-out, gather WebSocket et compensation), utilise le playbook opérationnel déterministe [`volontariapp-implement-async-event-flow`](\u002Fvolontariapp-implement-async-event-flow\u002FSKILL.md).\n\n## Règles\n\n- `UserService.requestDeletion` appelle `PostgresUserRepository.requestDeletionWithUserDeleted` : dans une seule transaction, le user passe `PENDING_DELETION` (`deletion_requested_at` renseigné) et `user.deleted` est écrit dans `event_queue`. Il n'y a aucun `DELETE` à ce stade.\n- `targetServices` de `user.deleted` : `USER_DELETED` (ws-service, créateur du gather), `SOCIAL_USER`, `USER_DELETED_POST`, `USER_DELETED_EVENT`, `USER_DELETED_STORAGE`, `USER_DELETED_RANKING` (ajouté par npm-packages@91040d72, `postgres-user.repository.ts:116`; le test d'intégration `user-deletion.int.spec.ts` liste les mêmes streams). Le pusher fait un `XADD` par stream, donc un stream par consommateur.\n- `UserService.finalizeDeletion` ne supprime que les users encore `PENDING_DELETION` (idempotent) et n'est appelé qu'après le succès du gather `user.deleted` côté ws-service.\n- Ne jamais supprimer un compte avec `IUserRepository.delete` (hérité de `BaseRepository`, `DELETE` physique sans événement).\n- Un user `PENDING_DELETION` doit être refusé au login et au refresh (côté `ms-user`, via `UserEntity.status`).\n- La migration réelle de `status` et `deletion_requested_at` vit dans `ms-user`; `domain-user\u002Fsrc\u002Ftest\u002Fmigrations` ne sert qu'aux tests d'intégration.\n- Les lignes de `impact_score_credits` (`ImpactScoreCreditModel`, dédup du crédit de score par `(event_id, user_id)`) ont une FK `ON DELETE CASCADE` sur `users` : `finalizeDeletion` les supprime avec le user, sans purge dédiée. La migration de la table vit dans `ms-user`. Il en va de même pour `badge_point_credits` (points crédités par badge, FK `ON DELETE CASCADE` sur `users` et sur `badges`) et `badge_progress_dedup` (déduplication de la progression, FK `ON DELETE CASCADE` sur `users`)[^badge-points-migration].\n- Voir la skill `volontariapp-implement-async-event-flow` pour le gather et les pièges des post-processors de purge.\n\n## Références\n\n- [Leçons apprises](\u002Fvolontariapp-user-account-deletion\u002Freferences\u002Flessons.md)\n\n## Scripts\n\n- Aucun script pour l'instant. Tests: `yarn test` (unitaires) et `yarn test:integration` (Postgres `ms_user` requis) dans `npm-packages\u002Fpackages\u002Fdomain-user`.\n\n[^badge-points-migration]: Migration des points de badges et de la deduplication de progression\n",{"name":5,"tags":43,"type":44,"paths":45,"title":47,"status":48,"sources":49,"verified":54,"generated":71,"mesh_keys":73,"description":7},[31],"Domain Reference",[46],"npm-packages\u002Fpackages\u002Fdomain-user\u002Fsrc\u002F**","User Account Deletion","stable",[50],{"id":51,"title":52,"resource":53},"badge-points-migration","Migration des points de badges et de la deduplication de progression","ms-user\u002Fsrc\u002Fmigrations\u002Fdomain\u002F1793970000000-AddBadgePointsAndProgressDedup.ts",[55,59,62,65,68],{"at":56,"by":57,"digest":58},"2026-10-17T12:32:08Z","claude-code\u002Fagent","f72b7f94d3a033ce",{"at":60,"by":57,"digest":61},"2026-10-23T14:44:32Z","42ff7c20c027a49a",{"at":63,"by":57,"digest":64},"2026-10-30T10:54:45Z","b63f31dbf26972ff",{"at":66,"by":57,"digest":67},"2026-11-04T20:26:39Z","9ff504371c918857",{"at":69,"by":57,"digest":70},"2026-11-08T12:02:24Z","478b23700fbfdb45",{"at":72,"by":57},"2026-10-11T16:59:33Z",[74,75,76,77],"PENDING_DELETION","requestDeletionWithUserDeleted","finalizeDeletion","USER_DELETED","main","6b8f03b57018fa66da4666071dc17c1577ff45e8",".agents\u002Fskills\u002Fvolontariapp-user-account-deletion","https:\u002F\u002Fgithub.com\u002FVolontariapp\u002Fmeta","https:\u002F\u002Fgithub.com\u002FVolontariapp","Volontariapp — Application Web\u002FMobile scalabelle construite sur une architecture microservices événementielle (Event-Driven Architecture), implémentant le Trans","2026-11-10 23:40:22",{"source":8,"skillName":5,"commands":86,"prompt":96,"zipAvailable":97},[87,90,93],{"tool":88,"command":89},"npx","npx skills add Volontariapp\u002Fmeta --skill volontariapp-user-account-deletion",{"tool":91,"command":92},"bunx","bunx skills add Volontariapp\u002Fmeta --skill volontariapp-user-account-deletion",{"tool":94,"command":95},"pnpm","pnpm dlx skills add Volontariapp\u002Fmeta --skill volontariapp-user-account-deletion","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FVolontariapp\u002Fmeta\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Fvolontariapp-user-account-deletion\u002FSKILL.md",true,[99,105,109],{"path":100,"resourceType":101,"resourceTypeDesc":102,"sizeBytes":103,"sourceHtmlUrl":104},"index.md","REFERENCE","参考文档",669,"https:\u002F\u002Fgithub.com\u002FVolontariapp\u002Fmeta\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Fvolontariapp-user-account-deletion\u002Findex.md",{"path":106,"resourceType":101,"resourceTypeDesc":102,"sizeBytes":107,"sourceHtmlUrl":108},"log.md",2840,"https:\u002F\u002Fgithub.com\u002FVolontariapp\u002Fmeta\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Fvolontariapp-user-account-deletion\u002Flog.md",{"path":110,"resourceType":101,"resourceTypeDesc":102,"sizeBytes":111,"sourceHtmlUrl":112},"references\u002Flessons.md",2394,"https:\u002F\u002Fgithub.com\u002FVolontariapp\u002Fmeta\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Fvolontariapp-user-account-deletion\u002Freferences\u002Flessons.md",[114,143,170,195,215,233],{"skillNo":115,"name":116,"nameZh":6,"description":117,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":118,"categories":119,"keywords":125,"publishedAt":38},"01M6CSVC1ZW30DDFZ8VMEYAAK6","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.","https:\u002F\u002Fgithub.com\u002FVolontariapp\u002Fmeta\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Fvolontariapp-proto-contract-evolution\u002FSKILL.md",[120],{"categoryNo":121,"categoryName":122,"taxonomyType":123,"taxonomyTypeDesc":124},"01JBSEEDCAT000000000000037","律师与法务","PROFESSION","适用职业",[126,127,128,30,129,130,131,132,133,134,135,37,136,27,137,138,139,140,141,142],"volontariapp proto contract evolution","evolution","lint","registry","sans","sync","yaml","playbook","github","message","analyze","workflows","rpc","ci","pr","grpc","protobuf",{"skillNo":144,"name":145,"nameZh":6,"description":146,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":147,"categories":148,"keywords":154,"publishedAt":38},"01M6CSV99ET2Z9W4W4DAK4CMQP","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.","https:\u002F\u002Fgithub.com\u002FVolontariapp\u002Fmeta\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Fvolontariapp-meta-scripts\u002FSKILL.md",[149],{"categoryNo":150,"categoryName":151,"taxonomyType":152,"taxonomyTypeDesc":153},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,27,28],"volontariapp meta scripts","Meta","node","json","workspace","install","repos","meta-scripts","shell","migrate","bump","cli","doctor","draft","setup",{"skillNo":171,"name":172,"nameZh":6,"description":173,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":174,"categories":175,"keywords":179,"publishedAt":38},"01M6CSTPHNTGE0WF5CPE8W7ZYQ","volontariapp-implement-async-event-flow","Guide pas-à-pas pour concevoir et implémenter un flux asynchrone complet (messaging -> outbox -> post-processors -> ws-service -> client).","https:\u002F\u002Fgithub.com\u002FVolontariapp\u002Fmeta\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Fvolontariapp-implement-async-event-flow\u002FSKILL.md",[176],{"categoryNo":177,"categoryName":178,"taxonomyType":152,"taxonomyTypeDesc":153},"01JBSEEDCAT000000000000009","前端开发",[180,181,182,183,184,185,186,129,187,188,189,190,36,191,37,192,193,27,194,32],"async","implement","volontariapp implement async event flow","flow","event","mapping","flux","shared","messaging","streams","flows","outbox","processor","architecture","runner",{"skillNo":196,"name":197,"nameZh":6,"description":198,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":199,"categories":200,"keywords":204,"publishedAt":38},"01M6CSRQHS0T9955M8CTA5BYJQ","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.","https:\u002F\u002Fgithub.com\u002FVolontariapp\u002Fmeta\u002Fblob\u002Fmain\u002F.agents\u002Fplugins\u002Fmatt-pocock\u002Fskills\u002Fresearch\u002FSKILL.md",[201],{"categoryNo":202,"categoryName":203,"taxonomyType":152,"taxonomyTypeDesc":153},"01JBSEEDCAT000000000000021","资料检索与研究",[197,205,206,207,19,208,209,210,211,212,213,214],"investigate","trust","api","file","repo","markdown","docs","capture","use","question",{"skillNo":216,"name":217,"nameZh":6,"description":218,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":219,"categories":220,"keywords":224,"publishedAt":38},"01M6CSRMZ82M1YK96Z4SW1STTD","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.","https:\u002F\u002Fgithub.com\u002FVolontariapp\u002Fmeta\u002Fblob\u002Fmain\u002F.agents\u002Fplugins\u002Fmatt-pocock\u002Fskills\u002Fprototype\u002FSKILL.md",[221],{"categoryNo":222,"categoryName":223,"taxonomyType":123,"taxonomyTypeDesc":124},"01JBSEEDCAT000000000000032","设计师",[217,225,226,19,227,213,228,214,229,230,231,232],"build","check","ui","look","design","explore","model","state",{"skillNo":234,"name":235,"nameZh":6,"description":236,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":237,"categories":238,"keywords":239,"publishedAt":38},"01M6CSRAZC0EJAK565DMY17TC7","grilling","Grill the user relentlessly about a plan, decision, or idea. Use when the user wants to stress-test their thinking, or uses any 'grill' trigger phrases.","https:\u002F\u002Fgithub.com\u002FVolontariapp\u002Fmeta\u002Fblob\u002Fmain\u002F.agents\u002Fplugins\u002Fmatt-pocock\u002Fskills\u002Fgrilling\u002FSKILL.md",[],[235,240,241,19,213,242,243,244,245],"decision","idea","grill","plan","thinking","test"]