- Remove Anki apkg import/export functionality - Remove OCR feature module - Remove note and note-type modules - Simplify card/deck modules (remove spaced repetition complexity) - Update translator and dictionary features - Clean up unused translations and update i18n files - Simplify prisma schema
177 lines
4.5 KiB
Plaintext
177 lines
4.5 KiB
Plaintext
generator client {
|
|
provider = "prisma-client"
|
|
output = "../generated/prisma"
|
|
}
|
|
|
|
datasource db {
|
|
provider = "postgresql"
|
|
}
|
|
|
|
// ============================================
|
|
// User & Auth
|
|
// ============================================
|
|
|
|
model User {
|
|
id String @id
|
|
name String
|
|
email String @unique
|
|
emailVerified Boolean @default(false)
|
|
image String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
displayUsername String?
|
|
username String @unique
|
|
bio String?
|
|
accounts Account[]
|
|
decks Deck[]
|
|
deckFavorites DeckFavorite[]
|
|
sessions Session[]
|
|
followers Follow[] @relation("UserFollowers")
|
|
following Follow[] @relation("UserFollowing")
|
|
|
|
@@map("user")
|
|
}
|
|
|
|
model Session {
|
|
id String @id
|
|
expiresAt DateTime
|
|
token String @unique
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
ipAddress String?
|
|
userAgent String?
|
|
userId String
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([userId])
|
|
@@map("session")
|
|
}
|
|
|
|
model Account {
|
|
id String @id
|
|
accountId String
|
|
providerId String
|
|
userId String
|
|
accessToken String?
|
|
refreshToken String?
|
|
idToken String?
|
|
accessTokenExpiresAt DateTime?
|
|
refreshTokenExpiresAt DateTime?
|
|
scope String?
|
|
password String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([userId])
|
|
@@map("account")
|
|
}
|
|
|
|
model Verification {
|
|
id String @id
|
|
identifier String
|
|
value String
|
|
expiresAt DateTime
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
|
|
@@index([identifier])
|
|
@@map("verification")
|
|
}
|
|
|
|
// ============================================
|
|
// Deck & Card
|
|
// ============================================
|
|
|
|
enum Visibility {
|
|
PUBLIC
|
|
PRIVATE
|
|
}
|
|
|
|
enum CardType {
|
|
WORD
|
|
PHRASE
|
|
SENTENCE
|
|
}
|
|
|
|
model Deck {
|
|
id Int @id @default(autoincrement())
|
|
name String
|
|
desc String @db.Text @default("")
|
|
userId String
|
|
visibility Visibility @default(PRIVATE)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
cards Card[]
|
|
favorites DeckFavorite[]
|
|
|
|
@@index([userId])
|
|
@@index([visibility])
|
|
@@map("decks")
|
|
}
|
|
|
|
model Card {
|
|
id Int @id @default(autoincrement())
|
|
deckId Int
|
|
word String
|
|
ipa String?
|
|
queryLang String
|
|
cardType CardType @default(WORD)
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
deck Deck @relation(fields: [deckId], references: [id], onDelete: Cascade)
|
|
meanings CardMeaning[]
|
|
|
|
@@index([deckId])
|
|
@@index([word])
|
|
@@map("cards")
|
|
}
|
|
|
|
model CardMeaning {
|
|
id Int @id @default(autoincrement())
|
|
cardId Int
|
|
partOfSpeech String?
|
|
definition String
|
|
example String?
|
|
createdAt DateTime @default(now())
|
|
updatedAt DateTime @updatedAt
|
|
card Card @relation(fields: [cardId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([cardId])
|
|
@@map("card_meanings")
|
|
}
|
|
|
|
model DeckFavorite {
|
|
id Int @id @default(autoincrement())
|
|
userId String
|
|
deckId Int
|
|
createdAt DateTime @default(now())
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
deck Deck @relation(fields: [deckId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([userId, deckId])
|
|
@@index([userId])
|
|
@@index([deckId])
|
|
@@map("deck_favorites")
|
|
}
|
|
|
|
// ============================================
|
|
// Social
|
|
// ============================================
|
|
|
|
model Follow {
|
|
id String @id @default(cuid())
|
|
followerId String @map("follower_id")
|
|
followingId String @map("following_id")
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
|
|
follower User @relation("UserFollowers", fields: [followerId], references: [id], onDelete: Cascade)
|
|
following User @relation("UserFollowing", fields: [followingId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([followerId, followingId])
|
|
@@index([followerId])
|
|
@@index([followingId])
|
|
@@map("follows")
|
|
}
|