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

1105 lines
38 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) // 目标用户类型
targetLogic TargetLogic @default(ANY) @map("target_logic") // 多标签匹配逻辑
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[]
targetTags NotificationTagTarget[] // BY_TAG 时使用
targetUsers NotificationUserTarget[] // SPECIFIC 时使用
@@index([isEnabled, publishedAt])
@@index([type])
@@index([targetType])
@@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 // 所有用户
BY_TAG // 按标签匹配
SPECIFIC // 指定用户列表
}
/// 多标签匹配逻辑
enum TargetLogic {
ANY // 匹配任一标签
ALL // 匹配所有标签
}
/// 通知-标签关联
model NotificationTagTarget {
id String @id @default(uuid())
notificationId String @map("notification_id")
tagId String @map("tag_id")
notification Notification @relation(fields: [notificationId], references: [id], onDelete: Cascade)
tag UserTag @relation(fields: [tagId], references: [id], onDelete: Cascade)
@@unique([notificationId, tagId])
@@index([tagId])
@@map("notification_tag_targets")
}
/// 通知-用户关联 (指定用户)
model NotificationUserTarget {
id String @id @default(uuid())
notificationId String @map("notification_id")
accountSequence String @map("account_sequence") @db.VarChar(12)
notification Notification @relation(fields: [notificationId], references: [id], onDelete: Cascade)
@@unique([notificationId, accountSequence])
@@index([accountSequence])
@@map("notification_user_targets")
}
// =============================================================================
// User Profile System (用户画像系统) - 面向通知 + 广告
// =============================================================================
// -----------------------------------------------------------------------------
// 标签分类 (Tag Category) - 标签的分组管理
// -----------------------------------------------------------------------------
/// 标签分类
model TagCategory {
id String @id @default(uuid())
code String @unique @db.VarChar(50) // "lifecycle", "value", "behavior"
name String @db.VarChar(100) // "生命周期", "价值分层", "行为特征"
description String? @db.Text
sortOrder Int @default(0) @map("sort_order")
isEnabled Boolean @default(true) @map("is_enabled")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
tags UserTag[]
@@index([code])
@@index([isEnabled])
@@map("tag_categories")
}
// -----------------------------------------------------------------------------
// 用户标签 (User Tag) - 增强版
// -----------------------------------------------------------------------------
/// 标签类型
enum TagType {
MANUAL // 手动打标 (管理员操作)
AUTO // 自动打标 (规则驱动)
COMPUTED // 计算型 (实时计算,不存储关联)
SYSTEM // 系统内置 (不可删除)
}
/// 标签值类型
enum TagValueType {
BOOLEAN // 布尔型: 有/无
ENUM // 枚举型: 高/中/低
NUMBER // 数值型: 0-100分
STRING // 字符串型
}
/// 用户标签定义
model UserTag {
id String @id @default(uuid())
categoryId String? @map("category_id")
code String @unique @db.VarChar(50) // "vip", "new_user", "whale"
name String @db.VarChar(100) // "VIP用户", "新用户", "大客户"
description String? @db.Text
color String? @db.VarChar(20) // "#FF5722"
type TagType @default(MANUAL) // 标签类型
valueType TagValueType @default(BOOLEAN) @map("value_type") // 标签值类型
// 枚举型标签的可选值
// 例如: ["高", "中", "低"] 或 ["活跃", "沉默", "流失"]
enumValues Json? @map("enum_values")
// 关联的自动规则 (type=AUTO 时使用)
ruleId String? @unique @map("rule_id")
rule UserClassificationRule? @relation(fields: [ruleId], references: [id], onDelete: SetNull)
// 广告相关
isAdvertisable Boolean @default(true) @map("is_advertisable") // 是否可用于广告定向
estimatedUsers Int? @map("estimated_users") // 预估覆盖用户数
isEnabled Boolean @default(true) @map("is_enabled")
sortOrder Int @default(0) @map("sort_order")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
// 关联
category TagCategory? @relation(fields: [categoryId], references: [id], onDelete: SetNull)
assignments UserTagAssignment[]
notifications NotificationTagTarget[]
@@index([categoryId])
@@index([code])
@@index([type])
@@index([isEnabled])
@@index([isAdvertisable])
@@map("user_tags")
}
// -----------------------------------------------------------------------------
// 用户-标签关联 - 支持标签值
// -----------------------------------------------------------------------------
/// 用户-标签关联
model UserTagAssignment {
id String @id @default(uuid())
accountSequence String @map("account_sequence") @db.VarChar(12)
tagId String @map("tag_id")
// 标签值 (根据 valueType)
// BOOLEAN: null (存在即为true)
// ENUM: "高" / "中" / "低"
// NUMBER: "85" (字符串存储)
// STRING: 任意字符串
value String? @db.VarChar(100)
assignedAt DateTime @default(now()) @map("assigned_at")
assignedBy String? @map("assigned_by") // null=系统自动, 否则为管理员ID
expiresAt DateTime? @map("expires_at") // 可选过期时间
source String? @db.VarChar(50) // 来源: "rule:xxx", "import", "manual", "kafka"
tag UserTag @relation(fields: [tagId], references: [id], onDelete: Cascade)
@@unique([accountSequence, tagId])
@@index([accountSequence])
@@index([tagId])
@@index([value])
@@index([expiresAt])
@@map("user_tag_assignments")
}
// -----------------------------------------------------------------------------
// 用户分类规则 (Classification Rule)
// -----------------------------------------------------------------------------
/// 用户分类规则
model UserClassificationRule {
id String @id @default(uuid())
name String @db.VarChar(100) // "30天内新用户"
description String? @db.Text
// 规则条件 (JSON)
// 示例:
// {
// "type": "AND",
// "rules": [
// { "field": "registeredAt", "operator": "within_days", "value": 30 },
// { "field": "kycStatus", "operator": "eq", "value": "VERIFIED" }
// ]
// }
conditions Json
isEnabled Boolean @default(true) @map("is_enabled")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
// 关联的自动标签
tag UserTag?
@@map("user_classification_rules")
}
// -----------------------------------------------------------------------------
// 用户特征 (User Features) - 数值型指标
// -----------------------------------------------------------------------------
/// 用户特征 - 计算后的用户画像指标
model UserFeature {
id String @id @default(uuid())
accountSequence String @unique @map("account_sequence") @db.VarChar(12)
// RFM 模型
rfmRecency Int? @map("rfm_recency") // 最近一次活跃距今天数
rfmFrequency Int? @map("rfm_frequency") // 过去30天活跃天数
rfmMonetary Decimal? @map("rfm_monetary") @db.Decimal(18, 2) // 累计消费金额
rfmScore Int? @map("rfm_score") // RFM综合分 (0-100)
// 活跃度
activeLevel String? @map("active_level") @db.VarChar(20) // "高活跃", "中活跃", "低活跃", "沉默"
lastActiveAt DateTime? @map("last_active_at")
// 价值分层
valueLevel String? @map("value_level") @db.VarChar(20) // "高价值", "中价值", "低价值", "潜力"
lifetimeValue Decimal? @map("lifetime_value") @db.Decimal(18, 2) // 用户生命周期价值 LTV
// 生命周期
lifecycleStage String? @map("lifecycle_stage") @db.VarChar(20) // "新用户", "成长期", "成熟期", "衰退期", "流失"
// 自定义特征 (JSON扩展)
customFeatures Json? @map("custom_features")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
@@index([rfmScore])
@@index([activeLevel])
@@index([valueLevel])
@@index([lifecycleStage])
@@map("user_features")
}
// -----------------------------------------------------------------------------
// 人群包 (Audience Segment) - 复杂定向
// -----------------------------------------------------------------------------
/// 人群包用途
enum SegmentUsageType {
GENERAL // 通用
NOTIFICATION // 通知定向
ADVERTISING // 广告定向
ANALYTICS // 数据分析
}
/// 人群包 - 多条件组合的用户群
model AudienceSegment {
id String @id @default(uuid())
name String @db.VarChar(100) // "高价值活跃用户"
description String? @db.Text
// 定向条件 (JSON)
// {
// "type": "AND",
// "conditions": [
// { "type": "tag", "tagCode": "vip", "operator": "eq", "value": true },
// { "type": "feature", "field": "rfmScore", "operator": "gte", "value": 80 },
// { "type": "profile", "field": "province", "operator": "in", "value": ["广东", "浙江"] }
// ]
// }
conditions Json
// 预估数据
estimatedUsers Int? @map("estimated_users")
lastCalculated DateTime? @map("last_calculated")
// 用途
usageType SegmentUsageType @default(GENERAL) @map("usage_type")
isEnabled Boolean @default(true) @map("is_enabled")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
createdBy String @map("created_by")
@@index([usageType])
@@index([isEnabled])
@@map("audience_segments")
}
// -----------------------------------------------------------------------------
// 标签变更日志 (审计追踪)
// -----------------------------------------------------------------------------
/// 标签变更操作
enum TagAction {
ASSIGN // 打标签
UPDATE // 更新标签值
REMOVE // 移除标签
EXPIRE // 过期移除
}
/// 标签变更日志
model UserTagLog {
id String @id @default(uuid())
accountSequence String @map("account_sequence") @db.VarChar(12)
tagCode String @map("tag_code") @db.VarChar(50)
action TagAction
oldValue String? @map("old_value") @db.VarChar(100)
newValue String? @map("new_value") @db.VarChar(100)
reason String? @db.VarChar(200) // "规则触发", "管理员操作", "导入", "过期清理"
operatorId String? @map("operator_id")
createdAt DateTime @default(now()) @map("created_at")
@@index([accountSequence, createdAt])
@@index([tagCode])
@@index([action])
@@index([createdAt])
@@map("user_tag_logs")
}
// =============================================================================
// 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")
}
// =============================================================================
// Referral Query View (推荐关系查询视图 - 通过 CDC 同步)
// =============================================================================
/// 推荐关系查询视图 - 通过 Debezium CDC 从 referral-service 同步
/// 用于 admin-web 查看用户推荐关系,避免跨服务调用
model ReferralQueryView {
id BigInt @id @map("relationship_id")
userId BigInt @unique @map("user_id")
accountSequence String @unique @map("account_sequence") @db.VarChar(12)
// 推荐人信息
referrerId BigInt? @map("referrer_id")
rootUserId BigInt? @map("root_user_id")
// 推荐码
myReferralCode String @unique @map("my_referral_code") @db.VarChar(20)
usedReferralCode String? @map("used_referral_code") @db.VarChar(20)
// 推荐链信息
ancestorPath BigInt[] @map("ancestor_path")
depth Int @default(0) @map("depth")
// 直推统计
directReferralCount Int @default(0) @map("direct_referral_count")
activeDirectCount Int @default(0) @map("active_direct_count")
// 时间戳
createdAt DateTime @map("created_at")
syncedAt DateTime @default(now()) @map("synced_at")
@@index([referrerId])
@@index([accountSequence])
@@index([myReferralCode])
@@index([usedReferralCode])
@@index([rootUserId])
@@index([depth])
@@map("referral_query_view")
}
// =============================================================================
// Wallet Query Views (钱包查询视图 - 通过 CDC 同步)
// =============================================================================
/// 钱包账户查询视图 - 通过 Debezium CDC 从 wallet-service 同步
model WalletAccountQueryView {
id BigInt @id @map("wallet_id")
accountSequence String @unique @map("account_sequence") @db.VarChar(20)
userId BigInt @unique @map("user_id")
// USDT 余额
usdtAvailable Decimal @default(0) @map("usdt_available") @db.Decimal(20, 8)
usdtFrozen Decimal @default(0) @map("usdt_frozen") @db.Decimal(20, 8)
// DST 余额
dstAvailable Decimal @default(0) @map("dst_available") @db.Decimal(20, 8)
dstFrozen Decimal @default(0) @map("dst_frozen") @db.Decimal(20, 8)
// BNB 余额
bnbAvailable Decimal @default(0) @map("bnb_available") @db.Decimal(20, 8)
bnbFrozen Decimal @default(0) @map("bnb_frozen") @db.Decimal(20, 8)
// OG 余额
ogAvailable Decimal @default(0) @map("og_available") @db.Decimal(20, 8)
ogFrozen Decimal @default(0) @map("og_frozen") @db.Decimal(20, 8)
// RWAD 余额
rwadAvailable Decimal @default(0) @map("rwad_available") @db.Decimal(20, 8)
rwadFrozen Decimal @default(0) @map("rwad_frozen") @db.Decimal(20, 8)
// 算力
hashpower Decimal @default(0) @map("hashpower") @db.Decimal(20, 8)
// 待领取/可结算/已结算收益
pendingUsdt Decimal @default(0) @map("pending_usdt") @db.Decimal(20, 8)
pendingHashpower Decimal @default(0) @map("pending_hashpower") @db.Decimal(20, 8)
settleableUsdt Decimal @default(0) @map("settleable_usdt") @db.Decimal(20, 8)
settleableHashpower Decimal @default(0) @map("settleable_hashpower") @db.Decimal(20, 8)
settledTotalUsdt Decimal @default(0) @map("settled_total_usdt") @db.Decimal(20, 8)
settledTotalHashpower Decimal @default(0) @map("settled_total_hashpower") @db.Decimal(20, 8)
expiredTotalUsdt Decimal @default(0) @map("expired_total_usdt") @db.Decimal(20, 8)
expiredTotalHashpower Decimal @default(0) @map("expired_total_hashpower") @db.Decimal(20, 8)
// 状态
status String @default("ACTIVE") @map("status") @db.VarChar(20)
hasPlanted Boolean @default(false) @map("has_planted")
// 时间戳
createdAt DateTime @map("created_at")
syncedAt DateTime @default(now()) @map("synced_at")
@@index([accountSequence])
@@index([usdtAvailable(sort: Desc)])
@@index([hashpower(sort: Desc)])
@@index([status])
@@map("wallet_account_query_view")
}
/// 提现订单查询视图 - 通过 Debezium CDC 从 wallet-service 同步
model WithdrawalOrderQueryView {
id BigInt @id @map("order_id")
orderNo String @unique @map("order_no") @db.VarChar(50)
accountSequence String @map("account_sequence") @db.VarChar(20)
userId BigInt @map("user_id")
// 提现信息
amount Decimal @map("amount") @db.Decimal(20, 8)
fee Decimal @map("fee") @db.Decimal(20, 8)
chainType String @map("chain_type") @db.VarChar(20)
toAddress String @map("to_address") @db.VarChar(100)
// 交易信息
txHash String? @map("tx_hash") @db.VarChar(100)
// 内部转账标识
isInternalTransfer Boolean @default(false) @map("is_internal_transfer")
toAccountSequence String? @map("to_account_sequence") @db.VarChar(20)
toUserId BigInt? @map("to_user_id")
// 状态
status String @default("PENDING") @map("status") @db.VarChar(20)
errorMessage String? @map("error_message") @db.VarChar(500)
// 时间戳
frozenAt DateTime? @map("frozen_at")
broadcastedAt DateTime? @map("broadcasted_at")
confirmedAt DateTime? @map("confirmed_at")
createdAt DateTime @map("created_at")
syncedAt DateTime @default(now()) @map("synced_at")
@@index([accountSequence])
@@index([userId])
@@index([status])
@@index([chainType])
@@index([txHash])
@@index([createdAt])
@@map("withdrawal_order_query_view")
}
/// 法币提现订单查询视图 - 通过 Debezium CDC 从 wallet-service 同步
model FiatWithdrawalOrderQueryView {
id BigInt @id @map("order_id")
orderNo String @unique @map("order_no") @db.VarChar(50)
accountSequence String @map("account_sequence") @db.VarChar(20)
userId BigInt @map("user_id")
// 金额
amount Decimal @map("amount") @db.Decimal(20, 8)
fee Decimal @map("fee") @db.Decimal(20, 8)
// 收款方式
paymentMethod String @map("payment_method") @db.VarChar(20)
// 银行卡信息 (脱敏)
bankName String? @map("bank_name") @db.VarChar(100)
bankCardNoMasked String? @map("bank_card_no_masked") @db.VarChar(50)
cardHolderName String? @map("card_holder_name") @db.VarChar(100)
// 支付宝/微信 (脱敏)
alipayAccountMasked String? @map("alipay_account_masked") @db.VarChar(100)
wechatAccountMasked String? @map("wechat_account_masked") @db.VarChar(100)
// 状态
status String @default("PENDING") @map("status") @db.VarChar(20)
errorMessage String? @map("error_message") @db.VarChar(500)
// 审核信息
reviewedBy String? @map("reviewed_by") @db.VarChar(100)
reviewedAt DateTime? @map("reviewed_at")
reviewRemark String? @map("review_remark") @db.VarChar(500)
// 打款信息
paidBy String? @map("paid_by") @db.VarChar(100)
paidAt DateTime? @map("paid_at")
// 时间戳
frozenAt DateTime? @map("frozen_at")
completedAt DateTime? @map("completed_at")
createdAt DateTime @map("created_at")
syncedAt DateTime @default(now()) @map("synced_at")
@@index([accountSequence])
@@index([userId])
@@index([status])
@@index([paymentMethod])
@@index([reviewedBy])
@@index([createdAt])
@@map("fiat_withdrawal_order_query_view")
}
// =============================================================================
// Planting Query Views (认种查询视图 - 通过 CDC 同步)
// =============================================================================
/// 认种订单查询视图 - 通过 Debezium CDC 从 planting-service 同步
model PlantingOrderQueryView {
id BigInt @id @map("order_id")
orderNo String @unique @map("order_no") @db.VarChar(50)
userId BigInt @map("user_id")
accountSequence String @map("account_sequence") @db.VarChar(20)
// 认种信息
treeCount Int @map("tree_count")
totalAmount Decimal @map("total_amount") @db.Decimal(20, 8)
// 省市选择
selectedProvince String? @map("selected_province") @db.VarChar(10)
selectedCity String? @map("selected_city") @db.VarChar(10)
// 订单状态
status String @default("CREATED") @map("status") @db.VarChar(30)
// 底池信息
poolInjectionBatchId BigInt? @map("pool_injection_batch_id")
// 时间戳
createdAt DateTime @map("created_at")
paidAt DateTime? @map("paid_at")
fundAllocatedAt DateTime? @map("fund_allocated_at")
miningEnabledAt DateTime? @map("mining_enabled_at")
syncedAt DateTime @default(now()) @map("synced_at")
@@index([userId])
@@index([accountSequence])
@@index([status])
@@index([selectedProvince, selectedCity])
@@index([createdAt])
@@index([paidAt])
@@map("planting_order_query_view")
}
/// 用户持仓查询视图 - 通过 Debezium CDC 从 planting-service 同步
model PlantingPositionQueryView {
id BigInt @id @map("position_id")
userId BigInt @unique @map("user_id")
// 持仓统计
totalTreeCount Int @default(0) @map("total_tree_count")
effectiveTreeCount Int @default(0) @map("effective_tree_count")
pendingTreeCount Int @default(0) @map("pending_tree_count")
// 挖矿状态
firstMiningStartAt DateTime? @map("first_mining_start_at")
// 时间戳
createdAt DateTime @map("created_at")
syncedAt DateTime @default(now()) @map("synced_at")
@@index([totalTreeCount])
@@map("planting_position_query_view")
}
/// 合同签署任务查询视图 - 通过 Debezium CDC 从 planting-service 同步
model ContractSigningTaskQueryView {
id BigInt @id @map("task_id")
// 关联信息
orderNo String @unique @map("order_no") @db.VarChar(50)
contractNo String @unique @map("contract_no") @db.VarChar(30)
userId BigInt @map("user_id")
accountSequence String @map("account_sequence") @db.VarChar(20)
// 合同信息
contractVersion String @map("contract_version") @db.VarChar(20)
// 订单信息快照
treeCount Int @map("tree_count")
totalAmount Decimal @map("total_amount") @db.Decimal(20, 8)
provinceCode String @map("province_code") @db.VarChar(10)
provinceName String @map("province_name") @db.VarChar(50)
cityCode String @map("city_code") @db.VarChar(10)
cityName String @map("city_name") @db.VarChar(50)
// 签署状态
status String @default("PENDING") @map("status") @db.VarChar(30)
expiresAt DateTime @map("expires_at")
// 签署时间戳
signedAt DateTime? @map("signed_at")
// 时间戳
createdAt DateTime @map("created_at")
syncedAt DateTime @default(now()) @map("synced_at")
@@index([userId])
@@index([status])
@@index([expiresAt])
@@map("contract_signing_task_query_view")
}
// =============================================================================
// Authorization Query Views (授权查询视图 - 通过 CDC 同步)
// =============================================================================
/// 授权角色查询视图 - 通过 Debezium CDC 从 authorization-service 同步
model AuthorizationRoleQueryView {
id String @id
userId String @map("user_id")
accountSequence String @map("account_sequence")
roleType String @map("role_type") @db.VarChar(30)
regionCode String @map("region_code")
regionName String @map("region_name")
status String @default("PENDING") @db.VarChar(20)
displayTitle String @map("display_title")
// 授权信息
authorizedAt DateTime? @map("authorized_at")
authorizedBy String? @map("authorized_by")
revokedAt DateTime? @map("revoked_at")
revokedBy String? @map("revoked_by")
// 软删除
deletedAt DateTime? @map("deleted_at")
// 考核配置
initialTargetTreeCount Int @map("initial_target_tree_count")
monthlyTargetType String @map("monthly_target_type") @db.VarChar(20)
// 权益状态
benefitActive Boolean @default(false) @map("benefit_active")
benefitActivatedAt DateTime? @map("benefit_activated_at")
// 月度考核追踪
lastAssessmentMonth String? @map("last_assessment_month")
monthlyTreesAdded Int @default(0) @map("monthly_trees_added")
// 时间戳
createdAt DateTime @map("created_at")
syncedAt DateTime @default(now()) @map("synced_at")
@@index([accountSequence])
@@index([userId])
@@index([roleType, regionCode])
@@index([status])
@@index([deletedAt])
@@map("authorization_role_query_view")
}
/// 月度考核查询视图 - 通过 Debezium CDC 从 authorization-service 同步
model MonthlyAssessmentQueryView {
id String @id
authorizationId String @map("authorization_id")
userId String @map("user_id")
accountSequence String @map("account_sequence")
roleType String @map("role_type") @db.VarChar(30)
regionCode String @map("region_code")
// 考核月份
assessmentMonth String @map("assessment_month")
monthIndex Int @map("month_index")
// 考核目标
monthlyTarget Int @map("monthly_target")
cumulativeTarget Int @map("cumulative_target")
// 完成情况
monthlyCompleted Int @default(0) @map("monthly_completed")
cumulativeCompleted Int @default(0) @map("cumulative_completed")
completedAt DateTime? @map("completed_at")
// 考核结果
result String @default("NOT_ASSESSED") @db.VarChar(20)
// 排名
rankingInRegion Int? @map("ranking_in_region")
isFirstPlace Boolean @default(false) @map("is_first_place")
// 豁免
isBypassed Boolean @default(false) @map("is_bypassed")
// 时间戳
assessedAt DateTime? @map("assessed_at")
createdAt DateTime @map("created_at")
syncedAt DateTime @default(now()) @map("synced_at")
@@index([accountSequence, assessmentMonth])
@@index([userId, assessmentMonth])
@@index([roleType, regionCode, assessmentMonth])
@@index([assessmentMonth, result])
@@map("monthly_assessment_query_view")
}
/// 系统账户查询视图 - 通过 Debezium CDC 从 authorization-service 同步
model SystemAccountQueryView {
id BigInt @id @map("account_id")
accountType String @map("account_type") @db.VarChar(30)
// 区域信息
regionCode String? @map("region_code") @db.VarChar(10)
regionName String? @map("region_name") @db.VarChar(50)
// 钱包地址
walletAddress String? @map("wallet_address") @db.VarChar(42)
// 余额
usdtBalance Decimal @default(0) @map("usdt_balance") @db.Decimal(20, 8)
hashpower Decimal @default(0) @map("hashpower") @db.Decimal(20, 8)
// 累计统计
totalReceived Decimal @default(0) @map("total_received") @db.Decimal(20, 8)
totalTransferred Decimal @default(0) @map("total_transferred") @db.Decimal(20, 8)
// 状态
status String @default("ACTIVE") @map("status") @db.VarChar(20)
// 时间戳
createdAt DateTime @map("created_at")
syncedAt DateTime @default(now()) @map("synced_at")
@@index([accountType])
@@index([walletAddress])
@@map("system_account_query_view")
}
// =============================================================================
// Ledger Views (分类账视图 - 通过 CDC 同步)
// =============================================================================
/// 钱包流水分类账 - 通过 Debezium CDC 从 wallet-service 同步
/// 记录所有用户钱包的资金变动(充值/提现/收益/扣款等)
model WalletLedgerEntryView {
id BigInt @id @map("entry_id")
accountSequence String @map("account_sequence") @db.VarChar(20)
userId BigInt @map("user_id")
// 流水类型
entryType String @map("entry_type") @db.VarChar(50)
// 金额变动 (正数入账, 负数支出)
amount Decimal @map("amount") @db.Decimal(20, 8)
assetType String @map("asset_type") @db.VarChar(20)
// 余额快照 (操作后余额)
balanceAfter Decimal? @map("balance_after") @db.Decimal(20, 8)
// 关联引用
refOrderId String? @map("ref_order_id") @db.VarChar(100)
refTxHash String? @map("ref_tx_hash") @db.VarChar(100)
// 备注
memo String? @map("memo") @db.Text
// 时间戳
createdAt DateTime @map("created_at")
syncedAt DateTime @default(now()) @map("synced_at")
@@index([accountSequence, createdAt(sort: Desc)])
@@index([userId, createdAt(sort: Desc)])
@@index([entryType])
@@index([assetType])
@@index([refOrderId])
@@index([refTxHash])
@@index([createdAt])
@@map("wallet_ledger_entry_view")
}
/// 认种资金分配分类账 - 通过 Debezium CDC 从 planting-service 同步
/// 记录每笔认种订单的资金分配明细
model FundAllocationView {
id BigInt @id @map("allocation_id")
orderId BigInt @map("order_id")
// 分配信息
targetType String @map("target_type") @db.VarChar(50)
amount Decimal @map("amount") @db.Decimal(20, 8)
targetAccountId String? @map("target_account_id") @db.VarChar(100)
// 时间戳
createdAt DateTime @map("created_at")
syncedAt DateTime @default(now()) @map("synced_at")
@@index([orderId])
@@index([targetType, targetAccountId])
@@index([createdAt])
@@map("fund_allocation_view")
}
/// 系统账户流水分类账 - 通过 Debezium CDC 从 authorization-service 同步
/// 记录系统账户(成本账户、运营账户、区域账户)的资金变动
model SystemAccountLedgerView {
id BigInt @id @map("ledger_id")
accountId BigInt @map("account_id")
// 流水类型
entryType String @map("entry_type") @db.VarChar(30)
// 金额
amount Decimal @map("amount") @db.Decimal(20, 8)
balanceAfter Decimal @map("balance_after") @db.Decimal(20, 8)
// 关联信息
sourceOrderId BigInt? @map("source_order_id")
sourceRewardId BigInt? @map("source_reward_id")
txHash String? @map("tx_hash") @db.VarChar(66)
memo String? @map("memo") @db.VarChar(500)
// 时间戳
createdAt DateTime @map("created_at")
syncedAt DateTime @default(now()) @map("synced_at")
@@index([accountId, createdAt(sort: Desc)])
@@index([sourceOrderId])
@@index([txHash])
@@index([createdAt])
@@map("system_account_ledger_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")
}
// =============================================================================
// System Config (系统配置)
// =============================================================================
/// 系统配置 - 键值对存储,用于存储各种系统设置
model SystemConfig {
id String @id @default(uuid())
key String @unique @db.VarChar(100) // 配置键
value String @db.Text // 配置值 (JSON 格式)
description String? @db.VarChar(255) // 配置描述
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
updatedBy String? @map("updated_by") // 更新人ID
@@index([key])
@@map("system_configs")
}
// =============================================================================
// System Maintenance (系统维护公告)
// =============================================================================
/// 系统维护公告 - 用于系统升级/维护期间阻断用户操作
model SystemMaintenance {
id String @id @default(uuid())
title String @db.VarChar(100) // 标题:如"系统升级中"
message String @db.Text // 说明:如"预计10:00恢复请稍候"
startTime DateTime @map("start_time") // 维护开始时间
endTime DateTime @map("end_time") // 维护结束时间
isActive Boolean @default(false) @map("is_active") // 是否激活
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
createdBy String @map("created_by") // 创建人ID
updatedBy String? @map("updated_by") // 更新人ID
@@index([isActive])
@@index([startTime, endTime])
@@map("system_maintenances")
}
// =============================================================================
// Co-Managed Wallet System (共管钱包系统)
// =============================================================================
/// 共管钱包会话状态
enum WalletSessionStatus {
WAITING // 等待参与方加入
READY // 所有参与方已就绪
PROCESSING // 密钥生成中
COMPLETED // 创建完成
FAILED // 创建失败
CANCELLED // 已取消
}
/// 共管钱包会话 - 钱包创建过程的会话记录
model CoManagedWalletSession {
id String @id @default(uuid())
walletName String @map("wallet_name") @db.VarChar(100) // 钱包名称
thresholdT Int @map("threshold_t") // 签名阈值 T
thresholdN Int @map("threshold_n") // 参与方总数 N
inviteCode String @unique @map("invite_code") @db.VarChar(20) // 邀请码
status WalletSessionStatus @default(WAITING) // 会话状态
participants String @db.Text // 参与方列表 (JSON)
currentRound Int @default(0) @map("current_round") // 当前密钥生成轮次
totalRounds Int @default(3) @map("total_rounds") // 总轮次
publicKey String? @map("public_key") @db.VarChar(200) // 生成的公钥
error String? @db.Text // 错误信息
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
createdBy String @map("created_by") @db.VarChar(100) // 创建者
@@index([inviteCode])
@@index([status])
@@index([createdBy])
@@index([createdAt])
@@map("co_managed_wallet_sessions")
}
/// 共管钱包 - 创建成功后的钱包记录
model CoManagedWallet {
id String @id @default(uuid())
sessionId String @unique @map("session_id") // 关联的会话 ID
name String @db.VarChar(100) // 钱包名称
publicKey String @map("public_key") @db.VarChar(200) // 钱包公钥
thresholdT Int @map("threshold_t") // 签名阈值 T
thresholdN Int @map("threshold_n") // 参与方总数 N
participants String @db.Text // 参与方列表 (JSON)
createdAt DateTime @default(now()) @map("created_at")
createdBy String @map("created_by") @db.VarChar(100) // 创建者
@@index([sessionId])
@@index([publicKey])
@@index([createdBy])
@@index([createdAt])
@@map("co_managed_wallets")
}