03Account & Sync运行中
StuMate Cloud
给 StuMate 桌面端配套的账号与同步服务。桌面端自己一直是本地优先的, 这个后端只补上「换一台电脑还能接着用」:账号、设备、GitHub 绑定, 以及基于 revision 游标的增量同步。
- Year
- 2026
- Form
- REST / JSON
- Stack
- Next.js · SQLite
- Auth
- Bearer + refresh
01Decisions / 取舍
三个必须先想清楚的问题
01
本地优先,云端只做补充
桌面端自己的 SQLite 永远是权威数据源。云端只负责「换一台电脑还能接着用」,所以任何一次同步失败都不该影响本地使用 —— 断网时照常记课表、写便签。
02
游标增量,而不是全量覆盖
服务端维护一条 revision 流水,客户端存自己的游标。pull 只回 revision 大于游标的部分,hasMore 为真就立刻接着拉;不是首端时会带 replaceLocal 让本地清空重拉。
03
设备是一等公民
每个 access token 都绑定一个 deviceId。设置页能列出所有登录设备并单独解绑;改密以后可以按设备踢人,不用把所有人一起登出。
02Sync / 同步模型
一条流水,一个游标
服务端维护 revision 流水,客户端只存一个数字。比大小就知道该不该拉、 拉多少 —— 不需要维护「谁同步到哪了」这种两边都会写坏的状态。
- cursor本次实际消费到的位置,下次原样传回来
- hasMore为真就立刻接着拉,别等下一轮定时
- replaceLocal不是首端:本地清空后全量重拉
- countsclasses / notes / deleted 三个计数
{
"cursor": 1284,
"is_initial_device": false,
"counts": {
"classes": 26,
"notes": 41,
"deleted": 3
}
}游标校验只收非负整数:`parseInt` 会把 `12abc` 悄悄读成 12, 也会让 `-5` 从未来往回拉。宁可返回 400,也不给客户端一个错游标。
03API / 接口
/api/stumate/v1 下面有什么
POST /auth/register邀请码注册POST /auth/login登录,发 access + refreshPOST /auth/refresh用 refresh 换新 accessPOST /auth/logout注销当前设备POST /auth/password修改密码POST /auth/password/set设置密码(OAuth 用户首次)POST /auth/password/reset-with-code验证码重置GET /auth/invite/check邀请码可用性
GET /me当前账号GET /me/devices登录设备列表DELETE /me/devices/:id解绑指定设备
POST /oauth/:provider/start发起绑定,拿授权地址GET /oauth/:provider/callback浏览器回调GET /oauth/:provider/poll桌面端轮询绑定结果POST /oauth/:provider/bind完成绑定
GET /sync/statuscursor / is_initial_device / countsGET /sync/pull?cursor=N增量拉取,单次上限 500POST /sync/push推送本地变更
Runtime
跟本站同一个 Next 进程
Storage
独立 SQLite(stumate.db)
Health
/api/stumate/v1/health
客户端在 StuMate 桌面端的设置页里登录即可。