# 足迹 Footprints > 个人成长档案馆 —— 面向大学生的留痕、检索、量化与多端同步系统。 ![License](https://img.shields.io/badge/license-MIT-blue.svg) ![Node](https://img.shields.io/badge/node-%E2%89%A522.5-green.svg) 平时随手留痕,需要时秒级检索:**大二上学期做过什么?拿过哪些省级奖?志愿时长总共多少?** 评奖评优、综测、简历、入党材料的素材库,也是一台记录成长的时光机。 ## 功能特性 - **留痕本体** —— 自定义记录类型 + 动态表单模板;竞赛、志愿、学生工作、荣誉、证书、科研、实习皆可配;正面/负面、进行中、草稿全留痕 - **秒级检索** —— FTS5 trigram 中文全文搜索 + 多条件筛选 + 保存视图(同一查询一键复用) - **时间线** —— 按学年/月分组的完整回顾 - **学业成绩** —— 学期 GPA/排名、课程成绩、可自定义绩点梯度(grade band)与趋势图 - **成长量化** —— 自定义维度与指标(如志愿时长),统计总览与年度对比 - **附件佐证** —— 图片/文档上传,SHA-256 内容寻址去重 - **多用户云优先** —— 所有数据存服务器,按用户独立 SQLite 档案库;浏览器 / PWA / Windows 桌面三端同源同步 - **管理后台** —— 邀请码全生命周期管理(自定义码、备注、启用/停用、删除、批量生成)、用户列表、注册配额 - **演示模式** —— 内置演示账号 `demo / demo1234`,自动播种 16 条足迹 + 4 学期成绩,开箱即看 - **PWA + 桌面** —— 可安装到桌面/手机;Windows Tauri 安装包;亮/暗双主题 ## 架构 ``` 浏览器 PWA ─┐ Windows 桌面 ─┤ HTTPS + Bearer Token(365 天) 移动端 PWA ─┘ │ ▼ ┌────────────────────────────────┐ │ sync-server(零依赖 Node ≥ 22.5)│ │ node:http + node:sqlite │ │ scrypt 认证 · 邀请码 · LWW 同步 │ └───────────────┬────────────────┘ ▼ data/users/.db 每用户独立 SQLite 档案库 data/blobs// 内容寻址附件存储 ``` 设计取向: - **服务器零 npm 依赖**:仅用 Node 内置模块(`node:http` / `node:sqlite` / `node:crypto`),攻击面与供应链风险极小 - **命令层同源**:Web、桌面、数据播种共用同一份 `app/server/db.mjs` 命令层,同一业务逻辑多处不漂移 - **同步元数据内建**:所有表带 uuid/hlc/origin 列 + oplog,为多端增量同步而生 ## 快速开始(Docker 部署) ```bash git clone https://gitea.linyux.cn/root/FootPrint.git footprints cd footprints/sync-server # 构建 + 启动(数据持久化在 ./data) docker compose -f docker-compose.caddy.yml up -d --build # 国内拉取 node:24-alpine 超时时,换镜像源构建: docker compose -f docker-compose.caddy.yml build \ --build-arg NODE_IMAGE=docker.1ms.run/library/node:24-alpine ``` 反向代理(Caddy 示例,容器网络需与 Caddy 同网): ```caddyfile footprints.example.com { reverse_proxy footprints-sync:8788 } ``` > compose 默认加入名为 `mynet` 的外部网络;没有就先 `docker network create mynet`,或把 compose 里的 networks 段改成你自己的。 首次使用: 1. 打开站点 → 注册 —— **第一个注册的账号自动成为管理员** 2. 管理员登录 → 侧边栏「管理」→ 新建/批量生成邀请码,发给需要注册的用户 3. 人齐之后建议收紧注册:compose 里 `REGISTER_ENABLED=false`(或改掉 `INVITE_CODE` 默认值)再 `up -d` 4. 想先看看界面?用演示账号 **demo / demo1234** 登录,数据管够 ## 本地开发 ```bash # 1) 启动同步服务器(Node ≥ 22.5,推荐 24;零依赖,无需 npm install) cd sync-server PORT=8788 DATA_DIR=./data node src/index.mjs # 2) 前端开发服务 npm install --prefix app # 或 pnpm -C app install npm run dev --prefix app # 3) 让网页版指向本地服务器(浏览器控制台执行一次) localStorage.setItem('fp-server-url', 'http://127.0.0.1:8788') # 4) Windows 桌面安装包(需 Rust + MSVC) pnpm -C app install && pnpm -C app tauri build ``` ## 测试与质量 ```bash node scripts/check.mjs # 语法 + 类型 + 构建 + 关键标记 tripwire node scripts/test-integration.mjs # 35 条集成断言(播种/登录/邀请码全矩阵/角色规则/幂等) node scripts/smoke.mjs # 部署后冒烟 git config core.hooksPath .githooks # 启用 pre-push 钩子:工作区不干净或测试红,push 直接拒绝 ``` ## 项目结构 ``` ├─ app/ # 前端 + 桌面端 │ ├─ src/ # React 19 + Vite + Tailwind v4 UI(三端共用) │ ├─ public/ # PWA:sw.js v3(接口绝不缓存)/ manifest / icons │ ├─ server/ # ★ 命令层 db.mjs:零依赖数据层(37 个命令) │ └─ src-tauri/ # Tauri 2 桌面壳 ├─ sync-server/ # 自建同步服务器 │ ├─ src/ # index/auth/db/sync/attachments(零依赖) │ ├─ www/ # 构建产物(部署时以卷挂载,git pull 即更新) │ └─ docker-compose.caddy.yml ├─ docs/ # api.md(HTTP API)· DESIGN.md(设计底稿)· examples/ ├─ scripts/ # check / test-integration / smoke ├─ tools/ # pnpm.cjs + 图标生成器 ├─ .gitea/ # Issue/PR 模板 ├─ .githooks/ # pre-push 质量门禁(check + 35 条集成断言) └─ .editorconfig ``` ## 环境变量(sync-server) | 变量 | 默认 | 说明 | |---|---|---| | `PORT` | `8788` | 监听端口 | | `DATA_DIR` | `./data` | 数据目录(用户库/附件/同步账本) | | `REGISTER_ENABLED` | `true` | 是否开放注册 | | `INVITE_CODE` | 空 | 静态兜底邀请码(动态码由管理员在管理页生成) | | `MAX_USERS` | `0` | 用户数上限,0 = 不限 | | `WWW_DIR` | `../www` | 前端静态目录 | ## 文档 - [HTTP API 参考](docs/api.md) - [设计方案(v0.5 底稿)](docs/DESIGN.md) —— 项目的原始设计思想;现产品已演进为云优先多用户架构 ## Roadmap - [ ] 附件缩略图 / 上传前压缩 / 大文件分片 - [ ] 评奖评优材料包一键导出 - [ ] 对象存储(S3)适配 - [ ] 端到端加密存储 - [ ] 移动端体验优化(手势、离线编辑队列) - [ ] 英文界面 ## License [MIT](LICENSE)