Skip to content
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

[FEATURE] Permettre la modification des sujets d'un profil cible non relié à une campagne (PIX-12436). #8842

Merged
merged 4 commits into from
May 30, 2024

Conversation

Jeyffrey
Copy link
Contributor

@Jeyffrey Jeyffrey commented May 6, 2024

🦄 Problème

Nous avons l'objectif de rendre possible la duplication d'un profil cible existant en autorisant la modification de son référentiel.

Or, à l'heure actuelle, il n'est pas permis de modifier ce référentiel.

🤖 Proposition

La route PATCH /api/admin/target-profiles/{id} accepte maintenant les tubes en payload.

Pour respecter le DDD, dans le modèle TargetProfileForAdmin, on a ajouté une méthode dédiée à l'update qui gère les besoins métier :

  • on permet la modification des tubes uniquement si le profil cible n'est pas relié à une campagne,
  • on vérifie la validité de la nouvelle valeur de la propriété category,
  • on vient mettre à jour les données du model directement dans cette méthode.

🌈 Remarques

  1. La méthode du TargetProfileSerializer deserializeCreationCommand a été renommée deserialize car elle est maintenant aussi utilisée pour la modification.

  2. Dans tous les cas, on ne permet pas la modification de la propriété isPublic.

  3. Le allowUnknown (https://github.com/1024pix/pix/blob/dev/api/lib/application/target-profiles/index.js#L337) sur la payload a été supprimé, il convient donc de modifier l'adapter d'Ember.

💯 Pour tester

  • Tests verts
  • Vérifier que la modification de profil cible fonctionne toujours sur PixAdmin.

@Jeyffrey Jeyffrey added 👀 Tech Review Needed team-evaluation PR relatives à l'expérience d'évaluation labels May 6, 2024
@Jeyffrey Jeyffrey self-assigned this May 6, 2024
@pix-bot-github
Copy link

Une fois les applications déployées, elles seront accessibles via les liens suivants :

Les variables d'environnement seront accessibles via les liens suivants :

@Jeyffrey Jeyffrey force-pushed the pix-12436-add-target-profile-tubes-update branch 2 times, most recently from 580434b to 6f2cf2c Compare May 6, 2024 12:45
@Jeyffrey Jeyffrey marked this pull request as ready for review May 6, 2024 12:53
@Jeyffrey Jeyffrey force-pushed the pix-12436-add-target-profile-tubes-update branch from 6f2cf2c to 5801346 Compare May 6, 2024 13:03
@Jeyffrey Jeyffrey requested review from a team May 6, 2024 13:55
@Jeyffrey Jeyffrey force-pushed the pix-12436-add-target-profile-tubes-update branch 2 times, most recently from 62d9dc5 to 9eacc6f Compare May 6, 2024 15:24
@Jeyffrey Jeyffrey force-pushed the pix-12436-add-target-profile-tubes-update branch from 3f5e5a8 to d67ea8e Compare May 7, 2024 15:53
@Jeyffrey Jeyffrey force-pushed the pix-12436-add-target-profile-tubes-update branch from d67ea8e to 2435843 Compare May 7, 2024 15:58
@@ -1,25 +1,23 @@
import { validate } from '../validators/target-profile/base-validation.js';
import { NotFoundError } from '../../domain/errors.js';
Copy link
Member

Choose a reason for hiding this comment

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

j'ai un avis de plus en plus tranché sur la pertinence de l'existence des usecases de ce style.
On a un cas parfait où il n'a pas vraiment de responsabilités, de pouvoir de décision puisque tout a été déplacé dans le modèle.
On pourrait aussi bien déplacer tout ce code dans le controller que personnellement ca ne me ferait ni chaud ni froid, et sans casser l'archi hexagonale.
Le truc qui met le clou final dans le cercueil pour moi c'est qu'on se retrouve à écrire un fichier de test unitaire de ce usecase, qui est assez peu utile et surtout très difficilement maintenable car dès qu'on change un détail d'implémentation le test se transforme en guirlande de Noël. Il mock tout dans tous les sens, il est bien trop proche de l'implémentation

Copy link
Member

Choose a reason for hiding this comment

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

Je remets la définition des usecases dans le livre "Clean Architecture" pour qu'on ait la même base dans la discussion

Use cases contain the rules that specify how and when the Critical Business Rules within the Entities are invoked. Use cases control the dance of the Entities.
Notice also that the use case does not describe the user interface other than to informally specify the data coming in from that interface, and the data going back out through that interface. From the use case, it is impossible to tell whether the application is delivered on the web, or on a thick client, or on a console, or is a pure service.
This is very important.

Il y a certain usecases où je suis d'accord avec toi @laura-bergoens sur le fait qu'ils sont des passes plat, comme celui là par exemple :

const acceptPixCertifTermsOfService = function ({ userId, userRepository }) {
  return userRepository.updatePixCertifTermsOfServiceAcceptedToTrue(userId);
};

export { acceptPixCertifTermsOfService };

Dans celui-là, effectivement le usecase ne fait que transmettre au repository les informations qu'il a en entrée et ne manipule donc aucun objet du domain. Il ne répond donc pas à la définition d'un usecase.

Par contre on pourrait le refactorer de la manière suivante pour qu'il en soit plus proche :

const acceptPixCertifTermsOfService = function ({ userId, userRepository }) {
  const user = userRepository.get(userId);

  user.acceptTermsOfService({ certif: true });

  return userRepository.update(user)
};

export { acceptPixCertifTermsOfService };

Et donc pour moi le usecase updateTargetProfile n'est pas juste un passe plat :

  • Il prend en entrée des données dans un certain format
  • Il va chercher le model du domain concerné
  • Appelle une méthode du model qui encapsule la logique métier
  • Persiste le model

Pour moi, si on appelle directement les repository dans le controller et qu'on manipule les models à ce niveau là on casse le découplage.

Use cases do not describe how the system appears to the user. Instead, they describe the application-specific rules that govern the interaction between the users and the Entities. How the data gets in and out of the system is irrelevant to the use cases.

Dans un commentaire plus haut tu parles des différents type de validation #8842 (comment). Si tout le code est dans le controller qu'est ce qui nous empêche de céder à la facilité de tout mettre dans la configuration du endpoint ?

Use cases expect input data, and they produce output data. However, a well-formed use case object should have no inkling about the way that data is communicated to the user, or to any other component. We certainly don’t want the code within the use case class to know about HTML or SQL!

Les controllers sont pour moi couplé à notre contexte d'utilisation de l'API (sur le web) et les libraries ou patterns qu'on utilise (ex : Hapi, json-api, ...). Ce qui fait que si demain on décide d'en changer (exemple au hasard GraphQL ce que permet EmberData) on va devoir potentiellement toucher à du code qui est sensé être dans le domain si on a pas été en mesure de bien décorrelé les deux.

Le truc qui met le clou final dans le cercueil pour moi c'est qu'on se retrouve à écrire un fichier de test unitaire de ce usecase, qui est assez peu utile et surtout très difficilement maintenable car dès qu'on change un détail d'implémentation le test se transforme en guirlande de Noël. Il mock tout dans tous les sens, il est bien trop proche de l'implémentation

Cela me semble normal puisque le usecase est un chef d'orchestre son seul rôle est de s'assurer qu'un ensemble d'actions a été éxécuté dans le bon ordre. Pour moi un bon usecase ne doit pas avoir de logique. Car si c'est le cas c'est que vraisemblablement c'est du métier et donc a plus sa place dans un model. Ses tests sont sensés changer que si le flow d'actions (l'enchaînement métier) change. En règle générale, si il n'y a pas d'embranchements il n'a même qu'un seul test "nominal" et éventuellement un ou plusieurs tests d'erreurs.

Un dernier point qui m'embête avec le fait de mettre directement l'appel aux repository et la manipulation des models dans les controllers c'est faire reposer sur les épaules des développeurs la décision de ce qui merite un fichier de usecase ou pas. C'est une heuristique compliquée et très subjective (la réponse variera d'un dev à un autre).

Quand quelqu'un arrive chez Pix, il doit se familiariser avec la Clean Architecture et DDD. Pour les devs juniors cela n'est pas évident du tout. On a régulièrement des remarques sur les différences de faire à certains endroits. Si l'architecture varie en fonction des endpoints cela va renforcer ce sentiment et la réponse aux questions a apporté ne sera pas évidente de mon point de vue.

Copy link
Member

Choose a reason for hiding this comment

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

Précision suite à une discussion Slack Ce thread est plus un échange d'idée qu'une vraie demande de changement dans le cadre de cette PR.

Comment on lines 331 to 338
category: Joi.valid(
categories.COMPETENCES,
categories.CUSTOM,
categories.DISCIPLINE,
categories.OTHER,
categories.PREDEFINED,
categories.SUBJECT,
),
Copy link
Member

Choose a reason for hiding this comment

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

Pour faire écho au commentaire de @laura-bergoens sur la validation sémantique. Cette validation a sa place dans le domain d'où cette liste est extraite.

Copy link
Contributor

Choose a reason for hiding this comment

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

Je suis en phase sur le fait de (re)valider cela côté Domain. Néanmoins cela peut être intéressant de garder cependant cette version côté Swagger car cela vient documenter nos API (swagger.json) pour les consommateurs

Côté Domain ce serait un MustHave, là où le swagger en CouldHave :)

Copy link
Member

Choose a reason for hiding this comment

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

Je trouve ça dommage pour des besoins de documentation de changer le fonctionnement du code. Si on laisse cette validation ici on est pas en mesure de produire des erreurs du domain 😬

@Jeyffrey Jeyffrey force-pushed the pix-12436-add-target-profile-tubes-update branch 5 times, most recently from e6830e8 to d3c2606 Compare May 22, 2024 13:50
@Jeyffrey Jeyffrey closed this May 22, 2024
@Jeyffrey Jeyffrey reopened this May 22, 2024
@1024pix 1024pix deleted a comment from pix-bot-github May 22, 2024
@frinyvonnick
Copy link
Member

frinyvonnick commented May 22, 2024

Revue fonctionnelle :
Je ne peux pas créer de nouveau profil cible :
image

Revue tech :
Cela me semble bon 👌 Merci pour tous les changements opérés 🙇

@Jeyffrey Jeyffrey force-pushed the pix-12436-add-target-profile-tubes-update branch 4 times, most recently from 473b03d to ee404ad Compare May 28, 2024 13:08
@Jeyffrey Jeyffrey added 🚀 Ready to Merge Func Review OK PO validated functionally the PR and removed 👀 Func Review Needed labels May 30, 2024
@pix-service-auto-merge pix-service-auto-merge force-pushed the pix-12436-add-target-profile-tubes-update branch 2 times, most recently from 04a2275 to c9cc234 Compare May 30, 2024 08:08
@pix-service-auto-merge pix-service-auto-merge force-pushed the pix-12436-add-target-profile-tubes-update branch from c9cc234 to c062d64 Compare May 30, 2024 08:14
@pix-service-auto-merge pix-service-auto-merge merged commit b91d447 into dev May 30, 2024
4 of 7 checks passed
@pix-service-auto-merge pix-service-auto-merge deleted the pix-12436-add-target-profile-tubes-update branch May 30, 2024 08:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Func Review OK PO validated functionally the PR 🚀 Ready to Merge team-evaluation PR relatives à l'expérience d'évaluation Tech Review OK
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants