Apparence
convex-helpers — utilitaires retenus
👔 Page technique — rien à valider côté métier
Cette page est la boîte à outils de l'équipe de développement : elle recense les briques réutilisables retenues pour ne pas réécrire à la main ce qui existe déjà (contrôle des droits, cohérence des données liées, pagination, migrations).
Ce qu'il faut en retenir côté projet : ces choix visent à réduire le code sur mesure, donc le risque de bug et le coût de maintenance. Ils n'ont aucun impact sur les fonctionnalités décrites dans le reste du cahier des charges.
Passez en mode Technique (en haut de page) pour lire le détail.
convex-helpers est déjà une dépendance du backend (packages/backend/package.json, ^0.1.120) et déjà utilisé : packages/backend/convex/functions.ts construit les wrappers de fonctions via customCtx + zCustomQuery/zCustomMutation.
Cette page recense les utilitaires à privilégier quand c'est possible et leur usage concret dans Recette ERP. Ce sont des recommandations d'architecture : chaque feature les adopte au moment de son implémentation.
Déjà en place
ts
// packages/backend/convex/functions.ts
import { customCtx } from "convex-helpers/server/customFunctions";
import { zCustomMutation, zCustomQuery } from "convex-helpers/server/zod";
import { mutation, query } from "./_generated/server";
import { authComponent } from "./auth";
export const zQuery = zCustomQuery(
query,
customCtx(async (ctx) => ({ user: await authComponent.getAuthUser(ctx) })),
);
export const zMutation = zCustomMutation(
mutation,
customCtx(async (ctx) => ({ user: await authComponent.getAuthUser(ctx) })),
);Chaque fonction Convex métier part de zQuery / zMutation → auth injectée (ctx.user) + validation Zod des arguments. C'est le point d'accroche de la couche autorisation (ABAC).
Utilitaires à privilégier
| Utilitaire | Import | Usage dans Recette ERP |
|---|---|---|
| Custom functions | convex-helpers/server/customFunctions | Wrappers zQuery/zMutation : injecter ctx.user (Better Auth) + organizationId, appliquer canInContext avant toute écriture. En place. |
| Zod validation | convex-helpers/server/zod (≥ récent : .../zod4) | Valider les args de fonction et dériver les tables via zodToConvex. Schémas mutualisés dans @recette/validators. En place. |
| Relationship helpers | convex-helpers/server/relationships | Traverser la hiérarchie Projet → Module → Fonctionnalité → Scénario → Flux → Étape (getManyFrom) et l'association CRIM ↔ test (getManyViaOrThrow) sans requêtes manuelles. |
| Row-Level Security | convex-helpers/server/rowLevelSecurity | wrapDatabaseReader/wrapDatabaseWriter + Rules : filtrer chaque table par organizationId de façon uniforme. Remplace les RLS Postgres v1 — et corrige leur incohérence (etapes/anomalies étaient USING(true) en v1). |
| Triggers | convex-helpers/server/triggers | Maintenir atomiquement les champs dénormalisés (metier, fonct_nom, sc_nom) et le cache tests.crims à chaque écriture. Remplace la propagation fire-and-forget fragile de v1. |
| Migrations | convex-helpers/server/migrations (ou composant @convex-dev/migrations) | Backfills et évolutions de schéma versionnés (ex. snapshot de campagne, normalisation des blocs JSON testeur/qualite). Remplace les migrations SQL manuelles. |
| Rate limiting | convex-helpers/server/rateLimit (ou composant @convex-dev/rate-limiter) | Limiter inscription/connexion et uploads de preuve. |
| Pagination / streams | convex-helpers/server/pagination, convex-helpers/server/stream | Paginer les grosses listes (Synthèse, Anomalies, Journal). mergedStream pour fusionner runs réels + entrées synthétiques du journal en gardant l'ordre. |
| Action retries | convex-helpers/server/retries (ou composant @convex-dev/action-retrier) | Fiabiliser l'upload de preuve (remplace le rollback Storage manuel de v1). |
| CRUD | convex-helpers/server/crud | Générer create/read/update/delete/paginate pour les tables simples (crims, projects). |
| Sessions | convex-helpers/react/sessions, convex-helpers/server/sessions | Suivre la session d'exécution / les infos testeur (SessionProvider, useSessionQuery). |
Richer useQuery | convex-helpers/react (useQueryWithStatus), convex-helpers/react/cache | États { status, data, error } propres côté client + cache des abonnements entre navigations. |
| Validators utils | convex-helpers/validators (partial, pick, omit, literals, nullable, doc…) | Composer les validateurs de tables/args sans duplication. |
Ce que ça résout de la dette v1
Plusieurs points de dette technique v1 deviennent des choix d'architecture en v2 :
- D2 (RLS incohérente
etapes/anomalies) → RLS helper appliqué uniformément. - D5 (dénormalisations divergentes) → triggers atomiques.
- D6 (CRIM sans FK) → relations Convex + triggers de cache.
- D7 (orphelins Storage) → cycle de vie Convex File Storage + action-retrier.
- D8 (
db-schema.jsonobsolète) →schema.tsConvex = source unique typée. - D13 (saisie CRIM via
window.prompt) → dialog@recette/ui.