Base de données Convex
Comment CodeCourier utilise Convex comme base de données réactive en temps réel pour tout l’état de l’application, y compris la conception du schéma, les queries, les mutations et les abonnements en temps réel.
Convex est la plateforme backend réactive qui sert de magasin de données central et de couche de coordination pour CodeCourier. Chaque élément de l’état de l’application -- utilisateurs, projets, sandboxes, workflows, runs, messages, learnings, enregistrements d’utilisation, et plus encore -- réside dans Convex. Ce qui rend Convex unique par rapport aux bases de données traditionnelles est sa réactivité intégrée : lorsque les données changent, chaque client abonné est automatiquement notifié et se ré-affiche avec l’état le plus récent. Cette page explique comment CodeCourier utilise Convex, la conception du schéma et les patterns de code pour travailler avec la base de données.
Ce que fournit Convex
- Abonnements en temps réel -- Les queries se ré-exécutent automatiquement lorsque leurs données sous-jacentes changent. Le tableau de bord affiche l’état des sandboxes, la progression des runs et les messages en temps réel sans polling.
- Mutations transactionnelles -- Chaque mutation s’exécute dans une transaction sérialisable. Les lectures et écritures au sein d’une mutation sont atomiques, empêchant les conditions de concurrence.
- Fonctions typées -- Les queries, mutations et actions sont définies en TypeScript avec une inférence de types complète. Le schéma Convex valide les arguments et les types de retour à l’exécution.
- Actions pour les effets de bord -- Les opérations qui appellent des services externes (E2B, Trigger.dev) sont définies comme des actions, qui peuvent lire des données et planifier des mutations mais ne sont pas elles-mêmes transactionnelles.
- Authentification intégrée -- Convex valide les JWT Clerk et rend l’identité de l’utilisateur authentifié disponible pour chaque fonction.
- Fonctions planifiées -- L’API
ctx.scheduler.runAfterpermet l’exécution différée, utilisée pour les opérations asynchrones comme le déclenchement de l’extraction des learnings. - Stockage de fichiers -- Convex fournit un stockage de fichiers intégré (la table
_storage) utilisé pour les images de référence et les logos de projet.
Vue d’ensemble du schéma
Le schéma Convex est défini dans convex/schema.ts et contient plus de vingt tables. Voici les principaux groupes d’entités :
Identité et accès
users-- Comptes utilisateur synchronisés depuis Clerk. Indexés parclerkIdetemail.projects-- Unités organisationnelles de niveau supérieur. Indexés parownerIdetslug.projectMembers-- Relation plusieurs-à-plusieurs entre utilisateurs et projets avec rôles (owner, admin, member) et statut d’invitation.projectSettings-- Configuration par projet incluant les prompts système, CLAUDE.md, les variables d’environnement, les skills et commandes sélectionnés, et les clés de déploiement.userSettings-- Préférences par utilisateur comme le dernier projet actif.
Clés API
apiKeys-- Clés API de fournisseur au niveau utilisateur (E2B, Anthropic, OpenRouter, OpenAI, GitHub). Stockage chiffré avec affichage des quatre derniers caractères.projectProviderKeys-- Clés API de fournisseur au niveau projet qui remplacent les clés au niveau utilisateur.projectApiKeys-- Clés API REST CodeCourier pour l’accès programmatique. Hachées en SHA-256, révocables, avec suivi de l’utilisation.
Exécution
sandboxes-- Instances de sandbox E2B avec état, configuration et suivi du cycle de vie.sandboxMessages-- Messages de conversation entre les utilisateurs et les agents IA au sein des sandboxes.workflows-- Modèles de workflow définissant le type de pipeline, les étapes et la configuration par défaut.runs-- Instances d’exécution de workflow avec état, progression et suivi de PR.runSteps-- Étapes d’exécution individuelles au sein des runs (designer, checker, optimizer, etc.).workChains-- Chaînes d’exécution séquentielle d’issues.
Connaissances IA
personas-- Personnalités d’agent IA avec instructions personnalisées, skills et préférences de modèle.skills/skillFiles-- Définitions de skill et leur contenu de fichier.commands-- Définitions de commandes réutilisables.scripts-- Définitions de scripts pour l’exécution dans les sandboxes.learnings-- Connaissances extraites des sessions de sandbox.learningVersions-- Instantanés de learnings compilés pour injection dans les sessions futures.
Issues
issueSessions-- Enregistrements de session de découverte d’issues.issues-- Issues individuelles découvertes pendant les sessions ou créées manuellement.
Analytique et utilisation
usageCostRates-- Taux de coût pour différents services (Claude Code, E2B, Trigger.dev, Convex, etc.) avec types de taux et paliers de modèle configurables.usageRecords-- Données d’utilisation détaillées par projet, service et date, avec des champs de suivi entreprise optionnels pour les comptages de tokens, les identifiants de modèle et l’attribution des étapes.projectCounters-- Compteurs dénormalisés pour un accès rapide aux nombres de sandboxes, runs, workflows et membres.dailyStats-- Statistiques quotidiennes agrégées de l’activité du projet.notifications-- Enregistrements de notification utilisateur pour les achèvements de run, les événements de PR et l’activité d’équipe.
Queries en temps réel
Le tableau de bord de CodeCourier exploite abondamment les abonnements de query en temps réel de Convex. Lorsque vous consultez une conversation de sandbox, la query sandboxMessages.listBySandbox s’abonne à tous les messages de cette sandbox. Lorsqu’un nouveau message arrive de l’agent IA (écrit par une tâche Trigger.dev via le point de terminaison de callback), la query se ré-exécute automatiquement et l’interface se met à jour instantanément -- pas de polling, pas de configuration WebSocket, pas d’invalidation manuelle.
Queries clés utilisées dans le tableau de bord :
sandboxes.listPaginated-- Alimente la vue liste des sandboxes avec pagination basée sur curseur.runs.listPaginated-- Alimente la vue liste des runs.workflows.listForProject-- Charge tous les workflows du projet actuel.sandboxMessages.listBySandbox-- Diffuse la conversation en temps réel.runSteps.listByRun-- Affiche la progression étape par étape pendant l’exécution du workflow.usage.getProjectUsageSummary-- Données du tableau de bord d’utilisation en temps réel.
Mutations
Les mutations dans Convex sont des écritures transactionnelles. CodeCourier utilise les mutations pour tous les changements d’état initiés par l’utilisateur :
- Créer, mettre à jour et supprimer des workflows
- Renommer les sandboxes et les runs
- Gérer les membres et invitations de projet
- Générer et révoquer des clés API
- Mettre à jour les paramètres du projet
- Enregistrer l’utilisation et mettre à jour les taux de coût
Les mutations internes (préfixées par internal) sont utilisées par les callbacks Trigger.dev et les fonctions planifiées. Elles ne sont pas accessibles depuis le frontend.
Index
Le schéma définit des index étendus pour un interrogation efficace. Chaque table possède au moins un index au-delà de l’index par défaut _id. Les patterns d’index clés incluent :
by_user/by_project-- Filtrer les enregistrements par propriété.by_deleted-- Filtrer efficacement les enregistrements supprimés en douceur.by_status-- Filtrer par état du cycle de vie.by_project_date-- Queries de séries temporelles pour l’analytique.by_key-- Recherche de clé API par hash.
Travailler avec Convex dans CodeCourier
Queries frontend
Le tableau de bord utilise le hook useQuery du client React Convex :
const sandboxes = useQuery(api.sandboxes.listPaginated, {
paginationOpts: { numItems: 20 }
});Les queries retournent undefined pendant le chargement et se mettent à jour automatiquement lorsque les données sous-jacentes changent.
Mutations frontend
Les mutations sont appelées via le hook useMutation :
const rename = useMutation(api.sandboxes.renameSandbox);
await rename({ id: sandboxId, name: "New Name" });Actions frontend
Les actions qui déclenchent des opérations externes utilisent useAction :
const launch = useAction(api.sandboxActions.launchSandboxes);
await launch({ config, prompt, projectId });