fix sso core folder

This commit is contained in:
lendry
2026-06-24 14:45:45 +03:00
parent 995adeedd4
commit d2bbf35d40
45 changed files with 6592 additions and 1 deletions

View File

@@ -0,0 +1,481 @@
generator client {
provider = "prisma-client-js"
output = "../src/generated/prisma"
}
datasource db {
provider = "postgresql"
}
enum UserStatus {
ACTIVE
SUSPENDED
DELETED
}
enum SessionStatus {
ACTIVE
LOCKED
REVOKED
EXPIRED
}
enum DeviceType {
WEB
IOS
ANDROID
DESKTOP
TV
SMART_SPEAKER
OTHER
}
enum OAuthClientType {
CONFIDENTIAL
PUBLIC
}
model User {
id String @id @default(uuid())
email String? @unique
phone String? @unique
backupEmail String? @unique
backupPhone String? @unique
passwordHash String?
displayName String
username String? @unique
avatarUrl String?
avatarStorageKey String?
birthDate DateTime?
gender String?
isSuperAdmin Boolean @default(false)
status UserStatus @default(ACTIVE)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
deletedAt DateTime?
pinCode PinCode?
sessions Session[]
devices Device[]
signInEvents SignInEvent[]
authCodes AuthCode[]
linkedAccounts LinkedAccount[]
userRoles UserRole[]
profile UserProfile?
documents UserDocument[]
addresses Address[]
oauthConsents OAuthConsent[]
oauthAuthCodes OAuthAuthorizationCode[]
ownedFamilyGroups FamilyGroup[]
familyMemberships FamilyMember[]
sentFamilyInvites FamilyInvite[] @relation("FamilyInviteInviter")
receivedFamilyInvites FamilyInvite[] @relation("FamilyInviteInvitee")
notifications Notification[]
chatRoomMembers ChatRoomMember[]
chatMessages ChatMessage[]
chatPollVotes ChatPollVote[]
}
model UserProfile {
id String @id @default(uuid())
userId String @unique
firstName String?
lastName String?
bio String?
age Int?
gender String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
}
model PinCode {
id String @id @default(uuid())
userId String @unique
hash String
isEnabled Boolean @default(false)
deletionRequestedAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
}
model Session {
id String @id @default(uuid())
userId String
deviceId String?
refreshHash String
pinVerified Boolean @default(true)
status SessionStatus @default(ACTIVE)
ipAddress String?
userAgent String?
expiresAt DateTime
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
device Device? @relation(fields: [deviceId], references: [id], onDelete: SetNull)
@@index([userId, status])
}
model Device {
id String @id @default(uuid())
userId String
name String
type DeviceType @default(OTHER)
fingerprint String
lastIp String?
lastSeenAt DateTime @default(now())
trusted Boolean @default(false)
createdAt DateTime @default(now())
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
sessions Session[]
signInEvents SignInEvent[]
@@unique([userId, fingerprint])
}
model SignInEvent {
id String @id @default(uuid())
userId String
deviceId String?
ipAddress String?
userAgent String?
success Boolean
reason String?
createdAt DateTime @default(now())
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
device Device? @relation(fields: [deviceId], references: [id], onDelete: SetNull)
@@index([userId, createdAt])
}
model LinkedAccount {
id String @id @default(uuid())
userId String
providerName String
providerId String
email String?
displayName String?
avatarUrl String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([providerName, providerId])
@@index([userId])
}
model Role {
id String @id @default(uuid())
slug String @unique
name String
description String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
users UserRole[]
permissions RolePermission[]
}
model Permission {
id String @id @default(uuid())
slug String @unique
name String
description String?
createdAt DateTime @default(now())
roles RolePermission[]
}
model UserRole {
userId String
roleId String
createdAt DateTime @default(now())
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
role Role @relation(fields: [roleId], references: [id], onDelete: Cascade)
@@id([userId, roleId])
}
model RolePermission {
roleId String
permissionId String
createdAt DateTime @default(now())
role Role @relation(fields: [roleId], references: [id], onDelete: Cascade)
permission Permission @relation(fields: [permissionId], references: [id], onDelete: Cascade)
@@id([roleId, permissionId])
}
model OAuthClient {
id String @id @default(uuid())
name String
clientId String @unique
clientSecret String?
type OAuthClientType @default(CONFIDENTIAL)
redirectUris String[]
scopes OAuthClientScope[]
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
consents OAuthConsent[]
authCodes OAuthAuthorizationCode[]
}
model OAuthAuthorizationCode {
id String @id @default(uuid())
code String @unique
userId String
clientId String
redirectUri String
scopes String[]
expiresAt DateTime
consumedAt DateTime?
createdAt DateTime @default(now())
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
client OAuthClient @relation(fields: [clientId], references: [id], onDelete: Cascade)
@@index([userId, clientId])
}
model OAuthScope {
id String @id @default(uuid())
slug String @unique
name String
description String?
clients OAuthClientScope[]
consents OAuthConsentScope[]
}
model OAuthClientScope {
clientId String
scopeId String
client OAuthClient @relation(fields: [clientId], references: [id], onDelete: Cascade)
scope OAuthScope @relation(fields: [scopeId], references: [id], onDelete: Cascade)
@@id([clientId, scopeId])
}
model OAuthConsent {
id String @id @default(uuid())
userId String
clientId String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
client OAuthClient @relation(fields: [clientId], references: [id], onDelete: Cascade)
scopes OAuthConsentScope[]
@@unique([userId, clientId])
}
model OAuthConsentScope {
consentId String
scopeId String
consent OAuthConsent @relation(fields: [consentId], references: [id], onDelete: Cascade)
scope OAuthScope @relation(fields: [scopeId], references: [id], onDelete: Cascade)
@@id([consentId, scopeId])
}
model UserDocument {
id String @id @default(uuid())
userId String
type String
number String
issuedAt DateTime?
expiresAt DateTime?
metadata Json?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
}
model AuthCode {
id String @id @default(uuid())
userId String?
channel String
target String
codeHash String
purpose String
expiresAt DateTime
usedAt DateTime?
createdAt DateTime @default(now())
user User? @relation(fields: [userId], references: [id], onDelete: Cascade)
@@index([target, purpose, expiresAt])
}
model FamilyGroup {
id String @id @default(uuid())
ownerId String
name String
avatarStorageKey String?
hasAvatar Boolean @default(false)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
owner User @relation(fields: [ownerId], references: [id], onDelete: Cascade)
members FamilyMember[]
invites FamilyInvite[]
chatRooms ChatRoom[]
}
model FamilyInvite {
id String @id @default(uuid())
groupId String
inviterId String
inviteeUserId String?
targetEmail String?
targetPhone String?
status String @default("PENDING")
token String @unique @default(uuid())
expiresAt DateTime
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
group FamilyGroup @relation(fields: [groupId], references: [id], onDelete: Cascade)
inviter User @relation("FamilyInviteInviter", fields: [inviterId], references: [id], onDelete: Cascade)
invitee User? @relation("FamilyInviteInvitee", fields: [inviteeUserId], references: [id], onDelete: SetNull)
@@index([inviteeUserId, status])
@@index([groupId, status])
}
model Notification {
id String @id @default(uuid())
userId String
type String
title String
message String
payload Json?
isRead Boolean @default(false)
createdAt DateTime @default(now())
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@index([userId, isRead, createdAt])
}
model ChatRoom {
id String @id @default(uuid())
groupId String
type String
name String
avatarStorageKey String?
hasAvatar Boolean @default(false)
createdById String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
group FamilyGroup @relation(fields: [groupId], references: [id], onDelete: Cascade)
members ChatRoomMember[]
messages ChatMessage[]
@@index([groupId, type])
}
model ChatRoomMember {
id String @id @default(uuid())
roomId String
userId String
notificationsMuted Boolean @default(false)
joinedAt DateTime @default(now())
room ChatRoom @relation(fields: [roomId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([roomId, userId])
}
model ChatMessage {
id String @id @default(uuid())
roomId String
senderId String
type String
content String?
replyToId String?
metadata Json?
storageKey String?
mimeType String?
createdAt DateTime @default(now())
editedAt DateTime?
room ChatRoom @relation(fields: [roomId], references: [id], onDelete: Cascade)
sender User @relation(fields: [senderId], references: [id], onDelete: Cascade)
poll ChatPoll?
@@index([roomId, createdAt])
}
model ChatPoll {
id String @id @default(uuid())
messageId String @unique
question String
allowsMultiple Boolean @default(false)
isAnonymous Boolean @default(false)
closedAt DateTime?
message ChatMessage @relation(fields: [messageId], references: [id], onDelete: Cascade)
options ChatPollOption[]
}
model ChatPollOption {
id String @id @default(uuid())
pollId String
text String
poll ChatPoll @relation(fields: [pollId], references: [id], onDelete: Cascade)
votes ChatPollVote[]
}
model ChatPollVote {
id String @id @default(uuid())
optionId String
userId String
option ChatPollOption @relation(fields: [optionId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([optionId, userId])
}
model FamilyMember {
id String @id @default(uuid())
groupId String
userId String
role String @default("member")
createdAt DateTime @default(now())
group FamilyGroup @relation(fields: [groupId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([groupId, userId])
}
model Address {
id String @id @default(uuid())
userId String
label String
city String
street String
house String
apartment String?
comment String?
latitude Float?
longitude Float?
fullAddress String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@index([userId, label])
}
model SystemSetting {
id String @id @default(uuid())
key String @unique
value String
description String?
isSecret Boolean @default(false)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model SocialProvider {
id String @id @default(uuid())
providerName String @unique
clientId String
clientSecret String?
isEnabled Boolean @default(false)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}