Skip to content

fix(server-nestjs): consume projectMember events in gitlab module - #2721

Merged
shikanime merged 3 commits into
mainfrom
fix/project-member-gitlab-sync
Oct 22, 2026
Merged

shikanime merged 3 commits into
mainfrom
fix/project-member-gitlab-sync

Conversation

@shikanime

@shikanime shikanime commented Sep 11, 2026 •

Copy link
Copy Markdown
Member

Issues liées

Refs #2590


Quel est le comportement actuel ?

project-members.service.ts émet projectMember.upsert / projectMember.delete via AppEventsService, mais aucun consommateur @OnEvent('projectMember.*') n'existe dans server-nestjs : les événements sont émis sans effet et la synchronisation des membres du groupe GitLab ne se fait plus sur les routes déjà basculées (/api/v1/projects).

Quel est le nouveau comportement ?

Le module gitlab consomme les deux événements :

  • projectMember.upsert → re-synchronisation complète des membres du groupe GitLab du projet (réutilise ensureProjectGroupMembers), en parité avec l'étape main du hook legacy upsertProjectMember ;
  • projectMember.delete → suppression ciblée du membre du groupe (résolution email → utilisateur GitLab, puis removeGroupMember) ; utilisateur absent de GitLab = OK, en parité avec l'étape post du hook legacy deleteProjectMember ; groupe absent = OK sans création (voir la différence assumée ci-dessous).

Différence assumée avec le legacy : le hook deleteProjectMember appelait gitlabApi.removeGroupMember, qui passait par getOrCreateProjectGroup et créait donc le groupe GitLab en effet de bord d'une suppression. Le consommateur NestJS ne crée plus le groupe : groupe absent ⇒ OK sans création, une suppression ne doit pas avoir d'effet créateur. C'est cette divergence (et non une parité stricte) qui est couverte par le test « should tolerate a missing GitLab group ».

Les trois sites d'émission restent inchangés. Les résultats passent par capturePluginResult (échec → KO tracé dans le journal admin), comme les consommateurs project.* existants.

Cette PR introduit-elle un breaking change ?

Non.

Autres informations

@shikanime shikanime self-assigned this Sep 11, 2026
@shikanime shikanime added the bug Something isn't working label Sep 11, 2026
@shikanime shikanime added this to the 9.27.0 milestone Sep 11, 2026
@github-actions github-actions Bot added the built label Sep 11, 2026
Comment thread apps/server-nestjs/src/modules/gitlab/gitlab.service.spec.ts Outdated
Comment thread apps/server-nestjs/src/modules/gitlab/gitlab.service.ts Outdated
Comment thread apps/server-nestjs/src/modules/gitlab/gitlab.service.ts
@shikanime shikanime added the preview Deploy preview app with Argo-cd label Sep 24, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🤖 Hey !

A preview of the application is available at : https://console-pr-2721.dso.cpin-hp.numerique-interieur.fr

Please be patient, deployment may take a few minutes.

@shikanime shikanime removed the preview Deploy preview app with Argo-cd label Sep 28, 2026
@shikanime shikanime moved this to Backlog in Cloud Pi Native Sep 29, 2026
@shikanime
shikanime requested review from a team and StephaneTrebel and removed request for StephaneTrebel September 29, 2026 13:07

@shikanime shikanime left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict : Commentaire

Le pont projectMember est propre : l'émission part après commit de la transaction (project-members.service.ts émet hors du $transaction), le handler relit l'état en base — donc idempotent au replay — et la suppression tolère un utilisateur GitLab ou un groupe absents sans faire échouer l'événement. Pas de finding.

Comment thread apps/server-nestjs/src/modules/gitlab/gitlab.service.ts
@shikanime
shikanime force-pushed the fix/project-member-gitlab-sync branch 2 times, most recently from 3993a89 to e88d29b Compare October 1, 2026 16:38

@StephaneTrebel StephaneTrebel left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Le pont projectMember couvre les deux événements et reste idempotent pour les suppressions rejouées. La branche est à 59 commits de main : rebase nécessaire, suivi d’une relance des contrôles, avant approbation.

@iliesmrf iliesmrf modified the milestones: 9.27.0, 9.28.0 Oct 2, 2026
@shikanime
shikanime force-pushed the fix/project-member-gitlab-sync branch from e88d29b to 7097409 Compare October 2, 2026 11:56
@StephaneTrebel

Copy link
Copy Markdown
Collaborator

Relecture de la tête actuelle : les consommateurs projectMember.upsert/delete utilisent capturePluginResult et les cas d’absence GitLab sont couverts. La PR étant en brouillon, aucun verdict formel n’est publié.

@shikanime
shikanime force-pushed the fix/project-member-gitlab-sync branch 2 times, most recently from 735349b to 613b8a9 Compare October 2, 2026 15:09

@shikanime shikanime left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Revue conventions + structure : titre et commits conformes (adresse -open + co-authored-by Automata), brouillon cohérent avec la dépendance à #2579. Le consommateur upsert réutilise ensureProjectGroupMembers (pas de duplication) et la suppression ne crée rien, avec la divergence assumée et testée vis-à-vis du legacy. Un point important en inline : la résolution email → utilisateur GitLab passe par une recherche floue sans vérification d'égalité exacte, sur un chemin destructif. Note : le garde suspended est absent de tout server-nestjs à ce head (fonctionnalité revertée, cf. 097376a3) — cohérent avec les handlers project.* existants, à réintroduire le moment venu. Le retrait des assertions négatives de #2579 après fusion est bien tracé dans la description.

Comment thread apps/server-nestjs/src/modules/gitlab/gitlab.service.ts
@shikanime
shikanime force-pushed the fix/project-member-gitlab-sync branch from 613b8a9 to 26c51a8 Compare October 8, 2026 12:25
@shikanime
shikanime force-pushed the fix/project-member-gitlab-sync branch from 26c51a8 to 9f0fee3 Compare October 15, 2026 13:30
@shikanime

Copy link
Copy Markdown
Member Author

Corrigé sur le head 3b291cf4 — gitlab-client.service.ts:420 ne prend plus le premier résultat de la recherche floue :

   async getUserByEmail(email: string) {
-    const users = await this.client.Users.all({ search: email, orderBy: 'username' })
-    if (users.length === 0) return undefined
-    return users[0] as UserSchema
+    // Fuzzy search matches username and display name too; only an exact
+    // email hit is safe on destructive paths (member removal).
+    const users = await this.client.Users.all({ search: email, orderBy: 'username' })
+    return users.find(user => user.email === email) as UserSchema | undefined
   }

createUser passe déjà par ce chemin pour sa réconciliation 409 : une absence de match exact renvoie undefined et la création 409 ressort — comportement inchangé. Bonus sur ce head : getOrCreateProjectSubGroup cassait nest build (TS2339, la méthode s'appelle ensureProjectSubGroup) et le spec moquait upsertUser disparu — les deux réparés, 116/116 locaux.

@shikanime
shikanime force-pushed the fix/project-member-gitlab-sync branch from 3b291cf to 0618b78 Compare October 21, 2026 13:56
@shikanime
shikanime marked this pull request as ready for review October 21, 2026 13:58
@shikanime

Copy link
Copy Markdown
Member Author

Branche rebasée sur main@origin courant (8739c158), conflits résolus et contrôles relancés localement — la branche passe de 3 commits derrière une base périmée à 3 commits directement sur main :

  • Rebase fix/project-member-gitlab-sync sur 8739c158 (main courant) ; nouvelle tête : 0618b789 (état distant vérifié par git ls-remote).
  • Conflits résolus en union : les handlers zone.upsert/zone.delete de main cohabitent avec les consommateurs projectMember.* ; la ligne d'import fusionne ProjectMemberEventPayload + ZoneEventPayload ; les renommages de main (ensureProjectSubGroup, ensureUser) sont repris dans les chemins de la PR.
  • Portée inchangée : jj diff -r main@origin..@ --stat = les 3 fichiers d'origine (gitlab.service.ts, gitlab.service.spec.ts, gitlab-client.service.ts).
  • Contrôles locaux sur la tête : nest build OK (0 erreur), vitest run src/modules/gitlab/gitlab.service.spec.ts → 39/39 passés, eslint ciblé OK (une collation perfectionist corrigée par eslint --fix, repliée dans le commit).
  • La PR test(server-nestjs): verrouille la parité d'émission projectMember + garde anti-consommateur fantôme #2579 (garde anti-consommateur fantôme) ayant été fermée sans fusion, le paragraphe correspondant de la description a été corrigé : aucune assertion négative à retirer.

shikanime and others added 3 commits October 21, 2026 17:26
projectMember.upsert/delete were emitted with no @onevent consumer, so GitLab group member sync silently stopped on the /api/v1/projects routes already cut over to server-nestjs. Add a gitlab consumer that reconciles the project group members on upsert (parity with the legacy main step) and removes the group member on delete (parity with the legacy post step; absent user or group tolerated as OK).

Refs #2590

Co-authored-by: Automata <automata@shikanime.studio>
Signed-off-by: William Phetsinorath <william.phetsinorath-open@interieur.gouv.fr>
Change-Id: I258b7d5035b1d05946e851297ec3a1376a6a6964

Signed-off-by: Shikanime Deva <22115108+shikanime@users.noreply.github.com>
Co-authored-by: Automata <automata@shikanime.studio>

Signed-off-by: Shikanime Deva <22115108+shikanime@users.noreply.github.com>
Co-authored-by: Automata <automata@shikanime.studio>
Signed-off-by: William Phetsinorath <william.phetsinorath-open@interieur.gouv.fr>
Change-Id: I3a35122664f8d2616ce94fe6d073a80e6a6a6964
@shikanime
shikanime force-pushed the fix/project-member-gitlab-sync branch from 0618b78 to 44af7c5 Compare October 21, 2026 15:27
@cloud-pi-native-sonarqube

Copy link
Copy Markdown

@StephaneTrebel StephaneTrebel left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No findings. Les deux consommateurs couvrent les trois sites d’émission après transaction et remontent leurs résultats via capturePluginResult, conformément au choix documenté dans #2590 et à la divergence assumée pour un groupe absent. Les 150 tests existants et quatre sondes supplémentaires passent, dont deux reproduisent le défaut de recherche floue avec l’ancienne méthode ; lint ciblé et CI verts, SonarQube sans nouvelle issue et cinq fils déjà résolus.

Test Files  8 passed (8)
     Tests  154 passed (154)

@github-project-automation github-project-automation Bot moved this from In Progress to Refinement in Cloud Pi Native Oct 22, 2026
@shikanime
shikanime added this pull request to the merge queue Oct 22, 2026
Merged via the queue into main with commit 19e8c6f Oct 22, 2026
34 checks passed
@shikanime
shikanime deleted the fix/project-member-gitlab-sync branch October 22, 2026 09:04
@github-project-automation github-project-automation Bot moved this from Refinement to Done in Cloud Pi Native Oct 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working built

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🐛 [BUG] server-nestjs: projectMember.upsert/delete events have no consumer (GitLab member sync dead) - Point d'architecture nécessaire

3 participants