TinyStudy 是一个面向小型学校、培训班和家庭学习场景的轻量学习卡片 SaaS。它保留 Quizlet 的卡片学习效率,以 Notion 式清晰信息层级组织内容,并用 Duolingo 式即时奖励让学生愿意持续完成练习。
超级管理员创建账号/礼物并调节金币
↓
教师创建或 AI 生成卡片集,设定售价与逐题奖励
↓
学生购买/领取卡片集 → 作答 → 获得金币
↓
金币兑换礼物 → 礼物陈列在礼物房 → 礼物转换钻石
RBAC 使用 User → UserRole → Role → RolePermission → Permission,权限检查只发生在服务端。前端菜单仅用于体验优化,不作为安全边界。
| 角色 | 主要权限 |
|---|---|
SUPER_ADMIN |
系统配置、账号与角色、金币调账、礼物、日志、全量迁移 |
TEACHER |
自己的卡片集、标签、AI、分配学生、结果统计 |
STUDENT |
购买/学习卡片集、金币与钻石、礼物中心和礼物房 |
默认权限采用 资源:动作 命名,如 users:write、sets:read:own、wallet:adjust。管理员可以新增角色并组合权限。
- 所有金币与钻石变动写入
WalletTransaction,余额与账本在同一数据库事务内更新。 - 管理员调账、购买卡片集、作答奖励、兑换礼物、转换钻石均带业务引用,避免重复提交重复发放。
- 卡片集售价扣款发生在购买时;分配给学生的卡片集默认无需重复购买。
- 每道卡片的首次奖励独立配置;
CardRewardProgress按学生与卡片记录历史答对次数,后续答对奖励依次为上一次的 50%,同一学习会话同一道题只结算一次。 - 礼物支持图片与 HTML ZIP。HTML ZIP 必须含
index.html,解压时拒绝路径穿越,预览使用受限iframe sandbox。 - 礼物兑换后进入礼物房;转换钻石后礼物状态变为
CONVERTED,不可再次转换且不再出现在学生礼物房。 - 全量迁移导出包含结构版本、业务数据和礼物资产清单。密码只以哈希形式导出。
apps/web (React 19 + Vite)
├─ routes / role layouts
├─ Zustand auth + UI state
├─ shadcn/ui primitives
└─ typed API client
↓ JWT / JSON / multipart
apps/api (Fastify, Node 22 ESM)
├─ routes: auth/admin/teacher/student/ai
├─ guards: JWT + RBAC + ownership
├─ services: wallet/study/gift/migration/ai
├─ OpenAPI: /docs and /openapi.json
└─ Prisma repository
↓
SQLite (default) or PostgreSQL
+
storage/gifts (image or unpacked HTML)
- 身份域:
User,Role,Permission,UserRole,RolePermission,RefreshToken - 内容域:
StudySet,Card,Tag,StudySetTag,StudySetAssignment,StudySetPurchase - 学习域:
StudySession,Answer,CardRewardProgress - 激励域:
Wallet,WalletTransaction,Gift,UserGift - 平台域:
SystemConfig,AuditLog,AiLog
- 密码使用 bcrypt;访问令牌短时有效,刷新令牌只保存 SHA-256 哈希。
- Fastify schema 校验所有关键请求;JWT、RBAC 和资源所有权逐层校验。
- AI 密钥只在后端配置;AI 输出经过 JSON 截取、Zod 校验与数量限制。
- 上传限制文件大小和 MIME;HTML 礼物 iframe 默认禁止同源、弹窗和顶层导航。
- 登录、调账、账号、礼物、导入等高价值动作写入审计日志。
- 生产环境必须更换 JWT 密钥、启用 HTTPS,并限制
ALLOWED_ORIGINS。
- 开发:Vite
5173+ Fastify3001,Vite 代理/api;两者监听所有网卡以支持局域网访问。 - 单机:构建后 Fastify 同时提供 API、前端静态文件和礼物资产;PM2 守护。
- 容器:一个应用容器,可配 SQLite 持久卷或 PostgreSQL 服务。
- 扩展:多实例时使用 PostgreSQL,并把
storage/替换为 S3/R2 兼容对象存储。
npm run setup 提供交互式安装:选择数据库、填写连接、创建超级管理员、生成安全密钥、初始化表和默认权限。迁移导出/导入位于管理员“系统迁移”,也提供受 RBAC 保护的 API。