Two new tabs in the Studio Notebook: - 📚 Classes: a binder for courses, workshops, books, and video series. Each class has a subject, source, link, status (taking / want / done), a what-it's-about note, photos, handout files, and dated pages of class notes that can be edited in place. - 💭 Mind Dump: idea capture filed by category (things to make — with a medium: clay / wood / silver / metal / mixed — marketing, packaging, display & booth, shop & site, other) with spark / trying / did it / parked status, sketch photos, one-tap 'make it a to-do', and filters. The Today jot box gains a 💭 idea chip; those land as 'unsorted' to file later. Schema: Course, CoursePage, Idea (additive; prisma db push at boot). Files tab now labels attachments that belong to a class. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
203 lines
5.9 KiB
Plaintext
203 lines
5.9 KiB
Plaintext
generator client {
|
|
provider = "prisma-client-js"
|
|
}
|
|
|
|
datasource db {
|
|
provider = "postgresql"
|
|
url = env("DATABASE_URL")
|
|
}
|
|
|
|
model User {
|
|
id Int @id @default(autoincrement())
|
|
email String @unique
|
|
passwordHash String
|
|
role String @default("OWNER")
|
|
created DateTime @default(now())
|
|
}
|
|
|
|
// spent OTM sign-in tokens (operator-magic + otm-sso) — jti is the single-use
|
|
// key; operatorEmail is the audit trail of who came in through OTM
|
|
model OperatorMagicConsumed {
|
|
jti String @id
|
|
operatorEmail String @default("")
|
|
consumedAt DateTime @default(now())
|
|
}
|
|
|
|
model Note {
|
|
id Int @id @default(autoincrement())
|
|
text String
|
|
tags String @default("")
|
|
created DateTime @default(now())
|
|
}
|
|
|
|
model Todo {
|
|
id Int @id @default(autoincrement())
|
|
text String
|
|
done Boolean @default(false)
|
|
started Boolean @default(false)
|
|
parentId Int?
|
|
created DateTime @default(now())
|
|
}
|
|
|
|
model Shopping {
|
|
id Int @id @default(autoincrement())
|
|
text String
|
|
done Boolean @default(false)
|
|
created DateTime @default(now())
|
|
}
|
|
|
|
model Glaze {
|
|
id Int @id @default(autoincrement())
|
|
name String
|
|
kind String @default("glaze")
|
|
cone String @default("")
|
|
atmosphere String @default("")
|
|
surface String @default("")
|
|
source String @default("mine")
|
|
sg String @default("")
|
|
swatch String @default("")
|
|
created DateTime @default(now())
|
|
materials GlazeMaterial[]
|
|
journal GlazeJournal[]
|
|
}
|
|
|
|
model GlazeMaterial {
|
|
id Int @id @default(autoincrement())
|
|
glazeId Int
|
|
glaze Glaze @relation(fields: [glazeId], references: [id], onDelete: Cascade)
|
|
name String
|
|
pct Float
|
|
addition Boolean @default(false)
|
|
}
|
|
|
|
model GlazeJournal {
|
|
id Int @id @default(autoincrement())
|
|
glazeId Int
|
|
glaze Glaze @relation(fields: [glazeId], references: [id], onDelete: Cascade)
|
|
text String
|
|
created DateTime @default(now())
|
|
}
|
|
|
|
model Firing {
|
|
id Int @id @default(autoincrement())
|
|
type String @default("glaze")
|
|
cone String @default("∆6")
|
|
schedule String @default("")
|
|
status String @default("firing")
|
|
resultNotes String @default("")
|
|
started DateTime @default(now())
|
|
unloaded DateTime?
|
|
items FiringItem[]
|
|
}
|
|
|
|
model FiringItem {
|
|
id Int @id @default(autoincrement())
|
|
firingId Int
|
|
firing Firing @relation(fields: [firingId], references: [id], onDelete: Cascade)
|
|
piece String
|
|
clay String @default("")
|
|
glaze String @default("")
|
|
rating String @default("")
|
|
note String @default("")
|
|
}
|
|
|
|
model Photo {
|
|
id Int @id @default(autoincrement())
|
|
entity String
|
|
entityId Int
|
|
filename String
|
|
created DateTime @default(now())
|
|
}
|
|
|
|
model FileAsset {
|
|
id Int @id @default(autoincrement())
|
|
entity String @default("")
|
|
entityId Int @default(0)
|
|
stored String
|
|
name String
|
|
tag String @default("")
|
|
size Int @default(0)
|
|
created DateTime @default(now())
|
|
}
|
|
|
|
model Product {
|
|
id Int @id @default(autoincrement())
|
|
name String
|
|
kind String @default("core line")
|
|
category String @default("")
|
|
price Float @default(0)
|
|
cost Float @default(0)
|
|
qty Int @default(0)
|
|
status String @default("in progress")
|
|
notes String @default("")
|
|
created DateTime @default(now())
|
|
sales Sale[]
|
|
}
|
|
|
|
model Sale {
|
|
id Int @id @default(autoincrement())
|
|
productId Int
|
|
product Product @relation(fields: [productId], references: [id], onDelete: Cascade)
|
|
qty Int @default(1)
|
|
price Float @default(0)
|
|
cost Float @default(0)
|
|
created DateTime @default(now())
|
|
}
|
|
|
|
model Supplier {
|
|
id Int @id @default(autoincrement())
|
|
name String
|
|
kind String @default("online")
|
|
distance String @default("")
|
|
url String @default("")
|
|
notes String @default("")
|
|
searchUrl String @default("")
|
|
created DateTime @default(now())
|
|
prices PriceEntry[]
|
|
}
|
|
|
|
model PriceEntry {
|
|
id Int @id @default(autoincrement())
|
|
item String
|
|
supplierId Int
|
|
supplier Supplier @relation(fields: [supplierId], references: [id], onDelete: Cascade)
|
|
price Float
|
|
unit String @default("")
|
|
shipping Float @default(0)
|
|
note String @default("")
|
|
created DateTime @default(now())
|
|
}
|
|
|
|
// ── Classes binder — a course, workshop, book, or video series Bonna learns from
|
|
model Course {
|
|
id Int @id @default(autoincrement())
|
|
title String
|
|
subject String @default("") // methods · skills · marketing · business · glaze chemistry …
|
|
source String @default("") // teacher / school / author / channel
|
|
url String @default("")
|
|
status String @default("taking") // taking · want · done
|
|
notes String @default("")
|
|
created DateTime @default(now())
|
|
pages CoursePage[]
|
|
}
|
|
|
|
model CoursePage {
|
|
id Int @id @default(autoincrement())
|
|
courseId Int
|
|
course Course @relation(fields: [courseId], references: [id], onDelete: Cascade)
|
|
title String @default("")
|
|
text String
|
|
created DateTime @default(now())
|
|
updated DateTime @default(now())
|
|
}
|
|
|
|
// ── Mind dump — ideas, filed by category ("" = unsorted, from the Today jot box)
|
|
model Idea {
|
|
id Int @id @default(autoincrement())
|
|
text String
|
|
category String @default("") // make · marketing · packaging · display · shop · other
|
|
medium String @default("") // for "make": clay · wood · silver · metal · mixed
|
|
status String @default("spark") // spark · trying · made · parked
|
|
created DateTime @default(now())
|
|
}
|