42c580d7e2
Maintenance mode banner: - App layout reads SystemConfig maintenance_mode at server render time - Amber sticky banner for regular users, dimmed indicator for superadmin Baby activities (3 new event types): - BATH (Bath icon, sky, timer+duration) - WALK / Balade (Footprints icon, lime) - TUMMY_TIME (Baby icon, amber) - Added to EventType enum, EVENT_CONFIG, event-icon.tsx, dashboard quick-log Pinned family note: - Shared across all family members, shown at top of dashboard - Inline edit with author + timestamp; /api/family/pinned-note GET/PATCH - pinnedNote + pinnedNoteUpdatedAt + pinnedNoteAuthor fields on Family model Event templates: - Named quick-log presets per family (type + label + metadata) - Dashboard row: tap to open pre-filled EventModal; hover ✕ to delete - Dropdown to create new template; /api/event-templates GET/POST + /[id] PATCH/DELETE - EventTemplate model in schema Weekly summary cron: - POST /api/cron/weekly-summary — auth via Bearer cron_secret (SystemConfig or env) - Per family, per baby: feeds count, sleep total+avg, diaper count, latest weight - Sends Pushover to all family members with pushoverUserKey - Optional body.familyId to target one family Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
268 lines
7.0 KiB
Plaintext
268 lines
7.0 KiB
Plaintext
generator client {
|
|
provider = "prisma-client"
|
|
output = "../src/generated/prisma"
|
|
}
|
|
|
|
datasource db {
|
|
provider = "postgresql"
|
|
}
|
|
|
|
enum UserRole {
|
|
PARENT
|
|
READONLY
|
|
DOCTOR
|
|
}
|
|
|
|
model User {
|
|
id String @id @default(cuid())
|
|
email String @unique
|
|
name String
|
|
password String?
|
|
image String?
|
|
role UserRole @default(PARENT)
|
|
isSuperAdmin Boolean @default(false)
|
|
pushoverUserKey String?
|
|
familyId String?
|
|
family Family? @relation(fields: [familyId], references: [id])
|
|
events Event[]
|
|
sessions Session[]
|
|
accounts Account[]
|
|
doctorNotes DoctorNote[]
|
|
journalNotes JournalNote[]
|
|
passwordResetTokens PasswordResetToken[]
|
|
forcedLogoutAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
}
|
|
|
|
model PasswordResetToken {
|
|
id String @id @default(cuid())
|
|
userId String
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
token String @unique @default(cuid())
|
|
expiresAt DateTime
|
|
used Boolean @default(false)
|
|
createdAt DateTime @default(now())
|
|
}
|
|
|
|
model SystemConfig {
|
|
key String @id
|
|
value String
|
|
updatedAt DateTime @updatedAt
|
|
}
|
|
|
|
model Account {
|
|
id String @id @default(cuid())
|
|
userId String
|
|
type String
|
|
provider String
|
|
providerAccountId String
|
|
refresh_token String?
|
|
access_token String?
|
|
expires_at Int?
|
|
token_type String?
|
|
scope String?
|
|
id_token String?
|
|
session_state String?
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([provider, providerAccountId])
|
|
}
|
|
|
|
model Session {
|
|
id String @id @default(cuid())
|
|
sessionToken String @unique
|
|
userId String
|
|
expires DateTime
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
}
|
|
|
|
model VerificationToken {
|
|
identifier String
|
|
token String @unique
|
|
expires DateTime
|
|
|
|
@@unique([identifier, token])
|
|
}
|
|
|
|
model Family {
|
|
id String @id @default(cuid())
|
|
name String
|
|
inviteCode String @unique @default(cuid())
|
|
users User[]
|
|
babies Baby[]
|
|
eventTemplates EventTemplate[]
|
|
pinnedNote String?
|
|
pinnedNoteUpdatedAt DateTime?
|
|
pinnedNoteAuthor String?
|
|
createdAt DateTime @default(now())
|
|
}
|
|
|
|
model EventTemplate {
|
|
id String @id @default(cuid())
|
|
familyId String
|
|
family Family @relation(fields: [familyId], references: [id], onDelete: Cascade)
|
|
label String
|
|
type EventType
|
|
metadata Json?
|
|
sortOrder Int @default(0)
|
|
createdAt DateTime @default(now())
|
|
}
|
|
|
|
model Baby {
|
|
id String @id @default(cuid())
|
|
name String
|
|
birthDate DateTime
|
|
gender String?
|
|
familyId String
|
|
family Family @relation(fields: [familyId], references: [id])
|
|
events Event[]
|
|
growthLogs GrowthLog[]
|
|
doctorNotes DoctorNote[]
|
|
journalNotes JournalNote[]
|
|
milestones Milestone[]
|
|
vaccinations Vaccination[]
|
|
medicationReminders MedicationReminder[]
|
|
milkStocks MilkStock[]
|
|
createdAt DateTime @default(now())
|
|
}
|
|
|
|
model Event {
|
|
id String @id @default(cuid())
|
|
babyId String
|
|
baby Baby @relation(fields: [babyId], references: [id], onDelete: Cascade)
|
|
userId String
|
|
user User @relation(fields: [userId], references: [id])
|
|
type EventType
|
|
startedAt DateTime
|
|
endedAt DateTime?
|
|
notes String?
|
|
metadata Json?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
}
|
|
|
|
enum EventType {
|
|
BREASTFEED
|
|
BOTTLE
|
|
PUMP
|
|
DIAPER_WET
|
|
DIAPER_STOOL
|
|
NAP
|
|
NIGHT_SLEEP
|
|
MEDICATION
|
|
TEMPERATURE
|
|
BATH
|
|
WALK
|
|
TUMMY_TIME
|
|
}
|
|
|
|
model GrowthLog {
|
|
id String @id @default(cuid())
|
|
babyId String
|
|
baby Baby @relation(fields: [babyId], references: [id], onDelete: Cascade)
|
|
date DateTime
|
|
weight Float?
|
|
height Float?
|
|
headCirc Float?
|
|
notes String?
|
|
createdAt DateTime @default(now())
|
|
}
|
|
|
|
model DoctorNote {
|
|
id String @id @default(cuid())
|
|
babyId String
|
|
baby Baby @relation(fields: [babyId], references: [id], onDelete: Cascade)
|
|
userId String
|
|
user User @relation(fields: [userId], references: [id])
|
|
content String
|
|
date DateTime @default(now())
|
|
createdAt DateTime @default(now())
|
|
}
|
|
|
|
model JournalNote {
|
|
id String @id @default(cuid())
|
|
babyId String
|
|
baby Baby @relation(fields: [babyId], references: [id], onDelete: Cascade)
|
|
userId String
|
|
user User @relation(fields: [userId], references: [id])
|
|
date DateTime
|
|
content String
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
}
|
|
|
|
model Milestone {
|
|
id String @id @default(cuid())
|
|
babyId String
|
|
baby Baby @relation(fields: [babyId], references: [id], onDelete: Cascade)
|
|
title String
|
|
date DateTime
|
|
notes String?
|
|
icon String?
|
|
createdAt DateTime @default(now())
|
|
}
|
|
|
|
model Vaccination {
|
|
id String @id @default(cuid())
|
|
babyId String
|
|
baby Baby @relation(fields: [babyId], references: [id], onDelete: Cascade)
|
|
name String
|
|
date DateTime?
|
|
dueDate DateTime?
|
|
notes String?
|
|
done Boolean @default(false)
|
|
createdAt DateTime @default(now())
|
|
}
|
|
|
|
model AuditLog {
|
|
id String @id @default(cuid())
|
|
userId String
|
|
userName String
|
|
action String
|
|
targetId String?
|
|
familyId String?
|
|
detail String?
|
|
createdAt DateTime @default(now())
|
|
}
|
|
|
|
model MedicationProfile {
|
|
id String @id @default(cuid())
|
|
familyId String
|
|
name String
|
|
molecule String?
|
|
defaultDose String?
|
|
unit String @default("mL")
|
|
intervalHours Float @default(6)
|
|
minIntervalHours Float?
|
|
isPreset Boolean @default(false)
|
|
createdAt DateTime @default(now())
|
|
}
|
|
|
|
model MilkStock {
|
|
id String @id @default(cuid())
|
|
babyId String
|
|
baby Baby @relation(fields: [babyId], references: [id], onDelete: Cascade)
|
|
volume Float
|
|
storedAt DateTime @default(now())
|
|
expiresAt DateTime
|
|
location String @default("fridge")
|
|
notes String?
|
|
used Boolean @default(false)
|
|
usedAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
}
|
|
|
|
model MedicationReminder {
|
|
id String @id @default(cuid())
|
|
babyId String
|
|
baby Baby @relation(fields: [babyId], references: [id], onDelete: Cascade)
|
|
name String
|
|
dose String?
|
|
unit String?
|
|
intervalHours Float
|
|
startAt DateTime
|
|
enabled Boolean @default(true)
|
|
lastSentAt DateTime?
|
|
createdAt DateTime @default(now())
|
|
}
|