// ============================================================================= // Admin Service - Prisma Schema // ============================================================================= generator client { provider = "prisma-client-js" } datasource db { provider = "postgresql" url = env("DATABASE_URL") } // ============================================================================= // App Version Management // ============================================================================= model AppVersion { id String @id @default(uuid()) platform Platform versionCode Int // Android: versionCode, iOS: CFBundleVersion versionName String // 用户可见版本号,如 "1.2.3" buildNumber String // 构建号 downloadUrl String // APK/IPA 下载地址 fileSize BigInt // 文件大小(字节) fileSha256 String // 文件 SHA-256 校验和 minOsVersion String? // 最低操作系统版本要求 changelog String // 更新日志 isForceUpdate Boolean @default(false) // 是否强制更新 isEnabled Boolean @default(true) // 是否启用 releaseDate DateTime? // 发布日期 createdAt DateTime @default(now()) updatedAt DateTime @updatedAt createdBy String // 创建人ID updatedBy String? // 更新人ID @@index([platform, isEnabled]) @@index([platform, versionCode]) @@map("app_versions") } enum Platform { ANDROID IOS } // ============================================================================= // Notification System (通知系统) // ============================================================================= /// 系统通知 - 管理员发布的公告/通知 model Notification { id String @id @default(uuid()) title String // 通知标题 content String // 通知内容 type NotificationType // 通知类型 priority NotificationPriority @default(NORMAL) // 优先级 targetType TargetType @default(ALL) // 目标用户类型 imageUrl String? // 可选的图片URL linkUrl String? // 可选的跳转链接 isEnabled Boolean @default(true) // 是否启用 publishedAt DateTime? // 发布时间(null表示草稿) expiresAt DateTime? // 过期时间(null表示永不过期) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt createdBy String // 创建人ID // 用户已读记录 readRecords NotificationRead[] @@index([isEnabled, publishedAt]) @@index([type]) @@map("notifications") } /// 用户已读记录 model NotificationRead { id String @id @default(uuid()) notificationId String userSerialNum String // 用户序列号 readAt DateTime @default(now()) notification Notification @relation(fields: [notificationId], references: [id], onDelete: Cascade) @@unique([notificationId, userSerialNum]) @@index([userSerialNum]) @@map("notification_reads") } /// 通知类型 enum NotificationType { SYSTEM // 系统通知 ACTIVITY // 活动通知 REWARD // 收益通知 UPGRADE // 升级通知 ANNOUNCEMENT // 公告 } /// 通知优先级 enum NotificationPriority { LOW NORMAL HIGH URGENT } /// 目标用户类型 enum TargetType { ALL // 所有用户 NEW_USER // 新用户 VIP // VIP用户 } // ============================================================================= // User Query View (用户查询视图 - 通过 Kafka 事件同步) // ============================================================================= /// 用户查询视图 - 本地物化视图,通过消费 Kafka 事件同步维护 /// 用于 admin-web 用户管理页面的查询,避免跨服务 HTTP 调用 model UserQueryView { userId BigInt @id @map("user_id") accountSequence String @unique @map("account_sequence") @db.VarChar(12) // 基本信息 (来自 identity-service 事件) nickname String? @db.VarChar(100) avatarUrl String? @map("avatar_url") @db.Text phoneNumberMasked String? @map("phone_number_masked") @db.VarChar(20) // 脱敏: 138****8888 // 推荐关系 inviterSequence String? @map("inviter_sequence") @db.VarChar(12) // KYC 状态 kycStatus String @default("NOT_VERIFIED") @map("kyc_status") @db.VarChar(20) // 认种统计 (来自 planting-service 事件) personalAdoptionCount Int @default(0) @map("personal_adoption_count") teamAddressCount Int @default(0) @map("team_address_count") teamAdoptionCount Int @default(0) @map("team_adoption_count") // 授权统计 (来自 authorization-service 事件) provinceAdoptionCount Int @default(0) @map("province_adoption_count") cityAdoptionCount Int @default(0) @map("city_adoption_count") // 排名 leaderboardRank Int? @map("leaderboard_rank") // 状态 status String @default("ACTIVE") @db.VarChar(20) isOnline Boolean @default(false) @map("is_online") // 时间戳 registeredAt DateTime @map("registered_at") lastActiveAt DateTime? @map("last_active_at") syncedAt DateTime @default(now()) @map("synced_at") @@index([accountSequence]) @@index([nickname]) @@index([status]) @@index([registeredAt]) @@index([personalAdoptionCount]) @@index([inviterSequence]) @@map("user_query_view") } // ============================================================================= // Kafka Event Tracking (事件消费追踪) // ============================================================================= /// 事件消费位置追踪 - 用于幂等性和断点续传 model EventConsumerOffset { id BigInt @id @default(autoincrement()) consumerGroup String @map("consumer_group") @db.VarChar(100) topic String @db.VarChar(100) partition Int offset BigInt updatedAt DateTime @default(now()) @map("updated_at") @@unique([consumerGroup, topic, partition]) @@map("event_consumer_offsets") } /// 已处理事件记录 - 用于幂等性检查 model ProcessedEvent { id BigInt @id @default(autoincrement()) eventId String @unique @map("event_id") @db.VarChar(100) eventType String @map("event_type") @db.VarChar(50) processedAt DateTime @default(now()) @map("processed_at") @@index([eventType]) @@index([processedAt]) @@map("processed_events") }