diff --git a/.gitignore b/.gitignore index 56c0217..5b2642d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ # AI辅助目录(整个目录忽略) -ai-aux/ +.ai/ # 依赖 node_modules/ @@ -65,6 +65,8 @@ CLAUDE.md backend/uploads/ # 数据库备份导出目录(⑨ 备份脚本产物) db/backups/ +# 客户发来的原始账套备份压缩包。 +/db/*.zip # 外部参考资料(2026-10-20):T+12.3 数据字典压缩包与解压目录不入版本库 docs/**/*.rar diff --git a/docs/T+字段映射草案_v0.1_2026-10-20.md b/docs/T+字段映射草案_v0.1_2026-10-20.md deleted file mode 100644 index 7b041a6..0000000 --- a/docs/T+字段映射草案_v0.1_2026-10-20.md +++ /dev/null @@ -1,289 +0,0 @@ -# T+ 12.3 字段映射草案(v0.1,2026-10-20) - -> 本文仅记录字段级事实与页面索引,不复制厂商文档正文。 -> 基线:`docs/T+对接数据需求清单_v1.4_2026-10-19.xlsx`(75 项)+ v1.3 IT 18 项 + 《T+12.3数据字典》。 - -## 0. 结论摘要 - -- 覆盖:清单 **75/75** 项均已给出 T+ 侧候选字段与系统目标列; -- 状态分布:候选待确认 42 / 字典明确 23 / 未检出 9 / 需 IT 1; -- 数据字典无法让 IT 18 项中的任何一项完全闭环;但 9 项可改写为「候选字段选择题」,6 项部分可答,2 项纯 IT,1 项转业务。 -- 收敛后:**13 项 IT 待确认 + 1 组业务裁决**(见第 12 节)。 -- 关键缺口:人员工号/入职日期/试用期无字段、客户 status 缺失、回款 payment_method/confirm_status 待补、明细行无显式行号、无源端更新时间与负向事件模型。 - -## 1. 编制说明与证据等级 - -| 标记 | 含义 | -| --- | --- | -| `D` | 字典明确 | -| `D?` | 候选待确认 | -| `IT` | 需 IT | -| `B` | 需业务 | -| `S` | 系统自维护 | -| `N` | 未检出 | - -- `D` 仅用于字段存在、类型明确且语义直接匹配的项;涉及「取哪个字段 / 业务口径」一律标 `D?` 或 `IT`。 -- 字典来源为 T+ 12.3 SchemaDoc;同一字段可能标注 `T+12.1/12.2/12.3` 版本,映射按 12.3 可用为准。 - -## 2. 公共字段与同步元数据 - -| 序号 | 数据项 | T+ 表.字段(字典) | T+ 类型/长度 | 枚举/取值 | 系统目标表.字段 | 转换/清洗规则 | 必要性 | 确认状态 | 来源/字典页 | -| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | -| 1 | T+ 原始单据号 / 档案编码 | 各表 code(人员/存货/客户/订单/出库/收付款单均有) | nvarchar(30~64) | — | personnel/products/customers/businesses/shipments/receipts.source_no | TRIM;作废重开是否换号待 IT(#4) | 必须 | D? | AA_Person.code、AA_Inventory.code、AA_Partner.code、SA_SaleOrder.code、SA_SaleDelivery.code、ARAP_ReceivePayment.code | -| 2 | T+ 系统内部标识 | 各表 id(整型主键) | int(4) | — | 六表 t_plus_id | int → 字符串存储;辅助对账/改名追溯 | 建议 | D | 各表 id(主键) | - -系统侧六张主表已预留 `source_no / t_plus_id / sync_batch_no / synced_at`;`source_no` 当前为普通索引,IT 确认幂等键后升级唯一约束。 - -## 3. 人员档案 - -人员主档;隶属关系需经部门树/部门负责人推断,T+ 无直属上级字段。 - -| 序号 | 数据项 | T+ 表.字段(字典) | T+ 类型/长度 | 枚举/取值 | 系统目标表.字段 | 转换/清洗规则 | 必要性 | 确认状态 | 来源/字典页 | -| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | -| 1 | 人员唯一编码(工号)★ | AA_Person.code | nvarchar(32) | — | personnel.source_no(建议补 personnel_code) | TRIM;编码优先、姓名辅助核对;是否即工号待 IT(#19) | 必须 | D? | AA_Person.code(编号) | -| 2 | 姓名 | AA_Person.name | nvarchar(200) | — | personnel.personnel_name | TRIM;仅辅助核对,不作唯一键 | 必须 | D | AA_Person.name(名称) | -| 3 | 在职状态 | AA_Person.disabled | tinyint(1) | 0 启用 / 1 停用(候选) | personnel.status(1 在职 / 0 离职) | disabled=1 → 0;无离职日期字段,离职时间需 IT 确认 | 必须 | D? | AA_Person.disabled(停用) | -| 4 | 是否试用期 | 未检出 | — | — | personnel.is_probation | T+ 人员档案无试用期字段;系统内人工维护或按入职日期规则推导 | 必须 | N | AA_Person 全表检索无 probation/试用 字段 | -| 5 | 入职日期 | 未检出(仅 madeDate 制单日期、birthday 出生日期) | — | — | personnel.hire_date | T+ 无入职日期字段;确认是否有自定义项承载,否则人工维护 | 必须 | N | AA_Person 全表检索无 hire/entry/入职 字段 | -| 6 | 联系电话 | AA_Person.mobilePhoneNo / officePhoneNo | nvarchar(20) / nvarchar(100) | — | personnel.phone | 优先 mobilePhoneNo,空则 officePhoneNo;日志脱敏 | 建议 | D | AA_Person.mobilePhoneNo(手机)、officePhoneNo(办公电话) | -| 7 | 业务员 ↔ 营销经理隶属关系 | AA_Person.iddepartment → AA_Department.idparent / iddirector | int(4) | — | personnel.manager_id | T+ 人员档案无直属上级字段;可经部门树/部门负责人推断,规则待确认;否则系统人工指定 | 必须 | D? | AA_Person.iddepartment(部门id);AA_Department.idparent(上级id)、iddirector(部门负责人) | -| 8 | 人员负责区域 / 产品辐射范围 | 未检出(可用 priuserdefnvc* 自定义项承载,需 IT 确认) | — | — | personnel_regions.region_name | 无专门字段则系统内人工维护 | 建议 | N | AA_Person 无区域/辐射范围字段 | -| 9 | 银行账户名 / 账号 / 开户行 | 未检出(AA_Partner 有银行账号字段,人员档案无) | — | — | 暂不落库 | 一期不采集;如后续代发工资再扩展 | 可选 | N | AA_Person 无银行账户字段 | - -## 4. 产品档案 - -产品主档不含库存量与售价,数量取现存量表、价格取价目表/订单明细。 - -| 序号 | 数据项 | T+ 表.字段(字典) | T+ 类型/长度 | 枚举/取值 | 系统目标表.字段 | 转换/清洗规则 | 必要性 | 确认状态 | 来源/字典页 | -| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | -| 1 | 产品名称 | AA_Inventory.name | nvarchar(200) | — | products.product_name | TRIM;与规格型号组成系统组合唯一键 | 必须 | D | AA_Inventory.name(名称) | -| 2 | 规格型号 | AA_Inventory.specification | nvarchar(200) | — | products.spec_model | 空值归一为空串 | 必须 | D | AA_Inventory.specification(规格型号) | -| 3 | 计量单位 | AA_Inventory.idunit → 计量单位表 | int(4) | — | products.unit | 按 idunit join 单位表取名称;单位表名待索引确认 | 建议 | D? | AA_Inventory.idunit(计量单位id)、idunitgroup | -| 4 | 数量 | ST_CurrentStock.baseQuantity(现存量) | decimal(13) | — | products.stock_quantity | 按存货+仓库汇总;语义(现存量/在途/累计销量)待 IT(#12) | 必须 | D? | ST_CurrentStock.baseQuantity(主计量数量);AA_Inventory 无库存量字段 | -| 5 | 销售单价 | AA_InventoryPrice(零售价/批发价)、AA_InventoryUnitPrice.retailPrice;订单明细实际成交价 | decimal(13~17) / nvarchar(1000) 公式 | — | products.sale_price | 产品档案参考价取价目表;绩效以订单/发货明细实际单价为准 | 必须 | D? | AA_InventoryPrice、AA_InventoryUnitPrice;AA_Inventory 无销售单价字段 | -| 6 | 产品分类(类目) | AA_Inventory.idinventoryclass → AA_InventoryClass.name | int(4) | — | products.product_category | T+ 分类仅辅助判定市政水利/轨交;系统分类人工维护不覆盖 | 必须 | D? | AA_Inventory.idinventoryclass(存货分类id)、AA_InventoryClass.name | -| 7 | 计量单位换算关系(如存在) | AA_Inventory_MultiUnit / AA_InventoryUnitPrice.rateOfExchange | decimal(13) | — | 暂不实现(系统单单位存储) | 如业务有多单位换算需求,另行设计 | 可选 | D? | AA_Inventory_MultiUnit、AA_InventoryUnitPrice.rateOfExchange(换算率) | - -## 5. 业务单据(销售订单) - -成本额在订单明细仅有最新成本,出库明细才有成本金额;销售额需按数量×单价计算。 - -| 序号 | 数据项 | T+ 表.字段(字典) | T+ 类型/长度 | 枚举/取值 | 系统目标表.字段 | 转换/清洗规则 | 必要性 | 确认状态 | 来源/字典页 | -| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | -| 1 | 订单单号 | SA_SaleOrder.code | nvarchar(30) | — | businesses.source_no | TRIM;不得写入内部 business_no | 必须 | D | SA_SaleOrder.code(编号) | -| 2 | 业务(订单)日期 | SA_SaleOrder.voucherdate | datetime(8) | — | businesses.business_date | 截断为 DATE | 必须 | D | SA_SaleOrder.voucherdate(单据日期) | -| 3 | 客户标识 | SA_SaleOrder.idcustomer → AA_Partner.code | int(4) | — | businesses.customer_id | 按客户编码解析;回退公司名称+负责人 | 必须 | D? | SA_SaleOrder.idcustomer(客户id)、idsettlecustomer(结算客户id) | -| 4 | 负责营销人员 | SA_SaleOrder.idclerk → AA_Person.code | int(4) | — | businesses.owner_personnel_id | 按人员编码解析;新插入写 T+ 负责人、更新是否覆盖人工归属待裁决 | 必须 | D? | SA_SaleOrder.idclerk(业务员id) | -| 5 | 协助营销人员 | 未检出独立协助人字段 | — | — | businesses.assistant_personnel_id | 业务已回馈 T+ 合同只挂单一负责人;协助人系统内记录 | 建议 | N | SA_SaleOrder 无 assist/协助 字段 | -| 6 | 特殊业务标记 | SA_SaleOrder.idbusinesstype → 业务类型表 | int(4) | 业务类型枚举待字典/IT 提供 | businesses.is_special | 业务类型是否等同特殊业务待确认;无则人工标记 | 必须 | D? | SA_SaleOrder.idbusinesstype(业务类型id) | -| 7 | 明细行 · 产品名称 + 规格 | SA_SaleOrder_b.idinventory → AA_Inventory.name/specification | int(4) | — | business_items.product_name / spec_model | 冗余固化名称与规格;未建档产品允许自由录入 | 必须 | D | SA_SaleOrder_b.idinventory(存货id) | -| 8 | 明细行 · 数量 | SA_SaleOrder_b.quantity | decimal(13) | — | business_items.quantity | 主计量数量;需 >0 校验 | 必须 | D | SA_SaleOrder_b.quantity(数量)、baseQuantity(主计量数量) | -| 9 | 明细行 · 销售单价 | SA_SaleOrder_b.price / taxPrice | decimal(13) | — | business_items.sale_price | price 为不含税单价、taxPrice 为含税单价;取哪个待确认 | 必须 | D? | SA_SaleOrder_b.price(单价)、taxPrice(含税单价) | -| 10 | 明细行 · 销售额 | SA_SaleOrder_b 无「销售额」字段;由数量×单价计算,或 taxAmount−tax | decimal(13) | — | business_items.sale_amount | 系统按数量×单价固化;T+ 用于对账 | 必须 | D? | SA_SaleOrder_b.quantity、price、taxAmount、tax | -| 11 | 明细行 · 成本额 ★ | SA_SaleOrder_b.LatestCost(最新成本);SA_SaleDelivery_b.costPrice/costAmount | decimal(13) | — | business_items.cost_amount | 取订单最新成本还是出库成本、成本类型/时点待 IT(#1) | 必须 | D? | SA_SaleOrder_b.LatestCost;SA_SaleDelivery_b.costPrice/costAmount/CostPriceGetType | -| 12 | 项目 / 工程编号或名称(如存在) | SA_SaleOrder.idproject → 项目表 | int(4) | — | 建议预留 project_code(当前不落库) | 按项目查询与报表归集;是否建列待业务 | 可选 | D? | SA_SaleOrder.idproject(项目id)、SA_SaleOrder_b.idproject | -| 13 | 服务类 / 维修类及其他收入单据(如存在) | 未检索到服务/维修类独立单据表 | — | — | 暂人工录入 | 业务规则未定前不纳入自动同步 | 可选 | N | SA_* 表索引未发现服务/维修类主表 | - -## 6. 发货单据(销售出库/发货) - -发货日期有四个候选字段;运费未在发货单据检出。 - -| 序号 | 数据项 | T+ 表.字段(字典) | T+ 类型/长度 | 枚举/取值 | 系统目标表.字段 | 转换/清洗规则 | 必要性 | 确认状态 | 来源/字典页 | -| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | -| 1 | 发货单号 | SA_SaleDelivery.code | nvarchar(30) | — | shipments.source_no | TRIM;不得写入内部 shipment_no | 必须 | D | SA_SaleDelivery.code(编号) | -| 2 | 发货日期 ★ | SA_SaleDelivery.voucherdate / SendDate / deliveryDate / auditeddate | datetime(8) | — | shipments.ship_date | 四个日期候选:单据日期/送货日期(T+12.3)/交货日期/审核日期;取哪个待 IT(#2) | 必须 | D? | SA_SaleDelivery.voucherdate、SendDate、deliveryDate、auditeddate | -| 3 | 关联订单号 | SA_SaleDelivery.SourceVoucherCode / idsourcevouchertype;明细 saleOrderCode/saleOrderId | nvarchar(50) / int(4) | — | shipments.business_id | 按订单号解析;主关联路径待 IT(#5) | 必须 | D? | SA_SaleDelivery.SourceVoucherCode、SA_SaleDelivery_b.saleOrderCode/saleOrderId/saleOrderDetailId | -| 4 | 运费金额 | 未检出运费字段(明细有 origExpenseAmount 费用分摊金额) | decimal(13) | — | shipments.freight_amount | T+ 运费可能在费用单/其他单据,需 IT 确认;系统暂人工 | 必须 | N | SA_SaleDelivery/SA_SaleDelivery_b 无 freight/运费字段 | -| 5 | 发货总金额 | SA_SaleDelivery.amount / taxAmount | decimal(13) | — | shipments.total_amount | 系统按明细汇总,不直写;T+ 金额用于对账 | 必须 | D | SA_SaleDelivery.amount(金额)、taxAmount(含税金额) | -| 6 | 明细行 · 产品/规格/数量/单价/行金额 | SA_SaleDelivery_b.idinventory / quantity / price / taxPrice / taxAmount | decimal(13) | — | shipment_items.product_name/spec_model/quantity/sale_price/amount | 行金额由系统按数量×单价固化;T+ 用于对账 | 必须 | D | SA_SaleDelivery_b.quantity、price、taxPrice、taxAmount | -| 7 | 发货单状态 | SA_SaleDelivery.voucherState / isCancel / auditeddate | int(4) / tinyint(1) | 单据状态枚举待 IT 提供 | 不落库(v1.4 统一) | 仅推已生效单据;状态随行供同步校验 | 必须 | D | SA_SaleDelivery.voucherState(单据状态)、isCancel(状态) | -| 8 | 承运商 / 物流单号 | SA_SaleDelivery.deliveryMode(运输方式 id) | int(4) | 运输方式枚举表待确认 | 暂不落库 | 承运商/物流单号无独立字段;如需建列再扩展 | 可选 | D? | SA_SaleDelivery.deliveryMode(运输方式) | - -## 7. 回款单据(收款/核销) - -到账日期无银行到账日字段;收款方式取结算方式表;确认/核销状态字段存在但枚举待 IT。 - -| 序号 | 数据项 | T+ 表.字段(字典) | T+ 类型/长度 | 枚举/取值 | 系统目标表.字段 | 转换/清洗规则 | 必要性 | 确认状态 | 来源/字典页 | -| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | -| 1 | 回款单号 | ARAP_ReceivePayment.code | nvarchar(30) | — | receipts.source_no | TRIM;不得写入内部 receipt_batch_no | 必须 | D | ARAP_ReceivePayment.code(编号) | -| 2 | 到账日期 ★ | ARAP_ReceivePayment.voucherDate / auditedDate / createdTime | datetime(8) | — | receipts.receipt_date | 无银行到账日字段;取单据日期/审核日期/创建时间哪个待 IT(#3) | 必须 | D? | ARAP_ReceivePayment.voucherDate、auditedDate、createdTime | -| 3 | 回款金额 | ARAP_ReceivePayment.amount(本币)/ origAmount(原币) | decimal(13) | — | receipts.amount | 取本币金额;一期禁负数,红字规则待 #8 | 必须 | D | ARAP_ReceivePayment.amount、origAmount | -| 4 | 关联订单号 | ARAP_ReceivePayment.SaleOrderCode/SaleOrderID;明细 saleordercode/saleorderid/sourceordercode | nvarchar(50) / int(4) | — | receipts.business_id | 回款↔订单按订单号解析;回款↔发货批次系统人工指定 | 必须 | D? | ARAP_ReceivePayment.SaleOrderCode/SaleOrderID;ARAP_ReceivePayment_b.saleordercode/sourceordercode | -| 5 | 收款方式 | ARAP_ReceivePayment.IdSettleStyle → AA_SettleStyle.code/name | int(4) | 结算方式枚举表(AA_SettleStyle:code/name/停用) | receipts.payment_method(待补列) | 枚举映射;完整枚举清单需 IT 提供 | 必须 | D? | ARAP_ReceivePayment.IdSettleStyle;AA_SettleStyle | -| 6 | 以物抵顶物说明 | 收款方式(以物抵顶枚举值)+ ARAP_ReceivePayment.memo | int(4) / nvarchar(200) | 以物抵顶对应结算方式代码待 IT 提供 | receipts.is_barter / remark | 按结算方式识别;抵顶物说明暂入备注 | 建议 | D? | ARAP_ReceivePayment.IdSettleStyle、memo | -| 7 | 回款确认 / 核销状态 | ARAP_ReceivePayment.cancelState / voucherstate / auditedDate | int(4) / datetime(8) | 核销/单据状态枚举待 IT 提供 | receipts.confirm_status(待补列) | 字段存在;哪个可作为人工确认依据待 IT(#16) | 必须 | D? | ARAP_ReceivePayment.cancelState(核销状态)、voucherstate(单据状态) | -| 8 | 银行流水号 / 回单参考号 | 未检出银行流水号/回单号字段(MultiSettle.documentCode 为票据号) | — | — | 建议预留 bank_serial_no | 需 IT 确认是否有对应字段 | 建议 | N | ARAP_ReceivePayment/ARAP_ReceivePayment_MultiSettle 仅票据号 | -| 9 | 票据信息(票号 / 到期日 / 贴现说明) | ARAP_ReceivePayment_MultiSettle.documentCode / amount / idsettlestyle | nvarchar(30) / decimal(13) | 票据类型枚举待 IT | 系统暂以备注承载 | 无票据到期日字段;承兑到期核销信息需 IT 确认 | 建议 | D? | ARAP_ReceivePayment_MultiSettle.documentCode(票据号) | -| 10 | 币种 / 汇率(如存在外币业务) | ARAP_ReceivePayment.idcurrency / exchangeRate | int(4) / decimal(13) | 币种表待索引 | 一期不落库(人民币记账) | 如存在外币业务再扩展 | 可选 | D | ARAP_ReceivePayment.idcurrency、exchangeRate | - -## 8. 客户档案 - -采用往来单位表 AA_Partner;客户编码/停用字段存在,status 列需系统补。 - -| 序号 | 数据项 | T+ 表.字段(字典) | T+ 类型/长度 | 枚举/取值 | 系统目标表.字段 | 转换/清洗规则 | 必要性 | 确认状态 | 来源/字典页 | -| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | -| 1 | 公司名称 | AA_Partner.name | nvarchar(200) | — | customers.company_name | TRIM;与负责人组成系统唯一键 | 必须 | D | AA_Partner.name(名称) | -| 2 | 负责人姓名 | AA_Partner.Contact(联系人)/ representative(法人代表) | nvarchar(50) | — | customers.owner_name | 「负责人」对应 Contact 还是 representative 待 IT/业务确认 | 必须 | D? | AA_Partner.Contact、representative | -| 3 | 客户编码 / 状态 / 启用停用时间 | AA_Partner.code / disabled / madeDate / updated | nvarchar(32) / tinyint(1) | disabled 0 启用 / 1 停用(候选) | customers.source_no / status(待补列) | 启停时间无独立列,可用 updated 近似(需 IT 确认) | 必须 | D? | AA_Partner.code、disabled、madeDate、updated | -| 4 | 联系人 / 电话 / 地址 / 行业 | AA_Partner.Contact / TelephoneNo / MobilePhone / CustomerAddress / iddistrict | nvarchar(30~200) | — | customers.contact_person / contact_phone / address / industry | 行业无直接字段;地区按 iddistrict 关联 | 可选 | D? | AA_Partner.Contact、TelephoneNo、MobilePhone、CustomerAddress、iddistrict | -| 5 | 开票信息(税号 / 开票名称 / 开票地址电话) | AA_Partner.taxRegcode / name / CustomerAddress | nvarchar(50~200) | — | 系统暂仅供展示,不落库 | 税号存在;开票地址电话需 IT 确认字段 | 可选 | D? | AA_Partner.taxRegcode(纳税号)、CustomerAddress | - -## 9. 同步完整性与补充字段 - -时间戳与负向字段部分存在;无统一事件表、无明细行号、无手续费字段。 - -| 序号 | 数据项 | T+ 表.字段(字典) | T+ 类型/长度 | 枚举/取值 | 系统目标表.字段 | 转换/清洗规则 | 必要性 | 确认状态 | 来源/字典页 | -| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | -| 1 | 数据最后更新时间 / 单据创建时间 / 修改时间 | 各表 createdTime/createdtime、updated、madeDate、auditedDate、ts | datetime(8) / timestamp(8) | — | 建议新增 source_created_at / source_updated_at(当前无) | 本地 update_time 不可作为源端水位;增量水位字段待 IT(#9) | 必须 | D? | 各表 updated/createdTime;ts(分布时间戳) | -| 2 | 变更类型 / 单据事件:新增、修改、删除、作废、红冲、退货、冲销 | 各表 isCancel(状态)、isCounteractDelivery(冲抵销货)、returnQuntity(退货数量) | int(4) / tinyint(1) / decimal(13) | 状态/事件枚举待 IT 提供 | 建议事件表(当前无) | 无统一变更事件表;负向事实需事件模型,规则待 #8 | 必须 | D? | SA_SaleOrder.isCancel、SA_SaleDelivery.isCounteractDelivery、SA_SaleDelivery_b.returnQuntity | -| 3 | 单据状态 / 财务审核状态 / 状态变更时间 | voucherState / auditedDate / auditor / auditorid | int(4) / datetime(8) / nvarchar(50) | 单据状态枚举待 IT | 不落库(仅同步校验) | 仅推已生效单据;状态随行校验 | 必须 | D | SA_SaleOrder/SA_SaleDelivery/ARAP_ReceivePayment 的 voucherState、auditedDate | -| 4 | 明细行行号 / 行状态 / 行级变更事件 | 明细表主键 ID、code(明细编号);无显式行号字段 | int(4) / nvarchar(30) | — | 建议补 source_line_no / source_item_id | 确认 code 是否即行号;否则用 T+ 明细 ID 作行级幂等键(待 IT) | 必须 | D? | SA_SaleOrder_b.id/code、SA_SaleDelivery_b.ID/code、ARAP_ReceivePayment_b.id/detailCode | -| 5 | 税率 / 税额 / 价税合计 / 折扣或折让 | 明细表 taxRate、tax、taxAmount、origTaxAmount、discount、discountRate、discountAmount | decimal(13) | — | 待业务 #20 答复后决定是否建列 | 字段齐全;金额是否含税、折扣关联方式待业务 | 必须 | D? | SA_SaleOrder_b/SA_SaleDelivery_b 税额与折扣字段 | -| 6 | 发货客户 / 收货人 / 收货地址 / 联系电话 | SA_SaleDelivery.idcustomer / address / contactPhone / idSendPerson / idConsignor | int(4) / nvarchar(100~200) | — | 建议预留(当前无列) | 用于核对发货对象与代发情形 | 必须 | D | SA_SaleDelivery.idcustomer、address、contactPhone、idSendPerson、idConsignor | -| 7 | 发货业务员 / 发货组织 / 仓库 | SA_SaleDelivery.idclerk / iddepartment / idwarehouse | int(4) | — | 建议预留(当前无列) | 识别代发、调拨与多组织差异 | 必须 | D | SA_SaleDelivery.idclerk、iddepartment、idwarehouse | -| 8 | 发货退回 / 红字发货 / 退回数量 / 退回金额 / 原发货单关联 | SA_SaleDelivery.isCounteractDelivery、_b.returnQuntity/returnQuntity2/backSentQuantity、sourceVoucher* | tinyint(1) / decimal(13) / nvarchar(50) | 冲抵/退货枚举待 IT | 待业务 #21 答复后决定是否建列 | 原单关联字段存在;是否冲减绩效待业务 | 必须 | D? | SA_SaleDelivery.isCounteractDelivery、SA_SaleDelivery_b.returnQuntity、backSentQuantity | -| 9 | 收款客户 / 经手人 / 财务审核状态 | ARAP_ReceivePayment.idpartner / idHandler / auditor / voucherstate | int(4) / nvarchar(50) / int(4) | — | 建议预留(当前无列) | 核对实际付款主体与经办责任 | 必须 | D | ARAP_ReceivePayment.idpartner、idHandler、auditor、voucherstate | -| 10 | 收款分配明细 / 分配金额 / 未分配金额 / 分配对象 | ARAP_ReceivePayment_b(源单/订单/金额/未结算)、ARAP_StrikeBalance(核销) | decimal(13) / int(4) | — | 人工指定发货批次的辅助参考 | 分配关系仅参考;系统仍人工指定(对照表 #18) | 必须 | D? | ARAP_ReceivePayment_b.saleordercode/amount/origNoSettleAmount;ARAP_StrikeBalance | -| 11 | 预收款 / 保证金 / 代收款 / 折让 / 抵扣 | ARAP_ReceivePayment.paymentAmount/origPaymentAmount(预收/预付)、overPayment(超收转预收)、allowances(折让) | decimal(13) | — | 待业务 #22 答复后决定是否建列 | 字段存在;是否计入绩效回款待业务 | 必须 | D? | ARAP_ReceivePayment.paymentAmount、overPayment、allowances | -| 12 | 手续费 / 交易费用 / 收款净额 | 未检出手续费/交易费用字段 | — | — | 待业务 #23 答复后决定 | 需 IT 确认手续费是否在其他单据/字段 | 必须 | N | ARAP_ReceivePayment 无 fee/charge 字段 | -| 13 | 红字收款 / 收款作废 / 收款退回 / 冲销及原单关联 | ARAP_ReceivePayment.voucherstate / isReceiveFlag;ARAP_StrikeBalance 冲销 | int(4) / tinyint(1) | 作废/红字状态枚举待 IT | 待业务 #24 答复后决定 | 无红字收款专用字段;负向事实需事件模型 | 必须 | D? | ARAP_ReceivePayment.voucherstate、isReceiveFlag;ARAP_StrikeBalance | -| 14 | 客户编码 / 客户状态 / 启用停用时间 | AA_Partner.code / disabled | nvarchar(32) / tinyint(1) | disabled 0 启用 / 1 停用 | customers.source_no / status(待补列) | 同六-3;客户编码唯一性待 IT | 必须 | D | AA_Partner.code、disabled | -| 15 | 客户分类 / 渠道 / 区域 / 所属组织 | AA_Partner.idpartnerclass / customerType / iddistrict / idMarketingOrgan | int(4) | 分类/客商类型枚举待 IT | customers.customer_type(不覆盖);渠道无列 | 系统客户分类人工维护;渠道/区域作备考 | 必须 | D? | AA_Partner.idpartnerclass、customerType、iddistrict、idMarketingOrgan | -| 16 | 客户名称变更 / 编码停用合并前后的对应关系 | AA_Partner.code(终身不变)+ updated;无变更历史表(待确认) | nvarchar(32) | — | 靠 source_no 追溯同一主体 | 改名/换负责人/合并靠 code 串同一主体;变更历史需 IT 确认 | 必须 | D? | AA_Partner.code、updated、HasEverChanged | -| 17 | 人员部门 / 岗位 / 调岗时间 / 离职和组织变更时间 | AA_Person.iddepartment / position / updated;调岗历史表待确认 | int(4) / datetime(8) | — | 不落库(备考/排查) | 字段部分存在;调岗/离职时间需 IT 确认 | 必须 | D? | AA_Person.iddepartment、position、updated | -| 18 | 产品编码 / 产品状态 / 启用停用时间 | AA_Inventory.code / disabled / madeDate | nvarchar(32) / tinyint(1) | disabled 0 启用 / 1 停用 | products.source_no / status | 稳定匹配;停用后历史明细仍可回溯 | 必须 | D | AA_Inventory.code、disabled、MadeRecordDate | -| 19 | 字典和枚举取值范围 / 编码与名称对照说明 | 枚举表:AA_SettleStyle、业务类型表、状态字典(需随数据导出) | — | 枚举字典随数据提供 | 同步映射表 | 不能只给代码;需编码与名称对照 | 必须 | D? | AA_SettleStyle、AA_BusinessType 等枚举表 | -| 20 | 对账汇总信息 / 数据记录数 / 数量合计 / 金额合计 / 抽取时间 | 由 IT 提供抽取汇总(接口/视图层) | — | — | 同步日志/对账表 | 记录明细条数、金额合计、抽取时间 | 必须 | IT | 字典不提供;需对接方式确定 | -| 21 | 单据历史版本 / 修改留痕(如 T+ 提供) | 未检索到统一单据历史版本表(待 IT 确认) | — | — | 系统同步快照可比对 | 无此数据不阻塞 | 可选 | D? | 表索引未见 history 类表 | - -## 10. 跨表关联与键 - -| 关系 | T+ 字段(字典) | 系统目标 | 状态 | -| --- | --- | --- | --- | -| 人员唯一键 | AA_Person.code | personnel.source_no(建议补 personnel_code) | D? | -| 客户唯一键 | AA_Partner.code;名称+联系人 | customers.source_no;company_name+owner_name | D? | -| 订单→发货 | SA_SaleDelivery.SourceVoucherCode / _b.saleOrderCode/saleOrderId | shipments.business_id | D? | -| 订单/发货→回款 | ARAP_ReceivePayment.SaleOrderCode/SaleOrderID;_b.saleordercode | receipts.business_id | D? | -| 回款→发货批次 | 系统人工指定(对照表 #18) | receipts.shipment_id | S | -| 明细行幂等 | 明细表 ID/code;无显式行号 | 建议补 source_line_no | D? | - -## 11. 枚举与状态 - -| 枚举 | T+ 来源 | 备注 | -| --- | --- | --- | -| 收款/结算方式 | AA_SettleStyle(code/name/disabled) | 完整枚举需随数据导出 | -| 单据状态 | 各单据 voucherState / isCancel | 仅同步校验,不落库 | -| 核销状态 | ARAP_ReceivePayment.cancelState | 含义待 IT | -| 业务类型 | SA_SaleOrder.idbusinesstype → 业务类型表 | 是否等同特殊业务待确认 | -| 产品分类 | AA_InventoryClass | 仅辅助系统分类人工维护 | - -## 12. 系统侧目标表缺口 - -| 缺口 | 说明 | 建议 | -| --- | --- | --- | -| `personnel.personnel_code` | T+ 工号/编码是否即 `source_no` 未定 | 若不等则补唯一列 | -| `customers.status` / 启停时间 | T+ 有 disabled,系统无列 | 补 status 与停用时间 | -| `receipts.payment_method` / `confirm_status` | T+ 有结算方式与核销状态 | 补两列并接枚举 | -| `source_created_at` / `source_updated_at` | 本地 update_time 不可作源端水位 | 补列或建 staging 表 | -| `source_line_no` / `source_item_id` | 明细表无行号 | 补列支持行级幂等 | -| 负向事件模型 | 无删除/作废/红冲/退货事件表 | 设计事件表或冲销单 | -| `sync_log` / 失败明细表 | 完全缺失 | 同步模块前置 | -| T+ 配置项 | `.env` 有 `T_PLUS_*`,`Settings` 未定义 | 补配置字段与校验 | - -## 13. IT 待确认事项收敛(18 → 13 + 1 组业务) - -| 新# | 原# | 事项 | 字典证据 | 字典可答 | 仍需确认 | 优先级 | -| --- | --- | --- | --- | --- | --- | --- | -| 1 | 1 | 成本额字段与成本口径 | SA_SaleOrder_b.LatestCost;SA_SaleDelivery_b.costPrice/costAmount/CostPriceGetType;AA_Inventory.invSCost/latestCost/avagCost | 字段存在性、类型精度、挂在订单还是出库单 | 请确认绩效成本取哪个字段(订单最新成本 / 出库成本 / 其他),取数时点与精度 | 高(阻塞核算) | -| 2 | 2+3 | 发货日与到账日口径 | 发货:SA_SaleDelivery.voucherdate/SendDate/deliveryDate/auditeddate;到账:ARAP_ReceivePayment.voucherDate/auditedDate/createdTime | 各日期字段存在性与类型 | 请分别确认发货日、到账日取哪个字段;签收日/银行到账日能否从 T+ 获取 | 高 | -| 3 | 4 | 幂等键与作废重开 | 各表 code + id 主键;SA_SaleOrder.ismodifiedcode、HasEverChanged | 编码字段与主键关系 | 各单据 code 是否唯一终身不变;作废重开是否换号;建议以 code 作 source_no | 高 | -| 4 | 5 | 三单关联与核销路径 | SA_SaleDelivery.SourceVoucherCode/idsourcevouchertype;SA_SaleDelivery_b.saleOrderCode/saleOrderId;ARAP_ReceivePayment.SaleOrderCode/SaleOrderID;ARAP_ReceivePayment_b;ARAP_StrikeBalance | 关联字段与核销表存在性 | 请确认订单→发货→回款的主关联路径(按单号还是 ID),以及分批发货/部分核销如何取 | 高 | -| 5 | 6 | 人员编码/工号与经理隶属 | AA_Person.code/name/iddepartment/isSalesman;AA_Department.idparent/iddirector | 编码/部门/负责人字段存在;无直属上级字段 | AA_Person.code 是否即工号;业务员→营销经理隶属在 T+ 如何维护(部门负责人?自定义项?) | 高 | -| 6 | 7 | 对接方式与安全 | 字典不涉及 | 无 | REST/视图/中间表/文件;只读账号与凭据、接口文档、样例数据 | 高 | -| 7 | 8 | 负数/红字/退货/冲销规则 | SA_SaleDelivery.isCounteractDelivery;SA_SaleDelivery_b.returnQuntity/backSentQuantity;ARAP_ReceivePayment.voucherstate;ARAP_StrikeBalance | 负向字段/单据形式存在性 | 负向单据的实际使用形式、原单关联字段、是否推送;绩效影响转业务 | 高 | -| 8 | 9 | 存量起始与增量水位 | 各表 updated/createdTime/madeDate/auditedDate/ts | 时间戳字段存在性 | 存量起始日期;增量用哪个时间戳(updated? ts?);时区 | 中 | -| 9 | 10+v1.4#18 | 客户主数据匹配与变更 | AA_Partner.code/name/Contact/representative/disabled/updated | 编码/名称/负责人/停用字段 | 客户唯一键;改名/换负责人/合并如何映射同一主体;负责人取 Contact 还是 representative | 中 | -| 10 | 11+16 | 收款方式与确认/核销枚举 | ARAP_ReceivePayment.IdSettleStyle;AA_SettleStyle.code/name;ARAP_ReceivePayment.cancelState/voucherstate | 枚举表与状态字段存在性 | 收款方式完整枚举与以物抵顶对应代码;核销/确认状态枚举含义及可否作为人工确认依据 | 高 | -| 11 | 12+13 | 产品数量语义与发货单价 | ST_CurrentStock.baseQuantity;AA_InventoryPrice/AA_InventoryUnitPrice;SA_SaleDelivery_b.price/taxPrice | 数量/价格字段存在性 | 产品「数量」取现存量/在途/累计销量;发货单价取订单价还是发货时价、含税与否 | 中 | -| 12 | 14+17 | 低频字段存在性:特殊业务标记/市场拓展计划 | SA_SaleOrder.idbusinesstype;AA_Person 自定义项;未检出市场拓展计划表 | 字段/表存在性 | 特殊业务是否有可识别字段;市场拓展计划 T+ 是否有表可提供;无则人工维护 | 低 | -| 13 | 15 | 同步窗口 | 字典不涉及 | 无 | 每周同步时间点,避开结账/备份;失败重试策略 | 低 | -| B1 | 18 | 业务裁决 5 项 | 税额/折扣/退货/预收/手续费字段已定位(待答复后决定是否建列) | 字段存在性 | 含税口径、退货红字冲减、预收/保证金/代收、手续费净额、负绩效表述 | 业务裁决 | - -### 原 18 项对照 - -| 原# | 事项 | 原优先级 | 收敛去向 | -| --- | --- | --- | --- | -| 1 | 成本额取数口径 | 高(阻塞核算) | 1 | -| 2 | 发货日期口径 | 高 | 2 | -| 3 | 到账日期口径 | 高 | 2 | -| 4 | 幂等唯一键 | 高 | 3 | -| 5 | 三单关联键 | 高 | 4 | -| 6 | 人员匹配键与经理隶属(v1.2 更新) | 高 | 5 | -| 7 | 对接方式与安全 | 高 | 6 | -| 8 | 负数 / 红字 / 退货 / 冲销处理规则 | 高 | 7 | -| 9 | 存量范围与增量口径 | 中 | 8 | -| 10 | 客户档案匹配与唯一键 | 中 | 9 | -| 11 | 收款方式枚举 | 中 | 10 | -| 12 | 产品「数量」语义 | 中 | 11 | -| 13 | 发货单价口径 | 中 | 11 | -| 14 | 特殊业务标记 | 低 | 12 | -| 15 | 同步窗口 | 低 | 13 | -| 16 | 回款确认 / 核销状态 | 高 | 10 | -| 17 | 市场拓展计划数据 | 低 | 12 | -| 18 | 口径裁决 5 项(移交业务方) | 业务裁决 | B1 | - -## 14. 待确认清单 - -**IT(13 项)**:见第 13 节新# 1–13。 - -**业务(1 组)**:含税口径、退货红字冲减、预收/保证金/代收、手续费净额、负绩效表述(原 #18 / 待澄清 #20–#24)。 - -**系统侧(不阻塞 IT)**:补 `personnel_code`、`customers.status`、`receipts.payment_method/confirm_status`、`source_updated_at`、`source_line_no`、`sync_log` 与 T+ 配置项。 - -## 15. 验证记录 - -- 解包:1,457 个 HTML、`.hhc/.hhk` 齐全、零字节 0; -- 全量解析:1,457 页、938 个 Table 类型页、**931 张表、21,019 个字段、0 失败页**; -- 编码:逐页检测,GB18030(无替换字符); -- 抽样核验:六类主表结构一致(6 列字段表),关键字段逐项比对通过; -- 输入 SHA-256:`3e8cd3146e22bdebe8bacda56b5dafbbd8be744c4279d7b2bbf3d7ecdc7e2726`; - -## 附录 A:六类主表索引 - -| 类别 | T+ 表 | 字典页 GUID | -| --- | --- | --- | -| 人员 | AA_Person | `fcd00c17-6778-4c6a-90ae-3f0dbaf2c102` | -| 产品 | AA_Inventory | `93b57dfa-4ca4-411d-a883-6d26c8e01787` | -| 客户 | AA_Partner | `871e93dd-c2cf-4bd2-af91-cbeb5951ac5e` | -| 业务 | SA_SaleOrder | `9a51f8a9-658a-4f7c-9372-8af2257511ee` | -| 发货 | SA_SaleDelivery | `bef98b52-c9f0-4d80-8e62-8968cced5b52` | -| 回款 | ARAP_ReceivePayment | `709de6e4-3b3d-4cf8-b5ed-5f657d42599a` | - -## 附录 B:75 项覆盖矩阵 - -| 节 | 项数 | 已映射 | -| --- | --- | --- | -| 公共要求 | 2 | 2 | -| 人员 | 9 | 9 | -| 产品 | 7 | 7 | -| 业务 | 13 | 13 | -| 发货 | 8 | 8 | -| 回款 | 10 | 10 | -| 客户 | 5 | 5 | -| 同步完整性 | 21 | 21 | - -## 附录 C:失败页 - -无(`failures.csv` 为空)。 - -## 附录 D:复现方法 - -```text -1. C:/Windows/hh.exe -decompile -2. py -3.14 -I 03_extract_fields.py --extracted --out -3. py -3.14 -I 08_build_md.py --out --target -``` - ---- - -*本文档由数据字典解析与人工核验生成,字段候选未经 IT 确认前不得视为同步契约。* diff --git a/docs/T+对接数据需求清单_v1.6_2026-10-20.xlsx b/docs/T+对接数据需求清单_v1.6_2026-10-20.xlsx deleted file mode 100644 index d4419fe..0000000 Binary files a/docs/T+对接数据需求清单_v1.6_2026-10-20.xlsx and /dev/null differ diff --git a/docs/T+对接数据需求清单_v1.7_2026-10-20.xlsx b/docs/T+对接数据需求清单_v1.7_2026-10-20.xlsx deleted file mode 100644 index 106ed5c..0000000 Binary files a/docs/T+对接数据需求清单_v1.7_2026-10-20.xlsx and /dev/null differ diff --git a/docs/T+数据表说明文档.doc b/docs/T+数据表说明文档.doc new file mode 100644 index 0000000..f2aa580 Binary files /dev/null and b/docs/T+数据表说明文档.doc differ diff --git a/docs/superpowers/plans/2026-10-12-M1-系统设置与参数体系.md b/docs/superpowers/plans/2026-10-12-M1-系统设置与参数体系.md index 70715c5..34bca94 100644 --- a/docs/superpowers/plans/2026-10-12-M1-系统设置与参数体系.md +++ b/docs/superpowers/plans/2026-10-12-M1-系统设置与参数体系.md @@ -265,4 +265,4 @@ def start_payment_ok(received, revenue, ratio) -> bool 1. 按 T1–T8 的验证节点逐任务执行(见第二章各任务);T8 后全量回归 + e2e; 2. 验收标准 6 条逐条核对(见第四章); -3. 与 `ai-aux/AI_CONTEXT.md` 需求裁决节交叉核对口径无冲突。 +3. 与 `.ai/AI_CONTEXT.md` 需求裁决节交叉核对口径无冲突。 diff --git a/docs/superpowers/plans/2026-10-12-剩余开发计划.md b/docs/superpowers/plans/2026-10-12-剩余开发计划.md index 0a70f09..15b6f0e 100644 --- a/docs/superpowers/plans/2026-10-12-剩余开发计划.md +++ b/docs/superpowers/plans/2026-10-12-剩余开发计划.md @@ -8,7 +8,7 @@ **技术栈:** 后端 Python 3.12 + FastAPI + SQLAlchemy 2.0(同步)+ MySQL 8.0 + Redis 7;前端 Vue 3.5 + TS 5.9 + Vite 8 + Element Plus 2.14 + Pinia 4。 -**规格:** `ai-aux/AI_CONTEXT.md`「需求裁决」节(权威口径);`docs/问题与解决方案对照表_v2.xlsx`(28 项裁决);`docs/2026.9.8修改方案.docx`(公式与生效日期)。需规(`docs/衍水绩效管理系统功能需规.docx`)中 4 类作废条款不再引用:26 天示例、含运费公式、协助 25%、经理个人户 8‰。 +**规格:** `.ai/AI_CONTEXT.md`「需求裁决」节(权威口径);`docs/问题与解决方案对照表_v2.xlsx`(28 项裁决);`docs/2026.9.8修改方案.docx`(公式与生效日期)。需规(`docs/衍水绩效管理系统功能需规.docx`)中 4 类作废条款不再引用:26 天示例、含运费公式、协助 25%、经理个人户 8‰。 ## 全局约束 @@ -759,7 +759,7 @@ git commit -m "test(system): 参数体系模块用例与测试记录" ## 验证方式 -1. 计划内容与 `ai-aux/AI_CONTEXT.md` 需求裁决节逐条核对(口径无冲突、无遗漏作废条款); +1. 计划内容与 `.ai/AI_CONTEXT.md` 需求裁决节逐条核对(口径无冲突、无遗漏作废条款); 2. 计划中的命令与项目现有命令体系一致(uv / pnpm / docker compose); 3. 首块每个任务有独立可测交付物;测试要点符合「模块整体完成时统一编写」约定(纯函数与 core 级随实现即时测); 4. 执行阶段验证:T1 后 `test_schema_sync.py` 通过;T2/T3 后纯单元全绿;T5 后冒烟链路完整;T8 后全量后端用例与 e2e 全绿(以 `backend/tests/README.md` 最新运行记录为准)。 diff --git a/docs/superpowers/plans/2026-10-13-M2-基础数据与业务数据.md b/docs/superpowers/plans/2026-10-13-M2-基础数据与业务数据.md index 9434353..ad3102e 100644 --- a/docs/superpowers/plans/2026-10-13-M2-基础数据与业务数据.md +++ b/docs/superpowers/plans/2026-10-13-M2-基础数据与业务数据.md @@ -92,7 +92,7 @@ - T1/T6:`uv run pytest tests/integration/test_schema_sync.py tests/unit/test_models.py -q` 全绿(双轨零漂移是硬关口)。 - T5/T11:模块集成用例统一编写并执行;T11 后 `uv run pytest -q` 全量回归。 - T12–T14:`pnpm type-check && pnpm build`。 -- T15:后端全量 pytest + 前端构建 + 两个 e2e 脚本全过;`ai-aux/AI_CONTEXT.md` 历史任务摘要由主会话收尾时更新。 +- T15:后端全量 pytest + 前端构建 + 两个 e2e 脚本全过;`.ai/AI_CONTEXT.md` 历史任务摘要由主会话收尾时更新。 ## 风险与开放问题(默认处理,不阻塞开工) diff --git a/docs/备份恢复手册.md b/docs/备份恢复手册.md deleted file mode 100644 index 0b51780..0000000 --- a/docs/备份恢复手册.md +++ /dev/null @@ -1,101 +0,0 @@ -# 备份恢复手册(⑨ 备份恢复与运维检查) - -> 用户强调「这个备份恢复很重要」。**备份不演练 = 没有备份**——本手册的一页纸目标:任何运维/开发拿到都能完成「备份 → 恢复到临时库核对 → 删临时库」全链路。 - -## 一、备份(每日一次,建议凌晨低峰) - -```bash -# 项目根目录执行 -bash scripts/backup_full.sh -``` - -- 产物:`db/backups/payroll_YYYYMMDD_HHMMSS.sql.gz`(gzip 压缩) -- 保留策略:自动清理 30 天前的旧备份 -- 凭据:从 `docker/.env` 读取(不入脚本、不入版本库) - -**Windows 定时任务**(任务计划程序 / `schtasks`): - -```cmd -:: 每日 02:30 备份(经 Git Bash) -schtasks /create /tn "ys-payroll-backup" /tr "\"C:\Program Files\Git\bin\bash.exe\" -lc \"bash scripts/backup_full.sh\"" /sc daily /st 02:30 /ru SYSTEM -``` - -## 二、恢复演练(备份后顺手跑一次,验证备份真能用) - -```bash -bash scripts/restore_drill.sh # 恢复到临时库 + 行数核对,临时库默认保留 -bash scripts/restore_drill.sh --drop-exec # 核对通过后再加此参数删除临时库 -``` - -- **绝不直接覆盖生产库**——演练恢复到独立临时库 `payroll_drill_<时间戳>` -- 行数对比覆盖 16 张关键表(users/roles/param_*/business*/personnel/products/customers/shipments*/receipts/approval_*/system_settings) -- 全部 ✓ 即备份可恢复;出现 ✗ 时临时库保留供排查 - -## 二·五、增量备份(澄清 #19 答复:每日全量 + 有更新时增量补充) - -全量之间的数据变更由 **binlog 归档**覆盖(MySQL 8 默认开启 binlog,ROW 格式、服务端保留 30 天): - -```bash -bash scripts/backup_incremental.sh -``` - -- 产物:`db/backups/binlog.NNNNNN.gz`(原始 binlog 文件逐个压缩) -- **有更新时才产出**:状态文件 `db/backups/.incremental_state` 记录上次归档到的文件,无新变更时直接退出 -- 只归档「已写完」的 binlog(正在写的最后一个留到下次收取) -- 保留策略同全量:自动清理 30 天前的增量包 - -**配套**:`backup_full.sh` 每次全量会同时产出位点文件 `payroll_*.sql.gz.pos`(binlog 文件名 + 位点),标记「该全量覆盖到此」——恢复重放从位点之后开始。 - -**恢复顺序**(真出事时):最新全量 → 依次 `gunzip` 其后的增量包 → 用 `mysqlbinlog` 重放(镜像内无此客户端,宿主机或临时容器执行): - -```bash -# 解出增量包后重放(示例:从全量位点之后开始) -gunzip -c db/backups/binlog.000003.gz > /tmp/binlog.000003 -mysqlbinlog --start-position=<全量位点> /tmp/binlog.000003 | \ - docker exec -i ys-mysql-dev sh -c 'mysql -uroot -p"$MYSQL_ROOT_PASSWORD" payroll' -``` - -**建议定时**:增量与全量同节奏(每日 02:30 全量后接一次增量;变更频繁的日子可在中午加跑一次): - -```cmd -schtasks /create /tn "ys-payroll-backup-incr" /tr "\"C:\Program Files\Git\bin\bash.exe\" -lc \"bash scripts/backup_incremental.sh\"" /sc daily /st 02:50 /ru SYSTEM -``` - -## 三、生产恢复(真出事了,七步) - -> ⚠️ 生产恢复是**高危操作**:先把容器停了再恢复,避免写冲突。下面假设恢复到**全新空数据卷**(最干净路径)。 - -1. **停容器保卷**:`docker compose -f docker/docker-compose.dev.yml down` -2. **删旧卷(谨慎!确认要全量重来才执行)**:`docker volume rm ys-payroll_mysql-dev-data` - - 若只想恢复到某个时间点**且不丢其它数据**,改用「恢复到临时库 → mysqldump 单表导出 → 手工回灌」的细粒度路径,勿整体覆盖。 -3. **起空库**:`docker compose -f docker/docker-compose.dev.yml up -d`(首启自动跑 `db/init/init-dev.sql` 建表 + 种子) -4. **选一份备份**:`ls -t db/backups/payroll_*.sql.gz | head` -5. **导入该备份**: - ```bash - gunzip -c db/backups/payroll_XXXXXXXX_XXXXXX.sql.gz | \ - docker exec -i ys-mysql-dev sh -c 'mysql -uroot -p"$MYSQL_ROOT_PASSWORD" payroll' - ``` -6. **核对行数**:再跑一次 `bash scripts/restore_drill.sh`(此时源库=刚恢复的库,应全 ✓) -7. **重启后端**:`cd backend && uv run uvicorn app.main:app --reload --port 8000`,登录抽查几个页面确认数据回来 - -## 四、运维健康检查(每日一次) - -```bash -bash scripts/health_check.sh -``` - -六项检查:容器健康 ×2 / 磁盘水位(80% 阈值)/ 备份新鲜度(24h 内)/ Redis 探活 / 24h 登录失败次数(暴力破解预警)。任一项 WARN/FAIL 时退出码非零,方便监控采集。 - -**Windows 定时**: - -```cmd -:: 每日 08:50 检查(上班前出报告) -schtasks /create /tn "ys-payroll-health" /tr "\"C:\Program Files\Git\bin\bash.exe\" -lc \"bash scripts/health_check.sh >> db/backups/health.log 2>&1\"" /sc daily /st 08:50 /ru SYSTEM -``` - -## 五、注意事项 - -- 备份含**全部业务数据与参数种子**,属敏感文件——`db/backups/` 已加入 `.gitignore`,**不要**把它提交到版本库 -- 恢复演练产生的 `payroll_drill_*` 库会占磁盘,核对完及时 `--drop-exec` 清理 -- 备份脚本与恢复脚本都只依赖 Docker(无需宿主机装 MySQL 客户端) -- 增量重放的 `mysqlbinlog` 是唯一需要宿主机(或临时容器)具备的客户端——官方 mysql:8.0 镜像内不含;重放前务必确认 binlog 序号连续(中间断号说明有未归档文件,先跑一次增量归档) diff --git a/docs/待澄清问题清单_2026-10-15(1).xlsx b/docs/待澄清问题清单_2026-10-15(1).xlsx new file mode 100644 index 0000000..dd2e2c8 Binary files /dev/null and b/docs/待澄清问题清单_2026-10-15(1).xlsx differ diff --git a/docs/待确认事项清单_2026-10-28_v2.xlsx b/docs/待确认事项清单_2026-10-28_v2.xlsx new file mode 100644 index 0000000..b69590f Binary files /dev/null and b/docs/待确认事项清单_2026-10-28_v2.xlsx differ diff --git a/docs/待答复催办清单_2026-10-19.md b/docs/待答复催办清单_2026-10-19.md deleted file mode 100644 index 36d9028..0000000 --- a/docs/待答复催办清单_2026-10-19.md +++ /dev/null @@ -1,95 +0,0 @@ -# 待答复事项催办清单(2026-10-19) - -> **用途**:对外跟催材料,分三块可直接拆分发送——一、业务方;二、IT/T+ 侧;三、报表口径补充确认(本轮新增)。 -> **基线**:《待澄清问题清单_2026-10-15(1)(2).xlsx》(业务 24 项,2026-10-16 已答复 19 项,其中部分答复 3 项;#1–#3/#20 仍空白)、《T+对接数据需求清单》v1.3「待IT确认事项」18 项 + v1.4(2026-10-19 勘误)、《问题与解决方案对照表_v2》(28 项已裁决口径)。 -> **原则**:已答复项不重复询问;未答复项按清单内「建议默认」执行中,答复后以答复为准并回填文档。 - -## 一、业务方(建议回复期限:____) - -### A. 仍未答复 —— 阻塞对应模块开工(4 项) - -| # | 问题(原文口径) | 当前执行默认 | 阻塞 | -| --- | --- | --- | --- | -| 1 | 二次分配的分配标的是什么——绩效工资金额、折算毛利润额,还是销售额(业绩额)? | 方案录入已交付;**分摊已按开发侧暂定口径实现**(非业务答复,答复后校准) | ④ 分摊计算 | -| 2 | 分配比例合计不足 100% 时,剩余部分归属谁? | 余额归合同负责营销人员(仅展示不落库) | ④ 分摊计算 | -| 3 | 二次分配与已作废的「协助 25% 分成」是什么关系? | 独立新机制;协助仍仅记录不核算 | ④ 分摊 | -| 20 | 含税口径:销售/成本/毛利润/运费各项是否含税?价税合计与折扣折让如何处理? | 按不含税口径实现中 | ④ 核算口径终验、⑥ 同步建列(是否建税率/税额列) | - -> 说明:#1–#3 未答复期间,二次分配方案可正常录入与审批;开发侧已按暂定口径把分摊拆行计入绩效(参与人份额×比例、负责人余额),**标的与余额归属仍待业务答复,答复后可能调整**;#20 影响历史算出的绩效是否需要按含税口径重算,越早答复返工面越小。 - -### B. 已有答复但需补具体值 / 勾选(4 项) - -| # | 事项 | 需补充 | -| --- | --- | --- | -| 12 | 经理个人户业绩是否计入其 12.5% 团队基数 | 答复为「做参数可调」,**请给出初始值**:计入 / 不计入(系统已实现为开关参数,当前默认不计入) | -| 14 | 「第 1 天 10‰」实现口径 | 请勾选:**A 仅首日覆盖**(推荐,保「360 天 = 6‰」锚点)或 B 整体平移(破坏锚点)。系统当前按 A 实现(首日 10‰、其余按公式 10 − 天数 × 4/360) | -| 4 | 二次分配方案修改窗口与权限 | 答复「暂定允许修改,走调整单」——请定:首次月结前可改(留痕)?月结后只读、仅走调整单?谁有权改(管理员 / 营销后勤)? | -| 6 | 营销后勤/财务/领导三类角色的账号归属、可见菜单、可操作点 | 答复「先预设角色,需与客户确认」——请给权限清单(三类角色各能看什么、能操作什么)。系统已按最小授权运行:后勤=提交录入,财务=复核+导出,领导=审核只读,营销后勤暂不可见审批列表 | - -### C. 请确认两处勘误(已按勘误实施,需业务回执存档)(2 项) - -| 项 | 原表述 | 现行勘误(v1.4) | -| --- | --- | --- | -| 人员识别 | 「负责营销人员以姓名为唯一识别」 | 改为「以人员编码(工号)为唯一识别、姓名辅助核对」——原表述与「编码为业绩归属唯一锚点(防重名错钱)」矛盾,疑笔误,请确认 | -| 回款↔发货批次 | 「由 T+ 收款分配关系指定,人工辅助」 | 改为「**系统人工指定**(对照表 #18 定稿),T+ 收款分配关系仅作辅助」——主次相反疑漏改,请确认 | - -### D. 2026-10-20 新增:需业务定口径(2 项) - -> 随「审批单内容快照 + 二次分配方案版本化」收口带出,开发侧已按现行默认实现,答复后按答复调整。 - -| # | 事项 | 当前默认(开发侧已实现) | 需确认 | -| --- | --- | --- | --- | -| 25 | **业务硬删除时,方案版本历史是否保留?** | 随业务一并删除(与既有「终态审批单随业务删除一并清理」规则一致)——业务被删后,方案参与人与比例的版本痕迹也不复存在 | 是否需要保留(如留归档表/只留审批单快照),还是维持一并删除 | -| 26 | **离职的历史参与人重新加入方案,是否允许?** | 按新参与人处理:曾参与过但当前不在生效方案里的人,若已离职,重新加入会被「离职人员禁入」拦截 | 是否应放行(把「历史参与过」视为豁免),还是维持按现任职校验 | - -### 已按默认执行、无需回复的项(供核阅) - -\#7 月结审批链默认开启、#8 人工确认回款可手动关闭、#9 调整单同链且跨月需授权、#10 风险预警参数化、#11 待办范围(待审批+同步失败+回款未指定批次)、#13 支付环节 5 默认值、#15 一期仅 FULL 模式、#17 参数查看放开/修改限管理员、#18 企业户 2‰ 回溯、#21 退货当期冲减已结算走调整单、#22 预收/保证金/代收款暂不计入、#23 按到账金额、#24 负绩效照算不归零。 - -## 二、IT / T+ 侧(建议回复期限:____) - -> **2026-10-20 更新**:已用 T+12.3 数据字典完成字段级核对(1,457 页 / 931 张表 / 21,019 个字段),下列问题由 18 项收敛为 **13 项 IT 待确认 + 1 组业务裁决**,每项附字典候选字段。字段级证据与来源页见《T+字段映射草案_v0.1_2026-10-20.md》,完整清单见《T+对接数据需求清单_v1.5_2026-10-20.xlsx》。 - -### A. 待确认(按优先级) - -| 新# | 原# | 事项 | 字典候选(已定位) | 仍需答复 | -| --- | --- | --- | --- | --- | -| 1 | 1 | 成本额字段与成本口径 | SA_SaleOrder_b.LatestCost;SA_SaleDelivery_b.costPrice/costAmount/CostPriceGetType | 取订单最新成本还是出库成本;取数时点与精度 | -| 2 | 2+3 | 发货日与到账日口径 | 发货:voucherdate/SendDate/deliveryDate/auditeddate;到账:voucherDate/auditedDate/createdTime | 分别取哪个字段;签收日/银行到账日能否提供 | -| 3 | 4 | 幂等键与作废重开 | 各表 code + id 主键 | code 是否终身唯一;作废重开是否换号 | -| 4 | 5 | 三单关联与核销路径 | SA_SaleDelivery.SourceVoucherCode、_b.saleOrderCode/saleOrderId;ARAP_ReceivePayment.SaleOrderCode/SaleOrderID;ARAP_StrikeBalance | 主关联路径;分批发货/部分核销如何取 | -| 5 | 6 | 人员编码/工号与经理隶属 | AA_Person.code/name/iddepartment;AA_Department.idparent/iddirector(无直属上级字段) | code 是否即工号;业务员→经理隶属如何维护 | -| 6 | 7 | 对接方式与安全 | 字典不涉及 | REST/视图/中间表/文件;只读账号、接口文档、样例数据 | -| 7 | 8 | 负数/红字/退货/冲销规则 | isCounteractDelivery、returnQuntity/backSentQuantity、voucherstate、ARAP_StrikeBalance | 实际使用形式、原单关联、是否推送 | -| 8 | 9 | 存量起始与增量水位 | updated/createdTime/madeDate/auditedDate/ts | 存量起始日;增量用哪个时间戳;时区 | -| 9 | 10+v1.4#18 | 客户主数据匹配与变更 | AA_Partner.code/name/Contact/representative/disabled/updated | 唯一键;改名/换负责人/合并;负责人取 Contact 还是 representative | -| 10 | 11+16 | 收款方式与确认/核销枚举 | AA_SettleStyle;ARAP_ReceivePayment.IdSettleStyle/cancelState/voucherstate | 完整枚举与以物抵顶代码;核销状态含义与人工确认依据 | -| 11 | 12+13 | 产品数量语义与发货单价 | ST_CurrentStock.baseQuantity;AA_InventoryPrice/AA_InventoryUnitPrice;SA_SaleDelivery_b.price/taxPrice | 数量取现存量/在途/累计销量;发货单价口径与含税 | -| 12 | 14+17 | 低频字段存在性:特殊业务标记/市场拓展计划 | SA_SaleOrder.idbusinesstype;AA_Person 自定义项;未检出市场拓展计划表 | 有无可识别字段/表;无则人工维护 | -| 13 | 15 | 同步窗口 | 字典不涉及 | 每周时间点,避结账/备份;失败重试策略 | - -### B. 口径裁决(1 组,转业务方) - -含税口径、退货红字冲减、预收/保证金/代收、手续费净额、负绩效表述(原 #18,对应《待澄清问题清单》#20–#24)。 - -### C. 已由字典补齐、仅需确认可用性 - -1. **人员编码**:字典已定位 `AA_Person.code`,请确认是否即工号;若为自动内部编码,请指明工号字段。 -2. **客户档案**:字典已定位 `AA_Partner` 主表(编码/名称/联系人/停用/地区等),请确认可提供。 -3. **映射列**:v1.5 清单已回填「T+ 表.字段 / 类型 / 枚举 / 系统目标列」,请按实际环境核对并修正。 - -## 三、报表口径补充确认(2026-10-19 新增,随本轮开发一并排) - -> 报表统计模块(需规 2.4 / FR-029~FR-032)开工在即,以下三项请确认;未答复按「建议默认」实现,后续可调。 - -| # | 事项 | 建议默认(将按此实现) | -| --- | --- | --- | -| R1 | 部门绩效汇总表的「部门」口径 | 部门 = 经理团队(经理 + 其直属业务员),按人员档案的隶属关系展开;离职人员历史业绩留在原团队;经理的 5% 全公司部分单独一列 | -| R2 | 回款统计的「回款天数区间」档位 | ≤0 天(先款后货)|1-30|31-60|61-90|91-180|181-360|361 以上|无回款天数,共 8 档;未命中区间显示 0 | -| R3 | 导出/打印模板要素 | 公司信息页眉(名称+logo)、报表标题、筛选条件、导出时间与导出人、模板版本号、财务复核栏、领导签字栏、日期栏 | - -另:报表查看权限(FR-029 参与者含「营销后勤(授权范围内)」)——请随第一部分 B-6 权限清单一并明确营销后勤是否需要查看报表、可见哪些列。 - ---- - -**发送建议**:第一部分发业务方(含 C 两项勘误确认);第二部分发 IT/T+(v1.4 附表一并);第三部分随开发进度与业务方顺带确认。 diff --git a/docs/部署硬件需求.txt b/docs/部署硬件需求.txt deleted file mode 100644 index b28e5fb..0000000 --- a/docs/部署硬件需求.txt +++ /dev/null @@ -1,241 +0,0 @@ -衍水集团营销人员工资管理系统 -部署硬件需求说明 -================================================================ -版本:v1.0 -日期:2026-10-21 -适用:内部系统部署(数十人并发,无公网访问) -依据:仓库实际运行架构(docker/docker-compose.dev.yml、backend/pyproject.toml、 - backend/app/core/db.py、docs/备份恢复手册.md、ai-aux/AI_CONTEXT.md) - - -================================================================ -一、结论摘要(先看这一节) -================================================================ - -推荐配置:2 核 CPU / 8 GB 内存 / 100 GB SSD(Linux 单机) -最低配置:2 核 CPU / 4 GB 内存 / 100 GB SSD -演示配置:1 核 CPU / 2 GB 内存 / 40 GB SSD(仅限试用,不适合正式使用) - -一句话:内部系统的瓶颈不在 CPU,而在「内存余量」和「磁盘容量」。 - 内存从 4 GB 升到 8 GB 的成本极低,却能一次性消除以后所有内存不足的排查; - 磁盘不要按当前数据量买,要按「备份 + 恢复演练」的双倍空间买。 - - -================================================================ -二、负载前提(为什么是这个配置) -================================================================ - -以下事实全部来自本仓库,不是通用模板: - -1) 内部系统、数十人并发 - 出处:ai-aux/AI_CONTEXT.md:101「并发极低(内部系统数十人)」 - 含义:CPU 核心数不是瓶颈,2 核足以支撑全部并发请求。 - -2) 全栈同步架构 + 单 worker,重活走线程池 - 出处:CLAUDE.md(分层约定)、backend/app/core/db.py:29 - 含义:一个请求占用一个线程;绩效批量核算、Excel 导出会短暂吃满一个核, - 因此要留出至少 1 个空闲核给后端,避免请求排队。 - -3) MySQL 8.0 + Redis 7 双容器,Redis 开启 AOF - 出处:docker/docker-compose.dev.yml:11、:44 - 含义:MySQL 是内存消耗大户(默认配置下性能很差,必须调参); - Redis 只存验证码、Token 黑名单、登录失败计数,用量极小(<50 MB)。 - -4) 备份策略:每日全量 gz + binlog 增量,各自保留 30 天 - 出处:docs/备份恢复手册.md:11 - 含义:磁盘需按「业务数据 + 索引 + 30 天 binlog + 30 份全量备份」计算。 - -5) 恢复演练需恢复到独立临时库 payroll_drill_* - 出处:docs/备份恢复手册.md:45 - 含义:演练瞬间需要约「2 倍数据库体积」的可用空间。 - 这是最容易被低估的一项,磁盘卡着下限买会在第一次演练时爆盘。 - -6) 报表导出用 openpyxl 全量载入内存 - 出处:backend/app/services/report_export.py:18 - 含义:导出大报表时后端进程内存峰值会翻倍,必须在内存预算里留余量。 - - -================================================================ -三、正式生产推荐配置(内部系统,数十人) -================================================================ - -项目 规格 说明 ----------------------------------------------------------------- -CPU 2 核(推荐 4 核) 2 核给容器与 MySQL, - 1 核给 uvicorn(workers=2 上限), - 1 核余量给系统与备份任务。 - -内存 8 GB(最低 4 GB) 8 GB 才有余量承受 - 「导出 + 核算 + 备份」同时发生。 - -磁盘 100 GB SSD(推荐 200 GB) 必须是 SSD。HDD 上 MySQL 的 - ON UPDATE CURRENT_TIMESTAMP - 高频写入会明显拖慢。 - -网络 内网千兆 无需公网 IP、域名、SSL 证书、CDN。 - -操作系统 Linux 推荐 Ubuntu 22.04 LTS / Rocky 9。 - (Ubuntu 22.04 / Rocky 9) 备份、恢复、巡检脚本全部是 .sh - (scripts/ 目录),Linux 为原生路径。 - 若必须用 Windows Server,需 2022 + - WSL2 或 Git Bash 运行脚本。 - - -================================================================ -四、内存分配明细(8 GB 的具体切法) -================================================================ - -组件 建议占用 关键设置与说明 ----------------------------------------------------------------- -MySQL 8.0 3.5 GB innodb_buffer_pool_size = 2G - ★ 默认仅 128 MB,不调会大量走磁盘, - MySQL 会成为整机最慢的一环。 - -后端 uvicorn 1.5 GB workers = 2 - 报表导出时单 worker 峰值可达 600 MB ~ 1 GB - (openpyxl 全量载入内存)。 - -Redis 7 256 MB maxmemory 256mb - 实际用量 < 50 MB,设置上限只为兜底防失控。 - -Nginx + 系统 1 GB 静态资源(前端 dist)+ 反向代理 /api。 - -余量 1.75 GB mysqldump 备份进程、binlog 压缩、系统缓存。 - ----------------------------------------------------------------- -4 GB 内存版(最低配置)的分配: - MySQL 1.5~2 GB(innodb_buffer_pool_size = 1G) - 后端 0.8~1 GB - Redis 128 MB(maxmemory 128mb) - Docker + Nginx + 系统 0.6 GB - 余量 ~0.6 GB - ★ 这是「刚好够用」,一旦「导出报表」与「每日备份」撞在同一时刻, - OOM Killer 会优先杀 MySQL。这就是推荐 8 GB 的原因。 - - -================================================================ -五、磁盘空间算式(100 GB 的来历) -================================================================ - -项目 估算占用 ----------------------------------------------------------------- -业务数据(数十人,5 年) ≈ 1 GB -索引 + binlog 30 天(ROW 格式) ≈ 5 GB -全量备份 30 份(gz,约数据量 20%) ≈ 6 GB -恢复演练临时库(峰值 = 2 倍数据量) ≈ 2 GB -系统 + Docker 镜像 + 应用日志 ≈ 25 GB ----------------------------------------------------------------- -合计 ≈ 39 GB - -结论:100 GB 可支撑 2~3 年不需扩容。 - 按 docs/备份恢复手册.md:87 的 80% 磁盘水位告警,100 GB 有充足缓冲。 - - -================================================================ -六、内部部署必须调整的四项(现有配置存在隐患) -================================================================ - -1) 数据库端口必须收敛,不能监听所有网卡 - 现状:docker/docker-compose.dev.yml:27 为 "3306:3306", - :48 为 "6379:6379",等价于绑定 0.0.0.0。 - 风险:内网任何一台办公电脑都能直连 MySQL 试 root 密码。 - 改法(二选一): - A. 只允许宿主机访问 - ports: - - "127.0.0.1:3306:3306" - - "127.0.0.1:6379:6379" - B. 后端与数据库在同一 compose 网络内时,直接删掉这两行 ports, - 容器之间通过服务名互访,宿主机只暴露 80/443。 - -2) 前端必须构建成静态文件 + Nginx 反向代理 - 禁止把 vite dev 服务器当正式环境用: - 开发服务器会暴露全部源码,且不提供任何访问控制。 - 正式做法:pnpm build 产出 frontend/dist,由 Nginx 托管, - /api 反向代理到后端 8000 端口。 - -3) 备份必须异地留一份 - 内部系统最常见的「数据全丢」场景就是单机故障。 - 在 scripts/backup_full.sh 之后追加一步 rsync 到 NAS 或公司文件服务器。 - -4) 提前预留反向代理层 - 不接公网就不需要 WAF / CDN / SSL。 - 但如果公司后续有统一域名单点登录(SSO)规划, - Nginx 反代层要提前留好,避免到时大改架构。 - - -================================================================ -七、三档速查表 -================================================================ - -场景 CPU 内存 磁盘 备注 --------------------------------------------------------------------------------- -试用 / 演示(< 5 人) 1 核 2 GB 40 GB SSD 仅跑小数据量; - 导出大报表会 OOM - -正式内部(数十人) 2 核 4 GB(建议 8 GB)100 GB SSD 推荐方案 -【推荐】 - -内部 + 冗余 4 核 ×2 8 GB ×2 200 GB SSD ×2 含从库与监控; -(从库 + 监控) 工资系统若需 - 审计级可靠性 - 值得投入 --------------------------------------------------------------------------------- - - -================================================================ -八、可选加速项(非必须) -================================================================ - -1) 图表库已本地化 - ECharts 静态文件已放在 docs/design/echarts.min.js, - 前端自托管即可,不依赖外网 CDN,符合「内网加载不可靠」的既定决策。 - -2) 日志盘分离 - 若开启审计日志长期留存,把 backend/logs/ 挂载到独立磁盘, - 避免日志写满系统盘导致 MySQL 无法写入。 - -3) 备份异地化 - 本机备份 + 定时 rsync 到 NAS 或对象存储,构成「本地 + 异地」两份。 - - -================================================================ -九、生产环境仍需完成的事项(本文件之外) -================================================================ - -1) 生成 docker/docker-compose.prod.yml: - - 端口收敛到 127.0.0.1 - - MySQL innodb_buffer_pool_size 等参数调优 - - 容器 mem_limit / cpus 资源限制 - - Nginx 反向代理静态前端 + /api - -2) 后端启动参数由开发模式改为生产模式: - - 去掉 --reload(生产环境必须去掉) - - 设置 workers=2 - -3) backend/.env 中 APP_SECRET_KEY 必须换成强随机值, - MYSQL_PASSWORD / REDIS_PASSWORD 两处(docker/.env 与 backend/.env)保持一致。 - -4) 首次部署执行 alembic upgrade head,并创建管理员账号: - uv run python -m app.cli create-admin --username admin - -5) 配置每日定时任务:全量备份 + 增量归档(见 docs/备份恢复手册.md) - - -================================================================ -十、附:数据来源索引 -================================================================ - -ai-aux/AI_CONTEXT.md:101 并发规模判断(数十人) -docker/docker-compose.dev.yml:11 MySQL 8.0 容器 -docker/docker-compose.dev.yml:27 MySQL 端口映射(需收敛) -docker/docker-compose.dev.yml:44 Redis 7 容器与 AOF -docker/docker-compose.dev.yml:48 Redis 端口映射(需收敛) -backend/app/core/db.py:29 同步引擎与连接池配置 -backend/app/services/report_export.py:18 报表导出(内存峰值来源) -docs/备份恢复手册.md:11 备份策略 -docs/备份恢复手册.md:45 恢复演练临时库 -docs/备份恢复手册.md:87 磁盘水位 80% 告警阈值 -scripts/ 备份 / 恢复 / 巡检脚本(.sh) - -================================================================ -(文件结束) diff --git a/docs/项目阶段报告_2026-10-20.md b/docs/项目阶段报告_2026-10-20.md deleted file mode 100644 index 2575ba0..0000000 --- a/docs/项目阶段报告_2026-10-20.md +++ /dev/null @@ -1,80 +0,0 @@ -# 衍水集团营销人员工资管理系统项目阶段报告 - -- **报告日期**:2026-10-20 -- **报告范围**:M4 ⑤ 报表统计、⑧ 工作台完成情况与 M4 收尾结论 -- **项目分支**:`feat/m3-increments`(已合并 `main`,merge commit `3611474`) -- **阶段结论**:除 ⑥ T+ 数据同步受外部答复阻塞外,十大功能块全部交付;后端全量 **862 用例通过**,报表、工作台、核算月结三条 e2e 链路实跑通过。 - -## 一、3P 阶段摘要 - -### Progress(进展) - -M4 两块(⑤ 报表统计、⑧ 工作台)已完成并通过 code-review 修复。报表侧交付个人绩效明细、部门汇总、业务统计、回款统计四张报表、Excel 签字导出与独立打印视图;工作台侧交付经营总览、待办事项、风险预警、最近动态四区块,待办与预警实时派生并参数化。本阶段同时完成 M4 修复批次的提交、全量回归与 e2e 实跑,开发计划 3.3 答复状态已回填。 - -### Plans(计划) - -下一步优先解析 T+12.3 数据字典,形成六类单据字段映射草案并自答 IT 清单中可自答部分;~~其次补齐 code-review 遗留的方案版本承载与审批单快照~~(已于 2026-10-20 完成,V11);需规 V2.2 修订与对照表回填择期进行。 - -### Problems(问题) - -⑥ T+ 数据同步仍受 IT 18 项答复阻塞,同步失败类待办/预警暂以「模块未启用」显式降级。业务方仍有 #1–#3 二次分摊、#20 含税口径、#4/#6/#12 补值与两处勘误待确认;审批角色权限细目未给出,当前按 `role_code` 粗粒度运行。需规仍含已作废条款,对外引用需注明以对照表/计划第三章为准。 - -## 二、阶段定位与完成度 - -| 维度 | 当前状态 | 说明 | -| --- | --- | --- | -| 项目阶段 | 开发收尾期 | M1–M3 与 M4 ⑤⑧ 已交付,仅 ⑥ 待外部输入 | -| 整体完成度 | 90% | 十大功能块交付;⑥ 按 0% 计入 | -| 交付主线 | M4 报表统计 + 工作台 | 前后端闭环,已合并 main | -| 质量状态 | 全绿 | 后端 862 passed(11:32);e2e role_home 4/4、report 12/12、calc_settlement 8/8 | -| 主要风险 | 外部对接与口径变更 | T+ 映射未定;含税口径未答复可能触发历史绩效重算 | - -## 三、已完成成果 - -### 1. 报表统计(M4 ⑤) - -- 四表接口 `/api/v1/reports/*`:个人绩效明细、部门绩效汇总、业务统计、回款区间统计。 -- 部门归属按 `personnel.manager_id` 实时上溯;回款区间 8 档(≤0 / 1-30 / 31-60 / 61-90 / 91-180 / 181-360 / 361+ / 无天数)。 -- 全公司 5% 按「有聚合行经理各计一次」计算,并与月结 `total_payable` 对拍;对账块单列聚合行舍入差。 -- Excel 签字导出(openpyxl + StreamingResponse,ASCII 文件名)与独立打印视图(五块结构、每页表头、签字栏)。 -- 权限 `admin/finance/leader` 前后端双层。 - -### 2. 工作台(M4 ⑧) - -- 单端点 `/api/v1/dashboard` 一次返回四区块:经营总览、待办事项、风险预警、最近动态。 -- 待办与预警**实时派生**(不落表、不引调度器);待办按角色过滤;逾期预警排除已终止业务。 -- 预警阈值参数化:`warning.enabled`、`warning.receipt.overdue.days=90`、`warning.approval.timeout.days=3`(V10,参数注册表 22 项)。 -- 前端 `/dashboard` 四区块 + ECharts 5.6 按需引入(SVG,显式思源黑体,规避 Windows 默认雅黑)。 -- 普通用户落地页统一由 `router/access.ts` 解析(工作台 → 业务数据 → 回款),修复无限重定向。 - -### 3. 质量与收尾 - -- 后端全量 `uv run pytest -q` → **862 passed(11:32)**;`pnpm type-check` 与 `pnpm build` 通过。 -- e2e 实跑:`role_home_flow` 4/4、`report_flow` 12/12、`calc_settlement_flow` 8/8;`report_flow` 回款统计改为按本次业务编号下钻断言,脚本可重复运行。 -- 运行后核对:月结审批开关恢复为 1,无 `e2e_role_*` 残留账号。 -- 开发计划 3.3.1 与《待确认事项汇总》已按 24 项答复分组回填(13 默认 / 4 按答复 / 3 部分 / 4 开放)。 - -## 四、当前进行中工作 - -无。M4 代码与文档已提交并合并 `main`(`3611474`)。 - -## 五、下一步计划 - -1. **T+ 同步前置**:解析 `docs/T_12.3数据字典/`,产出人员/产品/业务/发货/回款/客户六类字段映射草案,自答 IT 18 项中可从数据字典确认的部分。 -2. ~~**code-review 遗留 2 项**:方案生效版本承载、审批单内容快照(orders 加方案 JSON 快照列 + 前端详情展示)。~~ ✅ 已完成(2026-10-20,V11 迁移):方案行版本化 + 审批单版本号/内容快照 + 前端展示。 -3. **需规 V2.2**:修订 26 天示例、含运费公式、协助 25% 等过时条款,回填 2026-10-15 补充需求;对照表 v2 收编 24 项答复。 -4. **清理类**:5 处超长函数、散参数 DTO、`useDropdownOptions` 余两页、前端菜单图标。 -5. **待外部输入**:业务方催办、审批权限清单、IT 18 项答复。 - -## 六、风险与应对 - -| 风险 | 影响 | 应对 | -| --- | --- | --- | -| IT 答复持续缺失 | ⑥ 无法开工,同步类待办/预警无法真实展示 | 先做数据字典映射草案;催办清单已含高优 9 项与三缺口 | -| 含税口径(#20)改变 | 历史绩效可能需要重算 | 当前按不含税实现;答复后评估重算范围并授权留痕 | -| 二次分摊口径(#1–#3)改变 | 已生成台账/月结可能需要调整 | 暂定口径已标注;变更走口径调整,重算需授权留痕 | -| 需规含作废条款 | 对外交付物误导 | 引用以对照表/计划第三章为准;V2.2 修订前排期 | - -## 七、报告结论 - -M4 报表统计与工作台已完成交付并合并 `main`,系统除 ⑥ T+ 数据同步外具备完整业务闭环。质量证据充分(全量测试与三条 e2e 链路),剩余工作以外部输入与审计性技术债为主,可按计划推进。 diff --git a/tasks/archive/2026-10-27-tplus-sync-plan.md b/tasks/archive/2026-10-27-tplus-sync-plan.md new file mode 100644 index 0000000..ec16112 --- /dev/null +++ b/tasks/archive/2026-10-27-tplus-sync-plan.md @@ -0,0 +1,65 @@ +# 下一阶段开发计划:T+ 关联核验与同步管理 + +日期:2026-10-27。用户已选择“关联核验与同步管理”,并授权按计划实施。 + +## 本轮目标与当前证据 + +已有 933,203 条九类源数据快照,两轮去重通过;同步仍只有命令行入口。管理员需要查看批次、进度和异常,并能发起读取、关联核验和失败重试。 + +本轮补齐这条管理流程,同时用真实只读账套确认枚举和关联覆盖。工资业务表写入、退货计提、成本/日期口径及时间增量继续等待业务确认;不把本轮完成解释为整个项目已可交付。 + +## 设计决定 + +- 沿用 FastAPI、同步 SQLAlchemy、MySQL、Vue 3 和现有样式;不引入队列依赖。 +- HTTP 只创建持久化 QUEUED 任务并立即返回;独立 CLI worker 处理长任务,避免请求等待大量数据读取,也避免依赖进程内 BackgroundTasks。 +- 同一账套的读取和核验由 MySQL 连接级命名锁串行执行;CLI 直接读取与 worker 共用锁。进程中断留下的 RUNNING 记录只有在取得锁、确认无执行者后才可判失败并恢复。 +- 新批次记录实体范围、重复条数、来源重试批次、请求幂等键、请求人和核验结果。历史缺失元数据保持未知,不从名称/金额猜测。 +- 关联核验从 SM_VoucherType/eap_EnumItem 读取类型和状态,按单据类型关联收款明细与销货单、销售订单;不按客户名称或金额拼接,不自动分摊回款。 +- 只存系统字典、结构和数量汇总,不向页面返回 staging 的原始 payload、源连接参数或原始异常 SQL。 +- 连接默认关闭。可显式指定 D 盘的本地只读连接文件,不把凭据复制进项目配置或 HTTP 请求。 +- SQL Server 2008 R2(10.50.x)仍是交付目标;源查询保持旧版语法,2022 PoC 不能通过同版本验收。Docker 磁盘镜像位置保持不变。 + +## 接口合同 + +统一前缀 `/api/v1/system/tplus`,全部要求管理员,响应沿用 `{code,message,data}`;业务字段用蛇形,分页用 `pageNum/pageSize` 与 `list/total/pageNum/pageSize`。 + +| 接口 | 用途 | +|---|---| +| GET `/overview` | 配置可用性、任务数量、累计新增快照、最近关联核验概要;不查询源库 | +| GET `/batches` | 批次分页,按状态/任务类型筛选,按 id 倒序 | +| GET `/batches/{batch_no}` | 批次详情,含执行范围、重试关系和已脱敏核验结果 | +| GET `/batches/{batch_no}/errors` | 本批异常分页,可按实体筛选;不返回原始 payload | +| POST `/batches` | 创建 READ 或 AUDIT 任务;READ 指定白名单实体,AUDIT 不接受实体范围 | +| POST `/batches/{batch_no}/retry` | 仅重试 FAILED/PARTIAL;创建新批次并保留原批次,无法确定范围的历史记录需重新选择范围 | + +创建/重试请求携带 UUID `request_key`。数据库唯一约束原子保护;同键同意图返回原批次,同键不同意图返回 400。重试锁定父批次;同请求键复用已有任务,不同请求键遇到已有 QUEUED/RUNNING 重试时返回明确的 400,防止重复排队且不混淆幂等意图。 + +任务状态为 `QUEUED/RUNNING/SUCCEEDED/PARTIAL/FAILED`。成功/失败计数只反映原始读取,不伪造业务导入成功。重试依靠全量快照去重,时间水位保持禁用。 + +CLI 提供 `tplus-worker --once/--watch`,可处理读取和核验;原 `tplus-stage` 保持可用。worker 无任务时退出或等待;配置缺失、源连接失败、字段不符均写入任务失败记录。 + +## 实施任务与依赖 + +1. 核验查询与报告:固化系统枚举、收款方向、带类型的销货/订单关联和歧义统计;真实只读库执行,产出映射 v0.3 和客户确认单。 +2. 元数据迁移:新增批次范围/幂等键/重试关系/核验结果等字段;Alembic、V15 SQL、初始化脚本及模型同步,旧记录可读。 +3. 执行协调:实现队列创建、幂等与重试;共用命名锁、worker 和中断恢复,不修改工资业务表。 +4. 管理查询服务:批次/异常分页、详情和汇总,只返回受控字段;列表不加载核验结果大字段。 +5. 管理 API:管理员认证、请求校验、统一响应、创建/重试审计、源配置关闭时的可操作错误。 +6. 同步管理页面:接入实际接口,展示批次/异常/核验结果;支持选择读取范围、排队、失败重试和刷新,管理员菜单与后端权限一致。 +7. 真实流程验收:用只读副本做一次关联核验和小范围人员重读;浏览器验证筛选、详情、空态、重试、权限及响应式。 +8. 回归与交接:隔离数据库/Redis 验证迁移、服务/API;前端类型检查与构建,更新模块文档、上下文和本清单。 + +详细验收和执行状态记录在 `tasks/todo.md`。每个任务先完成定点测试,再进入依赖它的任务;本轮不自动提交、推送或部署。 + +## 验收与保留门槛 + +- 真实字典和关联数量有可重跑 SQL、源版本与时间证据;遇到多订单、无类型或金额分摊规则未定时明确保留待确认。 +- 相同请求不重复创建任务,同账套不并发执行;失败重试保留原记录并不重复写入相同快照。 +- 管理员可以完成“排队 → worker 执行 → 查看结果/异常 → 重试”流程,非管理员后端 403、前端无菜单。 +- 页面不显示凭据、原始个人信息、SQL 异常或误导性的“业务导入完成”;配置关闭、空态、加载和失败状态可见。 +- 测试只使用隔离的 MySQL/Redis;运行时核验只读 T+ 副本,业务数据表不接入写入。 +- 真正的 2008 R2 环境安装仍缺合法 Windows/SQL Server 安装介质;该项作为后续交付前置,不伪造完成。 + +## 项目后续路线 + +完成本轮后,依据客户确认的成本、日期、人员/客户/产品分类、单据有效范围和回款分摊规则,再实施业务表导入。取得合法介质后安装 D 盘虚拟机并执行完整 2008 R2 验收;随后才启用真实增量、每周任务和部署交付。 diff --git a/tasks/archive/2026-10-27-tplus-sync-todo.md b/tasks/archive/2026-10-27-tplus-sync-todo.md new file mode 100644 index 0000000..c926f02 --- /dev/null +++ b/tasks/archive/2026-10-27-tplus-sync-todo.md @@ -0,0 +1,52 @@ +# T+ 关联核验与同步管理任务清单 + +所有任务依照 `tasks/plan.md`。本轮已完成;真正 2008 R2 验收与客户业务确认保留为下一阶段门槛。 + +## 1. 真实枚举与关联核验 +- [x] 固化 SQL Server 2008 R2 语法的只读核验查询,按单据类型区分销货、费用、期初应收和收入。 +- [x] 对收款行 → 销货单/明细 → 订单进行覆盖、悬空和歧义计数,不按名称/金额拼接。 +- [x] 真实副本执行并生成映射 v0.3、客户确认单;仅记录系统字典和汇总。 +- 验证:源查询实跑,报告无凭据或客户个人信息。依赖:无。预计 3–5 文件。 + +## 2. 批次元数据迁移 +- [x] 记录实体范围、跳过数量、幂等键、父批次、请求人和核验结果,旧批次可读。 +- [x] 同步 Alembic、V15、初始化脚本和模型;空库迁移及旧库升级通过。 +- 验证:模型与 DDL 测试、隔离库迁移。依赖:无。预计 5 文件。 + +## 3. 队列、串行执行与重试 +- [x] READ/AUDIT 任务持久化排队;同键同意图复用,同键异意图拒绝。 +- [x] 共用命名锁防并发,worker 支持 once/watch,原 CLI 入口保持可用。 +- [x] 锁定父批次防重复重试;中断记录仅在无执行者时恢复,异常不泄漏源参数。 +- 验证:先失败测试再实现;真实隔离 MySQL 并发与 worker 定点核验。依赖:1、2。分服务/CLI 两批实施。 + +## 检查点 A +- [x] 核验、迁移与执行服务定点通过;工资业务表写入仍关闭。 + +## 4. 管理查询与接口 +- [x] 分页查询批次、详情和异常,列表不加载核验 JSON/原始 payload。 +- [x] 管理员接口与创建/重试审计完成,参数校验和源配置关闭行为明确。 +- [x] 汇总能区分暂存完成与 2008 R2/业务口径待确认。 +- 验证:隔离 API 测试覆盖 401/403/400/404、分页、幂等和重试。依赖:3。分查询层、API 两批实施。 + +## 5. 同步管理页面 +- [x] 管理员菜单、概况、批次表、异常详情和关联结果接入实际 API。 +- [x] 创建读取/核验、失败重试、刷新与筛选可用;状态均为业务中文。 +- [x] 空态、加载、异常、配置关闭、权限与小屏布局可验证。 +- 验证:Vue 类型检查、生产构建、真实浏览器。依赖:4。分 API/路由、页面两批实施。 + +## 检查点 B +- [x] “排队 → 执行 → 查看 → 重试”完整流程有实际运行证据。 + +## 6. 完整验证与文档 +- [x] 真实副本关联核验与人员重读通过,重复快照不新增;非管理员被拒绝。 +- [x] 定点及必要回归、迁移、Ruff、类型检查、构建和浏览器检查通过。 +- [x] 模块 README、字段确认材料、AI_CONTEXT、PROJECT_PROGRESS 和本清单更新。 +- [x] 完成逐项验收;未完成的 2008 R2 环境和业务确认明确列为交付前置,不计入本轮已完成项。 +- 依赖:1–5。 + +## 验收证据(2026-10-27) + +- 单元 602 项,管理/并发/结构定点 18 项,Ruff、类型检查、构建通过;完整回归中的环境覆盖影响已独立复验。 +- D 盘 reports/management_verification_2026-10-27.json:人员去重、关联检查、六类业务表行数不变。 +- ai-aux/preview/tplus/verification.json:浏览器真实流程与四档宽度;模拟状态另见 state-verification.json。 +- V15 隔离库回滚/升级通过;head=e5f607a8b9c0。运行步骤、映射和客户确认材料均已更新。 diff --git a/tasks/plan.md b/tasks/plan.md new file mode 100644 index 0000000..95bead2 --- /dev/null +++ b/tasks/plan.md @@ -0,0 +1,56 @@ +# 下一阶段开发计划:T+ 数据导入与同版本验收 + +日期:2026-10-28。基于关联核验与同步管理轮次完成后的实际情况制定;上一轮计划与任务清单已归档至 `tasks/archive/2026-10-27-tplus-sync-*.md`。 + +## 当前实际状况 + +- 同步管理已完成:批次/异常/重试/锁/页面验收通过;staging 累计 933,203 行,六类工资业务表尚未接入写入。 +- 口径进展:澄清清单 24 项答复基本到齐;对照表 v2 已裁决经理个人户(#7)、协助 25%(#6/#15)、信息员(#9)、企业户 3‰(#20)等冲突。9.8 方案中蓝色字体标注的原方案算法作废,毛利润率按不含运费口径执行。 +- 仍未确认:含税取数、预收/保证金/代收、二次分配三项、三级角色职权,连同 T+ 口径 13 项与环境接入 5 项,已整理于 `docs/待确认事项清单_2026-10-28_v2.xlsx`(L1–L7)。 +- 经理个人户:微信沟通确定按 9.8 方案执行、不计个人户部分,客户群确认中;系统参数已预留,确认后调整参数即可,无需开发。 +- 环境差距:合法 Windows 与 SQL Server 2008 R2 安装介质未到位,D 盘虚拟机仅有外壳;当前分支约 65 个文件未提交。 + +## 目标与顺序 + +先收口工程,再并行推进同版本环境验收与客户口径确认;口径闭环后实施 staging 到工资业务表的导入,最后交付托管与部署。 + +### P0 工程收口(无外部依赖,立即执行) + +1. 将本轮 T+ 同步管理成果按迁移、后端服务、前端页面、文档拆分为规范提交;合入前本地构建与测试通过。 + +### 轨道 A:同版本验收环境(外部依赖:安装介质) + +- A1 先行细化 `docs/SQLServer2008R2测试环境.md`:装机步骤、恢复步骤,以及驱动、只读权限、六类查询、中文/日期/金额、断连超时、重复同步的验收清单。 +- A2 取得合法介质后,在 `D:\work\app\tplus-vm` 完成系统与数据库安装。 +- A3 恢复原始备份并执行完整验收,产出报告,关闭同版本兼容 PENDING 状态。 + +### 轨道 B:业务口径确认(外部依赖:客户填写) + +- B1 发送 v2 清单:客户填「客户确认单-精简版」,IT/服务商填材料项;L1(含税取数)、L2(预收等)与确认单 #1/#3/#6 一并答复,避免重复提问。 +- B2 跟进客户群对经理个人户的反馈,回填 L6。 +- B3 答复回收后更新字段映射文档与暂定口径记录:二次分配三项(L3–L5)追认、三级角色职权(L7)在页面验收时核对。 + +### 轨道 C:T+ 数据导入开发(依赖轨道 B 闭环;设计可先行) + +- C1 先行起草「staging → 业务表写入」设计:表映射、金额精度(金额用 Decimal、比例和日斜率用 Fraction)、幂等与重算授权留痕、人工字段保护(回款/发货批次由系统人工指定,业务归属变更不回溯历史)、事务边界;明确标注等待确认的差异点,口径闭环后评审定稿。 +- C2 主数据导入(人员、客户、产品):依赖 #9、#10、#11。 +- C3 订单 → 发货 → 回款导入:依赖 #1–#8、#13(成本、日期、分摊、核销、初始化)。 +- C4 负向事件处理(退货、红冲、负绩效):依赖 #8;口径已定为负绩效照公式出数、不归零。 +- C5 增量变更发现:依赖 #13;收付款表无 `updated` 字段,需验证 rowversion 与删除/作废的发现方式,在此之前时间水位保持禁用。 + +### 轨道 D:交付收尾(依赖 A3 与轨道 C 完成) + +- D1 `tplus-worker` 服务托管(Windows 服务方案)。 +- D2 每周同步任务编排与失败告警。 +- D3 客户内网独立部署与最终验收。 + +## 验收与保留门槛 + +- 未确认项不进入正式核算;确认单未闭环前不实施业务表写入。 +- 导入保护人工字段;每笔回款只核算一次;重算须授权并留痕。 +- 2008 R2 验收未完成前,2022 恢复副本的结果不作为同版本兼容证据。 +- 每个任务先完成定点测试再进入依赖任务;回归使用隔离的 MySQL/Redis。 + +## 项目后续路线 + +轨道 C 完成、A3 通过后进入轨道 D;部署验收通过即转入运维期(每周同步、参数调整走系统设置与版本管理)。 diff --git a/tasks/todo.md b/tasks/todo.md new file mode 100644 index 0000000..e4844e0 --- /dev/null +++ b/tasks/todo.md @@ -0,0 +1,38 @@ +# T+ 数据导入与同版本验收任务清单 + +依照 `tasks/plan.md`(2026-10-28)。上一轮清单已归档至 `tasks/archive/2026-10-27-tplus-sync-todo.md`。 + +## P0 工程收口 +- [ ] 拆分提交本轮 T+ 同步管理成果(迁移、后端、前端、文档);提交前 Ruff、单元测试、前端类型检查与构建通过。 +依赖:无。 + +## 轨道 A:同版本验收环境 +- [ ] A1 细化 2008 R2 测试环境与验收手册(无介质可先做)。 +- [ ] A2 取得合法介质并完成虚拟机安装。 +- [ ] A3 恢复原始备份并执行完整验收,产出报告。 +依赖:A2 等介质到位;A3 依赖 A2。 + +## 轨道 B:业务口径确认 +- [ ] B1 发送 `docs/待确认事项清单_2026-10-28_v2.xlsx` 并跟进填写。 +- [ ] B2 回填经理个人户客户群反馈结果(L6)。 +- [ ] B3 答复回收后更新映射与暂定口径记录。 +依赖:无;B1 立即可发。 + +## 轨道 C:T+ 数据导入开发 +- [ ] C1 起草 staging → 业务表写入设计,标注等待确认的差异点。 +- [ ] C2 主数据导入实现与测试。 +- [ ] C3 订单/发货/回款导入实现与测试。 +- [ ] C4 负向事件处理实现与测试。 +- [ ] C5 增量变更发现方案与验证。 +依赖:C1 无前置,可先行;C2–C5 依赖轨道 B 闭环与 C1 评审。 + +## 轨道 D:交付收尾 +- [ ] D1 worker 服务托管。 +- [ ] D2 每周同步任务与失败告警。 +- [ ] D3 客户内网部署验收。 +依赖:A3 与轨道 C 完成。 + +## 检查点 +- [ ] 检查点 A:口径确认全部闭环(确认单 13 项 + 材料 5 项 + L1–L7)。 +- [ ] 检查点 B:主数据导入通过,业务表首次写入可回滚。 +- [ ] 检查点 C:全量导入与 2008 R2 验收通过,进入轨道 D。