Add reward ledger schema

This commit is contained in:
Wang Zhuoxuan 2026-05-11 17:59:03 +08:00
parent a23f1abc12
commit 51395bf5ec
2 changed files with 26 additions and 1 deletions

View File

@ -32,7 +32,7 @@
| G0-1 | 梳理游戏化规则常量模块 | [x] | 新增集中规则定义覆盖红心、挑战组、XP、等级、金币、道具、广告恢复、周榜周期 |
| G0-2 | 新增挑战组数据模型 | [x] | 支持 challenge session、session answers、组状态、正确数、完成时间、幂等提交 |
| G0-3 | 新增钱包和道具库存模型 | [x] | 支持金币余额、道具库存、道具获得/消耗流水 |
| G0-4 | 新增奖励流水模型 | [ ] | 记录奖励来源、幂等 key、奖励快照、发放前后状态 |
| G0-4 | 新增奖励流水模型 | [x] | 记录奖励来源、幂等 key、奖励快照、发放前后状态 |
| G0-5 | 新增每日任务或每日进度模型 | [ ] | 可统计每日首组挑战、每日任务完成、每日高奖励次数 |
| G0-6 | 新增周 XP 统计模型或扩展周榜快照 | [ ] | 可按自然周统计 XP支持每周一刷新和历史快照 |
| G0-7 | 生成并提交数据库迁移 | [ ] | `db/migrations/` 包含 schema 变更,迁移文件不被 `.gitignore` 遗漏 |

View File

@ -262,6 +262,31 @@ export const inventoryTransactions = mysqlTable('inventory_transactions', {
foreignKey({ columns: [table.inventoryItemId], foreignColumns: [userInventoryItems.id] }),
]);
// ── Reward Ledger ─────────────────────────────────────────────────
// 统一奖励结算流水,记录奖励来源、幂等边界、快照和发放前后状态。
export const rewardLedger = mysqlTable('reward_ledger', {
id: char('id', { length: 36 }).primaryKey(),
userId: char('user_id', { length: 36 }).notNull(),
sourceType: mysqlEnum('source_type', ['challenge_answer', 'challenge_completion', 'daily_task', 'streak_milestone', 'level_up', 'theme_node', 'knowledge_card', 'chest', 'shop_purchase', 'ad_recovery', 'leaderboard_settlement', 'subscription', 'admin_grant', 'system_adjust']).notNull(), // 奖励来源。
sourceId: varchar('source_id', { length: 120 }), // 来源业务 ID。
idempotencyKey: varchar('idempotency_key', { length: 160 }).notNull(), // 奖励结算幂等 key。
status: mysqlEnum('status', ['pending', 'settling', 'completed', 'failed', 'reversed']).default('pending'), // 奖励结算状态。
rewardSnapshot: json('reward_snapshot').$type<Record<string, unknown>>().notNull(), // 计划发放或已发放的奖励快照。
resourceDeltas: json('resource_deltas').$type<Record<string, unknown>>(), // XP、金币、红心、道具等资源变化。
stateBefore: json('state_before').$type<Record<string, unknown>>(), // 发放前用户资源状态。
stateAfter: json('state_after').$type<Record<string, unknown>>(), // 发放后用户资源状态。
failureReason: varchar('failure_reason', { length: 120 }), // 结算失败或回滚原因。
settledAt: datetime('settled_at'), // 奖励完成结算时间。
createdAt: datetime('created_at').default(sql`CURRENT_TIMESTAMP`), // 创建时间。
updatedAt: datetime('updated_at').default(sql`CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP`), // 更新时间。
}, (table) => [
uniqueIndex('uk_reward_ledger_user_idempotency').on(table.userId, table.idempotencyKey),
index('idx_reward_ledger_user_status_created').on(table.userId, table.status, table.createdAt),
index('idx_reward_ledger_source').on(table.sourceType, table.sourceId),
foreignKey({ columns: [table.userId], foreignColumns: [users.id] }),
]);
// ── Question Ratings ──────────────────────────────────────────────
// 用户对题目的好坏反馈数据。