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

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

model Task {
  id                         String    @id @default(uuid())
  title                      String
  description                String
  status                     String // Enum: TaskStatus (OPEN, EXECUTING, VERIFYING, COMPLETED, FAILED, etc)
  difficulty                 String // Enum: TaskDifficulty (HELLO_WORLD, COMPONENT, VIEW, EPIC)
  scope_clarity_score        Float
  error_classification       String? // Enum: TaskErrorClassification
  reward_amount              Int // Stored in cents
  reward_currency            String // USD, TWD, USDC
  acceptance_criteria        Json // Contains validation_mode, test_file_content, rules
  required_stack             String[]
  retry_count                Int       @default(0)
  stripe_payment_intent_id   String?
  stripe_checkout_session_id String? // Used for Scout flow
  expires_at                 DateTime?
  github_pr_url              String? // PR URL for PENDING_REVIEW tasks
  reward_points              Int       @default(10) // Points awarded upon PR merge
  created_at                 DateTime  @default(now())
  updated_at                 DateTime  @updatedAt

  scout_id      String?
  scout_agent   AgentProfile? @relation("ScoutTasks", fields: [scout_id], references: [agent_id])
  builder_id    String?
  builder_agent AgentProfile? @relation("BuilderTasks", fields: [builder_id], references: [agent_id])

  claims      Claim[]
  submissions Submission[]
}

model Claim {
  id               String       @id @default(uuid())
  task_id          String
  task             Task         @relation(fields: [task_id], references: [id])
  agent_id         String
  agent            AgentProfile @relation(fields: [agent_id], references: [agent_id])
  developer_wallet String
  status           String // EXECUTING, CANCELLED, VERIFYING, COMPLETED
  claim_token      String       @unique // Idempotency token for this claim
  held_amount      Int
  held_currency    String
  expires_at       DateTime
  created_at       DateTime     @default(now())
  updated_at       DateTime     @updatedAt

  submissions Submission[]
}

model Submission {
  id                          String    @id @default(uuid())
  task_id                     String
  task                        Task      @relation(fields: [task_id], references: [id])
  claim_id                    String
  claim                       Claim     @relation(fields: [claim_id], references: [id])
  status                      String // VERIFYING, JUDGED
  deliverables                Json // Files and notes submitted
  estimated_judge_complete_at DateTime?
  created_at                  DateTime  @default(now())
  updated_at                  DateTime  @updatedAt

  judge_results JudgeResult[]
}

model JudgeResult {
  id                   String     @id @default(uuid())
  submission_id        String
  submission           Submission @relation(fields: [submission_id], references: [id])
  overall_result       String // PASS, FAIL, TIMEOUT
  tests                Json // Array of test results
  artifacts            Json? // screenshot_url, logs_url, diff_url
  error_classification String? // Enum: JudgeErrorClassification
  error_signature      String?
  retryable            Boolean    @default(false)
  resource_usage       Json // cpu_ms, mem_peak_mb, io_bytes
  judge_completed_at   DateTime   @default(now())
}

model AuditEvent {
  id          String   @id @default(uuid())
  actorType   String
  actorId     String?
  action      String
  entityType  String
  entityId    String
  beforeState Json?
  afterState  Json?
  reason      String?
  metadata    Json?
  createdAt   DateTime @default(now())
}

model LedgerEntry {
  id               String   @id @default(cuid())
  task_id          String
  phase            String
  idempotency_key  String   @unique
  stripe_object_id String?
  response_status  String
  http_status      Int
  created_at       DateTime @default(now())
  updated_at       DateTime @updatedAt
}

model AgentProfile {
  id             String   @id @default(uuid())
  agent_id       String   @unique
  type           String // BUILDER or SCOUT
  wallet_address String?
  status         String // WHITELISTED, BANNED, PENDING
  created_at     DateTime @default(now())
  updated_at     DateTime @updatedAt

  tasks_as_scout   Task[]  @relation("ScoutTasks")
  tasks_as_builder Task[]  @relation("BuilderTasks")
  claims           Claim[]
}
