Modèle de données Prisma
Archive de conception. Cette page raconte ce qui etait vise le jour ou elle a ete ecrite, pas l'etat du code aujourd'hui. Ce qui a ete livre depuis est recense dans le README.
Archive de conception. Cette page raconte ce qui etait vise le jour ou elle a ete ecrite, pas l'etat du code aujourd'hui. Ce qui a ete livre depuis est recense dans le README.
← retour au README
5. Modèle de données Prisma
Schémas à créer
model Task {
id String @id @default(cuid())
storeId String
conversationId String?
title String
description String?
status TaskStatus
priority Int @default(0)
assigneeAgent String?
parentTaskId String?
dependsOnTaskIds String[]
plan Json?
output Json?
agentRunId String?
createdBy String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
completedAt DateTime?
store Store @relation(fields: [storeId], references: [id])
activities TaskActivity[]
@@index([storeId, status])
@@index([conversationId])
}
enum TaskStatus {
PENDING IN_PROGRESS WAITING_REVIEW DONE FAILED CANCELLED
}
model TaskActivity {
id String @id @default(cuid())
taskId String
type String
payload Json
ts DateTime @default(now())
task Task @relation(fields: [taskId], references: [id])
@@index([taskId, ts])
}
model ThemeBranch {
id String @id @default(cuid())
storeId String
shopifyThemeId String // draft theme ID on Shopify
name String
conversationId String? // chat-as-branch link
parentBranchId String?
status String // "active" | "archived" | "published"
createdBy String
createdAt DateTime @default(now())
store Store @relation(fields: [storeId], references: [id])
versions ThemeVersion[]
@@index([storeId, status])
}
model ThemeVersion {
id String @id @default(cuid())
branchId String
parentVersionId String?
message String // "iRen edit: hero copy"
authorAgent String?
authorUserId String?
filesDiff Json? // jsonpatch (V2)
filesSnapshot Json? // full snapshot (V1, then compacted)
publishedAt DateTime?
createdAt DateTime @default(now())
branch ThemeBranch @relation(fields: [branchId], references: [id])
@@index([branchId, createdAt])
}
model StoreReport {
id String @id @default(cuid())
storeId String
type String // "SEO" | "CRO" | "PERF" | "TRACKING" | "COMPETITOR" | "SECURITY"
status String // "pending" | "running" | "done" | "failed"
result Json?
triggeredBy String // userId or "scheduled"
createdAt DateTime @default(now())
completedAt DateTime?
store Store @relation(fields: [storeId], references: [id])
@@index([storeId, type, createdAt])
}
model StoreNote {
id String @id @default(cuid())
storeId String
content String @db.Text
pinnedToTask String? // optional Task ID
createdBy String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
store Store @relation(fields: [storeId], references: [id])
@@index([storeId])
}
Migrations à prévoir
- Ajouter
Task,TaskActivity,ThemeBranch,ThemeVersion,StoreReport,StoreNote - Relations :
Store← Task[], ThemeBranch[], StoreReport[], StoreNote[] - Index
(storeId, status),(branchId, createdAt),(storeId, type, createdAt)
16. Vérification croisée du schéma Prisma actuel
Audit du schéma existant avant d'ajouter les nouveaux modèles V2. Évite les collisions de noms et repère où une migration incrémentale vaut mieux qu'un doublon.
Modèles existants pertinents (35 au total)
| Existant | Rôle | Impact V2 |
|---|---|---|
Store | Conteneur principal d'une boutique Shopify (orgId, slug, framework) | ✅ Réutilisé : cible des relations de tous les nouveaux modèles |
StoreContext (un-à-un avec Store) | knowledge, todos, pipeline, agentState (Json) | 🔄 Cible de migration : todos Json → Task[] relationnel ; knowledge Json → StoreNote[] |
Workflow + WorkflowRun | Workflow legacy (canvas) | 🔍 À auditer : peut être réutilisé comme exécuteur des tâches, ou archivé, selon son état |
Conversation + Message | Chat @Atlas (multi-canal) | ✅ Réutilisé : ThemeBranch.conversationId référence Conversation.id |
RoadmapItem + ChangelogEntry + Feedback | Plateforme publique (distinct du Kernel au niveau boutique) | ⚠️ Pas de collision : StoreReport et le Kernel par boutique sont distincts |
AuditLog | Journal de sécurité de la plateforme | ✅ Réutilisé pour tracer la création d'une Task, la publication d'une ThemeBranch, etc. |
Connector + IntegrationConnection + McpConnector | Intégrations OAuth + MCP | ✅ Réutilisés : pas de duplication |
Skill | Catalogue de skills | 🔍 Mémoire de skills partagée entre boutiques, à imaginer |
Conflits / collisions à éviter
Workflow: ne pas créer un nouveau modèle du même nom. Soit on le réutilise (le canvas legacy, reconverti en exécuteur des tâches), soit on l'archive et on créeAgentRunpour la nouvelle infra.Workflow.WorkflowRun: déjà la persistance de runs. À voir s'il est compatible avec les flux durables de Workflow DevKit, ou à supprimer.- Aucun modèle « Theme »* existant → les noms
ThemeBranchetThemeVersionn'entrent pas en collision. - Aucun modèle « Task » existant → nom disponible. ⚠️ Il existe toutefois un
MonthlyReset.task: String?(champ texte) : sémantique différente, pas de collision Prisma.
Migration incrémentale recommandée
V1.0 — Tasks queue
StoreContext.todos (Json[]) → Task[] relationnel via migration
Migration script : pour chaque StoreContext, parse todos JSON →
insert Task rows avec storeId
Garder StoreContext.todos backward-compat 90 jours puis drop
V1.1 — Theme branches
Nouveau ThemeBranch + ThemeVersion (zero collision)
V1.2 — Notes
StoreContext.knowledge (Json) → StoreNote[] relationnel
Pareil que todos : migration script + 90 jours backward-compat
V1.3 — Reports
Nouveau StoreReport (zero collision)
V1.4 — Workflow legacy
Audit Workflow + WorkflowRun
Décision : repurpose (renommer en AgentRun) ou archive
Champs Json → tables relationnelles : pourquoi
Json= facile à faire évoluer, mais ni indexable, ni filtrable, ni typé- Volumes attendus : ~50 tâches par boutique × 1000 boutiques = 50K lignes, OK
- Notes, idem : ~10 notes par boutique × 1000 = 10K lignes
- Rapports : ~5 par boutique et par mois × 1000 = 60K par an
- Tous OK pour Postgres avec les bons index
(storeId, createdAt)
Action V2 — script de migration
Créer prisma/migrations/_workspace-v2-todos-to-tasks.sql qui :
- Lit chaque
StoreContext.todosJSON - En analyse la forme (à retrouver par rétro-ingénierie du code legacy)
- Insère les lignes
Taskcorrespondantes - Marque
StoreContext.todosMigratedAt(timestamp) - Le code legacy lit Task[] si
todosMigratedAtest renseigné, sinon se replie surtodos(Json)
Suivant : tools-shopify.md