feat(plan5): types création + modèle Prisma ProductCreation

This commit is contained in:
2026-06-09 09:33:11 +02:00
parent 1e48ca142f
commit 2e9df3659f
3 changed files with 93 additions and 7 deletions
@@ -0,0 +1,14 @@
-- CreateTable
CREATE TABLE "ProductCreation" (
"id" TEXT NOT NULL PRIMARY KEY,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"userId" TEXT NOT NULL,
"sheetTab" TEXT NOT NULL,
"sheetRow" INTEGER NOT NULL,
"shopifyId" TEXT NOT NULL,
"sku" TEXT NOT NULL,
"title" TEXT NOT NULL,
"status" TEXT NOT NULL DEFAULT 'success',
"errorMessage" TEXT NOT NULL DEFAULT '',
CONSTRAINT "ProductCreation_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
);
+22 -7
View File
@@ -7,13 +7,14 @@ datasource db {
} }
model User { model User {
id String @id @default(cuid()) id String @id @default(cuid())
email String @unique email String @unique
name String name String
password String password String
role String @default("gestionnaire") role String @default("gestionnaire")
createdAt DateTime @default(now()) createdAt DateTime @default(now())
syncRuns SyncRun[] syncRuns SyncRun[]
productCreations ProductCreation[]
} }
model SyncRun { model SyncRun {
@@ -28,3 +29,17 @@ model SyncRun {
errors Int @default(0) errors Int @default(0)
log String @default("[]") log String @default("[]")
} }
model ProductCreation {
id String @id @default(cuid())
createdAt DateTime @default(now())
userId String
user User @relation(fields: [userId], references: [id])
sheetTab String
sheetRow Int
shopifyId String
sku String
title String
status String @default("success")
errorMessage String @default("")
}
+57
View File
@@ -0,0 +1,57 @@
/** Un produit en attente de création, extrait d'un onglet Sheets */
export interface PendingProduct {
tab: string // nom de l'onglet (famille)
rowNumber: number // numéro de ligne 1-indexé dans le sheet
sku: string // UGS
title: string // Nom
priceMarket: string // Prix marché (compare_at_price), ex: "29.99"
priceActual: string // Prix remisé (price), ex: "19.99"
stock: number
weightKg: number
vendor: string // Marque
famille: string // Famille (contexte IA)
sousFamille: string
comment: string // Commentaire
collectionId: string // ID FAMILLE → collection Shopify
subCollectionId: string // ID SOUS FAMILLE
hasPhoto: boolean
specificFields: Record<string, string> // header → valeur pour les métachamps
}
/** Définition de métachamp existante dans Shopify */
export interface MetafieldDefinition {
id: string // ex: "123"
namespace: string // ex: "custom"
key: string // ex: "puissance"
name: string // ex: "Puissance"
type: string // ex: "single_line_text_field"
}
/** Résolution d'une colonne spécifique vers un métachamp */
export interface MetafieldResolution {
columnHeader: string // en-tête colonne Sheets, ex: "Puissance (AN)"
action: 'create' | 'map' | 'skip'
namespace: string // "custom" par défaut
key: string // clé normalisée
existingDefinitionId?: string // si action === 'map'
}
/** Événement streamé par /api/creation/execute */
export type CreationStreamEvent =
| { type: 'progress'; current: number; total: number; tab: string; title: string; step: string }
| { type: 'error'; title: string; message: string }
| { type: 'done'; summary: { created: number; errors: number; status: 'success' | 'partial' | 'error' } }
/** Résumé d'une création (stocké en DB) */
export interface CreationRecord {
id: string
createdAt: string
userName: string
sheetTab: string
sheetRow: number
shopifyId: string
sku: string
title: string
status: 'success' | 'error'
errorMessage?: string
}