Repository navigation
feat(admin): construire la file de modération et ses décisions - #365
Nascimento95 wants to merge 23 commits into
Conversation
|
Revue du 13 octobre 2026 — session d'Ilan, relecture par un agent du code à la tête Solide : rôle vérifié par l'API sur toutes les routes (éditeur refusé), décision prise sous verrou dans une transaction (409 sur un parcours déjà décidé), entrées validées, migration additive, recherche de l'app limitée à À corriger avant la sortie de brouillon
Écarts avec les planches A-02
En attente d'une décision d'Ilan
Relevé aussi, mineur : l'ancienneté repart de zéro à chaque changement de |
3bdf63e to
03d6216
Compare
a1931e0 to
1386f8a
Compare
|
Branche rebasée sur le socle mis à jour (#363, tête |
|
Quatre points de la revue du 13 octobre corrigés (
Vérification humaine : Marco a testé le 2026-10-14 en local (file à trois parcours, dont un « À corriger » de 4 jours non rouge, filtre « Plus de 72 h », message avec Restent : les écarts avec A-02 (état « Publié à l'instant », les 7 motifs au refus, colonne Ville à 1 024 px) et les trois décisions d'Ilan. |
|
Les trois écarts avec les planches A-02 relevés dans la revue du 13 octobre sont corrigés :
Vérification humaine : Marco a testé le 2026-10-14 en local, face aux planches A-02 (refus, publié, liste à 1 024 px) : publication et panneau « Publié à l'instant », refus avec motifs et message vide, colonne Ville selon la largeur. Lint, types et tests verts en local (95 tests admin, 37 UI). Restent les trois décisions d'Ilan : notification à l'auteur, « Premium » à la publication, confirmation avant « Publier ». |
03d6216 to
a850abb
Compare
228b5ae to
5282768
Compare
|
Branche remise à jour sur le socle rebasé sur Adaptations au rebase : le schéma, |
…on queue Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
a850abb to
b181be3
Compare
…rrors Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…isions Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…to the API Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rch (A-02) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s of a revision Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…story and queue place Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…confirmation Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…eens Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…the moderation sheet Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…heet Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…e and refresh the menu counter Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…-02) Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…er the title below 1280 px (A-02) Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
5282768 to
6135674
Compare
|
Branche remise à jour sur le socle rebasé (#363) : la migration de la modération est régénérée en |
Résultat et problème
L'équipe n'avait aucun moyen de relire un parcours soumis. Cette PR ajoute la file de modération (A-02) : la liste, la fiche d'un parcours et les décisions, côté API et côté admin.
PR en brouillon : deux critères d'acceptation sur quatre sont tenus ; les deux autres dépendent de données qui n'existent pas encore dans l'API (voir « Limites »).
Ce qui est fait :
packages/shared: les 7 motifs de refus et leurs libellés français et anglais, les schémas de la file, de la fiche et des décisions, le codealready_decided.apps/api: tablemoderation_actions;GET /admin/moderation(filtres statut, ville, retard, révision ; recherche ; tri ; pages) ;GET /admin/routes/:id(fiche, auteur, historique, place dans la file) ;publish,request-changes,reject,unpublish, chacune écrite dansmoderation_actionsetadmin_actionsdans une seule transaction ; 409already_decidedavec la décision prise quand un autre membre a tranché.apps/admin: la file (ancienneté, retard en rouge avec icône et texte lu, pastille « À corriger », filtres, tri et recherche gardés dans l'adresse, états vide, chargement, erreur) ; la fiche en page dédiée (« Parcours 1 sur 14 », avertissements, parcours tel qu'il sera publié, plan et étapes, auteur, historique) ; la charte à cocher, « Publier » actif quand les 6 règles sont cochées, « Demander des modifications » et « Refuser » avec leurs fenêtres, toasts, passage au parcours suivant.packages/ui: champ de recherche, filtre à menu, case à cocher, avatar à initiale, confirmation non destructive.Limites :
notifications. Chaque décision est journalisée, son message est gardé, mais rien n'est envoyé.route_revisionset la soumission d'un parcours viennent de Gérer PUT /routes/:id/steps, submit, statuts et lien privé #48, pas commencé. L'affichage est prêt (ligne « Révision », filtre « Révisions », bloc « Changements depuis la version publiée »), mais l'API répond qu'aucun parcours n'est une révision : une seule expression à remplacer dansmoderation/queue.tsetmoderation/detail.ts. Le format derevisionChangesa été défini d'après la planche et pourra bouger avec Gérer PUT /routes/:id/steps, submit, statuts et lien privé #48.isCertifiedest vrai, ce que l'API ne dit jamais tant que la certification n'existe pas (Migration profil : colonnes users (bio…), tables user_anecdotes, anecdote_questions, user_featured_routes, seuils de certification dans settings #126).routes.updated_at, faute d'événement de soumission.route_reportsn'existe pas (Migration : table route_reports et notifications.kind report_resolved #184) ; « Voir son compte » mène à une page introuvable tant que A-06 n'est pas fait (Admin : utilisateurs et rôles (A-06) #341).pendingà la main dans la base locale.img-srcde la CSP de l'admin accepte toute imagehttps, à resserrer quand elles seront dans le stockage de Widoo.Fixes #53
Écrans : A-02
Dépendance : empilée sur #363 (socle admin, #52).
Comment vérifier
Montage local de #363, puis passer des parcours en attente dans la base locale (
update routes set status = 'pending' where …) et se connecter avec un comptemoderatorouadmin.Testé par Marco le 2026-10-12, en local avec l'émulateur Auth, face aux planches A-02 du wiki :
Vérifié en base locale après ces décisions : une ligne dans
moderation_actionset une dansadmin_actionspar décision, avec l'état avant et après.Non vérifié à l'écran : la fenêtre « Refuser » jusqu'à l'envoi, et un parcours rouvert après décision (couverts par les tests de l'API). Rien n'a été testé contre un environnement déployé.
pnpm lint && pnpm typecheck && pnpm testverts en localFormatage mécanique : non
Risque
Niveau : 2 — migration additive (
moderation_actionset son type énuméré), nouveaux endpoints authentifiés, règle de modération.Taille : deux commits juste au-dessus de 400 lignes utiles.
82fcd73(419) : les composants de la liste, son conteneur et ses textes.0ad9a3f(415) : la colonne de décision, ses deux fenêtres, son hook et le conteneur de la fiche. Fichiers générés à part : migration0016_add_moderation_actions.sqlet son instantané.Revue OWASP (Top 10) :
requireAdminSection('moderation'); un éditeur reçoit 403 sur la file, la fiche et les décisions, sans rien écrire (testé).select … for update), vérifie son statut, puis écrit le statut et les deux journaux dans la même transaction ; deux décisions simultanées donnent un 200 et un 409, une seule ligne dans chaque journal (testé avec deux requêtes en parallèle).%et_de la recherche sont échappés ; filtres et tri validés par un schéma strict, un filtre inconnu est refusé (400).img-src https:ajouté à la CSP de l'admin (voir Limites).Nouvelle dépendance : aucune.
Retour arrière
Le revert de la PR suffit pour le code. La migration
0016est additive : après un revert, la tablemoderation_actionset le typemoderation_actionrestent en base sans effet ; un parcours déjà publié, refusé ou dépublié par une décision garde son statut.<img width="736" height="852" alt="Capture d’écran 2569-10-13 à 13 22 12" src="https://github.com/user-attachments/assets/07800634-b1f8-4163-a883-9f1d3cd85360"




/>