Files
stash/HANDOFF.md
T

10 KiB
Raw Blame History

Stash 交接文档

写于 2026-10-29。新会话第一件事:读这份 + docs/ADMIN-PLAN.md + stash-ui/README.md。

0. 一句话现状

Stash 已从「只读本地导航站」升级为可登录、可配置、可编辑内容的本地发布台:

  • 登录(单用户,argon2id + Cookie 会话);
  • /admin 设置页(页头滚动信息 / 首页卡片 / 归类 / 侧栏 / 资料 / 系统);
  • 条目就地编辑(Drawer + 乐观锁);
  • 分区新增/删除/归类编辑、侧栏子分类配置、浏览/点赞/分享/跳转;
  • 数据库自动迁移到 v17;
  • 前端 100% 使用组件库 @stash/ui(v0.3.1,42 个组件)。

当前数据库已设置管理员密码(2026-10-30 由使用者设置);忘记密码按 §6 删除 admin 行即可回到首次设置。

1. 仓库与运行环境

项目 路径 分支 端口 说明
新版(组件重构) D:\CNWei\CNW\Rust\stash feat/use-stash-ui 8080 所有新功能都在这里
旧版(1:1 基线) D:\CNWei\CNW\Rust\stash-old(worktree) develop 8081 只用于视觉对照,不要改
组件库 D:\CNWei\CNW\Rust\stash-ui master — tag v0.1.0 / v0.2.0 / v0.3.0 / v0.3.1

后端:Rust 2024 + Axum 0.8 + rusqlite(bundled)。前端:React 19 + Vite + TS + CSS Modules,@stash/ui 通过 file: 依赖引入。

启动 / 构建(顺序重要)

# 1) 前端(产物会被 build.rs 内嵌,必须先构建)
cd D:\CNWei\CNW\Rust\stash\stash-web
npm run build

# 2) 先杀掉正在运行的 stash.exe,否则 cargo 会报「拒绝访问」
Get-Process stash -ErrorAction SilentlyContinue | Where-Object { $_.Path -like '*stash\target*' } | Stop-Process -Force

# 3) 后端
cd ..
cargo build
Start-Process .\target\debug\stash.exe -RedirectStandardOutput "$env:TEMP\stash.log" -RedirectStandardError "$env:TEMP\stash-err.log" -WindowStyle Hidden

旧版(8081,仅在需要对照时):

D:\CNWei\CNW\Rust\stash-old\target\debug\stash.exe --port 8081

测试

Windows 下 TEMP 权限有问题,跑测试要覆盖临时目录:

$env:TEMP = "D:\CNWei\CNW\Rust\stash\target\tmp"; $env:TMP = $env:TEMP
cargo test        # 当前 48 passed

2. 目录 / 文件地图

src/
  main.rs / lib.rs            启动、日志
  config.rs                   端口 / 数据目录(默认 target/debug/data)
  server.rs                   全部路由(API + 内嵌前端 + SPA 回落)
  error.rs                    StashError(含 Conflict → 409)
  db/
    mod.rs                    Db 门面(所有方法)+ 迁移测试
    schema.rs                 建表、种子、版本迁移(0/15→16→17)
    auth.rs                   管理员、密码哈希、会话(token 只存 sha256)
    settings.rs               settings JSON(header/sidebar/sections/profile)
    entries.rs                条目读取/编辑、浏览数、点赞、审计
    categories.rs             分区新增/删除
    catalog.rs                查询组装(前端三种视图)
stash-web/src/
  App.tsx                     主页壳、登录弹窗、编辑器、设置应用
  main.tsx                    入口分流(/admin 与 /login)
  auth.ts / settings.ts / items.ts   前端 API 客户端
  components/
    header/SiteHeader.tsx     品牌 + 滚动信息 + 操作图标
    admin/AdminPage.tsx       /admin 全部 Tab
    auth/LoginDialog.tsx      Modal 登录
    auth/PasswordInput.tsx    带显隐切换的密码框
    content/                  首页、分区、条目、文章、编辑器
    sidebar/                  资料卡、服务面板、导航
docs/ADMIN-PLAN.md            后台方案 + P0–P4 实施记录 + 未做项
README.md                     运行、路由、库结构、登录说明

3. 功能清单(已完成)

登录

  • 单用户 admin,密码 argon2id;
  • 会话:随机 32 字节 token,HttpOnly + SameSite=Strict + Path=/,7 天,库里存 sha256;
  • 登录失败 5 次锁 60 秒;写接口校验 Origin;写接口需要会话。

/admin

Tab 能力
页头滚动信息 启用开关、速度 8–120、条目增删/排序、标签与色调、占位符 {count} {project} {status}
首页卡片 显示/隐藏、标题覆盖、预览条数、顺序、新增分类、删除分类(不可删的显示灰色按钮)
归类 每个分区的类型(应用/海报/图文)、标题、图标、色条、预览条数;改类型会自动迁移条目归属
侧栏导航 分类显示/隐藏、顺序、删除/新增;应用类分区下的子分类(分组)可单独显隐与排序
资料 头像 URL、名称、角色、简介、位置(应用到侧栏资料卡)
系统 修改密码(清空所有会话)、下载备份(VACUUM INTO 快照)

保存:PATCH /api/settings(version 乐观锁,冲突 409);成功用 Toast(2.4s 自动消失)。

内容编辑

  • 详情页 [编辑] 只在登录后显示;
  • 打开右侧 Drawer:标题、简介、标签、一句话评价、正文 Markdown、封面、跳转地址;
  • PATCH /api/items/{key},updatedAt 乐观锁;
  • 保存后 catalog.reload() 局部刷新,不整页刷新。

详情操作条

  • 浏览:进入页面 POST /api/items/{key}/view,数字 +1;
  • 点赞:可切换,POST /like,localStorage 记住状态;
  • 分享:复制当前链接,Toast 反馈;
  • 跳转:保存时规范化 href(www. 自动补 https://,拒绝 javascript: 等协议);为空或 # 时按钮置灰。

4. HTTP API

GET    /api/health
GET    /api/projects            GET /api/projects/events (SSE)
GET    /api/catalog             GET /api/catalog/events (SSE)

GET    /api/auth/session        -> {authenticated, has_admin, username}
POST   /api/auth/setup          {password}        仅当无管理员
POST   /api/auth/login          {password}
POST   /api/auth/logout
PATCH  /api/auth/password       {current, next}

GET    /api/settings            -> {version, settings}
PATCH  /api/settings            {version, settings}     需登录

GET    /api/items/{key}         -> 原始字段(编辑表单)
PATCH  /api/items/{key}         {updatedAt, item}       需登录
POST   /api/items/{key}/view
POST   /api/items/{key}/like    {liked}

POST   /api/categories          {id,title,kind}         需登录
PATCH  /api/categories/{id}     {title,icon,barColor,kind,previewLimit,emptyText}  需登录
DELETE /api/categories/{id}                             需登录,级联,local 不可删

GET    /api/backup              SQLite 快照附件         需登录

5. 数据库与迁移

  • 文件:开发态在 target/debug/data/stash.db;可用 --root / 数据目录覆盖(见 config.rs)。
  • 当前 PRAGMA user_version = 17;schema::migrate 逐级升级:0 建全量、15→16→17、更高版本拒绝启动。
  • 主要表:node、entry、entry_tag、section_block、admin、session、setting、audit。
  • entry.updated_at 用于编辑乐观锁;setting 表 key='site' 存站点 JSON。
  • 设置/内容都是 SQLite:备份用 /api/backup,恢复需停机替换文件。

6. 认证运维

  • 忘记密码:删除 admin 行(或整库)后重启 → 回到首次设置。
    node -e "const {DatabaseSync}=require('node:sqlite');const d=new DatabaseSync('target/debug/data/stash.db');d.exec('DELETE FROM admin; DELETE FROM session;')"
    
  • 改密码:/admin → 系统,成功后该账号所有会话失效,需要重新登录。
  • 首个管理员由 /api/auth/setup 创建,密码至少 8 位。

7. 组件库 @stash/ui

  • 42 个组件,文档站:cd stash-ui && npm run dev(也可 npm run build:site 后看 dist-site)。
  • 关键命令:npm run typecheck && npm run lint && npm run build && npm run build:site。
  • 组件契约:docs/COMPONENTS.md;设计规范:DESIGN.md;外部风格接入流程:docs/STYLE-INTAKE.md(闸门:截图 → 映射 → 决策 → 评审 → 再写代码)。
  • 主题:themes/example.css 只改变量;页面禁止写组件内部选择器。
  • 判断归属:全局配置放 /admin;页面版式(间距、布局容器)写在页面 CSS;只有「第二个页面也复用」的才抽组件。

8. 验证与截图

  • 后端逻辑:cargo test(48 passed,覆盖迁移/登录/设置/条目编辑/分区)。
  • 前端构建:stash-web npm run build(tsc -b + vite)。
  • 视觉/交互:Playwright 脚本在 stash-ui/.ref/*.mjs(不提交 git),截图在 stash-ui/shots/。
    • measure-final.mjs 已过时(旧 1:1 对照用),选择器 .app header 仍可用;
    • c3-check.mjs、d-check.mjs、p2-check.mjs 是后期功能检查脚本。
  • 常用冒烟:首页卡片、/admin 各 Tab、详情编辑、登录弹窗。

9. 已知限制 / 未做

项 状态
备份恢复/导入 只提供下载快照;恢复需停机替换 stash.db
回收站/软删除 未做,删除分类会级联删条目(有二次确认)
图片上传 只支持 URL;上传需存储目录、大小/类型校验
拖拽排序 用上移/下移按钮替代
多用户/角色 未做,当前单管理员
分区编辑 UI 已支持标题/图标/色条/类型/预览条数(PATCH /api/categories/{id});改类型会自动迁移条目
子分类(分组)管理 侧栏可显隐/排序;还不能新建、改名、删除分组
登录限流 进程内计数,重启清空

10. 约定与坑

  • 回复用中文,表格化优先;视觉工作要截图验证。
  • 任何共享组件改动都要在 docs/COMPONENTS.md 补契约 + changelog,并说明兼容性。
  • PowerShell 写文件注意 UTF-8;优先用编辑工具,别用 Set-Content 写带中文的源码。
  • 改前端后必须 npm run build 再 cargo build,否则内嵌资源是旧的。
  • 重启前先杀 stash.exe,否则 cargo 报「拒绝访问」。
  • /login 是旧地址,main.tsx 会重定向到 /;登录已改为弹窗。
  • 前端路由:/、/c/<分区>、/c/<分区>/<分组>、/c/<分区>/i/<条目>,/admin 独立壳。

11. 新会话建议的下一步

  1. 先跑 cargo test + 打开 8080 冒烟,确认基线;
  2. 若要继续产品化:分组(子分类)的新建/改名/删除、回收站、图片上传、拖拽排序;
  3. 若要发布:确认 stash-ui 以 file: 引入的方式在发布构建里如何锁定版本(建议改为 git tag 依赖或构建前 npm pack)。