Files
FootPrint/README.md
T

156 lines
6.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 足迹 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/<uid>.db 每用户独立 SQLite 档案库
data/blobs/<uid>/ 内容寻址附件存储
```
设计取向:
- **服务器零 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 {
encode zstd gzip
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 <url> <user> <pass> # 部署后冒烟
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)