rwadurian/backend/services/admin-service/prisma/schema.prisma

193 lines
6.6 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// =============================================================================
// 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")
}