Files
Storage/REQUIREMENTS.md
2026-09-26 22:46:15 +08:00

209 lines
12 KiB
Markdown
Raw Permalink 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.
# Storage 个人物品管理 App —— 需求文档
> 版本:v0.1(草稿)
> 日期:2026-09
> 状态:待评审
> 参考实现:D:\workbench\Wardrobe(Tauri 2 + React + TS + Express + DuckDB 架构)
---
## 1. 项目背景与目标
Wardrobe 是一款只管理「衣服」的衣柜 App,其记录、整理、统计分析的能力已被验证。
Storage 将沿用 Wardrobe 的架构与产品理念,但把管理对象从「衣服」扩展到「个人所有物品」。
典型使用场景:
- 搬进新家后,把客厅、卧室、厨房的每件物品登记下来,想找东西时快速定位「在哪个柜子的哪个收纳盒里」。
- 给每一件物品拍照、打标签、记录购买信息与保质期,临期自动提醒。
- 全家共用一份物品账本,谁都想把东西登记进去,但只有管理员能改,避免误删。
- 把物品从「A 家庭(如父母家)」搬到「B 家庭(自己的家)」,盒子整体搬走。
### 1.1 与 Wardrobe 的核心差异
| 维度 | Wardrobe | Storage |
|---|---|---|
| 管理对象 | 仅衣物 | 所有物品 |
| 归属单位 | 个人(user_id 隔离) | 家庭(family_id 隔离,家庭内共享) |
| 收纳体系 | 无(物品平铺) | 无限层级的「盒子」树 + 盒内相对位置 |
| 分类方式 | 固定 6 类枚举 | 家庭可自定义分类 + 自由标签 |
| 权限 | 仅本人 | 管理员(可改)/ 成员(只读) |
| 跨域移动 | 不适用 | 物品与盒子可整体跨家庭转移 |
---
## 2. 产品定位与范围
- **形态**:个人/家庭物品台账 + 收纳可视化定位系统。
- **核心价值**:(1) 分类、定位、一目了然;(2) 家庭共享协作;(3) 物品生命周期记录(购买、保质期、保养)。
- **范围外**(本期不包含):
- 购物、求购、二手交易等电商功能;
- 相机的 AR 识别、AI 自动分类(预留接口,不作为本期承诺);
- 物品维修/送洗的线下对接;
- 多端实时协同编辑(采用服务端为准、前端请求式刷新,不做 CRDT)。
---
## 3. 术语定义
| 术语 | 含义 |
|---|---|
| 家庭(Family) | 一组用户共享的协作空间,是所有物品、盒子、分类的归属单位。物品与盒子在家庭内共享。 |
| 家庭根层(Root) | 家庭内除盒子外的「顶层空间」。物品可以散放在根层,不必须放入盒子。 |
| 盒子(Box) | 收纳容器,可无限嵌套。盒子从属一个家庭,可整体移动/转移。 |
| 子盒(Sub-Box) | 某盒子内部的下一层盒子。 |
| 位置(Position) | 盒子在「父容器」内部的相对坐标(归一化 0~1000),用于将其绘制为父容器内的一块方块。 |
| 物品(Item) | 被管理的具体物件。强绑定一个家庭;可放入任意盒子,也可只在根层。 |
| 管理员 / 成员 | 家庭内的两种角色。管理员可修改,成员只读。 |
| 跨家庭转移(Transfer) | 将物品或整个盒子(含全部子盒与物品)从 A 家庭移动到 B 家庭。 |
---
## 4. 用户与权限
### 4.1 账号体系
- 沿用 Wardrobe:手机号/邮箱 + 验证码登录,Bearer Token 会话(`/api/auth/*`)。
- 验证码:开发期使用固定码 `1111`;上线前接入真实短信/邮件通道(见非功能需求)。
- 一个用户可属于 **多个家庭**,任意时刻「当前家庭」为全局上下文。
### 4.2 家庭
- 用户可 **创建家庭**,创建者为「创建者」并自动成为管理员。
- 用户可 **加入已有家庭**:通过邀请码或管理员邀请(先做邀请码)。
- 用户可 **离开家庭** / 被移除;**创建者可解散家庭**。
- 家庭名、家庭头像(首页家庭切换器展示)。
### 4.3 角色与权限(关键规则)
- 角色仅两级且不限数量:
- **管理员**:可增/删/改家庭内所有物品、盒子、分类;可管理成员(邀请、移除、改角色);可把物品/盒子转移到其他家庭;可解散家庭(仅创建者)。
- **成员**:**只读**。可查看、搜索、筛选、进入盒子查看;不可新增/编辑/删除/转移任何数据。
- 权限 **以服务端校验为准**(每个写接口按 family 角色校验),前端仅做展示层隐藏/禁用。
- 创建者为「超级管理员」,不可被降级或移除;可转让主持权(P2)。
- 成员操作越权时返回 `403`,前端给出「无权限」提示。
---
## 5. 功能需求
优先级标记:`P0` 首版必须 / `P1` 次版 / `P2` 远期可选。
### 5.1 家庭管理(P0)
- FR-家庭-1 创建/加入/离开/解散家庭。
- FR-家庭-2 家庭切换器:全局顶部展示当前家庭,点击切换,切换后所有数据按新家庭重载。
- FR-家庭-3 成员列表与角色管理(管理员操作)。
- FR-家庭-4 邀请码:生成/刷新/失效,凭码加入即成为成员。
- FR-家庭-5 各家庭数据完全隔离:列表、搜索、统计均只返回当前家庭数据。
### 5.2 盒子与收纳(P0)
- FR-盒-1 **无限层级嵌套**:盒子内可再建盒子,深度不设上限(如 客厅 → 柜子1 → 收纳盒x → 内胆)。
- FR-盒-2 盒子的基本属性:名称、图标(emoji)、颜色(自由自定义,可重复)。
- FR-盒-3 **相对位置**:每个盒子在其「父容器」(父盒子或家庭根层)内拥有一个归一化坐标 (x, y),渲染为父容器内的一块方块(如把「柜子1」画在「客厅」左上角)。
- FR-盒-4 进入/退出盒子:通过面包屑导航(家庭 / 客厅 / 柜子1 / 收纳盒x),逐层查看。
- FR-盒-5 盒子内两种视图:**画布视图**(俯视布局,方块按位置摆放,可拖拽改位置)与 **列表视图**(按创建顺序平铺,适合快速浏览)。切换自由。
- FR-盒-6 盒子的增删改、改名;删除盒子时要求确认(提示将删除其中全部物品,P2 提供「合并到上级」选项)。
- FR-盒-7 **整盒移动**:将某盒子(含子树)拖拽/移至另一盒子的内部,或直接移到家庭根层;位置在目标容器内重新指定。
- FR-盒-8 盒子的嵌套统计:每个盒子显示「物品总数(含嵌套)」与「深度」。
- FR-盒-9 画布中允许方块重叠,位置由用户自由摆放;提供「自动整理」按钮(按蛇形序排布,P1)。
### 5.3 物品管理(P0)
- FR-物-1 新增/编辑/删除物品,字段见「物品字段定义」。
- FR-物-2 物品必须属于某家庭;可放入盒子(box_id)或散放在家庭根层(box_id 为空)。
- FR-物-3 物品从一盒移至另一盒 / 移至根层。
- FR-物-4 物品图片:每个物品 0~9 张;拍照与相册上传(桌面/移动端);详情页缩略图 + 大图查看。
- FR-物-5 搜索与筛选(P0):
- 关键字:名称、品牌、型号、备注;
- 筛选:分类、标签、所在盒子(含子树)、是否收藏、数量>0、临期提醒;
- 结果可一键「定位所在位置」(逐层路径,如 客厅>柜子1>收纳盒x)。
- FR-物-6 收藏夹(P0),常用物品置顶。
- FR-物-7 物品生命周期:数量、购买日期/价格、保质期(临期提醒)、开始使用/最近使用(P1)、保养/清洁备注(P1)、借出记录(P2)。
### 5.4 分类与标签(P0)
- FR-类-1 分类为家庭内可自定义列表(管理所有东西,无法预置固定枚举)。允许用户自建分类层级(P1 支持两级,P0 平铺列表即可)。
- FR-类-2 标签(tags):自由多选,一个物品可打多个标签;标签全局共享、由管理员维护。
- FR-类-3 分类/标签的增删改由管理员操作;删除时物品回到「未分类」。
### 5.5 跨家庭移动(P0)
- FR-转移-1 **物品转移**:源家庭管理员可将物品转移到另一个家庭(前置条件:操作者同时是目标家庭成员,防越权散落;精确规则见设计文档 §6.3、§8.1)。
- FR-转移-2 **整盒转移**:含全部子盒与物品,整体移动到目标家庭的某盒子或根层。
- FR-转移-3 转移带审计:记录操作人、时间、源/目标家庭(P1 提供操作日志查询)。
- FR-转移-4 转移后:源家庭不可再看到该项;如无权限目标家庭则不可见。
### 5.6 首页与统计(P0)
- FR-统-1 当前家庭概览:总物品数、盒子总数、直接子盒数量、最大嵌套深度。
- FR-统-2 分类分布(数量、占比);盒子占用 Top N(物品最多的盒子)。
- FR-统-3 待办提醒:即将过期物品(30 天内)、无图物品、散放在根层未整理物品。
- FR-统-4 价值合计(存在 purchase_price 时求和)。
- FR-统-5 最近新增/最近操作列表。
### 5.7 其他
- FR-他-1 全局搜索入口(跨家庭可选,P1)。
- FR-他-2 导出数据(JSON/CSV,P1)。
- FR-他-3 深色模式(P2)。
- FR-他-4 数据备份(服务端磁盘备份 + 可下载快照,P1)。
- FR-他-5 MCP 能力:沿用 Wardrobe 的 MCP 服务,供 AI 助手查询物品位置(P1)。
---
## 6. 物品字段定义
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| 名称 | string | 是 | 用户可见名字 |
| 分类 | category_id | 否 | 家庭自定义分类;为空表示未分类 |
| 标签 | string[] | 否 | 自由标签 |
| 数量 | int | 否 | 默认 1 |
| 品牌/型号 | string | 否 | 便于搜索 |
| 序列号 | string | 否 | P1 |
| 购买日期/价格 | date / number | 否 | 用于统计与价值合计 |
| 保质期/有效期 | date | 否 | 临期提醒依据(可为「无期限」) |
| 图片 | string[] | 否 | 文件路径列表(最多 9 张) |
| 备注 | string | 否 | 自由文本 |
| 是否收藏 | bool | 否 | 默认 false |
| 使用记录 | 见 5.3-FR-物-7 | 否 | P1 |
| 创建/更新时间 | datetime | 否 | 系统生成 |
---
## 7. 非功能需求
| 编号 | 要求 |
|---|---|
| NFR-1 | 性能:家庭内物品 ≤5 万时,列表/搜索/盒子树展开响应 <300ms;盒子树(递归)加载 <500ms。 |
| NFR-2 | 数据安全:服务端为准,所有写接口必须通过家庭角色校验;不得在客户端以任何方式绕过权限。 |
| NFR-3 | 可靠性:DuckDB 单机文件持久化 + 启动迁移机制(schema_version),预留备份。 |
| NFR-4 | 跨端:Windows/macOS 桌面(Tauri)、Android(Tauri)、Web(浏览器),共享同一服务端与前端代码。 |
| NFR-5 | 可部署性:单镜像 Docker 部署(前端静态 + Express API + DuckDB 数据卷),沿用 Wardrobe 的 Gitea Actions 流水线。 |
| NFR-6 | 安全:会话 Token 存储于客户端(localStorage),Token 可撤销;图片路径做鉴权(经 /api 代理读取)。 |
| NFR-7 | 验证码:P0 开发期固定码 1111;上线前接入真实短信 API(预留 channel 抽象)。 |
| NFR-8 | 迁移友好:任何表结构变更通过迁移脚本顺序执行,禁止裸 `CREATE TABLE IF NOT EXISTS` 演进。 |
| NFR-9 | 时区:统一以 UTC 存储,前端本地化展示。 |
---
## 8. 需求优先级汇总
| 优先级 | 范围 |
|---|---|
| **P0(首版)** | 家庭创建/加入/切换;角色权限(管理/只读);物品 CRUD + 图片;盒子无限嵌套 + 相对位置 + 画布/列表视图 + 整盒移动;分类与标签;搜索/筛选/定位;跨家庭转移(物品 + 整盒);首页统计;验证码登录。 |
| **P1(次版)** | 操作日志;自动整理;导出;备份快照;真实短信;使用/保养记录;全局跨家庭搜索;MCP。 |
| **P2(远期)** | 借出记录;分类层级深化;深色模式;转让家庭主持权;AI 自动分类。 |
---
## 9. 验收要点(供评审确认)
1. 未登录不可访问任何业务接口;非家庭成员访问返回 403。
2. 成员对物品/盒子的任何写操作均被服务端拒绝(非仅前端隐藏)。
3. 盒子嵌套(含 3+ 层)下,物品定位路径显示正确;整盒移动后子树物品随迁。
4. 画布中拖拽盒子位置并刷新后位置保持;归一化坐标在 0~1000 内。
5. 物品跨家庭转移后,仅目标家庭可见,源家庭不可见,并留下审计记录。
6. 搜索可命中名称/品牌/标签;「定位」点击后可逐层导航到物品所在盒子。