-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
API Particulier x DataPass : handle Formulaire QF modality #1579
base: develop
Are you sure you want to change the base?
Conversation
96a999d
to
78e5316
Compare
Ça se lit commit par commit. Il manque le Pour un peu de contexte: j'ai jugé qu'il était plus logique de s'occuper de la création/gestion des accès à la suite de la validation d'une demande côté APIM (ici donc) plutôt que côté DataPass. Pourquoi ? Parce que ce n'est pas le job de DataPass. DataPass s'occupe juste de notifier des divers évenements qui surviennent sur les habilitations. En pratique ici on crée déjà chez nous l'accès via un jeton, c'est donc naturel, qu'en fonction des modalités, que l'on crée l'accès sur HubEE de notre côté. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
C'est ptêtre juste une impression mais j'ai le feeling que tu en as eu un peu marre à la fin x) le code perd un peu en clarté au fur et à mesure
Sinon quelques remarques mais rien de critique.
context 'when modalities does no include params' do | ||
before do | ||
datapass_webhook_params['data']['data']['modalities'] = ['formulaire_qf'] | ||
end | ||
|
||
it 'does not create a token' do | ||
expect { | ||
subject | ||
}.not_to change(Token, :count) | ||
end | ||
end | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
J'ai pas la tête dans datapass ni le formulaire QF donc je vois pas du tout ce que ça implique que modalities
inclue params
ou pas
Un describe
supplémentaire pour documenter peut-être serait pas de trop
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Je pense que ce qui me confuse c'est le fait que :
- sur un modalities = 'formulaire qf' on skip
- sur un modalities = 'params' on avance
Et le titre c'est "no params modalities". Ca fait beaucoup de params.
Je changerai bien le return if context.modalities.exclude?('params')
en return if !from_datapass
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Niveau modalité sur API Particulier il y a:
params
, qui correspond en fait à "faire des appels à l'API avec des paramètres d'entrée"formulaire qf
, qui correspond à utiliser le formulaire QFfranceconnect
qui utilise uniquement FC pour accéder à l'API
A noter que je n'ai pas trop réfléchi aux ids techniques, ça peut changer encore.
Pour 2. et 3. il n'y a pas besoin de jeton, seul 1. a besoin d'un jeton.
Si il n'y a pas la modalité params
il n'y a aucune raison de créer un jeton. En pratique à court terme params
sera toujours présent je pense.
Je changerai bien le
return if context.modalities.exclude?('params')
enreturn if !from_datapass
Tout vient de DataPass, je ne comprends pas bien ta remarque du coup.
stub_request(:get, "#{host}/referential/v1/organizations/SI-#{siret}-#{code_commune}").to_return( | ||
status: 200, | ||
headers: { 'Content-Type' => 'application/json' }, | ||
body: valid_payload.to_json | ||
) | ||
end | ||
|
||
it 'renders a valid json from payload' do | ||
expect(find_organization_payload).to eq(valid_payload) | ||
end | ||
end | ||
|
||
context 'when API returns 404' do | ||
before do | ||
stub_request(:get, "#{host}/referential/v1/organizations/SI-#{siret}-#{code_commune}").to_return( | ||
status: 404, | ||
headers: { 'Content-Type' => 'application/json' }, | ||
body: { | ||
'header' => { | ||
'statut' => 404, | ||
'message' => "Aucun élément trouvé pour le siret #{siret}" | ||
} | ||
}.to_json | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Je mettrais les stub requests dans un module comme tu as fait pour l'INSEE
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pour l'INSEE j'ai cherry-pick, j'ai hésité à jarter le module car en pratique c'est seulement utilisé dans le test du client, donc aucun intérêt de l'isoler dans un module. (contrairement à DataPass).
Du coup je vais potentiellement faire l'inverse et simplifier en jartant le module INSEE, ok pour toi ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is ok globalement pour moi.
J'trouve ca intéressant le fait qu'on passe pas par nos propres services pour aller fetch l'insee, mais je comprends parfaitement pourquoi.
J'trouve les clients un poil lourd, mais en même temps c'est pas grave, c'est assez isolé et si on veut les reprendre plus tard on pourra tjrs le faire.
context 'when modalities does no include params' do | ||
before do | ||
datapass_webhook_params['data']['data']['modalities'] = ['formulaire_qf'] | ||
end | ||
|
||
it 'does not create a token' do | ||
expect { | ||
subject | ||
}.not_to change(Token, :count) | ||
end | ||
end | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Je pense que ce qui me confuse c'est le fait que :
- sur un modalities = 'formulaire qf' on skip
- sur un modalities = 'params' on avance
Et le titre c'est "no params modalities". Ca fait beaucoup de params.
Je changerai bien le return if context.modalities.exclude?('params')
en return if !from_datapass
C'est un souci ici. Qu'est-ce qui n'est pas clair ? |
Une suggestion pour rendre ça moins lourd ? |
Je pense que c'est juste le feeling des payloads des méthodes de subscription à hubee / insee. On peut toujours pousser, je reprend l'exemple hubee on pourrait avoir une méthode |
Il est vrai que j'aurais pu wrapper dans un |
@skelz0r Pour clarifier mon commentaire, le code est toujours OK dans les dernier commits, sinon j'aurais relevé des points précis plutôt qu'un vague feeling C'est OK en l'état pour moi |
78e5316
to
ec4f1b4
Compare
a17cfb3
to
6747add
Compare
Remrque : Faut pas créer de jeton pour les communes sans éditeurs et sans dévellopeurs. |
Pour FQF, on voudrait pouvoir créer une subscription HubEE Active, en mode API, associée à un éditeur.
# POST /referential/v1/subscriptions
sub_body = {
"datapassId"=>99999,
"processCode"=>"CERTDC",
"subscriber"=>{"type"=>"SI", "companyRegister"=>"21890254200016", "branchCode"=>"89254"},
"notificationFrequency"=>"Unitaire",
"validateDateTime"=>DateTime.now.iso8601,
"updateDateTime"=>DateTime.now.iso8601,
"status"=>"Inactif",
"email"=>"user@yopmail.com",
"localAdministrator"=>{"email"=>"user@yopmail.com"},
# "accessMode"=>"API",
# "delegationActor"=>{"type"=>"EDT", "companyRegister"=>"42424242424299", "branchCode"=>"92062"},
}
# PUT /referential/v1/subscriptions/#{subscription_id}
sub_update_body = {
"datapassId"=>99999,
"processCode"=>"CERTDC",
"subscriber"=>{"type"=>"SI", "companyRegister"=>"21890254200016", "branchCode"=>"89254"},
"notificationFrequency"=>"Unitaire",
"validateDateTime"=>DateTime.now.iso8601, # à garder ?
"updateDateTime"=>DateTime.now.iso8601, # à garder ?
"email"=>"user@yopmail.com",
"status"=>"Inactif",
"localAdministrator"=>{"email"=>"user@yopmail.com"},
"accessMode" => "API",
"delegationActor"=>{"type"=>"EDT", "companyRegister"=>"42424242424299", "branchCode"=>"92062"},
"activateDateTime"=>DateTime.now.iso8601, #NEEDED !
"status"=>"Actif"
} |
2545d90
to
4f1339e
Compare
|
||
payload = subscription_payload.with_indifferent_access.merge({ | ||
status: 'Actif', | ||
activateDateTime: DateTime.now.iso8601, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@skelz0r tu parlais d'une date d'activation dans le passé, y'avait une raison particulière ? ça semble fonctionner comme ça
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
où ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ça me dit quelque chose, mais de toute manière ta ligne est une date dans le passé quasiment instantanément.
@skelz0r je te repasse la patate, je serai en vacances la semaine prochaine il faudra un token FQF de prod ça fonctionne (j'ai bidouillé pas mal pour réussir à faire des tests E2E en local) et ça va avec cette PR (n'hésitez pas à la reprendre !) https://github.com/etalab/data_pass/pull/476/files |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(je ne peux pas refuse vu que c'est ma PR)
2 gros points:
- Faut encapsuler la complexité du create puis update pour créer la subscription comme il faut, ça simplifiera la logique du code et cantonnera les trucs wtf dans le client (et on comprendra tout de suite que c'est l'API qui est mal foutu et non le dev qui a fait n'imp :D)
- Faut absolument séquencer avec gestion d'erreur la création de l'abo HubEE puis celle du FQF
|
||
payload = subscription_payload.with_indifferent_access.merge({ | ||
status: 'Actif', | ||
activateDateTime: DateTime.now.iso8601, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
où ?
|
||
payload = subscription_payload.with_indifferent_access.merge({ | ||
status: 'Actif', | ||
activateDateTime: DateTime.now.iso8601, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ça me dit quelque chose, mais de toute manière ta ligne est une date dans le passé quasiment instantanément.
app/clients/hubee_api_client.rb
Outdated
request.body.first | ||
end | ||
|
||
def update_subscription(authorization_request, subscription_payload, editor_payload = {}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Je renommerai cette méthode en activate_subscription
, ainsi que le create_subscription
en create_inactive_subscription
, et je wrapperai les 2 dans un create_subscription
Pourquoi tout faire ici ? Parce que c'est de la tambouille interne de l'API qui ne fonctionne pas comme il faudrait, et fondamentalement dans le séquençage on ne devrait que faire un create_subscription
, et les implémentations wtf vivent dans le client qui s'occupe de la complexité de l'API.
Bonus points:
- tu ne changes rien dans le code de l'organizer pour gérer ça, et demain si ils fixent, tu changes juste le client (ce qui est logique en fait) ;
- ça se comprend 100x plus en 1 commit avec un message
@@ -72,10 +72,17 @@ def authorization_request_attributes | |||
).merge(authorization_request_attributes_for_current_event).merge( | |||
'last_update' => fired_at_as_datetime, | |||
'previous_external_id' => context.data['pass']['copied_from_enrollment_id'], | |||
'api' => context.api | |||
'api' => context.api, | |||
'extra_infos' => extra_infos_with_service_provider |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dans 100% des cas il s'agit d'un éditeur, autant mettre editor
ici imo
CreateFormulaireQFHubEESubscriptionJob.perform_later(context.authorization_request.id) | ||
CreateFormulaireQFCollectivityJob.perform_later(context.authorization_request.id) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Je comprends mieux ta question plus haut: en effet ici on ne peut pas scheduler 2 jobs dépendant de manière indépendante, il faudrait faire un CreateFormulaireQFAccessJob
qui fait séquentiellement la création de l'accès HubEE, puis celui chez vous. Autrement c'est un sac de noeud à debug.
service_provider = authorization_request.extra_infos['service_provider'] | ||
subscription_update_payload = {} | ||
|
||
if service_provider.present? && service_provider['type'] == 'editor' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
je ne comprend pas: ce n'est pas systématiquement le cas ?
du coup si je comprends bien ça doit partir en prod semaine prochaine ? |
On n'a pas de hard deadline comme ça, mais on aimerait effectivement pouvoir embarquer plus facilement les nouveaux éditeurs et leurs communes en automatisant la création des communes/abonnements. Je sais qu'on en a quelques uns qui peuvent bientôt arriver, faut checker avec Miryad pour savoir si ça attend. |
62e40b2
to
1eb51ab
Compare
Prepare to store HubEE ids
Huge cherry-pick from DataPass v2 Ref etalab/data_pass@7c36324
Will be used for HubEE
Co-authored-by: Jean-Baptiste Feldis <5403+jbfeldis@users.noreply.github.com>
Les abonnements HubEE doivent être créées avant d'être activés, ce commit met en place cette séparation. Pour associer un éditeur le webhook envoie maintenant le service_provider associé à la demande (stocké dans extra_infos). Une méthode pour récupérer un abonnement existant a aussi été ajoutée pour rendre le webhook plus robuste. La collectivité est aussi créée du côté du FormulaireQF.
e633100
to
59020fe
Compare
f409288
to
7f38194
Compare
activationDate
dans le passéaccessMode
en mode API