Commit Graph

50 Commits

Author SHA1 Message Date
6c63b6e24a 暴露周榜元信息到排行榜 API
- 新增 LeaderboardMetaDto 含 weekStart/weekEnd/nextRefreshAt/groupId/rank/rewardPreview
- leaderboard-service 新增 getLeaderboardMeta() 获取当前周元信息
- /leaderboards 和 /leaderboards/me 响应中附带 meta 字段
- 奖励预览返回前 3 名的 300/150/50 金币配置
2026-05-13 21:48:54 +08:00
a3da577bf3 实现排行榜前三奖励结算
- weeklySettlement 按组结算,每组前 3 名发 300/150/50 金币
- 奖励通过 grantCoins 幂等发放,idempotencyKey 包含组+排名+用户
- 结算返回 SettlementResult 含 rewards 列表和 groupCount
- coin-service 新增 leaderboard_settlement 奖励来源
- schema inventoryTransactions.sourceType 新增 leaderboard_settlement 枚举值
2026-05-13 21:43:14 +08:00
66112c30f8 实现排行榜 20-30 人分组
- 用户本周首次获得 XP 时自动分配到 20-30 人榜组
- 分组策略:查找未满组加入,否则创建新组
- 组 ID 格式 week-{date}-group-{序号},方便调试
- 排行榜查询和我的排名改为组内排名
- getLeaderboard 新增 userId 参数获取用户所在组
2026-05-13 21:30:08 +08:00
08461485d5 实现每周一刷新逻辑与幂等周结算
- weeklySettlement 改为结算上一周数据(周一当前周 XP 为 0)
- 快照写入使用 onDuplicateKeyUpdate 保证幂等
- userWeeklyXp.settled 标记防止重复结算
- 新增 dryRun 模式返回结算预览不写库
- 时区策略注释:所有周榜计算统一 UTC,客户端本地转换
2026-05-13 21:06:15 +08:00
d7d5f8109c 改造排行榜数据源为本周 XP
- addXp() 每次获得 XP 时同步累加 userWeeklyXp 表的本周统计
- 使用 INSERT ON DUPLICATE KEY UPDATE 实现幂等周 XP 累加
- leaderboard-service 从 userWeeklyXp 查询本周 XP 排名替代累计 XP
- leaderboard-api-service DTO 中 xp 字段改为展示本周 XP
- weeklySettlement() 基于 userWeeklyXp 生成周快照
2026-05-13 21:00:48 +08:00
eee2116633 添加广告恢复回归测试覆盖 G4-7
新增 ad-recovery-service.test.ts,覆盖幂等 session 创建、Plus 拦截
与权益摘要、每日上限、会话过期、provider token 缺失、信任测试
provider、已完成会话幂等返回、rewardLedger 幂等命中 8 个场景。
Phase G4 全部完成。
2026-05-13 20:34:55 +08:00
de0055e794 标记旧恢复接口废弃并明确 Plus 用户分支
- 在 3 个旧恢复路由上标记 [废弃] 注释,指向新的 ad-recovery 两步流程
- Plus 用户调用广告恢复接口时返回 subscriptionBenefits 权益摘要
- 包含 tier、unlimitedHearts、dailyHighRewardSessions 供客户端展示
2026-05-13 20:24:32 +08:00
8401d8c714 对齐广告恢复奖励到统一奖励结算层
将 ad-recovery-service 的 applyReward() 从直接操作 users 表改为通过
rewardLedger 统一结算层发放,使用 ad_recovery:{sessionId} 幂等 key
防止重复结算,记录 stateBefore/After 资源快照便于审计追溯。
2026-05-13 20:04:32 +08:00
7aa53657fc 补齐金币商店测试覆盖 2026-05-13 17:45:58 +08:00
6bf9db9820 扩展游戏化启动与商店 DTO 2026-05-13 17:38:54 +08:00
b74201d6e0 实现游戏化道具使用接口 2026-05-13 17:31:54 +08:00
ff75c34873 实现游戏化商店购买接口 2026-05-13 17:16:30 +08:00
5a29c59cf0 实现游戏化道具库存服务 2026-05-13 16:57:34 +08:00
3bcaf0fbf3 实现游戏化宝箱奖励服务 2026-05-13 16:41:57 +08:00
18865e17ca 实现游戏化金币发放服务 2026-05-13 13:01:00 +08:00
1ad26d0fe8 补齐 XP 与连续学习测试覆盖 2026-05-13 10:55:17 +08:00
c08d3f75b9 实现每日首次进入红心补给 2026-05-13 10:53:27 +08:00
d71c45b2f1 实现连续学习里程碑奖励 2026-05-13 10:51:01 +08:00
447cef3dea 按挑战组完成更新连续学习 2026-05-13 10:47:46 +08:00
b5b3aaf3a7 实现游戏化 XP 来源与连对奖励 2026-05-13 10:26:21 +08:00
b590e60bce feat: implement non-linear 50-level XP curve (G2-1)
Replace flat 400 XP/level formula with the segmented curve from
LEVEL_RULES: Lv.1-5 steep ramp, Lv.6-10 moderate, Lv.11-20 linear +80,
Lv.21-35 +120, Lv.36-50 +180. Level 50 is hard-capped with xpToNextLevel=0.

Uses binary search over pre-computed cumulative thresholds for O(log n)
level lookup.
2026-05-12 11:04:23 +08:00
665efa4370 test: add comprehensive challenge group tests (G1-7)
Add 11 new test cases covering challenge session creation, correct/wrong
answers, idempotent duplicate submission, completion settlement, resource
exhaustion, Plus user bypass, and invalid input validation.

Refactor test helpers to use queue-based mockImplementation pattern for
more reliable db.select mocking across complex async flows.
2026-05-12 10:38:17 +08:00
c8a5d0bf25 feat: add high-reward quota fields to challenge answer DTO
Include highRewardSessionsLeft/Max in AnswerResultDto.progress
so clients can update UI after each answer without extra API calls.
2026-05-12 00:12:24 +08:00
05b9faa0ea feat: enforce daily high-reward session limits with tier-based quotas
Free users get 3 high-reward sessions/day, Plus users get 8. Sessions
after quota are still playable but with degraded XP rewards.
2026-05-12 00:01:31 +08:00
6ea5ed9de0 feat: add heart deduction boundaries with new user protection
Add 3-day new user heart protection (minimum 1 heart) and block
answering when hearts are exhausted for free-tier users.
2026-05-11 23:44:45 +08:00
9e0f97d162 Settle completed challenge sessions 2026-05-11 21:40:41 +08:00
5bb6ba29a2 Record idempotent challenge answers 2026-05-11 21:34:27 +08:00
1d84de8d15 Create challenge sessions with five questions 2026-05-11 18:32:40 +08:00
6a655d0ce2 Add weekly XP schema 2026-05-11 18:18:33 +08:00
7a617ce1f9 Add daily progress schema 2026-05-11 18:06:19 +08:00
51395bf5ec Add reward ledger schema 2026-05-11 17:59:03 +08:00
a23f1abc12 Add wallet and inventory schema 2026-05-11 17:41:26 +08:00
5570973f74 Add challenge session schema 2026-05-11 17:39:06 +08:00
8382183ee5 Add gamification rule constants 2026-05-11 17:33:53 +08:00
94b807ad16 docs: annotate database schema fields 2026-05-11 12:45:00 +08:00
2649b24277 Add ad recovery API contract 2026-05-05 16:12:04 +08:00
3ea44189e8 Add Flutter app-facing API routes 2026-05-04 01:24:23 +08:00
c70748dde2 fix: 修复 admin change-password 接口 401 和 CORS 问题
All checks were successful
CI/CD Pipeline / Code Quality (push) Successful in 18s
CI/CD Pipeline / Unit Tests (push) Successful in 45s
CI/CD Pipeline / Build & Deploy Test (push) Has been skipped
CI/CD Pipeline / Build & Deploy Production (push) Successful in 12m21s
- CORS 配置显式放行 PUT/PATCH/DELETE 方法(默认只有 GET/POST/HEAD)
- admin-auth 白名单路径修正 /v1/admin/auth/login → /v1/admin/login
- JWT verify 后手动赋值 request.user,修复 decoded payload 丢失
2026-04-23 22:27:23 +08:00
2c97412c82 fix: 修复 admin-auth 测试的 TypeScript 类型错误
Some checks failed
CI/CD Pipeline / Code Quality (push) Successful in 18s
CI/CD Pipeline / Unit Tests (push) Failing after 14s
CI/CD Pipeline / Build & Deploy Test (push) Has been skipped
CI/CD Pipeline / Build & Deploy Production (push) Has been skipped
将 mockDb 的类型从 Record<string, Mock> 改为显式的映射类型,
消除 CI 中 "possibly undefined" 的类型检查报错。
2026-04-23 12:55:01 +08:00
5b1f0848ac feat: 添加管理员修改自己密码的接口
Some checks failed
CI/CD Pipeline / Code Quality (push) Failing after 17s
CI/CD Pipeline / Unit Tests (push) Has been skipped
CI/CD Pipeline / Build & Deploy Test (push) Has been skipped
CI/CD Pipeline / Build & Deploy Production (push) Has been skipped
新增 PUT /v1/admin/change-password 端点,允许已登录管理员
(admin / super_admin)修改自己的密码。需验证旧密码,
且新旧密码不能相同。错误由全局 errorHandler 统一处理。
2026-04-23 12:32:31 +08:00
9d1f52d95b fix: health 路由路径修正为 /health
All checks were successful
CI/CD Pipeline / Code Quality (push) Successful in 15s
CI/CD Pipeline / Unit Tests (push) Successful in 8s
CI/CD Pipeline / Build & Deploy Test (push) Has been skipped
CI/CD Pipeline / Build & Deploy Production (push) Successful in 1m15s
healthRoutes 注册时无 /v1 前缀,实际路径是 /health 而非 /v1/health。
将 auth 中间件白名单从 /v1/health 改为 /health,并同步修正所有
HEALTHCHECK 和 CI health check 路径。
2026-04-18 04:13:59 +08:00
db2f3af8a3 feat: 完善题目列表查询接口,支持搜索、多维筛选和排序
- 新增关键词搜索(同时匹配题干 stem 和选项 distractors)
- 新增按难度(difficulty)、来源(source)筛选
- 新增动态排序:支持 createdAt/updatedAt/difficulty,可选 asc/desc
- 路由层增加 sortBy/sortOrder 白名单校验
2026-04-12 00:04:11 +08:00
aeebcba77c feat: 添加题目批量导入接口(JSON + CSV)
- POST /admin/questions/import 支持 JSON 数组导入(1-200 条)
- POST /admin/questions/import-csv 支持 CSV 文本导入
- 全有或全无事务策略,先验校验后统一插入
- 包含 categoryId 外键存在性校验
- CSV 解析器支持引号内逗号、换行和 "" 转义
2026-04-11 23:23:09 +08:00
1b142f2866 feat: 添加题目批量发布、归档和删除接口
- 新增 batchUpdateStatus 通用方法,带状态流转校验和 BatchResult 报告
- 改造 batchPublish 使用新方法,返回成功/失败详情
- 新增 batchArchive 和 batch-delete 端点(软删除)
- 使用 inArray 批量查询和更新,优化数据库往返
- 更新 API 文档,补充三个批量接口说明
2026-04-11 22:19:02 +08:00
6a5490dea4 feat: 添加题目状态变更接口(带流转校验)
新增 PATCH /admin/questions/:id/status 接口,支持题目状态流转并校验合法性:
- draft → reviewing, archived
- reviewing → published, draft, archived
- published → archived
- archived → draft
2026-04-11 21:17:34 +08:00
f260fd6bfb feat: 添加管理员管理 API
- 新增管理员类型定义 (src/types/admin.ts)
- 新增管理员管理服务 (src/services/admin/admin-management-service.ts)
- 新增管理员管理路由 (src/routes/admin/admins.ts)
- 更新 API 参考文档

功能:
- GET /v1/admin/admins - 获取管理员列表(支持分页和筛选)
- GET /v1/admin/admins/:id - 获取管理员详情
- POST /v1/admin/admins - 创建管理员(super_admin 专属)
- PUT /v1/admin/admins/:id - 更新管理员信息(super_admin 专属)
- DELETE /v1/admin/admins/:id - 软删除管理员(super_admin 专属)
- POST /v1/admin/admins/:id/reset-password - 重置密码(super_admin 专属)

安全特性:
- BCrypt 密码哈希
- 随机密码生成(12 位,包含大小写字母、数字、符号)
- 软删除机制
- 防止删除最后一个 super_admin
- 防止管理员修改自己的关键信息
- 使用 Drizzle ORM ne() 操作符防止 SQL 注入
2026-04-11 18:36:24 +08:00
3991a02a8c feat: 添加管理员用户名密码登录功能
新增 /v1/admin/auth/login 接口,支持用户名密码登录获取 JWT Token。
- 添加 admin_users 表存储管理员账号和哈希密码
- 使用 bcryptjs 进行密码哈希(cost=10)
- JWT Token 认证优先,保留 ADMIN_TOKEN 作为向后兼容
- 记录登录审计日志到 admin_audit_log
- 种子数据创建默认管理员(username: admin, password: admin123)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-11 15:25:31 +08:00
6e65993f89 feat: add pagination support to admin categories endpoint
- Add page/limit query parameters with Zod validation (max 50)
- Update listCategories service to return paginated results
- Response format includes pagination metadata (total, page, limit)
- Matches existing pattern from questions/feedback endpoints

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-11 12:56:40 +08:00
b872b1cad9 feat: implement Phase 1b core features and Phase 1c commercialization
Phase 1b — Core Features:
- Huawei ID Kit login (token exchange + user info) with guest mode
- Quiz engine: randomized questions, distractor shuffling, answer verification
- XP service with combo bonuses (3/5/10-hit streaks), daily reset
- Streak service: >=3 correct/day, freeze, UTC date handling
- Hearts service: 5/day, 30min auto-restore, Pro unlimited
- 50 quiz questions across 3 categories (history/drama/crosstalk)
- 13 skill tree chapters with linear progression
- Idempotent seed import script (categories → skill tree → questions)
- 7 admin CRUD services (questions, categories, knowledge cards,
  skill tree, users, stats, feedback) with Zod validation
- All routes use Zod schema validation, /auth/me endpoint

Phase 1c — Commercialization:
- Leaderboard with live XP ranking, 10 tiers, weekly settlement
- Achievement system with 15 seed achievements and condition checking
- Huawei IAP receipt verification + subscription management
- Differentiated rate limiting (auth 10/min, quiz 60/min)
- Admin audit logging middleware

Infrastructure:
- Vitest test framework with DB mock utilities (19 tests passing)
- 12 DB tables (5 new: question_ratings, user_feedback, achievements,
  user_achievements, leaderboard_snapshots, subscriptions, admin_audit_log)
- TypeScript strict mode: zero errors
2026-04-09 00:12:12 +08:00
f6e7be324e feat: initialize duoqi-api project skeleton
Set up Fastify + TypeScript + Drizzle ORM backend with:
- Database schema (7 tables: users, categories, questions, knowledge_cards, user_progress, skill_tree, user_chapter_progress)
- JWT auth middleware + admin token auth
- Route structure for auth, quiz, progress, gamification, payment, and admin
- Service stubs for Phase 1b implementation
- Zod-validated env config, custom error classes
2026-04-08 21:24:15 +08:00