generator client { provider = "prisma-client-js" } datasource db { provider = "mysql" url = env("DATABASE_URL") } enum UserStatus { ACTIVE DISABLED } enum PermissionType { MENU BUTTON API } enum LampStatus { NORMAL FAULT MAINTENANCE OFFLINE } enum OnlineStatus { ONLINE OFFLINE } enum AlarmLevel { LOW MEDIUM HIGH CRITICAL } enum AlarmStatus { OPEN PROCESSING RESOLVED IGNORED } model Tenant { id String @id @default(cuid()) name String code String @unique enabled Boolean @default(true) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt users User[] roles Role[] lamps StreetLamp[] alarms Alarm[] } model User { id String @id @default(cuid()) username String passwordHash String name String phone String? email String? status UserStatus @default(ACTIVE) tenantId String? tenant Tenant? @relation(fields: [tenantId], references: [id]) roles UserRole[] regionScopes UserRegionScope[] alarmHandles AlarmHandleRecord[] createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@unique([tenantId, username]) } model Role { id String @id @default(cuid()) name String code String description String? tenantId String? tenant Tenant? @relation(fields: [tenantId], references: [id]) users UserRole[] permissions RolePermission[] regionScopes RoleRegionScope[] createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@unique([tenantId, code]) } model Permission { id String @id @default(cuid()) name String code String @unique type PermissionType parentId String? path String? sort Int @default(0) roles RolePermission[] createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } model UserRole { userId String roleId String user User @relation(fields: [userId], references: [id], onDelete: Cascade) role Role @relation(fields: [roleId], references: [id], onDelete: Cascade) @@id([userId, roleId]) } model RolePermission { roleId String permissionId String role Role @relation(fields: [roleId], references: [id], onDelete: Cascade) permission Permission @relation(fields: [permissionId], references: [id], onDelete: Cascade) @@id([roleId, permissionId]) } model Region { id String @id @default(cuid()) code String @unique name String level Int parentId String? parent Region? @relation("RegionTree", fields: [parentId], references: [id]) children Region[] @relation("RegionTree") longitude Decimal? @db.Decimal(10, 6) latitude Decimal? @db.Decimal(10, 6) userScopes UserRegionScope[] roleScopes RoleRegionScope[] lamps StreetLamp[] alarms Alarm[] createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } model UserRegionScope { userId String regionId String user User @relation(fields: [userId], references: [id], onDelete: Cascade) region Region @relation(fields: [regionId], references: [id], onDelete: Cascade) @@id([userId, regionId]) } model RoleRegionScope { roleId String regionId String role Role @relation(fields: [roleId], references: [id], onDelete: Cascade) region Region @relation(fields: [regionId], references: [id], onDelete: Cascade) @@id([roleId, regionId]) } model StreetLamp { id String @id @default(cuid()) code String @unique name String tenantId String? tenant Tenant? @relation(fields: [tenantId], references: [id]) regionId String region Region @relation(fields: [regionId], references: [id]) address String? longitude Decimal @db.Decimal(10, 6) latitude Decimal @db.Decimal(10, 6) deviceType String? status LampStatus @default(NORMAL) onlineStatus OnlineStatus @default(ONLINE) isPowerOn Boolean? lastReportedAt DateTime? alarms Alarm[] createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@index([regionId]) } model Alarm { id String @id @default(cuid()) sourceAlarmId String? @unique tenantId String? tenant Tenant? @relation(fields: [tenantId], references: [id]) lampId String lamp StreetLamp @relation(fields: [lampId], references: [id]) regionId String region Region @relation(fields: [regionId], references: [id]) type String title String description String? level AlarmLevel @default(MEDIUM) status AlarmStatus @default(OPEN) occurredAt DateTime recoveredAt DateTime? handledAt DateTime? handleRecords AlarmHandleRecord[] events AlarmEvent[] createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@index([regionId, status]) @@index([lampId]) } model AlarmEvent { id String @id @default(cuid()) alarmId String alarm Alarm @relation(fields: [alarmId], references: [id], onDelete: Cascade) eventType String payload Json? createdAt DateTime @default(now()) } model AlarmHandleRecord { id String @id @default(cuid()) alarmId String alarm Alarm @relation(fields: [alarmId], references: [id], onDelete: Cascade) userId String? user User? @relation(fields: [userId], references: [id]) action String remark String? createdAt DateTime @default(now()) } model OperationLog { id String @id @default(cuid()) userId String? action String resource String detail Json? ip String? createdAt DateTime @default(now()) }