Skip to content

feat: le mandataire compose le groupement et envoie les invitations (FAS-573 US M3) - #494

Open
lordinatrice wants to merge 8 commits into
feature/fas-572-wicked-groupement-wizardfrom
feature/fas-573-groupement-composition-invitations
Open

feat: le mandataire compose le groupement et envoie les invitations (FAS-573 US M3)#494
lordinatrice wants to merge 8 commits into
feature/fas-572-wicked-groupement-wizardfrom
feature/fas-573-groupement-composition-invitations

Conversation

@lordinatrice

@lordinatrice lordinatrice commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

Résumé

  • Étend GroupingMember pour porter la composition du groupement (co-traitants, statuts d'invitation).
  • Résolution SIRET → raison sociale via API Entreprise (FetchRaisonSociale).
  • Le mandataire ajoute/retire des co-traitants (Candidate::AddGroupingMember, Candidate::RemoveGroupingMember).
  • Le mandataire confirme la composition, les invitations sont envoyées par email (Candidate::ConfirmGroupingComposition, GroupingInvitationMailer).
  • Tests cucumber du parcours complet de composition.

Test plan

  • bundle exec rspec — suite complète verte
  • bundle exec cucumber features/grouping_composition.feature — tout passe
  • bin/rubocop — aucun problème

@linear

linear Bot commented Aug 7, 2026

Copy link
Copy Markdown

FAS-573

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Cette PR étend le parcours candidat / groupement pour permettre au mandataire de composer le groupement (ajout/retrait de co‑traitants), de résoudre la raison sociale via API Entreprise, puis de confirmer la composition et déclencher l’envoi des invitations par email.

Changes:

  • Ajout de 2 nouvelles étapes au wizard groupement : grouping_composition et grouping_composition_confirmation (+ endpoints Turbo pour ajouter/retirer des membres).
  • Ajout de la résolution SIRET → raison sociale (FetchCompanyName) et persistance dans GroupingMember#company_name.
  • Envoi d’invitations (token + email) et page publique de consultation d’invitation.

Reviewed changes

Copilot reviewed 44 out of 44 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
spec/requests/candidate/grouping_wizard_spec.rb Ajoute la couverture request du wizard (composition, ajout/retrait Turbo, confirmation).
spec/requests/candidate/grouping_invitations_spec.rb Couvre l’accès à une invitation via token (200/404).
spec/organizers/fetch_company_name_spec.rb Teste l’organizer FetchCompanyName (succès/échec/credentials manquants).
spec/models/market_application_spec.rb Ajoute la logique de step requis grouping_composition côté modèle.
spec/models/grouping_member_spec.rb Ajoute la couverture de validation SIRET et du flag invitation_sent?.
spec/mailers/previews/grouping_invitation_mailer_preview.rb Ajoute un preview pour l’email d’invitation.
spec/mailers/grouping_invitation_mailer_spec.rb Ajoute la spec du mailer d’invitation (to/from/contenu).
spec/interactors/fetch_company_name/make_request_spec.rb Teste l’interactor HTTP de récupération des données entreprise.
spec/interactors/fetch_company_name/extract_name_spec.rb Teste l’extraction de raison_sociale et la gestion JSON invalide.
spec/interactors/candidate/remove_grouping_member_spec.rb Teste la suppression d’un co‑traitant (selon statut invitation / appartenance).
spec/interactors/candidate/confirm_grouping_composition_spec.rb Teste génération token + envoi email + cas déjà invité + cas sans co‑traitant.
spec/interactors/candidate/add_grouping_member_spec.rb Teste validations (SIRET/email) + stockage company_name + gestion erreurs API.
features/step_definitions/grouping_composition_steps.rb Ajoute les steps Cucumber du parcours de composition.
features/step_definitions/candidacy_mode_steps.rb Ajoute un step d’assertion de navigation vers la composition.
features/grouping_legal_type.feature Met à jour le scénario pour rediriger vers la composition.
features/grouping_composition.feature Ajoute la feature Cucumber du parcours complet (JS) de composition & invitations.
db/schema.rb Ajoute la colonne company_name sur grouping_members (schema principal).
db/queue_schema.rb Ajoute la colonne company_name sur grouping_members (queue schema).
db/migrate/20260804154855_add_company_name_to_grouping_members.rb Migration d’ajout de company_name à grouping_members.
config/routes.rb Ajoute routes invitation publique + endpoints members (POST/DELETE) du wizard.
config/locales/fr.yml Ajoute traductions UI wizard + validations + mailer invitation.
app/views/grouping_invitation_mailer/invitation.text.erb Template texte de l’email d’invitation.
app/views/grouping_invitation_mailer/invitation.html.erb Template HTML de l’email (ViewComponent).
app/views/candidate/grouping_wizard/grouping_composition.html.erb Nouvelle vue étape composition.
app/views/candidate/grouping_wizard/grouping_composition_confirmation.html.erb Nouvelle vue récap + confirmation/envoi invitations.
app/views/candidate/grouping_wizard/_members_table.html.erb Partial table des membres (statuts, suppression Turbo).
app/views/candidate/grouping_wizard/_member_form.html.erb Partial formulaire ajout co‑traitant (Turbo + Stimulus).
app/views/candidate/grouping_wizard/_composition_actions.html.erb Actions bas de page (back/continue avec aria-disabled).
app/views/candidate/grouping_invitations/show.html.erb Vue “invitation en cours de traitement”.
app/organizers/fetch_company_name.rb Nouvel organizer FetchCompanyName.
app/models/market_application.rb Ajoute grouping_composition_choice_required? et intégration au wizard.
app/models/grouping_member.rb Ajoute company_name, validation unicité SIRET par groupement, invitation_sent?.
app/mailers/grouping_invitation_mailer.rb Nouveau mailer d’invitation co‑traitant.
app/javascript/controllers/enable_on_fill_controller.js Nouveau controller Stimulus pour activer le bouton quand champs remplis.
app/interactors/fetch_company_name/make_request.rb Interactor pour requête API Entreprise (endpoint + credentials check).
app/interactors/fetch_company_name/extract_name.rb Interactor pour parser JSON et extraire raison_sociale.
app/interactors/candidate/remove_grouping_member.rb Interactor suppression co‑traitant (bloque si déjà invité).
app/interactors/candidate/confirm_grouping_composition.rb Interactor confirmation: token + deliver_later invitation.
app/interactors/candidate/add_grouping_member.rb Interactor ajout co‑traitant (validations + fetch company_name + erreurs).
app/controllers/candidate/grouping_wizard_controller.rb Étend le wizard: show/confirm + endpoints Turbo create/destroy member.
app/controllers/candidate/grouping_invitations_controller.rb Contrôleur public d’affichage d’invitation via token.
app/components/grouping_invitation_email_component.rb Nouveau composant email d’invitation (logo inline).
app/components/grouping_invitation_email_component.html.erb Template HTML email invitation (layout mail).
app/assets/stylesheets/application.css Styles pour l’UI de composition (actions, formulaire, table).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

fill_in I18n.t('candidate.grouping_compositions.email_label'), with: email
find_button(I18n.t('candidate.grouping_compositions.add_button'), disabled: false).click

within('#grouping_members_table') { page.has_content?(siret) } || page.has_css?('.fr-error-text')
@lordinatrice
lordinatrice force-pushed the feature/fas-573-groupement-composition-invitations branch from 615e9d3 to f388c10 Compare August 11, 2026 14:40
@lordinatrice
lordinatrice force-pushed the feature/fas-572-wicked-groupement-wizard branch from 478ef21 to 6200111 Compare August 13, 2026 13:59
…cked

Remplace les 2 controllers par un unique Candidate::GroupingWizardController
basé sur Wicked (même pattern que MarketApplicationsController), où
Précédent/Continuer naviguent toujours d'un cran réel dans une séquence
figée plutôt que de recalculer la destination à chaque clic.

Centralise la cascade de résolution "prochaine étape requise" dans
MarketApplication#next_required_wizard_step, utilisée par
sessions_controller, ApplicationModeGuard et l'API éditeur
(api/v1/market_applications_controller) pour éviter les divergences
entre ces 3 points d'entrée.
Vérifie qu'une reconnexion via magic link pendant le funnel groupement
d'une candidature mixte ramène bien sur l'étape en attente côté
groupement, plutôt que de perdre ce funnel au profit de la candidature
solo.
…n mixte

- update_application_mode redirige désormais vers l'étape courante si le
  mode est déjà choisi, au lieu d'accepter un PATCH qui écrasait le mode
  (et orphelinait le Grouping existant) sans passer par le garde-fou GET.
- sign_in_candidate propage désormais le user au groupement counterpart
  d'une candidature mixte, pas seulement à l'application solo signée.
  Sans ça, groupement_counterpart (filtré par user_id) ne retrouvait
  plus le counterpart après une connexion différée, cassant la
  redirection du wizard pour ce candidat.
@lordinatrice
lordinatrice force-pushed the feature/fas-572-wicked-groupement-wizard branch from 6200111 to d026168 Compare August 13, 2026 15:39
Ajoute company_name (résolue via API Entreprise à l'ajout d'un
co-traitant), la validation d'unicité du SIRET dans un groupement, le
rejet du SIRET du mandataire pour un co-traitant, et invitation_sent?
pour distinguer les co-traitants déjà invités.
@lordinatrice
lordinatrice force-pushed the feature/fas-573-groupement-composition-invitations branch from f388c10 to 62e42be Compare August 13, 2026 15:49
…API Entreprise

Interroge l'API Entreprise (SIRENE) pour résoudre la raison sociale d'un
co-traitant à partir de son SIRET, afin de l'afficher dans le tableau de
composition du groupement sans que le mandataire ait à la saisir.

Remplace FetchBuyerName, qui faisait le même appel mais n'avait aucun
appelant applicatif (FetchPublicMarketBuyerNameJob utilise le pipeline
Insee, pas cet organizer).
Étend GroupingWizardController avec le step grouping_composition et
les sous-routes Turbo Stream create_member/destroy_member. Le
mandataire ajoute un co-traitant par SIRET+email (résolution
automatique de la raison sociale, retrait possible tant que
l'invitation n'a pas été envoyée).
…nvoyées

Ajoute le step grouping_composition_confirmation : récapitulatif du
groupement, confirmation qui déclenche l'envoi d'un email d'invitation
à chaque co-traitant (GroupingInvitationMailer). Ajoute la route
placeholder de consultation de l'invitation par le co-traitant
(grouping_invitations#show), le contenu de la page viendra dans un
ticket dédié.
Couvre l'ajout/retrait de co-traitant, les erreurs de validation
(SIRET invalide, déjà présent, propre SIRET du mandataire, email
invalide) et la confirmation avec envoi des invitations.
@lordinatrice
lordinatrice force-pushed the feature/fas-573-groupement-composition-invitations branch from 62e42be to ab5fbab Compare August 14, 2026 13:08
@lordinatrice
lordinatrice requested a review from Un3x August 14, 2026 13:59
@lordinatrice
lordinatrice force-pushed the feature/fas-572-wicked-groupement-wizard branch 3 times, most recently from cf4e442 to 21c2921 Compare August 18, 2026 13:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants