Files
dofus-manager/docs/architecture/9-database-schema.md
2026-01-19 08:52:38 +01:00

4.3 KiB

9. Database Schema

Prisma Schema

// prisma/schema.prisma

generator client {
  provider = "prisma-client-js"
}

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

// ============================================
// USER & AUTHENTICATION
// ============================================

model User {
  id           String    @id @default(cuid())
  email        String    @unique
  passwordHash String    @map("password_hash")
  createdAt    DateTime  @default(now()) @map("created_at")
  updatedAt    DateTime  @updatedAt @map("updated_at")

  accounts Account[]
  teams    Team[]
  sessions Session[]

  @@map("users")
}

model Session {
  id        String   @id @default(cuid())
  userId    String   @map("user_id")
  expiresAt DateTime @map("expires_at")
  createdAt DateTime @default(now()) @map("created_at")

  user User @relation(fields: [userId], references: [id], onDelete: Cascade)

  @@index([userId])
  @@index([expiresAt])
  @@map("sessions")
}

// ============================================
// CORE ENTITIES
// ============================================

model Account {
  id        String   @id @default(cuid())
  name      String
  userId    String   @map("user_id")
  createdAt DateTime @default(now()) @map("created_at")
  updatedAt DateTime @updatedAt @map("updated_at")

  user       User        @relation(fields: [userId], references: [id], onDelete: Cascade)
  characters Character[]

  @@unique([userId, name])
  @@index([userId])
  @@map("accounts")
}

model Character {
  id         String   @id @default(cuid())
  name       String
  level      Int      @default(1)
  classId    Int      @map("class_id")
  className  String   @map("class_name")
  serverId   Int      @map("server_id")
  serverName String   @map("server_name")
  accountId  String   @map("account_id")
  createdAt  DateTime @default(now()) @map("created_at")
  updatedAt  DateTime @updatedAt @map("updated_at")

  account      Account                @relation(fields: [accountId], references: [id], onDelete: Cascade)
  teamMembers  TeamMember[]
  progressions CharacterProgression[]

  @@unique([accountId, name])
  @@index([accountId])
  @@index([classId])
  @@index([serverId])
  @@index([level])
  @@map("characters")
}

// ============================================
// TEAMS
// ============================================

enum TeamType {
  MAIN
  SECONDARY
  CUSTOM
}

model Team {
  id        String   @id @default(cuid())
  name      String
  type      TeamType @default(CUSTOM)
  userId    String   @map("user_id")
  createdAt DateTime @default(now()) @map("created_at")
  updatedAt DateTime @updatedAt @map("updated_at")

  user    User         @relation(fields: [userId], references: [id], onDelete: Cascade)
  members TeamMember[]

  @@unique([userId, name])
  @@index([userId])
  @@map("teams")
}

model TeamMember {
  id          String   @id @default(cuid())
  teamId      String   @map("team_id")
  characterId String   @map("character_id")
  joinedAt    DateTime @default(now()) @map("joined_at")

  team      Team      @relation(fields: [teamId], references: [id], onDelete: Cascade)
  character Character @relation(fields: [characterId], references: [id], onDelete: Cascade)

  @@unique([teamId, characterId])
  @@index([teamId])
  @@index([characterId])
  @@map("team_members")
}

// ============================================
// PROGRESSIONS
// ============================================

enum ProgressionType {
  QUEST
  DUNGEON
  ACHIEVEMENT
  DOFUS
}

model Progression {
  id        String          @id @default(cuid())
  name      String
  type      ProgressionType
  category  String
  dofusDbId Int?            @unique @map("dofusdb_id")

  characterProgressions CharacterProgression[]

  @@index([type])
  @@index([category])
  @@map("progressions")
}

model CharacterProgression {
  id            String    @id @default(cuid())
  characterId   String    @map("character_id")
  progressionId String    @map("progression_id")
  completed     Boolean   @default(false)
  completedAt   DateTime? @map("completed_at")

  character   Character   @relation(fields: [characterId], references: [id], onDelete: Cascade)
  progression Progression @relation(fields: [progressionId], references: [id], onDelete: Cascade)

  @@unique([characterId, progressionId])
  @@index([characterId])
  @@index([progressionId])
  @@index([completed])
  @@map("character_progressions")
}