notification

This commit is contained in:
vadim committed 2026-09-29 18:42:29 +03:00
1 parent 382cafa152
commit 60391ee123
26 files changed
+1077 -14

No files matched your search

+69 -13
View File
@@ -8,19 +8,22 @@ datasource db {
}
model User {
id String @id
name String
email String
emailVerified Boolean @default(false)
image String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
sessions Session[]
accounts Account[]
assigneeIssues Issue[] @relation(name: "assigneeIssues")
reporterIssues Issue[] @relation(name: "reporterIssues")
projects Project[]
projectMemberships ProjectMember[]
id String @id
name String
email String
emailVerified Boolean @default(false)
image String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
sessions Session[]
accounts Account[]
assigneeIssues Issue[] @relation(name: "assigneeIssues")
reporterIssues Issue[] @relation(name: "reporterIssues")
projects Project[]
projectMemberships ProjectMember[]
notificationDeviceTokens NotificationDeviceToken[]
notificationPreferences NotificationPreference[]
notificationMessages NotificationMessage[]
@@unique([email])
@@map("user")
@@ -132,3 +135,56 @@ model ProjectMember {
@@index([userId])
@@map("project_member")
}
/// Push-токены устройств пользователя. Регистрируются напрямую клиентом,
/// без участия остального приложения.
model NotificationDeviceToken {
id String @id @default(uuid(7))
userId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
token String
platform String // ios | android | web
createdAt DateTime @default(now()) @db.Timestamptz(3)
updatedAt DateTime @updatedAt @db.Timestamptz(3)
@@unique([userId, token])
@@index([userId])
@@map("notification_device_token")
}
/// Включён ли у пользователя конкретный канал доставки уведомлений.
/// Категорий нет — настройка одна на канал.
/// Допустимые значения channel валидируются в коде (NotificationChannel VO),
/// а не типом БД — расширение списка каналов не требует миграции.
model NotificationPreference {
id String @id @default(uuid(7))
userId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
channel String
enabled Boolean @default(true)
updatedAt DateTime @updatedAt @db.Timestamptz(3)
@@unique([userId, channel])
@@map("notification_preference")
}
/// Лог/история отправленных уведомлений — одна запись на попытку доставки
/// по одному каналу. channel/status — строки, валидируются в коде
/// (NotificationChannel/NotificationStatus VO), см. комментарий выше.
model NotificationMessage {
id String @id @default(uuid(7))
userId String
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
channel String
status String @default("PENDING")
subject String?
content String
error String?
sentAt DateTime? @db.Timestamptz(3)
createdAt DateTime @default(now()) @db.Timestamptz(3)
@@index([userId])
@@index([status])
@@index([createdAt])
@@map("notification_message")
}