Repository navigation
feat(admin): lire et traiter les messages du support - #552
Merged
Merged
Conversation
This was referenced Oct 20, 2026
Open
Collaborator
|
📋 MANAGER, 2026-10-21 — relecture de la pile admin pour Paul (tête Verdict : A, fusionnable telle quelle. Niveau 2, cohérent. Vérifié :
Labels |
PaulThiberville
force-pushed
the
issue/346-b2b-partners
branch
from
October 21, 2026 16:28
a8418f9 to
b8ddffc
Compare
PaulThiberville
requested review from
IlanAMG and
PaulThiberville
as code owners
October 21, 2026 16:28
…and their card (A-13) Types of the list and of the card of a message of « Nous écrire »: the subject, the account, the address to answer to, what the app joined, the status. A first line holds the beginning of the message, the card the whole of it. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…tors and admins (A-13) GET /admin/support lists the messages to handle first, the oldest first, then the handled ones, with a filter on the status. GET /admin/support/:id reads one in full. Moderators and admins only: they hold what users wrote and the address they gave. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
POST /admin/support/:id/handled marks a message handled with its journal line, and answers 409 already_decided with the time of the first decision. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
… the dashboard (A-13) The navigation and the tile of the dashboard count the messages to handle, late after 72 hours, as the code planned for this section. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
getAdminSupport, getAdminSupportMessage and markSupportMessageHandled. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A-13 opens on the list of the messages with a status filter, and the card of the one the address names: what was written, the account, the address, the version and the device. Until the answer by e-mail exists, the card says to answer from a mailbox. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The button of the card of a message to handle, with its toasts and the counter of the navigation read again. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
PaulThiberville
force-pushed
the
issue/349-support
branch
from
October 21, 2026 16:35
8aad547 to
fabb5b9
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Résultat et problème
Les messages envoyés par « Nous écrire » (E-19, D-063) étaient rangés dans
support_messagessans que personne de l'équipe puisse les lire. A-13 les liste, les ouvre et permet de les marquer traités ; le menu et le tableau de bord comptent ceux qui attendent.GET /admin/support(les messages à traiter d'abord, du plus ancien au plus récent, puis les traités du plus récent au plus ancien ; filtrestatus, pagination),GET /admin/support/:id(le message en entier) etPOST /admin/support/:id/handled(journalisé ; 409already_decidedavec l'heure du premier traitement si un autre membre l'a déjà fait)./support) : la liste (sujet et début du message, compte, date, statut, filtre par statut), le détail (statut, dates, lien vers la fiche du compte A-06, adresse de réponse, version de l'app, appareil, langue, message), le bouton « Marquer traité » et un encart qui explique comment répondre en attendant (voir plus bas).Ce qui manque dans cette PR, et pourquoi
« Répondre » par e-mail n'est pas fait. Le ticket et Admin-Web › A-13 le demandent (« e-mail Brevo au modèle
réponse du support, E-22, dans la langue de l'utilisateur ; la réponse est gardée dans la fiche »), et le critère d'acceptation (« une réponse part par e-mail dans la langue de l'utilisateur et reste visible dans la fiche ») n'est donc pas tenu. Décision de l'opérateur (Marco, 2026-10-20), pour quatre raisons :widooapp.comauthentifié dans Brevo, l'adresse de l'expéditeur, et la clé de staging dans Secret Manager (Authentifier widooapp.com dans Brevo pour la production et créer l'expéditeur Widoo (tâche de Paul) #467, après l'achat du domaine Acheter le domaine widooapp.com et convenir de la pose de ses enregistrements DNS (tâche d'Ilan) #366). Le compte Brevo a été transmis à Paul le 2026-10-14.Ce qui reste à faire, pour un ticket de suite bloqué par #397 (signalé sur l'Inbox, à créer par MANAGER) :
POST /admin/support/:id/reply, les colonnesreply_body,replied_byetreplied_atde Modele-de-Donnees (une migration), l'envoi par le modèle E-22 dans la langue du message, la réponse gardée et affichée dans la fiche, et le critère du ticket 349 sur la réponse par e-mail à déplacer vers lui.Autres limites
Fixes #349
Écrans : A-13
Dépendance : PR empilée sur #551 (ticket #346), elle-même sur #550, #501, #500, #499, #479, #398, #365 et #363 (base
issue/346-b2b-partners).Comment vérifier
Montage local de la pile, base locale migrée, compte
moderatorouadmin, et quelques lignes danssupport_messages(un message avec compte, un sans compte, un en anglais, un déjà traité, un vieux de plus de 72 h).support_message.handle.editorn'a pas la rubrique, et l'API lui répond 403.Tests : 10 tests d'API (
admin-support.test.ts: accès par rôle, l'ordre de la liste, les filtres, la carte, 404, « traité » avec son journal, le 409 avec l'heure du premier, l'éditeur refusé sans écriture, les compteurs et la tuile) et 2 de l'aperçu ; schémas, requête du client et adresse de la liste côtéshared, api-client et admin.Testé par Marco le 2026-10-20, en local, sur le commit
8aad547(base locale, 4 messages fictifs) : le compteur du menu, l'ordre et le filtre de la liste, le détail d'un message avec compte, sans compte et en anglais, le lien vers la fiche du compte, « Marquer traité » avec son effet sur le badge, la liste et le compteur, et un message déjà traité. Rien n'a été testé sur un environnement déployé, ni avec un compte éditeur.pnpm lint && pnpm typecheck && pnpm testverts en local (chaque commit passe lint et types)Formatage mécanique : non
Risque
Niveau : 2 — nouveaux endpoints authentifiés qui lisent des messages et des adresses e-mail d'utilisateurs et en écrivent le statut ; aucune migration.
Taille : tous les commits sous 400 lignes utiles (le plus gros : 377). Aucun fichier généré.
Revue OWASP (Top 10, édition en cours)
requireAdminSection('support')(modérateurs et admins). Un éditeur reçoit 403 sur la liste, le détail et « traité », sans rien écrire (testé) ; une requête sans jeton, 401. Le test de garde de toutes les routes/admin/*couvre ces routes.mailto:que pour une adresse e-mail valide).for update) le temps de la décision, avec son journal dans la même transaction ; deux décisions simultanées donnent un 200 et un 409 (testé).support_message.handlegarde l'auteur, l'état avant et après.Nouvelle dépendance : aucune.
Retour arrière
Le revert de la PR suffit : aucune migration, aucune donnée créée. Un message marqué traité garde sa date de traitement ; la lire de nouveau ne demande rien. Les compteurs du menu et du tableau de bord reviennent à zéro pour le support.
🤖 Generated with Claude Code