Build the Data Layer
20 min read
Model Annotations and Preferences
Model Annotations and Preferences
Finish the data model for the features that make Readly a personal reading space.
Task
Add bookmarks, highlights, notes, and reader preferences.
Use these models:
model Bookmark {
id String @id @default(cuid())
userId String
bookId String
cfi String
label String?
createdAt DateTime @default(now())
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
book Book @relation(fields: [bookId], references: [id], onDelete: Cascade)
@@index([userId, bookId])
}
model Highlight {
id String @id @default(cuid())
userId String
bookId String
cfi String
text String
color String @default("yellow")
favorite Boolean @default(false)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
book Book @relation(fields: [bookId], references: [id], onDelete: Cascade)
notes Note[]
@@index([userId, bookId])
}
model Note {
id String @id @default(cuid())
userId String
bookId String
highlightId String?
content String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
book Book @relation(fields: [bookId], references: [id], onDelete: Cascade)
highlight Highlight? @relation(fields: [highlightId], references: [id], onDelete: Cascade)
@@index([userId, bookId])
@@index([highlightId])
}
model ReaderPreference {
id String @id @default(cuid())
userId String @unique
theme String @default("paper")
fontFamily String @default("serif")
fontSize Int @default(105)
lineHeight Float @default(1.7)
contentWidth String @default("comfortable")
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
}
Update the User Relations
User should expose the collections used by these models:
bookmarks Bookmark[]
highlights Highlight[]
notes Note[]
readerPreferences ReaderPreference?
Update the Book Relations
Book should expose:
bookmarks Bookmark[]
highlights Highlight[]
notes Note[]
Check the Relationship Design
Highlights can have notes, while notes can also belong directly to a book. This gives the annotations UI enough information to support passage notes and book-level notes without coupling the reader to the database implementation.
Test
Run:
npx prisma format
npx prisma validate
Checkpoint
The Prisma schema now represents the complete persistence model required by the remaining Readly course modules.