# 进销存系统 **Repository Path**: whkwhk/inventory-management-system ## Basic Information - **Project Name**: 进销存系统 - **Description**: 一个进销存系统,自用的。 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-04-29 - **Last Updated**: 2026-08-15 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 进销存系统 一个独立的进销存系统,面向商品资料、往来单位、仓库、库存流水、采购/销售单据和基础应收应付场景。项目参考常见云进销存的业务结构,但不做全量 ERP 复刻,目标是稳定、易操作、可逐步扩展。 ## 技术栈 - 前端:React + Vite + TypeScript + Ant Design - 后端:NestJS + TypeScript - ORM:Prisma - 数据库:PostgreSQL - 鉴权:JWT + RBAC 基础权限 ## 本地启动 准备本地环境文件: ```powershell cd <项目目录> copy .env.example .env ``` 启动数据库并初始化: ```powershell corepack pnpm install docker compose up -d inventory-postgres corepack pnpm prisma:migrate corepack pnpm db:seed corepack pnpm dev ``` 默认本地访问: - 前端:http://localhost:5173 - 后端健康检查:http://localhost:3000/health - API 地址由 `VITE_API_BASE_URL` 控制 演示账号说明: 演示账号仅用于本地或演示环境。生产环境已禁用默认 demo 账号,正式管理员由部署方在私有环境中创建。不要把生产管理员账号密码写入仓库。 ## 环境变量 公开仓库只保留占位符。复制 `.env.example` 为 `.env` 后按本地或部署环境修改。 关键变量按 `.env.example` 配置,包含数据库连接、数据库账号、服务端口、前后端地址、跨域来源、鉴权密钥和过期时间。公开 README 不列出连接串、密码、密钥或私有环境值。 生产环境要求: - 使用强随机数据库密码。 - 使用强随机鉴权密钥。 - 报价系统单点登录默认关闭;如需灰度开启,部署方必须在私有环境中配置强随机 SSO 密钥,并确认报价系统和进销存系统使用同一组私有密钥。 - 不在 Git 仓库提交 `.env`、私钥、备份文件或生产部署信息。 - 生产部署路径、进程管理、反向代理和证书信息应保存在私有运维文档中。 ## 报价系统单点登录规范 - 报价系统作为身份提供方,进销存系统作为被登录系统。 - 用户登录报价系统后,由报价系统后端校验登录态和进销存授权,再签发短期 SSO 票据。 - 浏览器跳转到 `/inventory/sso?ticket=...`,进销存前端调用 `/inventory-api/auth/quote-sso` 换取进销存 JWT。 - SSO 票据只包含用户 ID、用户名、显示名、角色、签发时间、过期时间和 nonce,不包含密码、访问凭据、数据库连接串或任何私有密钥。 - 进销存后端验证签名、过期时间和 nonce;nonce 只能使用一次,重复使用会拒绝登录。 - SSO 票据建议有效期为 5 分钟;票据不绑定设备 IP、浏览器 UA 或浏览器 session,但仍必须一次性使用。 - 初版权限映射只允许报价系统 `super_admin` 映射为进销存“系统管理员”,其他报价系统角色默认拒绝。 - 本地登录保留为应急入口;生产环境是否展示本地登录入口由部署方私有策略控制。 - 相关环境变量为 `QUOTE_SSO_ENABLED`、`QUOTE_SSO_SECRET`、`QUOTE_SSO_TICKET_TTL_SECONDS`。公开文档只记录变量名,不记录真实值。 ## 中文化和北京时间规范 - 系统面向中国地区用户,所有用户可见页面、弹窗、按钮、表格、提示、导出表头、导出文件名和后端业务 message 必须使用中文。 - 内部代码字段名、数据库 enum、API 字段名可以保持英文;展示给用户前必须映射为中文。 - 状态码和错误码可以保留英文 code,例如 `SOURCE_CHANGED`、`PRODUCT_NOT_MAPPED`、`DRAFT`、`APPROVED`;页面展示必须转换为“来源内容已变化”“商品未映射”“草稿”“已审核”等中文说明。 - 所有用户可见时间统一使用北京时间,日期时间格式为 `YYYY-MM-DD HH:mm:ss`,日期格式为 `YYYY-MM-DD`。 - 页面、导出和日志展示不得出现 UTC、GMT、ISO Z 时间、AM/PM、英文月份或英文星期。 - 前端统一通过中文 locale 和北京时间格式化工具展示时间;后端导出文件名、CSV 日期和业务日志输出也必须按北京时间格式化。 - 生产运行环境建议显式设置 `TZ=Asia/Shanghai`;具体进程、反向代理、服务器路径和私有环境变量只记录在私有运维文档中。 ## 当前阶段 - 当前状态:第 31 阶段,产品主数据统一基础能力。 - 最近完成阶段:第 29 阶段,正式资料导入模板与期初数据准备。 - 最近功能 commit:见 Git 记录。 - 当前阶段边界:只补进销存侧商品主数据集成 API、报价产品迁移 dry-run 和映射规则,不切换报价系统正式选品,不导入 490 条报价产品,不改写历史报价快照。 - 正式产品迁移前必须先完成 dry-run 报告、人工确认清单、数据库备份和用户确认。 - README 维护规则:每个阶段开始和完成时都必须同步更新本文件,并随阶段性提交一起推送。 ## 开发进度总览 | 阶段 | 模块 | 状态 | commit | 是否已部署到私有环境 | 验收状态 | 更新时间 | | --- | --- | --- | --- | --- | --- | --- | | 第 1 阶段 | 项目骨架、Docker PostgreSQL、Prisma、基础布局 | 已完成 | `3578731` / `9170062` | 是 | 已验收 | 2026-04-30 | | 第 2 阶段 | 真实登录、JWT、用户、角色、基础权限、操作日志 | 已完成 | `02f0a23` | 是 | 已验收 | 2026-04-30 | | 第 3 阶段 | 商品、客户、供应商、仓库、基础字典 | 已完成 | `966f9da` | 是 | 已验收 | 2026-04-30 | | 第 4 阶段 | 期初库存过账、库存流水、库存余额表、商品收发明细表 | 已完成 | `7e339f0` | 是 | 已验收 | 2026-04-30 | | 第 5 阶段 | 购货单 | 已完成 | `738f3e4` | 是 | 已验收 | 2026-04-30 | | 第 6 阶段 | 销货单 | 已完成 | `57e02eb` | 是 | 已验收 | 2026-04-30 | | 第 7 阶段 | 购货退货单 / 销货退货单 | 已完成 | `3f82185` | 是 | 已验收 | 2026-04-30 | | 第 8 阶段 | 收款单 / 付款单 / 基础自动核销 | 已完成 | `c630034` | 是 | 已验收 | 2026-04-30 | | 第 9 阶段 | 报表中心 / 首页经营看板 / 基础导出 | 已完成 | `0b3b29b` / `0c9a7e6` | 是 | 已验收 | 2026-05-01 | | 第 10 阶段 | 稳定化 / 权限细化 / 操作便利性优化 | 已完成 | `75b7c7f` | 是 | 已验收 | 2026-05-01 | | 第 11 阶段 | 报价系统集成字段映射 / 接口契约设计 | 已完成设计稿 | `12ed368` | 否 | 设计稿已验收,待契约评审 | 2026-05-03 | | 第 12 阶段 | 外部商品映射 / 只读库存查询 | 已完成 | `7a5f470` / `eaa7c71` | 是 | 已验收 | 2026-05-03 | | 第 13 阶段 | 外部客户映射 / 外部单据幂等映射 | 已完成 | `8a31f93` | 是 | 已验收 | 2026-05-03 | | 第 14 阶段 | 报价成交生成销货单草稿接口 | 已完成 | `3870432` | 是 | 已验收 | 2026-05-03 | | 第 15 阶段 | 集成安全 / 审计 / 开关 / 失败重试策略 | 已完成 | `31988aa` | 是 | 已验收 | 2026-05-03 | | 第 18 阶段 | 报价系统批量只读预检查进销存侧配合 | 已完成 | `78c79f9` / `d64cd4b` | 是 | 进销存侧已线上验证,待报价系统侧接入验收 | 2026-05-03 | | 第 19 阶段 | 全系统中文化和北京时间统一治理 | 已完成 | `a4d07be` / `4239465` | 是 | 已线上验证 | 2026-05-03 | | 第 21 阶段 | 正式上线前全链路回归、数据初始化和使用门槛检查 | 已完成文档和脚本 | 见 Git 记录 | 是 | 线上只读复核通过 | 2026-05-03 | | 第 22 阶段 | 正式启用前生产数据初始化与上线执行准备 | 只读盘点与方案已补充 | 见 Git 记录 | 待部署 | 待线上只读盘点 | 2026-05-03 | | 第 23 阶段 | 正式启用前安全加固、备份验证和账号治理 | 进行中 | 见 Git 记录 | 待部署 | 待线上验证 | 2026-05-04 | | 第 24 阶段 | 正式数据清理与期初初始化 | 进行中 | 见 Git 记录 | 待部署 | 待线上验证 | 2026-05-04 | | 第 26 阶段 | 双系统 SSO 真实灰度联调与最终试运行验收 | 已完成进销存侧准备 | 见 Git 记录 | 是 | 待双系统共同确认 | 2026-05-04 | | 第 27 阶段 | 灰度 SSO + 0 期初内部试运行 | 进行中 | 见 Git 记录 | 待部署 | 待灰度试运行验收 | 2026-05-04 | | 第 28 阶段 | 内部试运行跟踪与试运行数据清理验证 | 进行中 | 见 Git 记录 | 待部署 | 待清理验证 | 2026-05-04 | | 第 29 阶段 | 正式资料导入模板与期初数据准备 | 进行中 | 见 Git 记录 | 待部署 | 待 dry-run 校验 | 2026-05-04 | | 第 31 阶段 | 产品主数据统一基础能力 | 进行中 | 见 Git 记录 | 待部署 | 待联调 dry-run | 2026-05-04 | ## 第 31 阶段进度记录:产品主数据统一基础能力 ### 阶段编号 第 31 阶段 ### 阶段名称 产品主数据统一基础能力 ### 当前边界 - 进销存逐步作为商品、库存和收款结算主系统。 - 本阶段只提供商品主数据集成 API、报价产品迁移 dry-run、字段白名单、扩展字段处理方案和映射规则。 - 报价系统仍使用原产品库,不切换正式选品,不删除报价产品表,不改写历史报价明细快照。 - 本阶段不导入 490 条报价产品,不上线商品新增、编辑、启停写接口,不生成业务单据,不改变库存、应收或应付。 ### 进销存侧接口 - `GET /integration/product-master/products` - `GET /integration/product-master/products/:id` - `GET /integration/product-master/product-categories` - `GET /integration/product-master/units` - `GET /integration/product-master/brands` - `GET /integration/product-master/suppliers` - `GET /integration/product-master/warehouses` - `POST /integration/product-master/import-dry-run` 接口走 JWT/RBAC 和服务间令牌校验。商品返回字段按报价选品白名单控制,不返回成本、库存成本、采购价、服务令牌或私有配置。 商品新增、编辑、启停等写接口不属于第 31 阶段上线范围;用户确认前不会通过配置打开,也不存在可达路由。 ### dry-run 规则 - `sourceType` 默认为 `quote_system`。 - 映射键为 `sourceType + sourceId`。 - 建议商品编码为 `QP-<报价产品ID>`。 - 单位规范化:`平米` 和 `平方米` 统一为 `平方米`。 - dry-run 只返回建议映射、异常统计和人工确认清单,不写数据库。 - 价格异常、重复候选、单位缺失、已存在映射、多个匹配或仅名称匹配但单位不同的商品不能自动创建,必须进入人工确认。 - 商品 API 白名单字段包括商品编号、名称、类别、单位、品牌、规格、条码、图片、零售价、批发价、建议售价、启用状态和北京时间更新时间。 - 商品 API 不返回成本、库存成本、采购价、供应商敏感价格、服务令牌或私有配置。 ### 扩展字段处理方案 - `image_url` 进入进销存商品图片字段。 - `protocol`、`colors`、`color_images`、`color_prices`、`department_type`、`product_type` 作为扩展属性候选随 dry-run 返回,正式迁移前由业务人工确认,不在本阶段写库。 - `usage_count` 仅作为报价系统历史快照和统计字段保留,不迁移为进销存商品主字段。 - 本阶段不新增数据库结构,不导入报价 490 条产品,不改变进销存 0 期初数据基线。 ### 正式迁移准备 - 已补充正式导入前准备设计:`docs/integration/product-master-formal-migration-preparation.md`。 - 最新远程 dry-run 已确认 490 条真实报价产品可返回 201;其中 `create_new=458`、`conflict=32`、有效颜色字段 374。 - 当前 458 条仅为可自动导入候选,不代表可立即写库;商品类别和单位基础资料必须先补齐。 - 32 条冲突项必须进入人工确认表,未确认前不得进入 apply。 - 正式 apply 仍默认关闭,必须在用户确认、备份验证、批次号和回滚方案明确后另行实现或执行。 ### 第 32 阶段产品正式导入执行器 - 已新增受控运维执行器:`corepack pnpm apply:product-master`。 - 执行器文档:`docs/integration/product-master-apply-executor.md`。 - 默认只生成导入计划报告,不写数据库。 - 正式执行必须同时提供人工确认文件、批次号、`--execute` 参数,并设置 `ALLOW_PRODUCT_MASTER_APPLY=1` 和批次确认环境变量。 - 写入范围仅限商品主数据和外部商品映射;不写库存、应收、应付、购销单据和操作日志,不修改报价系统。 - 回滚支持先 dry-run,再在显式开关下按批次回滚;如商品已有业务引用,禁止自动删除并输出阻断清单。 ### 第 33 阶段产品正式导入确认包 - 已生成确认包目录:`docs/integration/stage33-product-master-confirmation/`。 - 存档报告:`stage33-product-master-formal-import-confirmation.md`。 - 人工确认草案:`stage33-manualDecisions-draft.json`。 - 当前草案不可直接执行:`confirmedBy`、`confirmedAt` 留空,`autoCreateCandidatesConfirmed=false`。 - 32 条冲突项草案建议全部独立创建,但必须继续业务人工确认。 - 458 条自动创建候选中,232 条字段较完整但仍被基础资料阻断;226 条因规格为空、缺图或单位归一仍需确认或暂缓。 - 当前可执行正式 apply 数量为 0;未写商品、未生成外部商品映射、未切换报价选品来源。 ### 第 34 阶段正式导入前置补齐与可执行清单收敛 - 已生成收敛目录:`docs/integration/stage34-product-master-readiness/`。 - 收敛报告:`stage34-product-master-readiness-report.md`。 - 最终可执行清单 / 阻断清单:`stage34-product-master-executable-blocking-list.md`。 - 当前仍无可直接执行项,正式 apply 仍应保持关闭。 - 232 条基础资料阻断项在分类与单位补齐后可重新进入评估。 - 32 条冲突项仍保持人工确认,不自动合并。 - 226 条暂缓项仍需规格、图片或单位归一策略确认。 ## 第 29 阶段进度记录:正式资料导入模板与期初数据准备 ### 阶段编号 第 29 阶段 ### 阶段名称 正式资料导入模板与期初数据准备 ### 当前边界 - 本阶段只准备 CSV 模板、正确样例、错误样例、dry-run 校验脚本和导入说明。 - 本阶段不执行正式导入,不写入数据库,不生成购销单据,不改变库存余额、库存流水、应收或应付。 - 正式导入前必须先完成数据库完整备份、备份可读性验证、用户确认和回滚方案确认。 - 模板统一使用中文表头和 UTF-8 编码,业务日期使用北京时间日期格式 `YYYY-MM-DD`。 ### 模板清单 - 仓库资料:`docs/import-templates/templates/warehouses.csv` - 供应商类别:`docs/import-templates/templates/supplier-categories.csv` - 供应商资料:`docs/import-templates/templates/suppliers.csv` - 客户类别:`docs/import-templates/templates/customer-categories.csv` - 客户资料:`docs/import-templates/templates/customers.csv` - 商品类别:`docs/import-templates/templates/product-categories.csv` - 单位:`docs/import-templates/templates/units.csv` - 品牌:`docs/import-templates/templates/brands.csv` - 商品资料:`docs/import-templates/templates/products.csv` - 期初库存:`docs/import-templates/templates/opening-stocks.csv` - 期初应收:`docs/import-templates/templates/opening-receivables.csv` - 期初应付:`docs/import-templates/templates/opening-payables.csv` ### dry-run 校验 不传 `--base` 时,默认校验 `docs/import-templates/samples/valid`。正式资料校验必须显式传入实际模板目录。 ```powershell corepack pnpm validate:formal-import -- --base docs/import-templates/samples/valid --json ``` 错误样例校验: ```powershell corepack pnpm validate:formal-import -- --base docs/import-templates/samples/invalid --json ``` ### 校验原则 - 编号、名称、商品单位、商品类别、默认供应商、首选仓库、期初库存商品和仓库、期初应收客户、期初应付供应商必须可解释。 - 仓库、供应商、客户、商品编号不能重复;同一商品同一仓库期初库存不能重复。 - 期初数量、期初成本单价、期初应收、期初应付不能小于 0。 - 金额最多保留 2 位小数,数量和成本单价最多保留 4 位小数。 - 品牌默认按必须存在处理;如需自动创建品牌,必须在 dry-run 和正式导入前显式确认。 - 手机只做弱校验,异常作为 warning 输出,由业务人工复核。 ## 第 28 阶段进度记录:内部试运行跟踪与试运行数据清理验证 ### 阶段编号 第 28 阶段 ### 阶段名称 内部试运行跟踪与试运行数据清理验证 ### 试运行规则 - 所有试运行新增资料、单据编号或备注必须包含 `TRIAL20260504`。 - 试运行数据只用于流程熟悉和稳定性验证,不作为正式经营账。 - 不录入真实库存、真实应收或真实应付。 - SSO 用户映射保留用于灰度登录,试运行清理脚本不删除 `quote_system` 用户映射。 ### 清理验证规则 - `corepack pnpm audit:production-data` 用于只读审计试运行前缀和异常无前缀数据。 - `corepack pnpm cleanup:production-data` 默认 dry-run,只识别 `TRIAL20260504` 前缀数据,不写入、不删除。 - 真实清理必须先完成数据库备份,并显式设置清理开关、确认前缀和备份校验信息。 - 清理脚本只删除带试运行前缀的数据,保护正式管理员、系统角色权限、SSO 用户映射和无前缀 0 期初基线。 ## 第 27 阶段进度记录:灰度 SSO + 0 期初内部试运行 ### 阶段编号 第 27 阶段 ### 阶段名称 灰度 SSO + 0 期初内部试运行 ### 当前策略 - SSO 仅对部署方确认的管理员或测试人员灰度开放,不全量开放。 - 进销存保持 0 期初,不补录正式期初库存、期初应收或期初应付。 - 内部试运行只用于熟悉流程和验证系统稳定性,试运行数据不作为正式账。 - 进销存本地管理员登录保留为应急入口,演示账号不启用。 - 试运行期间新增业务数据必须使用 `TRIAL20260504` 前缀,避免混入正式资料。 ### 数据清理边界 - 只读盘点脚本会识别 `TRIAL20260504` 前缀并列入试运行数据风险。 - 生产清理脚本会把 `TRIAL20260504` 纳入已知测试前缀统计,真实清理仍必须先备份并显式开启清理开关。 - 正式经营前必须清理试运行数据,再导入正式基础资料、期初库存、期初应收和期初应付。 ## 第 24 阶段进度记录:正式数据清理与期初初始化 ### 阶段编号 第 24 阶段 ### 阶段名称 正式数据清理与期初初始化 ### 当前进度 - 已修正公开 README 中默认演示账号说明,生产环境不再声明默认演示账号可用。 - 本阶段会新增生产清理初始化脚本,默认 dry-run,只输出影响范围、数量和样例。 - 真实清理必须显式设置生产清理开关,并在执行前校验第 23 阶段备份文件和校验值。 - 没有用户提供正式资料清单时,只初始化最小可用正式资料模板,并明确后续需要业务补全字段。 ### 清理原则 - 测试单据、回归单据、联调草稿和演示映射必须清理或归档。 - 当前库存余额全部作废重录,清理后库存余额必须能由正式期初流水重算。 - 当前未结应收应付全部作废重录,清理后往来余额必须能由正式期初或正式单据解释。 - 不保留无法解释来源的库存流水、应收或应付。 - 不修改报价系统。 ### 初始化原则 - 初始化顺序为:单位、品牌、类别、仓库、供应商、客户、商品、期初库存、期初应收、期初应付。 - 最小模板只用于系统正式启用前占位和流程验证,不代表完整业务资料。 - 正式使用前仍需业务提供完整商品、客户、供应商、仓库、期初库存、期初应收和期初应付清单。 ### 新增脚本 ```powershell corepack pnpm cleanup:production-data ``` 默认只做 dry-run。真实执行必须显式设置生产清理开关。 ## 第 23 阶段进度记录:正式启用前安全加固、备份验证和账号治理 ### 阶段编号 第 23 阶段 ### 阶段名称 正式启用前安全加固、备份验证和账号治理 ### 当前进度 - 已明确本阶段不清理测试数据、不初始化正式期初,只处理安全配置基线、数据库备份验证、正式管理员和演示账号治理。 - 已新增正式启用安全加固记录文档,用于记录备份、账号、运行环境和验证要求。 - 执行顺序必须为:完整备份、备份可读性验证、必要的恢复演练、账号治理、运行环境加固、仅重启进销存 API、上线验证。 ### 执行边界 - 未完成备份验证前,不允许执行数据清理或批量修正。 - 不执行测试数据清理。 - 不录入正式期初库存、期初应收或期初应付。 - 不修改报价系统。 - 不使用批量重启命令。 - 涉及密码、密钥、数据库连接和联动鉴权凭据的内容只在私有运行环境处理,不写入公开文档。 ### 新增文档 - [正式启用安全加固记录](docs/operation/security-hardening-record.md) ### 下一阶段入口条件 - 数据库完整备份已生成并验证可读。 - 正式管理员可登录并具备完整权限。 - 演示账号已禁用或完成强密码、降权和演示数据重置权限移除。 - 运行环境显式使用北京时间。 - 健康检查、核心页面和关键鉴权接口验证通过。 ## 第 22 阶段进度记录:正式启用前生产数据初始化与上线执行准备 ### 阶段编号 第 22 阶段 ### 阶段名称 正式启用前生产数据初始化与上线执行准备 ### 当前进度 - 已新增生产数据只读盘点脚本,覆盖账号权限、基础资料、期初库存、库存流水和余额、购销退收付、集成映射、集成调用日志、操作日志和运行配置风险。 - 已新增生产数据盘点、正式启用切换、测试数据清理三份运维方案文档。 - 已明确本阶段第一步只做盘点和方案,不直接清理数据,不初始化生产数据。 - 已明确如后续需要执行任何清理或初始化,必须先完成数据库完整备份、备份文件可读性验证和恢复演练方案确认。 ### 新增脚本 ```powershell corepack pnpm audit:production-data ``` 该脚本默认只读,不执行写入、更新或删除;输出数据数量、疑似测试数据数量、账号风险、环境风险和清理建议,不输出数据库连接串、密码、密钥或鉴权凭据。 ### 新增文档 - [生产数据只读盘点说明](docs/operation/production-data-audit.md) - [正式启用切换计划](docs/operation/production-cutover-plan.md) - [测试数据清理方案](docs/operation/test-data-cleanup-plan.md) ### 执行边界 - 未备份前禁止清理或初始化生产数据。 - 不自动清空正式数据。 - 不修改数据库结构。 - 不改变已验收业务规则。 - 不修改报价系统。 - 仅新增只读脚本和通用方案文档时不需要重启服务。 ### 剩余风险 - 正式上线前仍需用户确认演示账号处理策略、正式管理员账号、测试数据清理范围、正式基础资料、期初库存、期初应收应付和备份恢复方案。 - 只读脚本识别出的疑似测试数据只是风险线索,不应直接作为删除依据。 ## 第 21 阶段进度记录:正式上线前全链路回归、数据初始化和使用门槛检查 ### 阶段编号 第 21 阶段 ### 阶段名称 正式上线前全链路回归、数据初始化和使用门槛检查 ### 当前进度 - 已新增写入型全链路回归脚本,覆盖基础资料、期初库存、购货、销货、退货、收付款核销、报表导出、权限、操作日志和报价集成预检查。 - 已新增上线只读检查脚本,覆盖健康检查、演示账号登录、未登录 401、预检查敏感字段、报表导出中文文件名、日志查询和核心页面访问。 - 已补充正式上线检查清单、正式数据初始化方案、备份和回滚方案。 - 已明确正式环境不自动清空数据;写入型回归默认只允许本地或演练环境执行。 - 已明确演示账号、默认密码、正式管理员、测试数据、期初库存、期初应收应付、负库存策略、移动加权平均成本、备份策略和北京时间运行环境都必须在正式使用前确认。 ### 新增脚本 ```powershell corepack pnpm regression:full-chain corepack pnpm check:go-live ``` `regression:full-chain` 默认干跑,不写入数据;如需执行写入型回归,必须显式设置 `REGRESSION_ALLOW_WRITE=1`。非本机演练环境还需设置 `REGRESSION_ALLOW_REMOTE=1`,避免误向正式环境写入测试数据。 ### 新增文档 - [全链路回归说明](docs/acceptance/full-chain-regression.md) - [正式上线检查清单](docs/operation/go-live-checklist.md) - [正式数据初始化方案](docs/operation/data-initialization.md) - [备份和回滚方案](docs/operation/backup-and-rollback.md) ### 验收要求 - 本地构建、类型检查和 Prisma schema 校验通过。 - 写入型全链路回归在本地或演练环境可复现。 - 正式环境只读检查通过。 - 正式使用前完成账号、密钥、演示数据、正式基础数据、期初库存、期初往来、备份和回滚负责人确认。 ### 剩余风险 - 写入型全链路回归会创建带前缀的验收数据,不建议直接在正式环境执行。 - 正式上线前仍需业务负责人确认是否保留演示账号、是否保留测试草稿以及是否清理历史测试单据。 - 数据库备份和恢复验证需要在真实运维环境完成,公开仓库只记录通用流程。 ## 第 19 阶段进度记录:全系统中文化和北京时间统一治理 ### 阶段编号 第 19 阶段 ### 阶段名称 全系统中文化和北京时间统一治理 ### 当前进度 - 已完成所有重点页面中文化治理,包括外部单据映射、外部单据映射详情弹窗、集成调用日志、报表中心、操作日志、外部客户映射、外部商品映射和报价销货草稿预检查相关展示。 - 已统一前端时间展示工具,所有用户可见日期时间按北京时间展示。 - 已统一状态码、错误码、来源类型、单据类型、集成结果和操作日志动作的中文展示。 - 已收口后端导出、日志返回、报表日期和业务提示的中文展示。 - 已补充生产运行环境建议使用 `Asia/Shanghai` 的通用说明;公开 README 不记录具体服务器路径、进程名称、反向代理配置、私有环境变量、数据库密码或鉴权凭据。 ### 验收结果 - 本地前后端构建、前端类型检查、Prisma schema 校验和北京时间脚本验证通过。 - 私有环境健康检查、演示账号登录、重点页面访问、日志日期格式、报表日期格式和预检查未登录鉴权验证通过。 - 英文残留扫描未发现重点旧英文界面短语;代码字段名、接口字段名、枚举、变量名和第三方库内部文本按规则保留。 - 部署只涉及进销存系统;运行时代码部署时仅重启进销存 API 服务,未重启或修改报价系统。 ### 剩余风险 - 低频弹窗和边缘异常提示仍建议后续用端到端截图巡检持续覆盖。 - 前端构建仍有既有大包体提示,后续可通过路由懒加载优化。 ## 已完成模块 ### 登录、用户、角色、权限 - 真实登录接口。 - JWT 鉴权。 - 当前用户接口。 - 退出登录。 - 用户、角色、权限点基础管理。 - 用户角色绑定、角色权限绑定。 - 操作日志记录登录、退出和权限相关变更。 ### 基础资料 - 商品资料。 - 客户资料。 - 供应商资料。 - 仓库资料。 - 商品类别。 - 客户类别。 - 供应商类别。 - 计量单位。 - 品牌。 ### 库存基础 - 期初库存录入。 - 期初库存过账。 - 库存流水 `stock_movements`。 - 库存余额 `stock_balances`。 - 库存余额表。 - 商品收发明细表。 - 库存余额重算基础能力。 ### 购货单 - 购货单列表。 - 新增购货单草稿。 - 编辑草稿购货单。 - 删除草稿购货单。 - 查看购货单详情。 - 审核购货单。 - 审核后生成 `PURCHASE` 库存流水。 - 审核后更新库存余额和移动加权平均成本。 - 审核后生成供应商应付。 - 商品收发明细表支持查询购货入库流水。 ### 销货单 - 销货单列表。 - 新增销货单草稿。 - 编辑草稿销货单。 - 删除草稿销货单。 - 查看销货单详情。 - 审核销货单。 - 默认禁止负库存。 - 审核后生成 `SALE` 库存流水。 - 审核后减少库存余额和成本金额。 - 审核后生成客户应收。 - 商品收发明细表支持查询销货出库流水。 ### 退货单 - 购货退货单列表。 - 购货退货单草稿新增、编辑、删除、详情查看和审核。 - 购货退货审核后写入 `PURCHASE_RETURN` 库存流水。 - 购货退货审核后减少库存余额和库存成本。 - 购货退货审核后生成供应商应付负数冲减记录。 - 销货退货单列表。 - 销货退货单草稿新增、编辑、删除、详情查看和审核。 - 销货退货审核后写入 `SALE_RETURN` 库存流水。 - 销货退货审核后增加库存余额和库存成本。 - 销货退货审核后生成客户应收负数冲减记录。 - 商品收发明细表支持查询购货退货和销货退货流水。 ### 收付款核销 - 收款单列表。 - 收款单草稿新增、编辑、删除、详情查看、自动核销和审核。 - 付款单列表。 - 付款单草稿新增、编辑、删除、详情查看、自动核销和审核。 - 客户应收未结明细查询。 - 供应商应付未结明细查询。 - 自动核销按往来单位筛选正数未结记录,并按单据日期和创建时间从早到晚分配。 - 草稿和自动核销草稿不影响应收/应付余额。 - 审核后更新应收/应付的已核销金额和余额。 - 审核接口幂等,重复审核不重复扣减余额。 ### 报表中心与首页看板 - 首页经营看板。 - 首页待办事项。 - 首页库存预警。 - 经营汇总报表。 - 库存余额报表增强。 - 商品收发明细报表。 - 客户应收汇总表和明细表。 - 供应商应付汇总表和明细表。 - 库存、收发明细、应收、应付、经营汇总 CSV 导出。 - 导出文件使用 UTF-8 BOM,中文表头可直接用表格软件打开。 ### 稳定化、权限细化与操作便利性 - 后端接口级权限强制校验。 - 前端菜单和按钮按当前用户权限过滤或禁用。 - 操作日志分页、筛选、详情和 CSV 导出。 - 演示数据状态只读接口。 - 受保护的演示数据 reset 脚本。 - 审核、删除、自动核销、导出、库存过账和库存重算操作防重复提交。 - 删除和审核二次确认。 - 表单明细行删除二次确认。 - 统一网络异常和后端中文错误提示。 ### 报价系统集成契约设计 - 新增集成设计文档:`docs/integration/quote-inventory-field-mapping.md`。 - 完成报价系统产品到进销存商品的字段映射设计。 - 完成报价客户到进销存客户的字段映射设计。 - 完成报价成交生成销货单草稿的字段映射和接口契约。 - 完成报价明细到销货单明细的字段映射设计。 - 完成配货任务到后续出库草稿 / 库存占用的契约草案。 - 完成施工增减项到后续销货草稿、销货退货草稿和采购建议的契约草案。 - 明确商品映射不共享数据库、不依赖双方内部 ID,建议使用外部映射表。 - 明确只读库存查询契约不返回成本价、不改变库存。 - 明确本阶段未做真实联动、未新增运行时代码、未修改报价系统。 ## 第 5 阶段完成记录:购货单 ### 阶段编号 第 5 阶段 ### 阶段名称 购货单开发 ### 已完成内容 - 购货单列表。 - 新增购货单草稿。 - 编辑草稿购货单。 - 删除草稿购货单。 - 查看购货单详情。 - 审核购货单。 - 审核后生成 `PURCHASE` 库存流水。 - 审核后更新 `stock_balances`。 - 审核后按移动加权平均更新库存成本。 - 审核后生成供应商应付 `payable_entries`。 - 商品收发明细表支持筛选 `PURCHASE / 购货入库`。 - 审核接口幂等,重复审核不重复生成库存流水或应付。 - 已审核购货单禁止编辑和删除。 ### 新增页面 - `/app/purchase-bills`:购货单列表、草稿新增/编辑、详情查看、审核操作。 - 商品收发明细表:新增 `购货入库` 业务类型筛选。 ### 新增接口 - `GET /purchase-bills` - `POST /purchase-bills` - `GET /purchase-bills/:id` - `PATCH /purchase-bills/:id` - `DELETE /purchase-bills/:id` - `POST /purchase-bills/:id/approve` ### 数据库变更 - 无新增 migration。 - 复用已有表: - `purchase_bills` - `purchase_bill_items` - `stock_movements` - `stock_balances` - `payable_entries` - Seed 增加 `purchase_bills:*` 权限点。 ### 核心业务规则 - 草稿单据不影响库存和账款。 - 购货单审核后增加库存。 - 购货单审核后生成供应商应付。 - 库存变化必须写入 `stock_movements`。 - 当前库存由 `stock_balances` 保存,并可由库存流水重算。 - 成本算法使用移动加权平均。 - 审核接口必须幂等。 ### 测试结果 本地代码验证: - `corepack pnpm build` 通过。 - `corepack pnpm exec prisma validate --schema api/prisma/schema.prisma` 通过。 - `node --check api/prisma/seed.js` 通过。 接口和页面验证: - 健康检查通过。 - 未登录访问受保护接口返回 401。 - 演示账号登录成功。 - 创建草稿购货单成功。 - 草稿阶段未生成 `PURCHASE` 流水。 - 草稿阶段库存余额未变化。 - 编辑草稿成功。 - 审核成功,生成 `PURCHASE` 库存流水。 - 重复审核返回 `alreadyApproved=true`,未重复入账。 - 审核后库存数量和库存成本按明细增加。 - 审核后生成供应商应付。 - 已审核后编辑返回 400。 - 已审核后删除返回 400。 - 浏览器自动化覆盖登录、打开购货单页面、刷新保持登录、退出登录、未登录访问自动跳转登录页。 ### 线上部署状态 已部署到私有环境并完成验证。公开 README 不展示真实域名、服务器路径、进程名称、反向代理配置、数据库密码或密钥。 ### 当前 commit `738f3e4 feat: add purchase bill module` ### 剩余风险 / 下一阶段任务 - 细粒度按钮权限尚未做强制拦截,当前以 JWT 鉴权为主。 - 历史日期插单后的成本重算规则尚未实现。 - 下一阶段建议开发销货单:保存草稿、审核出库、默认禁止负库存、生成客户应收。 ## 第 6 阶段完成记录:销货单 ### 阶段编号 第 6 阶段 ### 阶段名称 销货单开发 ### 已完成内容 - 销货单列表。 - 新增销货单草稿。 - 编辑草稿销货单。 - 删除草稿销货单。 - 查看销货单详情。 - 审核销货单。 - 审核前默认禁止负库存。 - 审核后生成 `SALE` / 销货出库库存流水。 - 审核后减少 `stock_balances.quantity` 和 `stock_balances.cost_amount`。 - 审核后按当前移动加权平均成本写入销货明细成本。 - 审核后生成客户应收 `receivable_entries`。 - 商品收发明细表支持筛选 `SALE / 销货出库`。 - 审核接口幂等,重复审核不重复生成库存流水或客户应收。 - 已审核销货单禁止编辑和删除。 ### 新增页面 - `/app/sales-bills`:销货单列表、草稿新增/编辑、详情查看、审核操作。 - 商品收发明细表:新增 `销货出库` 业务类型筛选。 - 首页概览:更新为购销主链基础阶段提示。 ### 新增接口 - `GET /sales-bills` - `POST /sales-bills` - `GET /sales-bills/:id` - `PATCH /sales-bills/:id` - `DELETE /sales-bills/:id` - `POST /sales-bills/:id/approve` ### 数据库变更 - 无新增 migration。 - 复用已有表: - `sales_bills` - `sales_bill_items` - `stock_movements` - `stock_balances` - `receivable_entries` - Seed 增加 `sales_bills:*` 权限点。 ### 核心业务规则 - 草稿销货单不影响库存和应收。 - 审核销货单时按商品和仓库聚合校验库存。 - 当前阶段默认禁止负库存,库存不足返回明确错误。 - 审核成功后写入 `SALE` 出库流水。 - 出库成本使用审核时 `stock_balances.avgCost`。 - 出库后库存余额数量减少,成本金额按出库成本减少。 - 审核成功后生成客户应收,金额为 `商品金额 - 优惠金额 - 已收金额`。 - 重复审核已审核单据返回幂等结果,不重复出库、不重复生成应收。 ### 测试结果 本地代码验证: - `corepack pnpm exec prisma validate --schema api/prisma/schema.prisma` 通过。 - `corepack pnpm --filter @inventory/api build` 通过。 - `corepack pnpm --filter @inventory/web build` 通过。 - `corepack pnpm build` 通过。 - `node --check api/prisma/seed.js` 通过。 - `git diff --check` 通过。 - 本地开发机未安装 Docker 命令,数据库接口级验证放在线上独立进销存环境完成。 线上功能验证: - 健康检查返回 200。 - 未登录访问销货单接口返回 401。 - `演示账号` 登录成功。 - 草稿新增、编辑、删除成功。 - 草稿阶段未生成 `SALE` 流水,库存余额未变化。 - 审核成功后生成 `SALE` 出库流水。 - 审核成功后库存数量减少,库存成本金额减少。 - 审核成功后生成客户应收。 - 重复审核返回 `alreadyApproved=true`,`SALE` 流水数量保持 1。 - 已审核后编辑返回 400。 - 已审核后删除返回 400。 - 库存不足审核返回 409,并显示商品、仓库、当前库存、需要数量和缺口。 - 浏览器自动化覆盖登录、打开销货单页面、刷新保持登录、退出登录、未登录访问自动跳回登录页。 - 报价系统关键页面复测正常。 ### 线上部署状态 已部署到私有环境并完成验证。公开 README 不展示真实域名、服务器路径、进程名称、反向代理配置、数据库密码或密钥。 ### 当前 commit `57e02eb feat: add sales bill module` ### 剩余风险 / 下一阶段任务 - 细粒度按钮权限尚未做强制拦截,当前以 JWT 鉴权为主。 - 并发极高时的库存扣减冲突依赖数据库事务隔离处理,后续可增加更细的重试策略。 - 历史日期插单后的成本重算规则尚未实现。 - 下一阶段建议开发购货退货单和销货退货单。 ## 第 7 阶段完成记录:购货退货单 / 销货退货单 ### 阶段编号 第 7 阶段 ### 阶段名称 购货退货单 / 销货退货单开发 ### 已完成内容 - 购货退货单列表。 - 购货退货单新增草稿、编辑草稿、删除草稿、查看详情、审核。 - 购货退货审核后减少库存。 - 购货退货审核后生成 `PURCHASE_RETURN` 库存流水。 - 购货退货审核后生成供应商应付负数冲减记录。 - 销货退货单列表。 - 销货退货单新增草稿、编辑草稿、删除草稿、查看详情、审核。 - 销货退货审核后增加库存。 - 销货退货审核后生成 `SALE_RETURN` 库存流水。 - 销货退货审核后生成客户应收负数冲减记录。 - 商品收发明细表支持筛选 `PURCHASE_RETURN / 购货退货` 和 `SALE_RETURN / 销货退货`。 - 审核接口幂等,重复审核不重复生成库存流水或往来冲减记录。 - 已审核退货单禁止编辑和删除。 ### 新增页面 - `/app/purchase-return-bills`:购货退货单列表、草稿新增/编辑、详情查看、审核操作。 - `/app/sales-return-bills`:销货退货单列表、草稿新增/编辑、详情查看、审核操作。 - 商品收发明细表:新增 `购货退货`、`销货退货` 业务类型筛选。 - 首页概览:更新为购销退货主链阶段提示。 ### 新增接口 - `GET /purchase-return-bills` - `POST /purchase-return-bills` - `GET /purchase-return-bills/:id` - `PATCH /purchase-return-bills/:id` - `DELETE /purchase-return-bills/:id` - `POST /purchase-return-bills/:id/approve` - `GET /sales-return-bills` - `POST /sales-return-bills` - `GET /sales-return-bills/:id` - `PATCH /sales-return-bills/:id` - `DELETE /sales-return-bills/:id` - `POST /sales-return-bills/:id/approve` ### 数据库变更 - 无新增 migration。 - 复用已有表: - `purchase_return_bills` - `purchase_return_bill_items` - `sales_return_bills` - `sales_return_bill_items` - `stock_movements` - `stock_balances` - `payable_entries` - `receivable_entries` - Seed 增加 `purchase_return_bills:*` 和 `sales_return_bills:*` 权限点。 ### 核心业务规则 - 草稿退货单不影响库存和往来。 - 购货退货审核时按商品和仓库聚合校验库存,默认禁止负库存。 - 购货退货审核后按当前库存平均成本出库,减少库存数量和成本金额。 - 购货退货审核后生成负数应付记录,用于冲减供应商应付。 - 销货退货审核后入库,优先使用当前商品仓库平均成本;平均成本为 0 时使用明细成本价。 - 销货退货审核后生成负数应收记录,用于冲减客户应收。 - 重复审核已审核单据返回幂等结果,不重复更新库存或往来。 ### 测试结果 本地代码验证: - `corepack pnpm exec prisma validate --schema api/prisma/schema.prisma` 通过。 - `corepack pnpm --filter @inventory/api build` 通过。 - `corepack pnpm --filter @inventory/web typecheck` 通过。 - `corepack pnpm build` 通过。 - `node --check api/prisma/seed.js` 通过。 - `git diff --check` 通过。 - 公开 README 未新增真实域名、服务器路径、进程名称、反向代理配置、数据库密码或密钥。 线上功能验证: - 健康检查返回 200。 - 未登录访问退货接口返回 401。 - `演示账号` 登录成功。 - 购货退货草稿新增、编辑、删除成功。 - 购货退货草稿阶段未生成 `PURCHASE_RETURN` 流水,库存余额未变化。 - 购货退货审核成功后库存数量减少、库存成本减少。 - 购货退货审核成功后生成供应商应付负数冲减记录。 - 购货退货重复审核返回 `alreadyApproved=true`,流水和应付冲减未重复。 - 购货退货库存不足返回 409,并显示商品、仓库、当前库存、需要数量和缺口。 - 销货退货草稿新增、编辑、删除成功。 - 销货退货草稿阶段未生成 `SALE_RETURN` 流水,库存余额未变化。 - 销货退货审核成功后库存数量增加、库存成本增加。 - 销货退货审核成功后生成客户应收负数冲减记录。 - 销货退货重复审核返回 `alreadyApproved=true`,流水和应收冲减未重复。 - 已审核退货单编辑和删除均返回 400。 - 浏览器自动化覆盖登录、打开购货退货单和销货退货单页面、刷新保持登录、退出登录、未登录访问自动跳回登录页。 - 报价系统关键页面复测正常。 ### 线上部署状态 已部署到私有环境并完成验证。公开 README 不展示真实域名、服务器路径、进程名称、反向代理配置、数据库密码或密钥。 ### 当前 commit `3f82185 feat: add return bill modules` ### 剩余风险 / 下一阶段任务 - 当前退货不关联原购货单或原销货单,成本采用阶段定义的简化口径。 - 细粒度按钮权限尚未做强制拦截,当前以 JWT 鉴权为主。 - 历史日期插单后的成本重算规则尚未实现。 - 下一阶段建议开发收款单、付款单和基础自动核销。 ## 第 8 阶段完成记录:收款单 / 付款单与基础自动核销 ### 阶段编号 第 8 阶段 ### 阶段名称 收款单 / 付款单与基础自动核销 ### 已完成内容 - 收款单列表。 - 新增收款单草稿。 - 编辑草稿收款单。 - 删除草稿收款单。 - 查看收款单详情。 - 收款单自动核销。 - 审核收款单并冲销客户应收。 - 付款单列表。 - 新增付款单草稿。 - 编辑草稿付款单。 - 删除草稿付款单。 - 查看付款单详情。 - 付款单自动核销。 - 审核付款单并冲销供应商应付。 - 客户应收未结明细查询。 - 供应商应付未结明细查询。 - 操作日志记录收款、付款、自动核销和审核相关动作。 ### 新增页面 - `/app/receipt-bills`:收款单列表、草稿新增/编辑、详情查看、自动核销、审核操作。 - `/app/payment-bills`:付款单列表、草稿新增/编辑、详情查看、自动核销、审核操作。 - 首页概览:更新为收款 / 付款与基础自动核销阶段提示。 ### 新增接口 - `GET /receipt-bills` - `POST /receipt-bills` - `GET /receipt-bills/:id` - `PATCH /receipt-bills/:id` - `DELETE /receipt-bills/:id` - `POST /receipt-bills/:id/auto-allocate` - `POST /receipt-bills/:id/approve` - `GET /payment-bills` - `POST /payment-bills` - `GET /payment-bills/:id` - `PATCH /payment-bills/:id` - `DELETE /payment-bills/:id` - `POST /payment-bills/:id/auto-allocate` - `POST /payment-bills/:id/approve` - `GET /receivable-entries` - `GET /payable-entries` ### 数据库变更 - 无新增 migration。 - 复用已有表: - `receipt_bills` - `receipt_lines` - `receipt_allocations` - `payment_bills` - `payment_lines` - `payment_allocations` - `receivable_entries` - `payable_entries` - Seed 增加 `receipt_bills:*`、`payment_bills:*`、`receivable_entries:*` 和 `payable_entries:*` 权限点。 ### 核心业务规则 - 草稿收款单不影响客户应收。 - 草稿付款单不影响供应商应付。 - 自动核销只生成草稿核销明细,不更新应收/应付余额。 - 收款单只允许核销同一客户的正数未结应收记录。 - 付款单只允许核销同一供应商的正数未结应付记录。 - 自动核销按 `billDate ASC, createdAt ASC` 从早到晚分配。 - 核销金额不得超过收款/付款单总金额。 - 核销金额不得超过源单未结余额。 - 审核后更新源单 `allocatedAmount` 和 `balanceAmount`。 - 重复审核已审核单据返回幂等结果,不重复扣减往来余额。 - 第 7 阶段产生的负数退货记录保留为往来冲减项,本阶段不自动对冲负数记录。 ### 测试结果 本地代码验证: - `corepack pnpm exec prisma validate --schema api/prisma/schema.prisma` 通过。 - `corepack pnpm --filter @inventory/api build` 通过。 - `corepack pnpm --filter @inventory/web typecheck` 通过。 - `corepack pnpm build` 通过。 - `node --check api/prisma/seed.js` 通过。 - `git diff --check` 通过。 - 公开 README 未新增真实域名、服务器路径、进程名称、反向代理配置、数据库密码或密钥。 线上功能验证: - 健康检查返回 200。 - 未登录访问收款单、付款单、应收明细和应付明细接口返回 401。 - `演示账号` 登录成功。 - 收款单草稿新增成功。 - 收款单草稿阶段未更新客户应收余额。 - 收款单自动核销生成核销明细,草稿阶段仍未更新客户应收余额。 - 收款单审核成功后客户应收余额减少,已核销金额增加。 - 收款单重复审核返回 `alreadyApproved=true`,未重复核销。 - 收款单已审核后编辑和删除均返回 400。 - 收款单超额核销返回 409。 - 收款单跨客户核销返回 400。 - 付款单草稿新增成功。 - 付款单草稿阶段未更新供应商应付余额。 - 付款单自动核销生成核销明细,草稿阶段仍未更新供应商应付余额。 - 付款单审核成功后供应商应付余额减少,已核销金额增加。 - 付款单重复审核返回 `alreadyApproved=true`,未重复核销。 - 付款单已审核后编辑和删除均返回 400。 - 付款单超额核销返回 409。 - 付款单跨供应商核销返回 400。 - 收款单、付款单、应收明细、应付明细列表接口均可访问。 - 前端收款单、付款单路由返回 200。 - 报价系统关键页面复测正常。 ### 线上部署状态 已部署到私有环境并完成验证。公开 README 不展示真实域名、服务器路径、进程名称、反向代理配置、数据库密码或密钥。 ### 当前 commit `c630034 feat: add receipt and payment bills` ### 剩余风险 / 下一阶段任务 - 本阶段不做独立账户管理、账户余额、资金转账、退款单、反审核或红冲。 - 负数退货往来记录当前只作为明细和汇总中的负数冲减项展示,尚未自动对冲正数未结记录。 - 自动核销第一版按时间顺序分配,不支持复杂指定优先级、折扣核销或月结对账。 - 细粒度按钮权限尚未做强制拦截,当前以 JWT 鉴权为主。 - 下一阶段建议开发首页待办、库存预警、应收/应付基础概况和基础报表入口。 ## 第 9 阶段完成记录:报表中心、首页经营看板和基础导出 ### 阶段编号 第 9 阶段 ### 阶段名称 报表中心 / 首页经营看板 / 基础导出 ### 已完成内容 - 完善首页工作台经营看板。 - 新增首页待办事项。 - 新增首页库存预警。 - 新增经营汇总报表。 - 增强库存余额报表。 - 新增商品收发明细报表查询入口。 - 新增客户应收汇总和明细报表。 - 新增供应商应付汇总和明细报表。 - 新增库存、收发明细、应收、应付、经营汇总 CSV 导出。 - 所有新增后端接口接入 JWT 鉴权。 ### 新增页面 - `/app`:经营看板、待办事项、库存预警和关键指标入口。 - `/app/reports`:报表中心,包含经营汇总、库存报表、收发明细、应收报表和应付报表。 ### 新增接口 - `GET /dashboard/summary` - `GET /dashboard/todos` - `GET /dashboard/inventory-warnings` - `GET /reports/business-summary` - `GET /reports/inventory-balance` - `GET /reports/stock-movements` - `GET /reports/receivables/summary` - `GET /reports/receivables/detail` - `GET /reports/payables/summary` - `GET /reports/payables/detail` - `GET /reports/inventory-balance/export` - `GET /reports/stock-movements/export` - `GET /reports/receivables/export` - `GET /reports/payables/export` - `GET /reports/business-summary/export` ### 数据库变更 - 无新增 migration。 - 复用已有业务表、库存表和往来表。 - Seed 增加报表和看板相关权限点: - `dashboard:view` - `reports:view` - `reports:export` - `reports:inventory` - `reports:receivables` - `reports:payables` - `reports:business_summary` ### 首页看板统计口径 - 经营指标默认统计当前自然月。 - 采购额取已审核购货单金额,购货退货作为冲减。 - 销售额取已审核销货单金额,销货退货作为冲减。 - 收款和付款取已审核收款单、付款单金额。 - 当前应收和应付取往来记录余额合计。 - 库存金额取库存余额成本金额合计。 - 待办统计未审核草稿单据数量。 - 库存预警按库存余额和商品预警上下限判断。 ### 报表统计口径 - 经营汇总支持今日、本周、本月和自定义日期范围,按日期汇总采购、销售、退货、收款、付款和净额。 - 库存余额报表读取 `stock_balances`,支持商品、仓库、类别、品牌和关键词筛选。 - 商品收发明细读取 `stock_movements`,支持日期、商品、仓库、业务类型和关键词筛选。 - 应收汇总按客户聚合 `receivable_entries`,明细读取应收往来记录。 - 应付汇总按供应商聚合 `payable_entries`,明细读取应付往来记录。 - 应收和应付报表支持未结筛选,余额不为 0 的记录视为未结。 ### 导出实现说明 - 导出第一版使用 CSV。 - 导出文件带 UTF-8 BOM,中文表头可直接用常见表格软件打开。 - 导出接口复用报表筛选条件。 - 导出当前不做异步任务和导出历史管理。 ### 测试结果 本地代码验证: - `corepack pnpm --filter @inventory/web typecheck` 通过。 - `corepack pnpm --filter @inventory/api build` 通过。 - `corepack pnpm exec prisma validate --schema api/prisma/schema.prisma` 通过。 - `corepack pnpm build` 通过。 - `node --check api/prisma/seed.js` 通过。 - `git diff --check` 通过。 - 公开 README 未新增真实域名、服务器路径、进程名称、反向代理配置、数据库密码或密钥。 线上功能验证: - 健康检查返回 200。 - 未登录访问看板和报表接口返回 401。 - `演示账号` 登录成功。 - 看板汇总、待办事项和库存预警接口返回 200。 - 经营汇总、库存余额、收发明细、应收汇总、应收明细、应付汇总和应付明细接口返回 200。 - 库存、收发明细、应收、应付和经营汇总导出返回 CSV 文件。 - 导出文件类型和 UTF-8 BOM 验证通过。 - 首页、登录页、后台入口和报表中心前端路由返回 200。 - 报价系统关键页面复测正常。 ### 线上部署状态 已部署到私有环境并完成验证。公开 README 不展示真实域名、服务器路径、进程名称、反向代理配置、数据库密码或密钥。 ### 当前 commit `0b3b29b feat: add dashboard and report center` `0c9a7e6 fix: send report csv exports as files` ### 剩余风险 / 下一阶段任务 - 当前导出为同步 CSV,数据量较大时需要后续扩展异步导出。 - 报表第一版不做复杂毛利分析、账户余额、资金流水或成本重算。 - 库存预警基于当前余额和商品预警上下限,不做智能补货建议。 - 细粒度按钮权限尚未做强制拦截,当前以 JWT 鉴权为主。 - 下一阶段建议补充操作日志报表、导入导出体验优化和更细的权限控制。 ## 第 10 阶段完成记录:稳定化、权限细化与操作便利性优化 ### 阶段编号 第 10 阶段 ### 阶段名称 稳定化 / 权限细化 / 操作便利性优化 ### 已完成内容 - 新增后端权限装饰器和全局权限守卫。 - 核心基础资料、单据、库存、报表、用户、角色、权限和往来接口接入权限强制校验。 - 前端菜单和核心操作按钮按权限过滤或禁用。 - 新增操作日志页面。 - 操作日志支持分页、操作人、动作类型、业务对象、日期和关键词筛选。 - 操作日志支持详情弹窗,展示 before / after JSON。 - 操作日志支持 CSV 导出。 - 新增只读演示数据状态接口。 - 新增受保护演示数据 reset 脚本。 - 审核、删除、自动核销、导出、期初过账和库存重算操作增加 loading 防重复提交。 - 删除、审核、禁用、库存过账和明细行删除增加二次确认。 - 前端网络异常统一提示为“网络异常,请稍后重试”。 - 后端异常统一返回中文 `message`。 ### 新增页面 - `/app/operation-logs`:操作日志列表、筛选、详情、导出和演示数据状态摘要。 ### 新增接口 - `GET /operation-logs` - `GET /operation-logs/:id` - `GET /operation-logs/export` - `GET /demo-data/status` ### 数据库变更 - 无新增 migration。 - Seed 新增或确认以下权限点: - `operation_logs:view` - `operation_logs:export` - `demo_data:view` - `demo_data:reset` - 系统管理员角色和 `demo` 演示账号保留全部权限。 ### 权限强化说明 - 未登录访问受保护接口返回 `401`。 - 已登录但缺少接口所需权限时返回 `403`。 - 后端权限守卫以接口装饰器声明的权限点为准,前端按钮隐藏或禁用只是体验层保护。 - 关键写操作包括新增、编辑、删除、审核、自动核销、库存过账、库存重算和导出。 ### 操作日志和导出说明 - 操作日志列表支持分页和多条件筛选。 - 详情弹窗展示操作前后 JSON,便于追溯。 - 导出文件为 CSV,带 UTF-8 BOM,中文表头可直接用常见表格软件打开。 - 导出接口同样需要权限校验。 ### demo 数据管理说明 - 前端仅展示演示数据状态,不提供默认清库按钮。 - reset 脚本默认拒绝执行。 - 只有显式设置 `ALLOW_DEMO_RESET=1` 且数据库地址符合本地/演示库特征时,脚本才允许执行。 - 不自动清理线上真实业务数据。 ### 测试结果 本地代码验证: - `corepack pnpm exec prisma validate --schema api/prisma/schema.prisma` 通过。 - `corepack pnpm --filter @inventory/api build` 通过。 - `corepack pnpm --filter @inventory/web typecheck` 通过。 - `corepack pnpm build` 通过。 - `node --check api/prisma/seed.js` 通过。 - `node --check api/prisma/reset-demo.js` 通过。 - `git diff --check` 通过。 - 公开 README 未新增真实域名、服务器路径、进程名称、反向代理配置、数据库密码或密钥。 线上功能验证: - 健康检查返回 200。 - 未登录访问操作日志、商品和报表导出接口返回 401。 - `演示账号` 登录成功。 - demo 账号拥有核心权限点,包括基础资料新增、单据审核、报表导出、操作日志查看/导出和演示数据查看。 - 操作日志列表返回 200。 - 操作日志导出返回 CSV,类型和 UTF-8 BOM 验证通过。 - 演示数据状态接口返回 200。 - 采购、销售、退货、收款、付款和库存报表核心列表接口返回 200。 - 无权限测试账号访问写接口返回 403。 - 报表导出仍返回 CSV,类型和 UTF-8 BOM 验证通过。 - 首页、登录页和操作日志页面路由返回 200。 - 报价系统关键页面复测正常。 ### 线上部署状态 已部署到私有环境并完成验证。公开 README 不展示真实域名、服务器路径、进程名称、反向代理配置、数据库密码或密钥。 ### 当前 commit `75b7c7f feat: harden permissions and operation usability` ### 剩余风险 / 下一阶段任务 - 当前权限为接口级强制校验和前端按钮适配,尚未做数据范围权限。 - 表单离开前未保存改动提醒仍可继续增强。 - 前端包体积存在构建警告,后续可做路由级代码分割。 - 无权限测试账号保留在演示环境中用于验收 403 行为。 - 下一阶段建议先做报价系统打通前的字段映射和接口契约设计,不直接进入联动开发。 ## 第 11 阶段完成记录:报价系统打通前字段映射与接口契约设计 ### 阶段编号 第 11 阶段 ### 阶段名称 报价系统集成字段映射 / 接口契约设计 ### 已完成内容 - 新增正式集成设计文档:`docs/integration/quote-inventory-field-mapping.md`。 - 梳理报价系统产品到进销存商品的字段映射。 - 梳理报价客户到进销存客户的字段映射。 - 梳理报价单到进销存销货单草稿的字段映射。 - 梳理报价单明细到销货单明细的字段映射。 - 梳理报价配货任务到后续库存占用 / 出库草稿的契约草案。 - 梳理施工增减项到后续销货草稿、销货退货草稿和采购建议的契约草案。 - 设计外部商品映射表和外部单据映射表建议。 - 设计只读商品映射查询接口契约。 - 设计只读库存可用量查询接口契约。 - 设计报价成交生成销货单草稿接口契约。 - 设计幂等、重复提交、未映射、库存不足和服务不可用的处理规则。 ### 新增文档 - `docs/integration/quote-inventory-field-mapping.md` ### 新增接口 - 无。本阶段只做设计文档,不新增运行时代码接口。 ### 数据库变更 - 无。本阶段不新增 migration。 - 文档中仅提出后续建议表:`external_product_mappings`、`external_customer_mappings`、`external_bill_mappings`。 ### 设计结论 - 两个系统不共享数据库。 - 不直接依赖双方内部 ID。 - 商品映射建议使用 `sourceType`、`sourceId`、`sourceCode`、`externalCode`。 - 报价成交生成销货单第一版只允许生成草稿。 - 不允许自动审核。 - 不允许自动扣库存。 - 只读库存查询不允许返回成本价或库存成本金额。 - 未映射商品、客户未映射、单位不一致等情况必须返回结构化错误。 ### 测试结果 本地文档验证: - `git diff --check` 通过。 - 公开 README 和新增集成文档未新增真实服务器路径、进程名称、反向代理配置、数据库密码或密钥。 线上部署状态 - 无运行时代码变更,本阶段无需部署。 - 未重启任何服务。 ### 当前 commit `12ed368 docs: add quote integration contract design` ### 剩余风险 / 下一阶段任务 - 集成契约需要与报价系统字段实际情况再次评审。 - 第 12 阶段已实现商品映射和库存可用量只读接口。 - 第 13 阶段正在补齐外部客户映射和外部单据幂等映射。 - 报价生成销货草稿接口尚未实现,仍需单独评审和开发。 ## 第 12 阶段完成记录:外部商品映射与只读库存查询 ### 阶段编号 第 12 阶段 ### 阶段名称 外部商品映射 / 只读库存查询 ### 已完成内容 - 新增外部商品映射表 `external_product_mappings`。 - 新增商品映射维护接口,支持分页、搜索、新增、编辑和禁用。 - 新增商品映射维护页面 `/app/external-product-mappings`。 - 新增只读商品映射查询接口 `GET /integration/products/lookup`。 - 新增只读库存可用量查询接口 `GET /integration/stock-availability`。 - 接入 JWT 和 RBAC 权限点 `external_product_mappings:*`。 - 商品映射新增、修改、禁用写入操作日志。 - Seed 增加外部商品映射权限和 2 条 demo 映射数据。 - 只读接口不返回成本价、平均成本、库存成本金额或供应商成本信息。 - 本阶段未修改报价系统,未做真实联动,未生成销货单草稿,未扣减或占用库存。 ### 新增页面 - `/app/external-product-mappings`:外部商品映射维护、只读映射查询、只读库存可用量查询。 ### 新增接口 - `GET /external-product-mappings` - `POST /external-product-mappings` - `GET /external-product-mappings/:id` - `PATCH /external-product-mappings/:id` - `DELETE /external-product-mappings/:id` - `GET /integration/products/lookup` - `GET /integration/stock-availability` ### 数据库变更 - 新增 enum:`ExternalProductMappingStatus`,包含 `ACTIVE`、`DISABLED`、`CONFLICT`、`PENDING_REVIEW`。 - 新增表:`external_product_mappings`。 - 新增唯一约束:`sourceType + sourceId`。 - 新增索引:`productId`、`sourceType + sourceCode`、`externalCode`、`matchStatus`。 - 新增 migration:`api/prisma/migrations/0004_add_external_product_mappings/migration.sql`。 - `products` 增加 Prisma 关系字段 `externalProductMappings`。 ### 映射与只读查询规则 - 外部系统通过 `sourceType`、`sourceId`、`sourceCode`、`externalCode` 与进销存商品建立映射。 - 不共享数据库,不依赖报价系统或进销存系统内部跨库 ID。 - `sourceType + sourceId` 重复创建返回冲突错误。 - 禁用映射保留历史记录,状态设为 `DISABLED`,不物理删除。 - 未映射商品查询库存时返回结构化 `PRODUCT_NOT_MAPPED`,不返回 500。 - 只读库存查询仅返回商品公开字段、仓库、库存数量、可用量和预警状态。 - 当前可用量等于库存余额数量;未实现库存占用、锁库或扣库。 ### 测试结果 本地代码验证: - `corepack pnpm exec prisma validate --schema api/prisma/schema.prisma` 通过。 - `corepack pnpm exec prisma generate --schema api/prisma/schema.prisma` 通过。 - `corepack pnpm --filter @inventory/api build` 通过。 - `corepack pnpm --filter @inventory/web typecheck` 通过。 - `corepack pnpm --filter @inventory/web build` 通过。 - `corepack pnpm build` 通过。 - `node --check api/prisma/seed.js` 通过。 - `git diff --check` 通过。 线上自测: - 健康检查返回 200。 - 进销存入口和登录页返回 200。 - `演示账号` 登录成功。 - `GET /external-product-mappings` 返回 2 条 demo 映射数据。 - `GET /integration/products/lookup?source_type=quote_system&source_id=QUOTE-PROD-001` 精确返回 1 条 active 映射。 - `GET /integration/stock-availability?source_type=quote_system&source_id=QUOTE-PROD-001` 返回 mapped=true 和库存可用量,且不包含成本字段。 - 未映射或非 active 映射返回结构化 `PRODUCT_NOT_MAPPED`,不返回 500。 - 未登录访问 integration 接口返回 401。 - 报价系统首页和后台登录页复测正常。 ### 线上部署状态 - 已部署到私有环境。 - 已执行 `0004_add_external_product_mappings` migration。 - 已执行 seed,demo 账号拥有外部商品映射权限,演示映射数据已写入。 - 已重新构建前后端。 - 仅重启进销存 API 服务,未重启报价系统。 - 公开 README 未新增真实域名、服务器路径、进程名称、反向代理配置、数据库密码或密钥。 ### 当前 commit `7a5f470 feat: add external product mapping readonly integration` / `eaa7c71 fix: support snake case integration query params` ### 剩余风险 / 下一阶段任务 - 本地开发机未安装 Docker,本地数据库级联调未覆盖;数据库迁移和接口联调已在私有环境验证。 - 只读库存可用量第一版不包含库存占用、锁库、在途量和可承诺量。 - 第 13 阶段正在补齐外部客户映射、外部单据幂等映射、只读客户映射查询和单据来源幂等检查。 - 报价成交生成销货单草稿仍未实现,需在后续阶段单独评审和开发。 ## 第 13 阶段进度记录:外部客户映射与外部单据幂等映射 ### 阶段编号 第 13 阶段 ### 阶段名称 外部客户映射 / 外部单据幂等映射 ### 当前进度 - 已新增外部客户映射表和后端维护接口。 - 已新增外部单据幂等映射表和 check / record / status 接口。 - 已新增只读客户映射查询接口。 - 已新增外部客户映射和外部单据映射后台页面。 - 本阶段不修改报价系统,不生成销货单草稿,不自动审核,不扣减或占用库存。 ### 新增页面 - `/app/external-customer-mappings`:外部客户映射维护和只读客户 lookup 验证。 - `/app/external-bill-mappings`:外部单据幂等映射列表、详情、check、record 和状态维护。 ### 新增接口 - `GET /external-customer-mappings` - `POST /external-customer-mappings` - `GET /external-customer-mappings/:id` - `PATCH /external-customer-mappings/:id` - `DELETE /external-customer-mappings/:id` - `GET /integration/customers/lookup` - `GET /external-bill-mappings` - `GET /external-bill-mappings/:id` - `POST /external-bill-mappings/check` - `POST /external-bill-mappings/record` - `PATCH /external-bill-mappings/:id/status` ### 数据库变更 - 已新增 enum:`ExternalCustomerMappingStatus`。 - 已新增 enum:`ExternalBillMappingStatus`。 - 已新增表:`external_customer_mappings`。 - 已新增表:`external_bill_mappings`。 - 已新增 migration:`api/prisma/migrations/0005_add_external_customer_bill_mappings/migration.sql`。 ### 测试结果 - 本地 `node --check api/prisma/seed.js` 通过。 - 本地 `prisma validate` 通过。 - 本地 API build、Web typecheck、Web build、全仓 build 通过。 - 线上 `/inventory-api/health` 返回 200。 - 线上 demo 登录成功,JWT 权限包含外部客户映射和外部单据映射权限。 - 线上只读客户 lookup 不返回应收余额、交易记录、内部备注等敏感字段。 - 线上重复 `source_type + source_id` 客户映射返回 409。 - 线上 pending_review 客户映射默认 lookup 不生效,显式筛选可查看。 - 线上外部单据 check 可识别 EXISTS 和 SOURCE_CHANGED。 - 线上外部单据 record 前后销货单数量不变。 - 本地开发机未安装 Docker,数据库迁移联调已在私有环境完成。 ### 线上部署状态 - 已部署到私有进销存环境。 - 已应用 migration `0005_add_external_customer_bill_mappings`。 - 已执行 seed,新增 demo 客户映射和单据幂等映射数据。 - 仅重启进销存 API 服务;未重启或修改报价系统。 ### 当前 commit `8a31f93` ### 剩余风险 / 下一阶段任务 - `POST /external-bill-mappings/record` 仅记录幂等来源,不生成任何销货单草稿。 - 当前只读客户 lookup 只面向映射查询,不返回应收余额、交易记录或内部备注。 - 后续如进入报价成交生成销货单草稿,仍需单独设计请求签名、字段校验、库存不足返回和草稿幂等落地规则。 - 前端构建仍有 Vite 大包体提示,后续可用路由懒加载优化。 ## 第 14 阶段进度记录:报价成交生成销货单草稿接口 ### 阶段编号 第 14 阶段 ### 阶段名称 报价成交生成销货单草稿接口 ### 当前进度 - 已新增 `POST /integration/sales-bills/from-quote` 接口。 - 接口只在进销存侧生成 `DRAFT` 销货单草稿。 - 本阶段不修改报价系统,不在报价系统新增按钮,不让报价系统真实调用。 - 本阶段不自动审核,不扣减或占用库存,不生成客户应收。 ### 新增接口 - `POST /integration/sales-bills/from-quote` ### 数据库变更 - 未新增表或字段。 - 复用 `sales_bills`、`sales_bill_items`、`external_customer_mappings`、`external_product_mappings`、`external_bill_mappings`。 ### 字段和幂等规则 - 客户通过 active 外部客户映射解析为进销存客户。 - 商品通过 active 外部商品映射解析为进销存商品。 - 同一 `source_type + source_bill_type + source_id + request_hash` 重复提交返回已有草稿。 - 同一 `source_type + source_bill_type + source_id` 但 `request_hash` 不同返回 `SOURCE_CHANGED`。 - 库存不足只返回 warning,不阻断草稿生成,不扣库存。 - 返回结果不包含成本价、采购价或毛利。 ### Demo 测试数据 - 示例 payload:`docs/integration/quote-sales-draft-demo-payload.json`。 - 成功场景使用 demo 映射 `QUOTE-CUST-001` 和 `QUOTE-PROD-001`。 - 未映射商品场景可把 payload 中 `source_product_id` 改为未映射编号。 ### 测试结果 - 本地 `node --check api/prisma/seed.js` 通过。 - 本地 `prisma validate` 通过。 - 本地 API build、Web typecheck、Web build、全仓 build 通过。 - 线上未登录访问返回 401。 - 线上无权限账号访问返回 403。 - 线上 demo / 管理员账号可成功生成 `DRAFT` 销货单草稿。 - 线上重复提交同一 `source_id + request_hash` 返回已有草稿,不重复创建。 - 线上同一 `source_id` 但 `request_hash` 不同返回 `SOURCE_CHANGED`。 - 线上客户未映射返回 `CUSTOMER_NOT_MAPPED`。 - 线上商品未映射返回 `PRODUCT_NOT_MAPPED`。 - 线上成功请求不会新增 `SALE` 库存流水。 - 线上成功请求不会扣减库存余额。 - 线上成功请求不会新增 `receivable_entries`。 - 线上返回结果未包含成本价、采购价或毛利字段。 ### 线上部署状态 - 已部署到私有进销存环境。 - 无新增数据库 migration。 - 已执行 seed 补充 `integration_sales_bills:create_from_quote` 权限。 - 仅重启进销存 API 服务;未重启或修改报价系统。 ### 当前 commit `3870432` ### 剩余风险 / 下一阶段任务 - 本接口只是进销存侧能力,不代表报价系统已接入。 - 后续如允许报价系统真实调用,还需要单独评审鉴权方式、调用按钮、失败重试和用户提示。 - 前端构建仍有 Vite 大包体提示,后续可用路由懒加载优化。 ## 第 15 阶段进度记录:集成安全、审计、开关与失败重试策略 ### 阶段编号 第 15 阶段 ### 阶段名称 集成安全 / 审计 / 开关 / 失败重试策略 ### 当前进度 - 已新增 integration 全局开关和 quote-to-sales 单接口开关配置。 - 已为 `POST /integration/sales-bills/from-quote` 增加开关检查,关闭时返回 `INTEGRATION_DISABLED`,且不生成销货草稿。 - 已预留服务间鉴权凭据;是否强制由私有环境变量控制。 - 已新增 integration 调用日志表和只读查询接口。 - 已新增集成调用日志页面 `/app/integration-call-logs`。 - 已增强外部单据幂等映射,记录最近调用时间、结果码和结果信息。 - 已新增运行控制文档 `docs/integration/quote-to-sales-runtime-control.md`。 - 本阶段不修改报价系统,不让报价系统真实调用,不自动审核,不扣减或占用库存,不生成客户应收。 ### 新增页面 - `/app/integration-call-logs`:集成调用日志分页、筛选和详情查看。 - `/app/external-bill-mappings`:增强最近调用时间、最近结果码、最近结果信息展示。 ### 新增接口 - `GET /integration/call-logs` - `GET /integration/call-logs/:id` ### 数据库变更 - 新增枚举 `IntegrationCallStatus`:`SUCCESS`、`FAILED`、`BLOCKED`、`DUPLICATE`、`SOURCE_CHANGED`。 - 新增表 `integration_call_logs`,记录 integration 调用摘要、状态、结果码、目标单据、耗时、脱敏 IP、User-Agent 和创建时间。 - `external_bill_mappings` 新增字段: - `lastCallAt` - `lastResultCode` - `lastResultMessage` - 新增 migration:`0006_add_integration_call_logs`。 ### 开关策略 - `INTEGRATION_ENABLED=false` 为默认安全值。 - `INTEGRATION_QUOTE_TO_SALES_ENABLED=false` 为默认安全值。 - 任一开关关闭时,`POST /integration/sales-bills/from-quote` 返回 `INTEGRATION_DISABLED`,不生成草稿、不写库存、不写应收。 - 私有环境如需启用,必须通过未提交的 `.env` 配置。 ### 鉴权策略 - 保留 JWT + RBAC,接口仍要求 `integration_sales_bills:create_from_quote` 权限。 - 可选服务间鉴权凭据头。 - 私有鉴权开关开启时,缺失或错误鉴权凭据返回联动鉴权无效错误。 - 真实鉴权凭据只允许保存在私有环境变量中,不写入 README、代码、测试脚本或日志。 ### 日志策略 - integration 调用日志只保存摘要和结果,不保存完整请求内容。 - 不保存鉴权凭据。 - 不保存成本、采购价、毛利、利润或供应商成本字段。 - IP 入库前做脱敏,User-Agent 做长度截断。 - 成功、失败、幂等重复、`SOURCE_CHANGED`、开关/鉴权拦截都写入日志。 ### 测试结果 - `corepack pnpm exec prisma validate --schema api/prisma/schema.prisma` 通过。 - `corepack pnpm --filter @inventory/api build` 通过。 - `corepack pnpm --filter @inventory/web typecheck` 通过。 - `corepack pnpm build` 通过。 - `node --check api/prisma/seed.js` 通过。 - `git diff --check` 通过。 - 本地开发机未安装 Docker,数据库级接口验证放到线上独立进销存环境完成。 - 线上 `/inventory-api/health` 返回 200。 - 线上 `/inventory/`、`/inventory/login`、`/inventory/app/integration-call-logs` 返回 200。 - `演示账号` 登录正常。 - 开关关闭时,`POST /integration/sales-bills/from-quote` 返回 503 / `INTEGRATION_DISABLED`,销货单数量不变,并写入调用日志。 - 临时开启私有开关和服务间鉴权后,缺失或错误鉴权凭据均返回 401 / 联动鉴权无效错误。 - 临时开启后,成功请求只生成 `DRAFT` 销货单草稿,不生成库存流水,不扣减库存,不生成应收。 - 重复同一 `source_id + request_hash` 返回已有草稿,不重复创建。 - 同一 `source_id` 但 `request_hash` 改变返回 409 / `SOURCE_CHANGED`。 - 未映射商品返回 400 / `PRODUCT_NOT_MAPPED`。 - 未映射客户返回 400 / `CUSTOMER_NOT_MAPPED`。 - 成功、失败、幂等、`SOURCE_CHANGED`、开关拦截和鉴权拦截均写入 integration 调用日志。 - 日志检查未发现鉴权凭据、成本、采购价、毛利或利润字段。 - 线上测试后已将私有 integration 开关恢复为关闭状态,保留服务间鉴权强制校验配置。 - 报价系统根路径返回 302 到后台登录页,后台登录页返回 200。 - 仅重启进销存 API 服务,未重启或修改报价系统。 ### 线上部署状态 - 已部署到私有进销存环境。 - 已执行 `0006_add_integration_call_logs` migration。 - 已执行 seed,demo 账号拥有 `integration_call_logs:view` 权限。 - 已重新生成 Prisma Client 并完成前后端构建。 - 仅重启进销存 API 服务。 - 未修改、不重启报价系统。 ### 当前 commit `31988aa feat: add integration runtime controls` ### 剩余风险 / 下一阶段任务 - 本阶段未实现 Redis 或分布式限流,短时间重复提交主要依赖数据库唯一约束、事务和幂等 request hash。 - 后续报价系统真实接入前,需要单独评审集成服务账号、调用按钮、用户提示和失败人工处理流程。 - 当前接口仍只生成草稿,不代表报价系统已接入。 ## 第 18 阶段进度记录:报价系统批量只读预检查进销存侧配合 ### 阶段编号 第 18 阶段 ### 阶段名称 报价系统批量只读预检查进销存侧配合 ### 当前进度 - 已核对现有只读接口 `GET /integration/customers/lookup`、`GET /integration/products/lookup`、`GET /integration/stock-availability`,可满足单客户、单商品和单商品库存可用量预检查。 - 已新增批量只读预检查接口 `POST /integration/precheck/quote-sales-draft`,支持一次传入客户和多个报价明细商品。 - 已新增独立 RBAC 权限点 `integration_quote_sales_precheck:view`,接口接入 JWT 和 RBAC;未登录返回 401,无权限返回 403。 - 已更新 seed,demo 管理员角色会获得 `integration_quote_sales_precheck:view` 权限。 - 已补外部客户映射页面列表工具栏 `sourceId`、`sourceCode` 快速筛选;外部商品映射页面列表工具栏显式展示 `sourceId`、`sourceCode` 快速筛选。 - 本阶段未修改报价系统,不重启报价系统。 ### 新增接口 - `POST /integration/precheck/quote-sales-draft` ### 请求范围 - 支持客户 `source_type/sourceType`、`source_id/sourceId`、`source_code/sourceCode`。 - 支持多个 item 的 `source_product_id/sourceProductId`、`source_product_code/sourceProductCode`、`source_unit/sourceUnit`、`quantity`。 - 支持可选 `warehouse_id/warehouseId`;未传时使用商品首选仓库,再回退默认启用仓库。 ### 只读预检查规则 - 只查询 active 外部客户映射和 active 外部商品映射。 - 只查询商品、客户、仓库、库存余额基础信息。 - 不生成 `sales_bills`。 - 不生成 `sales_bill_items`。 - 不写 `stock_movements`。 - 不写 `receivable_entries`。 - 不写 `external_bill_mappings`。 - 不写 `integration_call_logs`。 - 单位不一致返回 `unit_warning`,不阻断预检查。 - 库存可用量不足返回 `stock_warning`,不写库存、不占用库存。 - 客户未映射、商品未映射或仓库不可解析时 `can_create=false`,返回 `reason_code/reason_message`。 ### 响应字段 - 顶层返回 `can_create`、`reason_code`、`reason_message`。 - `customer.mapped` 表示客户是否映射。 - `customer.inventory_customer_code/name` 返回映射后的进销存客户基础信息。 - `items[].mapped` 表示商品是否映射。 - `items[].inventory_product_code/name/unit` 返回映射后的进销存商品基础信息。 - `items[].unit_warning` 返回单位差异 warning。 - `items[].stock_warning` 返回库存可用量 warning。 ### 敏感字段控制 - 不返回 `unitCost`。 - 不返回 `avgCost`。 - 不返回 `costAmount`。 - 不返回 `stockCost`。 - 不返回 `purchasePrice`。 - 不返回 `costPrice`。 - 不返回 `supplierPrice`。 - 不返回联动鉴权凭据或任何鉴权凭据字段。 ### 页面调整 - `/app/external-customer-mappings`:新增 sourceId 搜索、sourceCode 搜索,保留 sourceType 筛选和状态筛选。 - `/app/external-product-mappings`:列表工具栏显式展示 sourceId 搜索、sourceCode 搜索,保留 sourceType 筛选和状态筛选。 ### 本地测试结果 - `corepack pnpm --filter @inventory/web typecheck` 通过。 - `corepack pnpm --filter @inventory/web build` 通过,仍有既有 Vite 大包体提示。 - 使用本地数据库连接配置执行 `prisma validate --schema api/prisma/schema.prisma` 通过。 - `node --check api/prisma/seed.js` 通过。 - `git diff --check` 通过。 - 本地 `prisma generate` 在 Windows 开发机两次长时间无输出卡住,导致 `@prisma/client` 未生成,本地 API build 只剩 Prisma Client 缺失类错误;API build 放到线上目录完成验证。 - `pnpm install` 未修改 `package.json`、`api/package.json`、`web/package.json` 或 `pnpm-lock.yaml`。 ### 线上部署状态 - 已部署到私有进销存环境,线上功能 HEAD 已更新到 `d64cd4b`。 - 线上已执行依赖安装、`prisma generate`、`prisma migrate deploy`、seed、API build、Web typecheck、Web build。 - 本阶段无新增数据库 migration,`prisma migrate deploy` 确认无待应用迁移。 - seed 已执行,demo 管理员拥有 `integration_quote_sales_precheck:view`。 - 部署时仅重启进销存 API 服务。 - 未重启报价系统服务。 - 未使用批量重启命令。 ### 线上测试结果 - `/inventory-api/health` 返回 200。 - `演示账号` 登录正常,demo 用户拥有 `integration_quote_sales_precheck:view`。 - 未登录调用 `POST /integration/precheck/quote-sales-draft` 返回 401。 - 无权限用户调用 `POST /integration/precheck/quote-sales-draft` 返回 403。 - 映射客户和商品可返回 `customer.mapped=true`、进销存客户 code/name、`items[].mapped=true`、进销存商品 code/name/unit。 - 单位差异返回 `items[].unit_warning.code=UNIT_MISMATCH`。 - 库存不足返回 `items[].stock_warning.code=INSUFFICIENT_STOCK` 和可用量。 - 调用前后 `sales_bills` 数量保持 `11/11`。 - 调用前后 `stock_movements` 数量保持 `21/21`。 - 调用前后 `receivable_entries` 数量保持 `8/8`。 - 调用前后 `integration_call_logs` 数量保持 `19/19`。 - 调用前后 `external_bill_mappings` 数量保持 `9/9`。 - 响应敏感字段扫描未命中成本、采购价、供应商价格或鉴权凭据字段。 ### 当前 commit `78c79f9 feat: add quote sales draft precheck` ### 剩余风险 / 下一阶段任务 - 报价系统尚未接入本接口,本阶段仅完成进销存侧配合能力。 - 后续报价系统侧接入时,需要按本接口的 `can_create`、`reason_code`、`reason_message`、`unit_warning`、`stock_warning` 做用户提示,并单独验收报价系统侧调用链路。 ## 明确不做的范围 - 购货订单。 - 销货订单。 - 报价单。 - 独立账户管理。 - 账户余额。 - 资金转账。 - 在线开票。 - 云打印。 - 复杂反审核/红冲。 - 结账/反结账。 - 重算成本。 - 客户经营模块。