# 系统标准初始化工具设计

## 背景

当前系统已经从嘉恒测试环境切到百华客制化分支。数据库中存在大量嘉恒/测试业务数据，百华正式启用前需要初始化为干净系统。

这次初始化不能只做一次性清库脚本。后续给其他公司部署时，也需要一套标准工具，能够在全新的 MySQL 数据库上完成建库、建表和系统骨架初始化，同时也能对已经建好表、已经产生测试数据的系统做正式启用前重置。

## 目标

初始化工具提供两个模式：

- `fresh`：面向全新 MySQL 或全新 schema，创建 ERP 数据库下所有 ERP 表和智能报工小程序相关表，并写入最小系统骨架。
- `reset`：面向已有 schema，先备份，再清空业务数据、主数据、人员账号、小程序数据，然后重建最小系统骨架。

初始化完成后，系统应满足：

- 可以用一个超级管理员账号登录 ERP。
- 系统权限、菜单、角色关系完整。
- 六大仓库和默认库位存在，后续可直接做出入库。
- 系统配置存在，例如原材料库存批次前缀、是否对接智能报工小程序。
- 没有嘉恒或测试业务数据、客户、供应商、物料、产品、库存、订单、报工、发货、财务、单据归档数据残留。
- 如果后续客户购买小程序，小程序后端所需表也已经创建好。

## 非目标

- 不做客户真实主数据导入。客户、供应商、物料、产品、BOM、工艺路线后续用现有导入功能导入。
- 默认不删除上传文件和 PDF 实体文件，只清数据库记录。文件删除作为显式参数单独开启。
- 不重命名数据库 schema，例如仍可使用当前 `jiaheng_erp` 作为历史技术库名，避免改动部署配置和小程序连接。
- 不在初始化工具里修改业务逻辑。

## 命令形态

建议新增入口：

```bash
python backend/scripts/system_initialize.py fresh \
  --company-name 百华 \
  --admin-name 超级管理员 \
  --admin-phone 13800000000 \
  --admin-password '正式密码'

python backend/scripts/system_initialize.py reset \
  --company-name 百华 \
  --admin-name 超级管理员 \
  --admin-phone 13800000000 \
  --admin-password '正式密码' \
  --confirm-reset
```

脚本读取 `backend/.env` 中的 MySQL 连接信息：

- `MYSQL_HOST`
- `MYSQL_PORT`
- `MYSQL_DATABASE`
- `MYSQL_USER`
- `MYSQL_PASSWORD`

## 模式一：fresh

`fresh` 用于全新部署，是后续交付其他公司最常用的路径。

流程：

1. 读取 `.env` 中的 MySQL 连接信息。
2. 连接 MySQL server。
3. 如果目标 database 不存在，执行 `CREATE DATABASE`。
4. 切换到目标 database。
5. 创建 ERP 全量表。
6. 创建小程序全量表。
7. 执行所有已纳入标准基线的 patch。
8. 初始化系统权限、角色、角色权限。
9. 初始化系统配置。
10. 初始化单位、物料分类等基础字典。
11. 初始化六大仓库和默认库位。
12. 初始化根组织节点、超级管理员人员、超级管理员系统账号、用户角色绑定。
13. 输出初始化报告。

`fresh` 模式不写入任何业务主数据和业务流水。

## 模式二：reset

`reset` 用于已有系统正式启用前清理，例如这次百华切换。

流程：

1. 读取 `.env` 中的 MySQL 连接信息。
2. 检查必须显式传入 `--confirm-reset`。
3. 打印目标数据库连接摘要，包括 host、port、database、当前时间。
4. 统计关键表行数。
5. 强制导出备份 SQL 到 `outputs/cleanup_backups/system_init_backup_<timestamp>.sql`。
6. `SET FOREIGN_KEY_CHECKS=0`。
7. 清空业务流水表。
8. 清空库存表。
9. 清空业务主数据表。
10. 清空人员、组织、账号、组织绑定、角色绑定。
11. 清空小程序业务数据和小程序主数据。
12. 清空系统广播、单据归档记录。
13. 重置相关自增 ID。
14. 重建系统权限、角色、角色权限、系统配置、单位、分类、仓库、库位、根组织、超级管理员。
15. `SET FOREIGN_KEY_CHECKS=1`。
16. 再次统计关键表行数。
17. 输出 JSON 报告到 `outputs/cleanup_backups/system_init_summary_<timestamp>.json`。

## 小程序表覆盖范围

ERP 当前代码已映射部分小程序表，但小程序后端模型更完整。标准初始化必须覆盖两侧共同需要的完整表集合。

小程序基础主数据：

- `attendance_points`
- `personnel`
- `person_roles`
- `person_attendance_points`
- `products`
- `equipment`
- `work_schedules`

小程序业务数据：

- `work_sessions`
- `work_session_devices`
- `production_reports`
- `production_report_items`
- `report_audit_logs`
- `mold_lock_feedbacks`
- `device_qrcodes`
- `device_qrcode_batch_tasks`
- `notices`
- `notice_points`
- `reconciliation_ledger_entries`

`fresh` 模式需要创建这些表。`reset` 模式需要清空这些表，并只重建必要的考勤点/管理员人员数据。

## 清理表分层

### 业务流水表

销售：

- `so_sales_order_item`
- `so_sales_order`
- `so_delivery_item`
- `so_delivery`

采购：

- `po_purchase_order_sales_order`
- `po_purchase_order_item`
- `po_purchase_order`
- `po_receipt_item`
- `po_receipt`
- `po_purchase_return_item`
- `po_purchase_return`

库存：

- `wh_special_adjustment_line`
- `wh_special_adjustment`
- `wh_stocktake_adjustment`
- `wh_stocktake_line`
- `wh_stocktake_warehouse`
- `wh_stocktake`
- `wh_inventory_txn`
- `wh_stock_balance`
- `wh_stock_lot`

生产：

- `pp_production_batch_ledger_txn`
- `pp_production_batch_ledger`
- `pp_completion_receipt_item`
- `pp_completion_receipt`
- `pp_scrap_record`
- `pp_operation_report`
- `pp_material_issue_item`
- `pp_material_issue`
- `pp_work_order_material_issue`
- `pp_work_order_operation`
- `pp_work_order_material`
- `pp_work_order`

发货与售后：

- `rt_return_disposition`
- `rt_return_item`
- `rt_return_order`

财务：

- `fi_statement_snapshot`
- `fi_cost_allocation`
- `fi_overhead_entry`
- `fi_accounting_period`
- `reconciliation_ledger_entries`

单据归档：

- `document_archives`

MRP：

- `mrp_material_demand`

### 业务主数据表

- `em_maintenance_order`
- `em_maintenance_plan`
- `em_equipment`
- `md_bom_item`
- `md_bom`
- `md_process_route_operation`
- `md_process_route`
- `md_work_center`
- `md_process`
- `md_product`
- `md_material`
- `md_item`
- `md_customer`
- `md_supplier`

### 组织和账号

选择标准为“只保留一个超级管理员”。

需要清空：

- `sys_user_role`
- `sys_user`
- `sys_org_manager_binding`
- `sys_org_employee_binding`
- `hr_employee`
- `sys_department`

需要重建：

- 根组织节点，例如 `COMPANY_ROOT`
- 超级管理员人员
- 超级管理员系统账号
- 超级管理员角色绑定

### 系统骨架

需要保留或重建：

- `sys_permission`
- `sys_role`
- `sys_role_permission`
- `sys_system_config`
- `sys_ai_assistant_config`
- `md_unit`
- `md_item_category`
- `wh_warehouse`
- `wh_location`

需要清空：

- `sys_broadcast_message`

## 系统配置初始化

必须至少初始化：

- `RAW_MATERIAL_LOT_PREFIX`：默认 `YL`。
- `SMART_OPERATION_REPORT_ENABLED`：默认可通过参数设置。百华当前建议按实际购买情况设置。
- AI 助手名称：默认 `<company-name>工艺助手`。

配置项必须使用 upsert，确保 `fresh` 和 `reset` 都可重复执行。

## 仓库初始化

初始化六大库和默认库位：

- 原材料库：`RAW`
- 半成品库：`SEMI`
- 成品库：`FINISHED`
- 辅料库：`AUX`
- 废料库：`SCRAP`
- 退货库：`RETURN`

每个仓库创建一个默认库位。命名可保持当前业务通用名称，例如：

- 原料主库位
- 半成品主库位
- 成品主库位
- 辅料主库位
- 废料主库位
- 退货主库位

仓库名可根据公司名生成，例如 `百华原材料库`，也可以保持通用名 `原材料库`。推荐保持通用名，避免系统内部业务文案过长。

## 备份与报告

`reset` 模式必须生成备份：

```text
outputs/cleanup_backups/system_init_backup_<timestamp>.sql
```

必须生成报告：

```text
outputs/cleanup_backups/system_init_summary_<timestamp>.json
```

报告内容包括：

- 执行模式
- 执行时间
- 数据库 host、port、database
- 备份路径
- 清理表清单
- 每张表清理前行数
- 每张表清理后行数
- 重建骨架数据摘要
- 是否清理文件
- 执行结果

## 文件清理

默认不删除实体文件，只清数据库引用。

如显式传入 `--delete-files`，才允许清理：

- 单据归档 PDF 目录
- 批量下载临时 zip 目录
- 辅助照片上传目录

文件清理必须记录到报告中。

## 安全保护

`reset` 模式必须满足：

- 未传 `--confirm-reset` 时禁止执行删除，只输出预检摘要。
- 执行前必须成功备份。
- 打印目标 database，并要求命令行参数显式确认。
- 默认拒绝清理未知 database，除非传入 `--allow-any-database`。
- 清理前后检查 `FOREIGN_KEY_CHECKS` 恢复为 `1`。
- 清理后必须能查询到一个超级管理员用户。
- 清理后业务流水表行数必须为 `0`。

## 测试策略

单元测试：

- `fresh` 在临时 SQLite 或测试 MySQL schema 上可创建所有 SQLAlchemy metadata 表。
- `reset` 对带测试数据的测试库执行后，业务表为空。
- `reset` 后系统账号、角色、权限、仓库、库位、系统配置存在。
- `reset` 未传 `--confirm-reset` 时不会删除数据。
- 小程序关键表存在，并可写入最小人员、考勤点、产品清单、报工记录。

集成测试：

- 初始化后调用 `/api/system/health` 返回数据库连接正常。
- 初始化后用超级管理员登录成功。
- 初始化后打开仓库页面不会因为缺仓库/库位报错。
- 初始化后打开系统权限管理页面能看到根组织节点和超级管理员。

人工验收：

- 前端登录成功。
- 左侧菜单正常。
- 基础资料中客户、供应商、产品、物料为空。
- 六大仓库库存为空，但仓库入口可正常进入。
- 销售、采购、生产、发货、财务台账为空。
- 系统管理中只有初始化创建的超级管理员账号。

## 实施顺序

1. 补齐小程序完整 SQLAlchemy 模型或标准 SQL，确保初始化可创建小程序全部表。
2. 新增初始化脚本 `backend/scripts/system_initialize.py`。
3. 新增 SQL seed/cleanup 分组文件。
4. 编写测试覆盖 `fresh` 和 `reset`。
5. 在本地测试库执行 `fresh`。
6. 在本地测试库导入当前测试数据后执行 `reset`。
7. 确认报告和备份文件。
8. 用户审核后，在百华服务器数据库执行 `reset`。

## 开放决策

本设计已固定采用“只保留一个超级管理员”的账号策略。

执行前仍需确定：

- 百华超级管理员姓名、手机号、初始密码。
- 百华是否默认开启智能报工小程序对接。
- 是否在本次初始化时删除服务器上的历史上传图片和 PDF 实体文件。默认不删除。
