// Prisma Schema file
// https://pris.ly/d/prisma-schema

// Use the PostgreSQL database at the URL specified via the DATABASE_URL environment variable.
datasource db {
    provider = "postgresql"
    url      = env("DATABASE_URL")
}

// Generate @prisma/client for use in JavaScript and TypeScript.
generator client {
    provider = "prisma-client-js"
}

/// A person who is using the Festa website, who may have logged in via various account types.
model User {
    /// A unique id for the user on the Festa website.
    id               String            @id @default(uuid()) @db.Uuid
    /// The power level of the user on the Festa website.
    powerLevel       PowerLevel        @default(USER)
    /// The displayed name of the user.
    displayName      String
    /// The URL of the displayed avatar of the user.
    displayAvatarURL String?
    /// The tokens the user can use to login.
    tokens           Token[]
    /// The Telegram accounts associated with this user.
    accountsTelegram AccountTelegram[]
    /// The events created by this user.
    eventsCreated    Event[]
}

/// A possible powerLevel value for an {@link User}.
enum PowerLevel {
    /// The user has no special privileges.
    USER
    /// The user can override any permission check.
    SUPERUSER
}

/// A container for user data associated with a single [Telegram](https://telegram.org/).
model AccountTelegram {
    /// The id of the {@link User} associated with this account.
    userId     String   @db.Uuid
    /// The {@link User} associated with this account.
    user       User     @relation(fields: [userId], references: [id])
    /// The Telegram id of the account.
    telegramId Int      @id
    /// The Telegram first name of the account. Always present.
    firstName  String
    /// The Telegram last name of the account. May be omitted.
    lastName   String?
    /// The username of the account. May not be present if the account has not opted in to public discovery on Telegram.
    /// If set, allows the user to be contacted via `https://t.me/USERNAME`.
    username   String?
    /// The URL where the user's avatar is accessible at.
    photoUrl   String?
    /// The locale of the user. Its presence is VERY inconsistent, don't make any assumption based on that.
    lang       String?
    /// The last time the account was updated.
    updatedAt  DateTime @updatedAt
}

/// An entity that can be used to authenticate to the API as an {@link User}.
model Token {
    /// The id of the user that the token allows to login as.
    userId    String   @db.Uuid
    /// The user that the token allows to login as.
    user      User     @relation(fields: [userId], references: [id])
    /// The token itself, a string.
    token     String   @id
    /// The datetime after which the token should cease to be valid for authentication.
    expiresAt DateTime
}

/// The core of the project, a single instance of people gathering in a certain place at a certain time.
model Event {
    /// An unique url-safe string identifying the event, and allowing it to be accessed at `/events/SLUG`.
    slug        String    @id
    /// The id of the {@link User} who created the event.
    creatorId   String    @db.Uuid
    /// The {@link User} who created the event.
    creator     User      @relation(fields: [creatorId], references: [id])
    /// The name of the event.
    name        String
    /// The URL to the postcard of the event.
    postcard    String?
    /// The description of the event. It will be parsed in Markdown!
    description String    @default("")
    /// The time when the event will start at.
    startingAt  DateTime?
    /// The time when the even will end at.
    endingAt    DateTime?
}