# 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. 搜索可命中名称/品牌/标签;「定位」点击后可逐层导航到物品所在盒子。