/home/techb158/balavpn.abdallabala.com/prisma
Edit: /home/techb158/balavpn.abdallabala.com/prisma/schema.prisma (18036B)
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
relationMode = "prisma"
}
enum PlatformRole {
NONE
SUPER_ADMIN
SUPER_OWNER
}
enum OrganizationStatus {
TRIAL
ACTIVE
SUSPENDED
CANCELED
}
enum WorkspaceType {
B2B_TEAM
CONSULTANT_CLIENT
ENTERPRISE
}
enum MembershipStatus {
INVITED
ACTIVE
DISABLED
}
enum SubscriptionSource {
MANUAL
STRIPE
}
enum SubscriptionStatus {
TRIALING
ACTIVE
PAST_DUE
CANCELED
SUSPENDED
}
enum RiskStatus {
OPEN
IN_MITIGATION
ACCEPTED
CLOSED
}
enum ApprovalStatus {
PENDING
APPROVED
REJECTED
ACCEPTED
}
enum MitigationStatus {
NOT_STARTED
IN_PROGRESS
DONE
REJECTED
}
enum GateStatus {
READY
WARNING
BLOCKED
}
enum GateDecisionValue {
APPROVED
REJECTED
ACCEPTED
NEEDS_CHANGES
}
enum IntegrationProvider {
TRELLO
JIRA
ASANA
MICROSOFT_PLANNER
}
enum IntegrationStatus {
CONNECTED
NEEDS_CONFIGURATION
DISABLED
}
model Organization {
id String @id @default(cuid())
name String
slug String @unique
status OrganizationStatus @default(TRIAL)
planCode String @default("pilot")
manualBilling Boolean @default(true)
stripeCustomerId String?
ssoEnforced Boolean @default(false)
allowedDomains String[] @default([])
dataRetentionDays Int?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
workspaces Workspace[]
memberships Membership[]
subscriptions Subscription[]
auditEvents AuditEvent[]
usageEvents UsageEvent[]
invitations Invitation[]
oauthTokens OAuthToken[]
organizationAccess OrganizationAccess[]
}
model Workspace {
id String @id @default(cuid())
organizationId String
name String
slug String
type WorkspaceType @default(B2B_TEAM)
status OrganizationStatus @default(TRIAL)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
projects Project[]
integrations Integration[]
reports ReportExport[]
auditEvents AuditEvent[]
@@unique([organizationId, slug])
@@index([organizationId])
}
model User {
id String @id @default(cuid())
email String @unique
displayName String
passwordHash String?
platformRole PlatformRole @default(NONE)
emailVerifiedAt DateTime?
lastLoginAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
memberships Membership[]
invitationsSent Invitation[] @relation("InvitationSender")
auditEvents AuditEvent[]
sessions Session[]
organizationAccess OrganizationAccess[]
}
model OrganizationAccess {
id String @id @default(cuid())
userId String
organizationId String
role String @default("SUPER_ADMIN")
createdAt DateTime @default(now())
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
@@unique([userId, organizationId])
@@index([userId])
@@index([organizationId])
}
model Session {
id String @id @default(cuid())
userId String
token String @unique
expiresAt DateTime
createdAt DateTime @default(now())
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@index([token])
@@index([userId])
}
model Role {
id String @id @default(cuid())
code String @unique
name String
permissions String[] @default([])
system Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
memberships Membership[]
}
model Membership {
id String @id @default(cuid())
organizationId String
userId String
roleId String
status MembershipStatus @default(INVITED)
workspaceScope String[] @default([])
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
role Role @relation(fields: [roleId], references: [id])
@@unique([organizationId, userId])
@@index([userId])
}
model Invitation {
id String @id @default(cuid())
organizationId String
email String
roleCode String
tokenHash String @unique
expiresAt DateTime
acceptedAt DateTime?
invitedById String?
createdAt DateTime @default(now())
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
invitedBy User? @relation("InvitationSender", fields: [invitedById], references: [id])
@@index([organizationId, email])
}
model Subscription {
id String @id @default(cuid())
organizationId String
source SubscriptionSource @default(MANUAL)
status SubscriptionStatus @default(TRIALING)
planCode String @default("pilot")
stripeSubscriptionId String?
currentPeriodEnd DateTime?
userLimit Int @default(5)
projectLimit Int @default(3)
reportLimitMonthly Int @default(25)
integrationLimit Int @default(2)
storageMbLimit Int @default(1024)
adminOverride Boolean @default(false)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
@@index([organizationId])
}
model Project {
id String @id @default(cuid())
workspaceId String
name String
subtitle String?
projectType String @default("AI-Enabler")
currentLifecyclePhase String?
riskAppetite Int @default(50)
assessmentDate DateTime?
status String @default("Active")
ownerDisplayName String?
description String?
thresholds Json @default("{}")
reviews Json @default("{}")
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)
lifecyclePhases LifecyclePhase[]
risks Risk[]
indicators Indicator[]
experiments Experiment[]
gateEvaluations GateEvaluation[]
auditEvents AuditEvent[]
reports ReportExport[]
scheduledReports ScheduledReport[]
@@index([workspaceId])
}
model LifecyclePhase {
id String @id @default(cuid())
projectId String
name String
status String
readinessScore Int
sequence Int
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
@@unique([projectId, name])
@@index([projectId])
}
model Risk {
id String @id @default(cuid())
projectId String
ownerDisplayName String?
title String
description String?
dimension String
domain String
lifecyclePhase String
probability Int
impact Int
detectability Int
status RiskStatus @default(OPEN)
approvalStatus ApprovalStatus @default(PENDING)
dueDate DateTime?
evidenceSummary String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
mitigations Mitigation[]
evidence Evidence[]
@@index([projectId])
}
model Mitigation {
id String @id @default(cuid())
riskId String
ownerDisplayName String?
title String
description String?
status MitigationStatus @default(NOT_STARTED)
progressPercent Int @default(0)
effectivenessPercent Int @default(0)
dueDate DateTime?
sequence Int @default(1)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
risk Risk @relation(fields: [riskId], references: [id], onDelete: Cascade)
evidence Evidence[]
@@index([riskId])
}
model Evidence {
id String @id @default(cuid())
projectId String
riskId String?
mitigationId String?
type String @default("Review")
title String
uri String?
createdById String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
risk Risk? @relation(fields: [riskId], references: [id], onDelete: Cascade)
mitigation Mitigation? @relation(fields: [mitigationId], references: [id], onDelete: Cascade)
@@index([projectId])
@@index([riskId])
@@index([mitigationId])
}
model Indicator {
id String @id @default(cuid())
projectId String
name String
dimension String
measurand String
unit String
target String?
interpretationRule String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
@@unique([projectId, name])
@@index([projectId])
}
model Experiment {
id String @id @default(cuid())
projectId String
name String
modelName String?
selected Boolean @default(false)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
metrics ModelMetric[]
@@unique([projectId, name])
@@index([projectId])
}
model ModelMetric {
id String @id @default(cuid())
experimentId String
metricName String
metricValue Float
thresholdValue Float?
status String
measuredAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
experiment Experiment @relation(fields: [experimentId], references: [id], onDelete: Cascade)
@@index([experimentId])
}
model GateEvaluation {
id String @id @default(cuid())
projectId String
status GateStatus
reviewStatus String @default("Pending review")
summary String
evaluatedByUserId String?
evaluatedAt DateTime @default(now())
reviewedAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
criteria GateCriterion[]
decisions GateDecision[]
@@index([projectId])
}
model GateCriterion {
id String @id @default(cuid())
gateId String
name String
actualValue String
expectedRule String
status String
blocking Boolean @default(false)
evidenceTitle String?
evidenceUri String?
reviewerStatus String @default("Open")
reviewerNote String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
gate GateEvaluation @relation(fields: [gateId], references: [id], onDelete: Cascade)
@@index([gateId])
}
model GateDecision {
id String @id @default(cuid())
gateId String
decision GateDecisionValue
reviewerName String
reason String?
createdByUserId String?
decidedAt DateTime @default(now())
createdAt DateTime @default(now())
gate GateEvaluation @relation(fields: [gateId], references: [id], onDelete: Cascade)
@@index([gateId])
}
model Integration {
id String @id @default(cuid())
workspaceId String
provider IntegrationProvider
workspaceName String
externalProjectKey String?
baseUrl String?
authMode String
connectionStatus IntegrationStatus @default(NEEDS_CONFIGURATION)
syncDirection String @default("COSMIC to PM")
liveEnabled Boolean @default(false)
liveConfig Json @default("{}")
lastSyncAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)
mappings ExternalWorkItemMapping[]
syncRuns IntegrationSyncRun[]
@@unique([workspaceId, provider])
@@index([workspaceId])
}
model ExternalWorkItemMapping {
id String @id @default(cuid())
integrationId String
projectId String
localEntityType String
localEntityId String
localTitle String
externalItemType String
externalItemId String
externalItemKey String
externalUrl String?
externalStatus String
syncStatus String
fieldMapping Json @default("{}")
lastSyncedAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
integration Integration @relation(fields: [integrationId], references: [id], onDelete: Cascade)
@@index([integrationId])
@@index([projectId])
}
model IntegrationSyncRun {
id String @id @default(cuid())
integrationId String
projectId String
provider IntegrationProvider
status String
startedAt DateTime
finishedAt DateTime?
createdCount Int @default(0)
updatedCount Int @default(0)
failedCount Int @default(0)
summary String?
failureLog Json @default("[]")
createdAt DateTime @default(now())
integration Integration @relation(fields: [integrationId], references: [id], onDelete: Cascade)
@@index([integrationId])
@@index([projectId])
}
model OAuthToken {
id String @id @default(cuid())
organizationId String
provider IntegrationProvider
integrationId String?
encryptedToken Json
redactedToken String
expiresAt DateTime?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
@@index([organizationId, provider])
}
model ReportExport {
id String @id @default(cuid())
workspaceId String
projectId String
reportType String
format String
status String @default("Generated")
metadata Json @default("{}")
createdById String?
createdAt DateTime @default(now())
workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
@@index([workspaceId])
@@index([projectId])
}
model ScheduledReport {
id String @id @default(cuid())
projectId String
reportType String
format String @default("csv")
cronExpr String
recipients Json @default("[]")
enabled Boolean @default(true)
lastRunAt DateTime?
nextRunAt DateTime?
createdById String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
project Project @relation(fields: [projectId], references: [id], onDelete: Cascade)
@@index([projectId])
@@index([nextRunAt])
}
model AuditEvent {
id String @id @default(cuid())
organizationId String
workspaceId String?
projectId String?
actorUserId String?
entityType String
entityId String
action String
beforeJson Json?
afterJson Json?
ipAddress String?
userAgent String?
createdAt DateTime @default(now())
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
workspace Workspace? @relation(fields: [workspaceId], references: [id], onDelete: SetNull)
project Project? @relation(fields: [projectId], references: [id], onDelete: SetNull)
actor User? @relation(fields: [actorUserId], references: [id], onDelete: SetNull)
@@index([organizationId])
@@index([workspaceId])
@@index([projectId])
}
model UsageEvent {
id String @id @default(cuid())
organizationId String
metric String
quantity Int @default(1)
metadata Json @default("{}")
createdAt DateTime @default(now())
organization Organization @relation(fields: [organizationId], references: [id], onDelete: Cascade)
@@index([organizationId, metric])
}