generator client { provider = "prisma-client-js" output = "./generated/gateway" engineType = "binary" } datasource db { provider = "postgresql" } enum OAuthType { NONE KAKAO } enum GatewayProfileStatus { RESERVED PREOPEN RUNNING PAUSED COMPLETED STOPPED DISABLED } enum GatewayBuildStatus { IDLE QUEUED RUNNING FAILED SUCCEEDED } enum GatewayOperationType { RESET DEPLOY START STOP } enum GatewayReleaseOperationType { DEPLOY ROLLBACK } enum GatewayOperationStatus { QUEUED RUNNING SUCCEEDED FAILED CANCELLED } enum GatewayRuntimeActionStatus { REQUESTED PARTIAL APPLIED FAILED IGNORED } enum AdminAuditOutcome { STARTED SUCCEEDED FAILED } enum SpecialAccountAccessKind { TESTER RECOVERY OTHER } enum GatewaySourceMode { BRANCH COMMIT } model AppUser { id String @id @default(uuid()) loginId String @unique @map("login_id") displayName String @unique @map("display_name") passwordHash String @map("password_hash") passwordSalt String @map("password_salt") roles Json @default(dbgenerated("'[]'::jsonb")) sanctions Json @default(dbgenerated("'{}'::jsonb")) oauthType OAuthType @default(NONE) @map("oauth_type") oauthId String? @unique @map("oauth_id") email String? @unique oauthInfo Json @default(dbgenerated("'{}'::jsonb")) @map("oauth_info") picture String @default("default.jpg") imageServer Int @default(0) @map("image_server") iconUpdatedAt DateTime? @map("icon_updated_at") iconRevision DateTime? @map("icon_revision") profileIconResetAt DateTime? @map("profile_icon_reset_at") iconRetiredAt DateTime? @map("icon_retired_at") thirdPartyUse Boolean @default(true) @map("third_party_use") termsAcceptedAt DateTime? @map("terms_accepted_at") privacyAcceptedAt DateTime? @map("privacy_accepted_at") kakaoVerifiedAt DateTime? @map("kakao_verified_at") kakaoTalkVerifiedUntil DateTime? @map("kakao_talk_verified_until") kakaoGraceStartedAt DateTime @default(now()) @map("kakao_grace_started_at") kakaoGraceUntil DateTime? @map("kakao_grace_until") deleteAfter DateTime? @map("delete_after") createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") lastLoginAt DateTime? @map("last_login_at") legacyData Json @default(dbgenerated("'{}'::jsonb")) @map("legacy_data") icons UserIcon[] specialAccessGrants SpecialAccountAccessGrant[] @@map("app_user") } model SpecialAccountAccessGrant { id String @id @default(uuid()) userId String @map("user_id") user AppUser @relation(fields: [userId], references: [id], onDelete: Cascade) kind SpecialAccountAccessKind profiles String[] @default([]) allowsGeneralCreation Boolean @default(true) @map("allows_general_creation") expiresAt DateTime? @map("expires_at") reason String grantedByUserId String @map("granted_by_user_id") revokedAt DateTime? @map("revoked_at") revokedByUserId String? @map("revoked_by_user_id") revokedReason String? @map("revoked_reason") createdAt DateTime @default(now()) @map("created_at") @@index([userId, revokedAt, expiresAt]) @@index([kind, createdAt]) @@map("special_account_access_grant") } model AdminAuditEvent { id String @id @default(uuid()) correlationId String @map("correlation_id") actorUserId String @map("actor_user_id") actorUsername String @map("actor_username") credentialKind String @default("SESSION") @map("credential_kind") capability String? scope String? action String targetType String? @map("target_type") targetId String? @map("target_id") profileName String? @map("profile_name") reason String? outcome AdminAuditOutcome summary Json @default(dbgenerated("'{}'::jsonb")) errorCode String? @map("error_code") errorMessage String? @map("error_message") createdAt DateTime @default(now()) @map("created_at") @@index([correlationId, createdAt]) @@index([actorUserId, createdAt]) @@index([targetType, targetId, createdAt]) @@index([profileName, createdAt]) @@index([action, createdAt]) @@map("admin_audit_event") } model UserIcon { id String @id @default(uuid()) userId String @map("user_id") user AppUser @relation(fields: [userId], references: [id], onDelete: Cascade) picture String @unique imageServer Int @default(1) @map("image_server") createdAt DateTime @default(now()) @map("created_at") retiredAt DateTime? @map("retired_at") @@index([userId, retiredAt, createdAt]) @@map("user_icon") } model LegacyMemberLog { id BigInt @id memberNo Int @map("member_no") userId String @map("user_id") date DateTime actionType String @map("action_type") action Json? @@index([userId, date]) @@index([memberNo, date]) @@map("legacy_member_log") } model LegacyBannedMember { id Int @id @map("no") hashedEmail String @unique @map("hashed_email") info String? @@map("legacy_banned_member") } model LegacyRootKeyValue { id Int @id @default(autoincrement()) sourceTable String @map("source_table") namespace String key String value Json migratedAt DateTime @default(now()) @map("migrated_at") @@unique([sourceTable, namespace, key]) @@map("legacy_root_key_value") } model GatewayProfile { profileName String @id @map("profile_name") profile String scenario String apiPort Int @map("api_port") status GatewayProfileStatus buildStatus GatewayBuildStatus @default(IDLE) @map("build_status") buildCommitSha String? @map("build_commit_sha") buildWorkspace String? @map("build_workspace") buildLastUsedAt DateTime? @map("build_last_used_at") preopenAt DateTime? @map("preopen_at") openAt DateTime? @map("open_at") scheduledStartAt DateTime? @map("scheduled_start_at") buildRequestedAt DateTime? @map("build_requested_at") buildStartedAt DateTime? @map("build_started_at") buildCompletedAt DateTime? @map("build_completed_at") buildError String? @map("build_error") lastError String? @map("last_error") meta Json @default(dbgenerated("'{}'::jsonb")) createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") operations GatewayOperation[] runtimeActions GatewayRuntimeAction[] @@unique([profile, scenario]) @@map("gateway_profile") } model GatewayRuntimeAction { id String @id @default(uuid()) profileName String @map("profile_name") profile GatewayProfile @relation(fields: [profileName], references: [profileName], onDelete: Cascade) action String durationMinutes Int? @map("duration_minutes") scheduledAt DateTime? @map("scheduled_at") reason String? requestedBy String @map("requested_by") status GatewayRuntimeActionStatus @default(REQUESTED) detail String? handler String? handledAt DateTime? @map("handled_at") attempts Int @default(0) nextAttemptAt DateTime? @map("next_attempt_at") createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") @@index([profileName, status, createdAt]) @@index([profileName, createdAt]) @@map("gateway_runtime_action") } model GatewayOperation { /// A partial unique index in the gateway migration chain permits only one /// QUEUED or RUNNING operation per profile. id String @id @default(uuid()) profileName String @map("profile_name") profile GatewayProfile @relation(fields: [profileName], references: [profileName], onDelete: Cascade) type GatewayOperationType status GatewayOperationStatus @default(QUEUED) sourceMode GatewaySourceMode? @map("source_mode") sourceRef String? @map("source_ref") resolvedCommitSha String? @map("resolved_commit_sha") payload Json @default(dbgenerated("'{}'::jsonb")) reason String? requestedBy String @map("requested_by") scheduledAt DateTime? @map("scheduled_at") startedAt DateTime? @map("started_at") completedAt DateTime? @map("completed_at") error String? leaseOwner String? @map("lease_owner") leaseUntil DateTime? @map("lease_until") heartbeatAt DateTime? @map("heartbeat_at") attempts Int @default(0) createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") logs GatewayOperationLog[] @@index([status, scheduledAt, createdAt]) @@index([status, leaseUntil, createdAt]) @@index([profileName, createdAt]) @@map("gateway_operation") } model GatewayOperationLog { id BigInt @id @default(autoincrement()) operationId String @map("operation_id") level String phase String message String @db.Text createdAt DateTime @default(now()) @map("created_at") operation GatewayOperation @relation(fields: [operationId], references: [id], onDelete: Cascade) @@index([operationId, id]) @@map("gateway_operation_log") } model GatewayReleaseState { id String @id @default("gateway") activeCommitSha String? @map("active_commit_sha") activeWorkspace String? @map("active_workspace") previousCommitSha String? @map("previous_commit_sha") previousWorkspace String? @map("previous_workspace") lastSuccessfulAt DateTime? @map("last_successful_at") lastError String? @map("last_error") updatedAt DateTime @updatedAt @map("updated_at") @@map("gateway_release_state") } model GatewayReleaseOperation { /// A partial unique index in the gateway migration chain permits only one /// QUEUED or RUNNING control-plane release at a time. id String @id @default(uuid()) type GatewayReleaseOperationType status GatewayOperationStatus @default(QUEUED) sourceMode GatewaySourceMode? @map("source_mode") sourceRef String? @map("source_ref") resolvedCommitSha String? @map("resolved_commit_sha") payload Json @default(dbgenerated("'{}'::jsonb")) reason String? requestedBy String @map("requested_by") startedAt DateTime? @map("started_at") completedAt DateTime? @map("completed_at") error String? leaseOwner String? @map("lease_owner") leaseUntil DateTime? @map("lease_until") heartbeatAt DateTime? @map("heartbeat_at") attempts Int @default(0) createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") logs GatewayReleaseLog[] @@index([status, leaseUntil, createdAt]) @@index([createdAt]) @@map("gateway_release_operation") } model GatewayReleaseLog { id BigInt @id @default(autoincrement()) operationId String @map("operation_id") level String phase String message String @db.Text createdAt DateTime @default(now()) @map("created_at") operation GatewayReleaseOperation @relation(fields: [operationId], references: [id], onDelete: Cascade) @@index([operationId, id]) @@map("gateway_release_log") } model SystemSetting { id Int @id @default(1) @map("no") registrationEnabled Boolean @default(false) @map("registration_enabled") loginEnabled Boolean @default(false) @map("login_enabled") notice String @default("") @map("notice") createdAt DateTime? @map("created_at") updatedAt DateTime? @map("updated_at") @@map("system") }