Apparence
convex-helpers — utilitaires retenus
👔 Pour le client
Page purement technique (boîte à outils de l'équipe). Rien à valider côté métier — vous pouvez la passer.
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.