From 335511147365ded2256991c584a57987c46b8c02 Mon Sep 17 00:00:00 2001 From: Baptiste LAFOURCADE Date: Tue, 28 Jul 2026 20:34:28 +0200 Subject: [PATCH] feat(update): self-service flow to update member info after emission Adds the missing "modify my info" path alongside create (certification) and delete (removal). A signed badge encodes only handle + dates + status, so name/LinkedIn/photo/description are directory-only: an update never re-signs, regenerates the record with github/role/status_index preserved, and emission reproduces a byte-identical credential. certified_on (add-commit date) and the proof link stay stable. Empty field = unchanged. - Issue Form update-request.yml (all fields optional) + update-* labels - update-pr.yml workflow: requires an existing record, reuses status_index, gates the photo step on a photo actually provided, moderation shows a before -> after diff - lib/update-request.mjs (pure) reusing the certification validators, which are now exported; toMemberYaml passes role + renewed_on through so no field is lost - round-trip byte-identical test proves the credential is untouched by an update - ARCHITECTURE.md: update sequence + instant-text / lagged-photo note Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01PC9TRnYr5AXe7GmBmHjkBy --- .github/ISSUE_TEMPLATE/update-request.yml | 59 ++++++ .github/scripts/lib/certification-request.mjs | 27 ++- .github/scripts/lib/update-request.mjs | 121 +++++++++++ .github/scripts/lib/update-request.test.mjs | 110 ++++++++++ .github/scripts/read-update-request.mjs | 56 +++++ .github/workflows/update-pr.yml | 200 ++++++++++++++++++ docs/ARCHITECTURE.md | 25 +++ 7 files changed, 587 insertions(+), 11 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/update-request.yml create mode 100644 .github/scripts/lib/update-request.mjs create mode 100644 .github/scripts/lib/update-request.test.mjs create mode 100644 .github/scripts/read-update-request.mjs create mode 100644 .github/workflows/update-pr.yml diff --git a/.github/ISSUE_TEMPLATE/update-request.yml b/.github/ISSUE_TEMPLATE/update-request.yml new file mode 100644 index 0000000..166058c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/update-request.yml @@ -0,0 +1,59 @@ +name: Mettre à jour mes informations +description: Modifier votre nom, photo, profil LinkedIn, site ou description dans l'annuaire des certifiés. +title: "[Certifié] Mise à jour de mes informations" +labels: ["update-request"] +body: + - type: markdown + attributes: + value: | + Modifiez uniquement ce que vous voulez changer. **Un champ laissé vide reste inchangé.** + + Votre identité est le compte GitHub avec lequel vous ouvrez cette demande ; elle n'est pas modifiable ici. Votre badge et sa date de certification ne changent pas : seule votre fiche d'annuaire est mise à jour. Un mainteneur relit la modification avant publication. + - type: input + id: name + attributes: + label: Nom complet + description: Laissez vide pour garder le nom actuel. + placeholder: Prénom Nom + validations: + required: false + - type: input + id: linkedin + attributes: + label: Profil LinkedIn + description: L'adresse complète de votre profil LinkedIn. Laissez vide pour garder l'actuel. + placeholder: https://www.linkedin.com/in/votre-profil + validations: + required: false + - type: input + id: website + attributes: + label: Site web + description: Votre site personnel. Laissez vide pour garder l'actuel. + placeholder: https://votre-site.fr + validations: + required: false + - type: input + id: description + attributes: + label: Description + description: Une phrase de présentation. Laissez vide pour garder l'actuelle. + placeholder: "Développeur passionné d'IA appliquée au dev." + validations: + required: false + - type: textarea + id: photo + attributes: + label: Photo + description: Glissez une nouvelle photo pour remplacer l'actuelle. Laissez vide pour la garder. + validations: + required: false + - type: checkboxes + id: consent + attributes: + label: Exactitude et publication + options: + - label: Je contrôle ce compte GitHub et les informations que je fournis sont exactes. + required: true + - label: J'accepte que ces informations mises à jour soient publiées dans l'annuaire public. + required: true diff --git a/.github/scripts/lib/certification-request.mjs b/.github/scripts/lib/certification-request.mjs index a939552..38f1ef4 100644 --- a/.github/scripts/lib/certification-request.mjs +++ b/.github/scripts/lib/certification-request.mjs @@ -5,12 +5,12 @@ import { clean, parseIssueFormBody } from './issue-form.mjs'; import { extractImageUrl } from './photo-url.mjs'; import { recordPathFor, photoPathFor } from './member-paths.mjs'; -const NO_RESPONSE = '_No response_'; +export const NO_RESPONSE = '_No response_'; -const LIMIT = Object.freeze({ name: 120, linkedin: 200, website: 200, description: 280 }); +export const LIMIT = Object.freeze({ name: 120, linkedin: 200, website: 200, description: 280 }); // Le heading d'un champ Issue Form = son `label`, rendu en `###