020539e2e2
New pages: - /calendar — monthly grid with event dots, day detail on tap - /medications — CRUD for medication profiles (presets + custom, dose/unit/intervals/crisis mode) - /milk — milk stock management with location-based expiry, alerts, mark-as-used - /reminders — recurring medication reminder CRUD with Pushover notifications New APIs: - /api/medication-profiles — profiles CRUD + last-intakes endpoint (auto-seeds 10 presets per family) - /api/milk — milk stock CRUD with auto-calculated expiry - /api/reminders + /api/reminders/check — reminder CRUD + cron-callable check endpoint - /api/upload — multipart photo upload to public/uploads/ - /api/invite/send-email — email invitation with family invite link - /api/admin/audit — last 100 audit log entries (superadmin only) Event modal improvements: - PUMP event type (side selector + volume + timer) - MEDICATION: profile chip picker, next-dose timing status, crisis mode toggle - Photo attachment (upload + thumbnail preview) - Datetime inputs split into date + time (iOS Safari datetime-local fix) - Edit mode via initialEvent prop (pre-fills all fields, saves via PATCH) - Timer now shows h:mm:ss when >= 1 hour Timeline: - Modify button opens pre-filled edit modal per event - Photo thumbnail in expanded view Dashboard: - PUMP in quick-log - Medication status card (too-soon / available with next-dose time) Schema additions: MedicationProfile, MedcationReminder, MilkStock, AuditLog models Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
250 lines
6.5 KiB
Plaintext
250 lines
6.5 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[]
|
|
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
|
|
}
|
|
|
|
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())
|
|
}
|