Skip to content

feat(admin): écrans argent, arbitrage des litiges et aperçu des emails - #20

Open
jeremie0342 wants to merge 1 commit into
masterfrom
feat/money-disputes-emails
Open

feat(admin): écrans argent, arbitrage des litiges et aperçu des emails#20
jeremie0342 wants to merge 1 commit into
masterfrom
feat/money-disputes-emails

Conversation

@jeremie0342

@jeremie0342 jeremie0342 commented Aug 14, 2026

Copy link
Copy Markdown
Collaborator

Trois surfaces backend n'avaient aucune interface opérateur : rien ne montrait un paiement qui avait pris l'argent sans rien livrer, les litiges contestés attendaient une décision que personne ne pouvait prendre, et le seul moyen de relire un email était d'en envoyer un.

Ce que ça ajoute

/money — les compteurs qui devraient être à zéro (payé-non-livré, écart de solde, paiements et virements en attente, litiges à trancher, notifications abandonnées), la position par prestataire, et quatre onglets : paiements, virements, corridors, opérateurs.

Les corridors et les opérateurs se coupent depuis cet écran. Fermer une voie pendant une panne prestataire est donc une colonne, pas un déploiement — et c'est aussi comme ça qu'on active le rail bac à sable en staging sans toucher à la production.

/disputes — les deux versions côte à côte et au même poids. Un opérateur qui ne lit que la plainte ne tranche que la plainte. La note est obligatoire (10 caractères minimum) et part aux deux parties : celui qui perd en a plus besoin que celui qui gagne.

/emails — tous les types prévisualisables, groupés par catégorie, rendus dans une iframe pour que les styles de l'email n'atteignent pas la page admin autour. Les locales sans traduction sont signalées dans la liste, pas découvertes après un envoi.

Deux détails qui comptent

Les montants sont rendus tels que le backend les envoie, en chaîne décimale. Les passer par Intl.NumberFormat supposerait de les parser en flottant d'abord, et un écran sur lequel on rapproche des comptes est le dernier endroit où introduire une différence d'arrondi.

testTimeout passe à 30 s. Les 5 s par défaut partaient dans la transformation des modules SvelteKit, pas dans les assertions : les mêmes tests passaient isolément et tombaient en suite complète sur une machine chargée. Une suite qui échoue pour cette raison est une suite qu'on réapprend à relancer au lieu de la lire. Avant : 8 fichiers en échec sur 16. Après : 17/17 fichiers, 135/135 tests.

Dépendances

Consomme des endpoints livrés dans la PR backend fix/api-contract-and-payment-silences (#72) : /admin/money/*, /admin/disputes, /admin/disputes/{id}/decide, /admin/email-preview. À merger après elle.

CI

Type check, unit tests, build et Playwright public smoke passent.

Playwright admin flows échoue, pour une raison qui n'est pas dans cette
branche : le jeu GeoNames manque au backend du job et les migrations ne sont
pas jouées (relation "users" does not exist). C'est exactement ce que
corrige la PR #19. Cette branche part de master pour ne pas embarquer ses
commits CI ; le job repassera au vert une fois #19 mergée.

Vérifications

  • npm run check : 0 erreur, 0 warning
  • npx vitest run : 17/17 fichiers, 135/135 tests
  • 10 nouveaux tests sur money.ts (URLs, corps, direction obligatoire sur le toggle de corridor, échappement de la query string d'aperçu)
  • i18n complet dans les trois locales (fr, en, ar) + Translations, qui impose la parité

Three backend surfaces had no operator UI: nothing showed a payment that
took money and delivered nothing, contested disputes waited on a decision
nobody could make, and emails could only be reviewed by sending one.

- /money: the counts that should be zero, provider positions, and four
  tabs (payments, payouts, corridors, operators). Corridors and operators
  toggle from here, so closing one during an outage is a column and not a
  deployment.
- /disputes: both accounts shown side by side and equally weighted, with
  a mandatory note that goes to both sides.
- /emails: every previewable kind, rendered in an iframe so the email's
  own styles cannot reach the admin page, with untranslated locales
  flagged in the list rather than discovered after a send.
- Amounts are rendered as the decimal strings the backend sends. Parsing
  them into floats is how a reconciliation screen starts disagreeing with
  the ledger.
- testTimeout raised to 30s: the default 5s was being spent transforming
  SvelteKit modules, so the suite failed on a loaded machine for reasons
  unrelated to any assertion.
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.

1 participant