浏览器 PWA
显示页面、压缩图片、让用户校对、保存游客数据、导出 ICS 和申请通知权限。
frontend/ + public/项目说明书 · 无需先看懂源码
顺着“浏览器 → 主 Worker → 数据库 → 提醒 Worker”理解项目。需要修改功能时,再查对应文件,不必从第一行开始阅读全部代码。
第一部分
显示页面、压缩图片、让用户校对、保存游客数据、导出 ICS 和申请通知权限。
frontend/ + public/提供 API、检查登录、调用 DeepSeek/Resend、校验课表并读写 D1。
src/保存用户确认后的校历、课程、发生时间、提醒设置和推送订阅。
migrations/只从图片提出课程候选,不负责计算真实日期。
隔离第三方格式,未来换模型时尽量不动业务代码。
src/services.py只负责发送邮箱验证码。
第二部分
Learning-in-BJTU-assistant/ ├── frontend/ 浏览器交互的 TypeScript 源码 │ ├── app.ts 页面全部交互逻辑 │ └── rules.ts 浏览器侧周次规则 ├── public/ 浏览器直接访问的静态文件 │ ├── index.html 应用首页结构 │ ├── styles.css 页面视觉样式 │ ├── sw.js 离线缓存和通知展示 │ ├── manifest.webmanifest PWA 安装配置 │ └── app.js 自动生成,不要手改 ├── src/ Python 主 Worker │ ├── main.py API 总入口 │ ├── models.py 数据格式与字段校验 │ ├── services.py DeepSeek 和 Resend 适配器 │ ├── rules.py 日期、单双周、冲突、ICS │ ├── db.py D1 数据访问封装 │ └── security.py 验证码、哈希和随机 ID ├── migrations/ D1 建表脚本 ├── reminder-worker/ 独立提醒 Worker ├── tests/ 自动化规则测试 ├── scripts/ 运维辅助脚本 ├── wrangler.jsonc 主 Worker 部署配置 ├── package.json 构建与测试命令 ├── pyproject.toml Python 依赖 └── README.md 启动和部署说明
frontend/app.ts页面的大脑:保存用户、学期和课程状态;处理图片;调用 API;渲染课表;完成登录、导出和 Push 订阅。
frontend/rules.ts把“1-16周(单)”等文字变成明确周次数组,让格式错误在浏览器里立刻出现。
public/index.html页面骨架。按钮、输入框、课表区和登录弹窗在这里,但按钮点击后的行为不在这里。
public/styles.css控制颜色、间距、手机适配、课程卡片、对话框和本报告的排版。
public/sw.js负责离线缓存;收到 Push 后显示提醒;点击通知后打开网站。
public/app.js自动生成。浏览器实际加载它,但开发时修改 app.ts,再运行 npm run build。
src/main.py后端总入口:FastAPI 路由、中间件、Cookie 鉴权、课表保存事务、数据导出和静态页面返回。
src/models.py数据合同:规定星期、节次、周次、置信度等字段允许什么值,非法数据先被拒绝。
src/services.py外部服务隔离层:调用 DeepSeek/Resend、清理模型 JSON、转换错误,并提供开发模拟识别。
src/rules.py正确性核心:后端周次规则、冲突检测、上海时区日期实例化和 ICS 生成。
src/db.py统一 D1 的 first、all_rows、run、batch,并处理 Cloudflare JS/Python 类型转换。
src/security.py生成验证码和随机 ID,计算 HMAC 哈希,并执行常量时间比较。
migrations/0001_initial.sql创建九张 D1 表。上线后不要重写 0001,新改动应新增 0002、0003。
reminder-worker/src/index.ts每分钟寻找需提醒课程、生成 VAPID 签名、发送 Push、记录结果并清理失效订阅。
wrangler.jsonc声明主 Python Worker、静态资源、D1 和公开环境变量。
reminder-worker/wrangler.jsonc声明每分钟 Cron,并绑定与主 Worker 相同的 D1。
tests/test_rules.py验证后端单双周、冲突、上海时区和 ICS。
tests/frontend.test.mjs验证浏览器侧周次规则,保证前后端理解一致。
第三部分
第四部分
| 表 | 作用 | 核心数据 | 关键约束 |
|---|---|---|---|
users | 账号主体 | 邮箱、创建/删除状态 | 连接会话、学期和课程 |
otp_challenges | 一次性验证码 | 哈希、IP、尝试次数、过期时间 | 10 分钟、最多 5 次 |
sessions | 登录会话 | Token 哈希、过期时间 | 不保存明文 Token |
terms | 校历版本 | 首周周一、周数、时区、作息 | 课程日期计算的根 |
courses | 确认后的课程规则 | 星期、节次、周次、地点 | 不保存原始图片 |
course_occurrences | 实际课程实例 | UTC 开始/结束、第几周 | 提醒和 ICS 使用 |
reminders | 提醒设置 | 提前分钟数、是否启用 | 每门课程一条 |
push_subscriptions | 设备订阅 | endpoint、公钥、auth | 失效后自动停用 |
reminder_deliveries | 投递账本 | 计划时间、状态、错误 | 唯一约束防重复 |
第五部分
| 目标 | 主要文件 | 注意事项 |
|---|---|---|
| 改首页文案或模块顺序 | public/index.html | 按钮行为不在这里 |
| 改颜色、手机布局、弹窗 | public/styles.css | 同时测试手机宽度 |
| 改按钮行为或图片处理 | frontend/app.ts | 之后运行 npm run build |
| 新增 API | src/main.py + models.py | 用户资源必须带 user_id |
| 更换 AI 或邮件服务 | src/services.py | 保持业务层接口稳定 |
| 改单双周或日期 | frontend/rules.ts + src/rules.py | 前后端同时改并补测试 |
| 增加数据库字段 | migrations/0002_*.sql | 不要重写已执行的 0001 |
| 改提醒调度 | reminder-worker/src/index.ts | 保留幂等和订阅清理 |
| 改通知显示 | public/sw.js | 修改后升级 CACHE 名 |
| 改域名或 D1 绑定 | 两份 wrangler.jsonc | D1 ID 必须一致 |
node_modules/、.venv/、.venv-workers/、python_modules/、.wrangler/、.tmp/ 是依赖、缓存或本地数据;public/app.js 是构建产物。
npm run typecheck:类型检查。npm test:前端规则测试。python -m unittest discover -s tests:后端规则测试。npm run build:生成 app.js。npm run db:local:迁移本地 D1。npm run dev:启动完整本地网站。第六部分
先看“总体架构”和“四条功能流程”。需要修改功能时,回到“修改指南”查对应文件;不需要先学完 Python 或 TypeScript。