数据库模型
MysticX 使用 PostgreSQL 18 数据库,Prisma 7 作为 ORM。数据库包含 35+ 个模型,按功能域组织。
核心模型
User(用户)
核心用户记录。
| 字段 | 类型 | 说明 |
|---|---|---|
| id | String | 主键 |
| name | String | 显示名称 |
| String | 邮箱(唯一) | |
| emailVerified | Boolean | 邮箱验证状态 |
| image | String? | 头像 URL |
| credits | Int | 当前积分余额 |
| tier | SubscriptionTier | FREE、GOLD 或 DIAMOND |
| role | String? | 管理员为 'admin',普通用户为 null |
| timezone | String? | IANA 时区 |
| stripeCustomerId | String? | Stripe 客户 ID |
| subscriptionProvider | String? | 'stripe'、'apple'、'google' 或 null |
| subscriptionInterval | String? | 'week'、'month'、'year' 或 null |
| inviteCode | String? | 唯一邀请码 |
| invitedByUserId | String? | 邀请该用户的用户 ID |
| activeCardSkinId | String? | 当前使用的牌面皮肤 |
| activeTarotReaderId | String? | 当前选择的读者 |
| banned | Boolean? | 封禁状态 |
| banReason | String? | 封禁原因 |
| banExpires | DateTime? | 封禁到期时间(null = 永久封禁) |
| deletedAt | DateTime? | 软删除时间戳(null = 正常账号) |
Session / Account / Verification
Better Auth 标准表,用于会话管理、OAuth 账号和邮箱验证令牌。
解读模型
TarotReading(塔罗解读)
核心解读记录。
| 字段 | 类型 | 说明 |
|---|---|---|
| id | String | 主键 |
| userId | String? | 所有者(访客解读为 null) |
| guestToken | String? | 访客标识符 |
| readerId | String | 使用的 AI 读者角色 |
| spreadId | String | 使用的牌阵类型 |
| question | String | 用户的问题 |
| selectedCards | Json | 牌序号和正逆位状态数组 |
| locale | String | 解读语言 |
| status | ReadingStatus | PENDING、PROCESSING、COMPLETED、FAILED |
| ipAddress | String? | 客户端 IP |
| timezone | String? | 客户端时区 |
Chat(对话)
每次解读关联一个对话,用于后续追问。
Message(消息)
对话中的单条消息。
| 字段 | 类型 | 说明 |
|---|---|---|
| role | String | user、assistant、system |
| type | String | 消息类型 |
| content | String | 消息内容 |
| status | MessageStatus | PENDING、STREAMING、COMPLETED、FAILED |
| tokensCount | Int? | 用于计费的 Token 数量 |
| feedbackRating | FeedbackRating? | THUMBS_UP 或 THUMBS_DOWN(null = 未评价) |
| feedbackReason | String? | THUMBS_DOWN 时填写的文字原因 |
AiApiCall(AI 调用记录)
每次 AI 模型调用的遥测数据。
| 字段 | 类型 | 说明 |
|---|---|---|
| callType | AiCallType | INITIAL_READING、FOLLOW_UP、DRAW_CARD、SPREAD_SUGGEST |
| model | String | 模型标识符 |
| status | AiCallStatus | SUCCESS、FAILED、TIMEOUT |
| durationMs | Int | 总调用耗时 |
| timeToFirstTokenMs | Int? | 首个 Token 的延迟时间 |
| inputTokens | Int? | 输入 Token 数量 |
| outputTokens | Int? | 输出 Token 数量 |
| totalTokens | Int? | 合计 Token 数量 |
| errorMessage | String? | 失败时的错误详情 |
塔罗内容模型
TarotCard(塔罗牌)
78 张牌的完整牌组,包含多语言名称和释义。
| 字段 | 类型 | 说明 |
|---|---|---|
| cardIndex | Int | 0–77 索引 |
| suit | String? | 大/小阿尔卡纳花色 |
| rank | String? | 牌面等级 |
| name | Json | TLocalizedString |
| imageUrl | String | 牌面图片 |
| meaningUp | Json | 正位释义(多语言) |
| meaningRev | Json | 逆位释义(多语言) |
| keywordsUp | Json | 正位关键词 |
| keywordsRev | Json | 逆位关键词 |
| yesNoUpVerdict | String? | 是/否正位判定 |
| yesNoRevVerdict | String? | 是/否逆位判定 |
TarotSpread(塔罗牌阵)
牌阵定义及位置信息。
| 字段 | 类型 | 说明 |
|---|---|---|
| slug | String | URL slug(如 celtic-cross) |
| name | Json | TLocalizedString |
| description | Json | TLocalizedString |
| cardsCount | Int | 总抽牌数(含系统自动抽取的牌) |
| userSelectionCount | Int | 用户手动选择的牌数 |
| positions | Json | 位置定义(顺序、名称、说明、isMainCard) |
| layoutImageUrl | String? | 牌阵布局缩略图 |
| sortOrder | Int | 管理员可调整的显示顺序 |
TarotReader(塔罗读者)
AI 读者角色。
| 字段 | 类型 | 说明 |
|---|---|---|
| slug | String | URL slug |
| isDefault | Boolean | 是否为默认读者 |
| isActive | Boolean | 软删除标志(false 时隐藏) |
| name | Json | TLocalizedString |
| avatarUrl | String? | 头像图片 URL |
| coverImageUrl | String? | 背景封面图片 URL |
| bio | Json | 读者选择界面展示的简介(TLocalizedString) |
| description | Json | 详细背景故事(TLocalizedString) |
| specialties | Json | TLocalized<string[]> — 读者擅长领域标签 |
| introAudioUrls | Json? | Partial<TLocalizedString> — 各语言介绍音频 URL |
| voiceIds | Json? | Partial<TLocalizedString> — 各语言 MiniMax 音色 ID |
| systemPrompt | String | AI 系统提示词(纯英文,非面向用户) |
| temperature | Float | 模型温度参数(0.0–1.0) |
| topP | Float | Top-P 采样参数 |
| thinkingLevel | ThinkingLevel | AI 思考强度 |
| unlockPrice | Int | 解锁所需积分(0 = 免费) |
| sortOrder | Int | UI 显示排序 |
TarotQuestionCategory / TarotQuestion / SpreadQuestion / SpreadInspiration
问题目录和牌阵选择灵感内容。
商业模型
Subscription(订阅)
关联用户的 Stripe 订阅记录。
| 字段 | 类型 | 说明 |
|---|---|---|
| plan | String | GOLD 或 DIAMOND |
| stripeSubscriptionId | String | Stripe 订阅 ID |
| status | String | active、canceled、past_due 等 |
| periodStart | DateTime | 当前周期开始时间 |
| periodEnd | DateTime | 当前周期结束时间 |
CreditTransaction(积分交易)
每次积分变动的审计日志。
| 字段 | 类型 | 说明 |
|---|---|---|
| userId | String | 用户 |
| amount | Int | 正数(收入)或负数(支出) |
| type | CreditTransactionType | 详见下方枚举值 |
| description | String? | 人类可读的描述 |
个性化模型
UserMemory(AI 记忆)
每个用户的 AI 记忆事实。
| 字段 | 类型 | 说明 |
|---|---|---|
| facts | Json | 最多 5 条英文事实字符串数组 |
| translations | Json | 按需生成的多语言翻译 |
WeeklyGuidance(每周指引)
每周 AI 生成的灵性报告。
| 字段 | 类型 | 说明 |
|---|---|---|
| content | String | Markdown 格式的指引内容 |
| translations | Json | 多语言版本 |
| status | GuidanceStatus | GENERATING、READY、FAILED |
| weekStart / weekEnd | DateTime | 覆盖的时间段 |
| autoGenerated | Boolean | Diamond 用户自动生成为 true |
SoulJourney(灵魂旅程)
个人成长记录文档。
| 字段 | 类型 | 说明 |
|---|---|---|
| content | String | Markdown 格式的旅程内容 |
| translations | Json | 多语言版本 |
| status | GuidanceStatus | GENERATING、READY、FAILED |
| themes | Json | 提取的主题字符串 |
| themeTranslations | Json | 主题的缓存多语言翻译 |
| readingCount | Int | 分析的解读数量 |
CardOfDayEntry(每日一牌)
每日抽牌记录。
| 字段 | 类型 | 说明 |
|---|---|---|
| cardIndex | Int | 抽到的牌 |
| isReversed | Boolean | 牌的正逆方向 |
| emotionalWeather | String | AI 生成的情绪天气 |
| actions | Json | 建议行动 |
| questions | Json | 探索问题 |
| resonanceCount | Int | 用户共鸣追踪 |
| credits | Int | 发放的积分 |
互动模型
Referral(邀请推荐)
追踪邀请关系。
| 字段 | 类型 | 说明 |
|---|---|---|
| inviterUserId | String | 邀请者 |
| inviteeUserId | String | 被邀请者 |
| status | ReferralStatus | REGISTERED、QUALIFIED、REWARDED |
ReferralMilestoneReward(里程碑奖励)
里程碑奖励追踪(3、10、25 次邀请)。
Notification(通知)
应用内通知记录。
| 字段 | 类型 | 说明 |
|---|---|---|
| category | NotificationCategory | READING、ACCOUNT、SOCIAL、SYSTEM |
| type | NotificationType | 具体通知类型枚举 |
| targetUrl | String? | 深链接 URL |
| metadata | Json? | 可选附加数据 |
| isRead | Boolean | 已读状态 |
UserFeedback(用户反馈)
用户提交的反馈,包含截图 URL。
内容模型
BlogPost / BlogCategory / BlogTag / BlogAuthor / BlogPostTag
完整的博客系统,包含分类、标签和作者资料。所有内容字段使用 TLocalizedString JSON 格式。
市场模型
CardSkin / UserCardSkin(牌面皮肤)
牌背设计和用户拥有记录。
UserTarotReader(读者解锁记录)
记录用户已购买解锁的读者。
分析模型
PageView(页面浏览)
服务端页面浏览追踪,使用访客 Cookie ID。
TelegramLink(Telegram 关联)
将 Telegram 账号关联到 MysticX 用户账号。
关键枚举
| 枚举 | 值 |
|---|---|
| SubscriptionTier | FREE、GOLD、DIAMOND |
| CreditTransactionType | REGISTRATION_BONUS、REFERRAL_INVITER_REWARD、REFERRAL_INVITEE_BONUS、REFERRAL_MILESTONE_BONUS、DAILY_CLAIM、CARD_OF_DAY_CLAIM、READING_DEDUCTION、FOLLOWUP_DEDUCTION、SPREAD_SUGGEST_DEDUCTION、SUBSCRIPTION_GRANT、ONE_TIME_PURCHASE、ADMIN_ADJUSTMENT、WEEKLY_GUIDANCE_DEDUCTION、SOUL_JOURNEY_DEDUCTION、READER_UNLOCK_DEDUCTION、CARD_SKIN_UNLOCK_DEDUCTION |
| ReadingStatus | ACTIVE、PRECREATED |
| MessageStatus | PENDING、STREAMING、COMPLETED、FAILED |
| FeedbackRating | THUMBS_UP、THUMBS_DOWN |
| GuidanceStatus | GENERATING、READY、FAILED |
| ReferralStatus | REGISTERED、QUALIFIED、REWARDED |
| FeedbackStatus | PENDING、REVIEWED、RESOLVED |
| BlogPostStatus | DRAFT、PUBLISHED、SCHEDULED、ARCHIVED |
| NotificationCategory | READING、ACCOUNT、SOCIAL、SYSTEM |
| AiCallType | INITIAL_READING、FOLLOW_UP、DRAW_CARD、SPREAD_SUGGEST |
| AiCallStatus | SUCCESS、FAILED、TIMEOUT |
| ThinkingLevel | MINIMAL、LOW、MEDIUM、HIGH |