// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema

generator client {
    provider = "prisma-client"
    output   = "../src/generated/prisma"
}

datasource db {
    provider = "postgresql"
}

enum ArchivedReason {
    segment_closed
    superseded
    contradicted
    escalated
    expired
    duplicate
}

enum ResolutionState {
    not_applicable
    pending
    resolved
}

enum ResolutionOutcome {
    not_applicable
    challenger_won
    original_retained
}

enum Surface {
    claude
    chatgpt
    gemini
    deepseek
    dev_cli
    web_ui
    manual
}

enum TokenScope {
    dev_cli
    mcp_consumer_t0
    mcp_consumer_oauth
    pairing_temp
}

enum FeedbackType {
    bug
    praise
    suggestion
    general
}

// ── Identity ───────────────────────────────────────────────────────────────

model User {
    id         Int       @id @default(autoincrement())
    email      String?   @unique
    createdAt  DateTime  @default(now())
    mergedInto Int?
    parent     User?     @relation("UserMerge", fields: [mergedInto], references: [id])
    children   User[]    @relation("UserMerge")
    tokens     Token[]
    entries    KnowledgeEntry[]

    @@map("users")
}

model Token {
    id         Int        @id @default(autoincrement())
    tokenHash  String     @unique
    userId     Int
    user       User       @relation(fields: [userId], references: [id])
    scope      TokenScope
    surface    Surface
    createdAt  DateTime   @default(now())
    lastUsedAt DateTime   @default(now())
    revokedAt  DateTime?

    @@index([userId])
    @@map("tokens")
}

model KnowledgeEntry {
    id           Int       @id @default(autoincrement())
    entityType   String
    entityId     String
    key          String
    valueRaw     Json
    valueSummary String
    confidence   Int       @default(50)
    source       String
    validFrom    DateTime  @default(now())
    validUntil   DateTime?
    lastAccessedAt DateTime @default(now())
    stability    Float     @default(30)
    createdBy    String
    createdAt    DateTime  @default(now())
    updatedAt    DateTime  @updatedAt
    conflictLog  Json      @default("[]")
    isProtected  Boolean   @default(false)
    properties   Json      @default("{}")
    embedding    Unsupported("vector(256)")?
    userId       Int       @default(1)
    surface      Surface?
    user         User      @relation(fields: [userId], references: [id])

    @@unique([userId, entityType, entityId, key])
    @@index([userId, entityType, entityId, key])
    @@map("knowledge_base")
}

model Archive {
    id                Int               @id @default(autoincrement())
    entityType        String
    entityId          String
    key               String
    valueRaw          Json
    valueSummary      String
    confidence        Int
    source            String
    validFrom         DateTime
    validUntil        DateTime?
    createdBy         String
    createdAt         DateTime
    conflictLog       Json              @default("[]")
    properties        Json              @default("{}")
    archivedAt        DateTime          @default(now())
    archivedReason    ArchivedReason
    resolutionState   ResolutionState   @default(not_applicable)
    resolutionOutcome ResolutionOutcome @default(not_applicable)
    supersededBy      Int?
    supersededByEntityType String?
    supersededByEntityId   String?
    supersededByKey        String?

    @@index([entityType, entityId, key])
    @@index([entityType, entityId, key, validFrom])
    @@index([entityType, entityId, key, validFrom, validUntil])
    @@map("archive")
}

model EntityRelationship {
    id               Int      @id @default(autoincrement())
    fromType         String
    fromId           String
    relationshipType String
    toType           String
    toId             String
    properties       Json     @default("{}")
    createdBy        String
    createdAt        DateTime @default(now())

    @@unique([fromType, fromId, relationshipType, toType, toId])
    @@index([fromType, fromId])
    @@index([toType, toId])
}

model WriteReceipt {
    id             Int      @id @default(autoincrement())
    requestId      String   @unique
    entityType     String
    entityId       String
    key            String
    outcome        String
    resultEntryId  Int?
    escalationFile String?
    createdAt      DateTime @default(now())

    @@index([entityType, entityId, key])
    @@map("write_receipts")
}

model Entity {
    entityType  String
    entityId    String
    displayName String
    createdAt   DateTime      @default(now())
    aliases     EntityAlias[] @relation("EntityAliasToEntity")

    @@id([entityType, entityId])
    @@map("entities")
}

model EntityAlias {
    id                  Int      @id @default(autoincrement())
    entityType          String
    aliasNorm           String
    rawAlias            String
    canonicalEntityType String
    canonicalEntityId   String
    source              String
    confidence          Int      @default(50)
    createdAt           DateTime @default(now())

    entity Entity @relation("EntityAliasToEntity", fields: [canonicalEntityType, canonicalEntityId], references: [entityType, entityId], onDelete: Cascade)

    @@unique([entityType, aliasNorm])
    @@index([canonicalEntityType, canonicalEntityId])
    @@map("entity_aliases")
}

model StaffEvent {
    eventId        String   @id @map("event_id") @db.Uuid
    timestamp      DateTime @default(now()) @db.Timestamptz(6)
    staffComponent String   @map("staff_component")
    actionType     String   @map("action_type")
    agentId        String   @map("agent_id")
    source         String
    entityType     String?  @map("entity_type")
    entityId       String?  @map("entity_id")
    key            String?
    reason         String?
    level          String
    metadata       Json     @default("{}")

    @@index([timestamp])
    @@index([agentId, timestamp])
    @@index([source, timestamp])
    @@index([level, timestamp])
    @@index([entityType, entityId, key, timestamp])
    @@map("staff_events")
}

// ── Feedback ───────────────────────────────────────────────────────────────

model Feedback {
    id               String       @id @default(uuid()) @db.Uuid
    feedbackId       String       @unique @map("feedback_id") @db.Uuid
    rating           Int
    comment          String?
    type             FeedbackType
    version          String
    os               String
    arch             String
    nodeVersion      String       @map("node_version")
    sessionCount     Int?         @map("session_count")
    factCount        Int?         @map("fact_count")
    instanceId       String       @map("instance_id")
    milestoneContext String?      @map("milestone_context")
    submittedAt      DateTime     @map("submitted_at")
    receivedAt       DateTime     @default(now()) @map("received_at")

    @@index([instanceId])
    @@index([receivedAt])
    @@index([rating])
    @@map("feedback")
}
