- README: real counts (44 commands, 61 integration asserts, demo=25 records + 4 semesters + 7 attachments), add resume/assessment module features, env vars incl. LSKY, doc navigation table, done-roadmap items checked - docs/api.md: /auth/logout, admin users/demo-rebuild/sync-lsky routes, attachment thumb/download channels, profile_upsert top-key merge semantics, full footprint_list query reference, 44-command table - sync-server/README: replace stale ADMIN_TOKEN/X-Admin-Token admin section (actual is_admin Bearer model), add go-live checklist, backup note for WAL - CHANGELOG: add Unreleased section (resume/assessment modules, security fixes, perf tuning) - CONTRIBUTING: 61 asserts, security-sensitive-change guidance, perf baseline table, security issue routing - docs/SECURITY.md: new - report channel, threat model table, hardening summary, known tradeoffs - LICENSE: ensure MIT file matches README badge
5.4 KiB
5.4 KiB
HTTP API 参考
Base URL:部署域名(如 https://footpr.example.com)。除 /health 与 /auth/register|login 外,
所有接口都鉴权。登录限速:同一 IP + 用户名连续失败 5 次会收到 429,冷却 10 分钟。
统一响应格式:
{ "ok": true, "data": { ... } }
{ "ok": false, "error": "错误原因" }
健康检查
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /health |
存活探针,无需鉴权 |
认证
| 方法 | 路径 | 说明 |
|---|---|---|
| POST | /auth/register |
注册(REGISTER_ENABLED/邀请码/MAX_USERS 门控;首个非 demo 账号自动成为管理员)。请求体里的 seed 标志一律被服务端剥离,仅供内部播种 |
| POST | /auth/login |
登录,返回 Bearer Token(365 天) |
| POST | /auth/logout |
吊销当前 Bearer Token(服务端删除 token 行) |
| GET | /auth/me |
当前用户信息(user_id / username / is_admin / device_id) |
TOKEN=$(curl -s https://footpr.example.com/auth/login \
-H 'content-type: application/json' \
-d '{"username":"demo","password":"demo1234","device_name":"cli"}' | jq -r .data.token)
管理(仅 is_admin 会话)
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /admin/users |
用户列表(设备数/记录数/附件用量),元数据不含档案内容 |
| POST | /admin/users/delete |
删除用户 {"user_id":"..."},级联清理图床/档案库/附件/会话;不能删自己、不能删最后一位管理员 |
| GET | /admin/invites |
邀请码列表(remark、创建者/使用者、valid、holder_gone) |
| POST | /admin/invites/generate |
批量生成随机码 {"count": 5}(1-50) |
| POST | /admin/invites/create |
新建自定义码 {"code":"XIONG-2025","remark":"备注"}(4-32 位字母数字-_) |
| POST | /admin/invites/update |
改备注 / 启停 {"id":1,"remark":"...","valid":false}(已使用的码不可再启用) |
| POST | /admin/invites/delete |
删除 {"id":1} |
| POST | /admin/invites/revoke |
作废(等价 update valid=false,兼容保留) |
| POST | /admin/demo-rebuild |
级联删除现有 demo 并重建、重播种演示数据 |
| POST | /admin/demo-seed |
给 demo 播种演示数据(幂等;档案库非空时返回 seeded:false) |
| POST | /admin/attachments/sync-lsky |
把当前用户全部未上图床的附件批量推送到 Lsky(需配置 LSKY_API/LSKY_TOKEN) |
同步
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /sync/status |
当前用户同步账本统计 |
| POST | /sync/push |
推送 wire 变更(LWW 上/删除,立即生效) |
| GET | /sync/pull?cursor=...&limit=... |
按 seq 游标增量拉取 |
| POST | /sync/attachment |
上传附件 {"sha256","size","mime","file_name","data_b64"}(内容寻址去重,哈希校验) |
| GET | /sync/attachment/<sha256> |
下载附件(Cache-Control: private, immutable) |
附件另有两个业务命令通道:POST /api/attachment_read(base64 全文,含缩略图通道 attachment_thumb)
与 POST /api/attachment_download(直接落盘,Content-Disposition 带原始文件名)。
业务命令层 POST /api/<command>
与桌面端共用同一命令层(app/server/db.mjs),按用户隔离。44 个命令:
| 分组 | 命令 |
|---|---|
| 应用 | app_info · sync_status |
| 记录类型 | type_list · type_upsert · type_delete |
| 字典/维度 | taxonomy_list · taxonomy_upsert · taxonomy_delete · dimension_list · dimension_upsert · dimension_delete |
| 足迹 | footprint_list · footprint_get · footprint_upsert · footprint_delete · timeline |
| 统计 | stats_overview · metric_list · metric_upsert · metric_delete |
| 成绩 | grades_overview · semester_upsert · semester_delete · course_upsert · course_delete · band_upsert · band_delete · gpa_settings_get · gpa_settings_upsert |
| 附件 | attachment_add · attachment_list · attachment_delete · attachment_read · attachment_thumb · attachment_set_remote · attachment_set_thumb |
| 档案 | profile_get · profile_upsert |
| 保存视图 | view_list · view_upsert · view_delete |
| 播种/同步内核 | demo_seed · sync_apply_wire · sync_pull_wire |
profile_upsert 语义
顶层 key 合并:info / resume / zongce 是互相独立的子文档,只更所提交的 key,
其余原样保留(避免三张页面互相覆盖):
{ "info": { "name": "...", "phone": "...", "eduStart": "2023-09" } }
footprint_list 的 query
| 字段 | 说明 |
|---|---|
q |
全文检索(≥3 字符走 FTS5 trigram 子串匹配,短词回退 LIKE) |
year |
起始年份过滤 |
types / levels / roles / statuses |
数组多选过滤 |
dims |
维度多选 |
polarity |
positive / negative |
has_attachment |
仅看有附件记录 |
tag |
标签匹配 |
sort |
date_desc(默认)/ date_asc / updated_desc / weight_desc |
page /page_size |
分页(page_size 上限 2000) |
分页约定
page_size 上限 2000;传非 {query:{...}} 形状的载荷会按默认 20 条处理(客户端请按此约定传参)。
示例(检索记录):
curl -s https://footpr.example.com/api/footprint_list \
-H 'content-type: application/json' -H "authorization: Bearer $TOKEN" \
-d '{"query":{"page":1,"page_size":20,"year":2025}}'