Files
webflash/platform/backend/prisma/schema.prisma
root 9a9967bed8 feat: mock payment flow + flash token page (test mode)
- Mock purchase: order create → mock-pay → FlashToken issued instantly (no real billing)
- Flash page (/flash/:token): esp-web-tools integration, token state display, consume on complete
- Orders route: create/mock-pay/me/refund with full audit logging
- Flash route: GET validate, GET manifest (esp-web-tools compatible), POST consume
- MinIO file proxy (/api/files/*): browser CORS solved, firmware served through backend
- Schema: chipFamily on Project, flashOffset on ProjectFile
- ProjectNew: chipFamily selector + firmware flash offset option
- MyOrders: real order list with flash token status and buttons
- Dockerfile: prisma db push (no migration files needed for dev)
- TOSS_PAYMENT_GUIDE.md: step-by-step guide for real payment after business registration

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 06:18:19 +09:00

205 lines
5.0 KiB
Plaintext

generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
enum UserRole {
admin
seller
buyer
}
enum ProjectStatus {
draft
pending
approved
rejected
suspended
}
enum OrderStatus {
pending
paid
cancelled
refunded
}
enum PaymentGateway {
toss
stripe
}
model User {
id String @id @default(uuid())
email String @unique
passwordHash String
nickname String @unique
role UserRole @default(buyer)
profileImageUrl String?
isEmailVerified Boolean @default(false)
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
lastLoginAt DateTime?
lastLoginIp String?
projects Project[]
orders Order[]
reviews Review[]
auditLogs AuditLog[]
}
model Project {
id String @id @default(uuid())
userId String
user User @relation(fields: [userId], references: [id])
title String
description String @db.Text
difficultyLevel Int @default(3)
chipFamily String @default("ESP32-S3")
requiredParts Json?
status ProjectStatus @default(draft)
adminNote String?
commissionRate Float @default(0.1)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
files ProjectFile[]
product Product?
}
model ProjectFile {
id String @id @default(uuid())
projectId String
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
fileType String
url String
thumbnailUrl String?
fileSize Int
mimeType String
originalName String?
flashOffset String @default("0x0")
displayOrder Int @default(0)
createdAt DateTime @default(now())
}
model Product {
id String @id @default(uuid())
projectId String @unique
project Project @relation(fields: [projectId], references: [id])
price Int
isOnSale Boolean @default(true)
totalSales Int @default(0)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
orders Order[]
reviews Review[]
}
model Order {
id String @id @default(uuid())
buyerId String
buyer User @relation(fields: [buyerId], references: [id])
productId String
product Product @relation(fields: [productId], references: [id])
amount Int
commissionAmount Int
sellerAmount Int
paymentGateway PaymentGateway @default(toss)
paymentKey String?
tossOrderId String? @unique
status OrderStatus @default(pending)
buyerInfo Json
deviceInfo Json?
orderedAt DateTime @default(now())
paidAt DateTime?
refundedAt DateTime?
refundReason String?
flashToken FlashToken?
review Review?
}
model FlashToken {
id String @id @default(uuid())
token String @unique @default(uuid())
orderId String @unique
order Order @relation(fields: [orderId], references: [id])
isUsed Boolean @default(false)
usedAt DateTime?
macAddress String?
chipFamily String?
expiresAt DateTime
createdAt DateTime @default(now())
flashLog FlashLog?
}
model FlashLog {
id String @id @default(uuid())
flashTokenId String @unique
flashToken FlashToken @relation(fields: [flashTokenId], references: [id])
macAddress String
chipFamily String
firmwareName String
firmwareId String
success Boolean
errorMessage String?
clientIp String
userAgent String?
flashedAt DateTime @default(now())
}
model Review {
id String @id @default(uuid())
orderId String @unique
order Order @relation(fields: [orderId], references: [id])
userId String
user User @relation(fields: [userId], references: [id])
productId String
product Product @relation(fields: [productId], references: [id])
rating Int
title String
content String @db.Text
isVisible Boolean @default(true)
createdAt DateTime @default(now())
media ReviewMedia[]
}
model ReviewMedia {
id String @id @default(uuid())
reviewId String
review Review @relation(fields: [reviewId], references: [id], onDelete: Cascade)
mediaType String
url String
thumbnailUrl String?
createdAt DateTime @default(now())
}
model AuditLog {
id String @id @default(uuid())
userId String?
user User? @relation(fields: [userId], references: [id])
action String
targetType String?
targetId String?
ipAddress String
userAgent String?
requestMethod String?
requestPath String?
requestBody Json?
responseStatus Int?
metadata Json?
createdAt DateTime @default(now())
@@index([userId])
@@index([action])
@@index([createdAt])
}