engineering-rules.md 7.8 KB

工程规则与当前系统边界

本文承接根 AGENTS.md 的通用硬约束。修改代码前必读;子目录 AGENTS.md 补充各端规则。

当前工程事实与历史资料

本仓库是 Python FastAPI 后端、Vue 3 Web 管理端、uni-app 小程序三个应用组成的单仓库。Web 同时承载 web-admin/src/views/m/ 移动 H5 页面;各端共用后端与租户模型。

当前仓库已经包含 CRM、地磅(db)、报销(bx)、运输(pl)业务,不能再按“CRM 或地磅只能去外部仓库”限制维护现有实现。证据入口:backend/app/api/crm.py、backend/app/api/db/、backend/app/api/bx/、backend/app/api/pl/,以及 web-admin/src/views/crm/、web-admin/src/views/db/、web-admin/src/views/bx/、web-admin/src/views/pl/。

docs/sql/shanxia2.0.sql 是本仓库数据库快照;docs/sql/sx.sql 和 docs/sql/dibang.sql 是 CRM / 地磅来源系统模型资料,不能替代当前表结构与迁移。并列的 shanxia/crm/ 是历史来源位置描述,不是本仓库现有 CRM 的唯一代码位置。跨系统修改须先确认实际 API、表归属和变更范围,不能仅凭表名前缀推断。

旧生态规范 openspec/changes/zkxw-engineering-standards/specs/ecosystem-landscape/spec.md 中“CRM 仅在外部 / 地磅独立”的描述与当前实现冲突,此处明确为历史参考;本文件的当前事实用于代码定位。这不表示旧变更已经归档,也不表示所有历史需求均已实现。其他未冲突的 SHALL 约束仍须遵守。

API 与数据访问

  • Cell-storage sample cross-table key(仅在涉及现有细胞存储样本功能时适用): Matching biz_protocol_sample to downstream rows (sample reception, QC work orders, etc.) SHALL use tenant_no + sample_code only—not collection_protocol_id or protocol_sample_id (protocol may change; sample code does not). See openspec/changes/zkxw-engineering-standards/specs/api-conventions/spec.md §「细胞存储样本跨表关联键」.
  • Tenant isolation: All business data queries SHALL filter by current user's tenant_no. All write/update endpoints SHALL set tenant_no to the current user's tenant. MUST NOT trust client-submitted tenant overrides (unless multi-tenant admin API with security review).
  • Data permission: All business queries SHALL apply data scope filtering based on the union of all roles assigned to the current user (menu + data permissions both use union semantics).
  • Default sort: Lists SHALL sort by create_time DESC when no custom sort is specified.
  • Route registration: New route modules SHALL be registered in app/api/__init__.py AND app/main.py. SHALL NOT bypass auth/crypto/audit middleware.

数据库

  • Engine: MySQL 5.7, charset utf8mb4.
  • Public fields (every business table SHALL include these after business fields): id VARCHAR(64) UUID, tenant_no, order_num, remark, create_by, create_dept_id, create_time, update_by, update_time, del_flag (default 0).
  • Field order: id → business fields → public fields (tenant_no through del_flag).
  • Soft delete: SHALL NOT physically delete business data. Delete = set del_flag=1. Queries SHALL exclude del_flag=1 by default.
  • Primary key: id SHALL be VARCHAR(64) NOT NULL, UUID value.

数据库改动必须同步维护 docs/sql/ 的 schema / 迁移 SQL,并评估 API、Pydantic 和 TypeScript 类型影响。数据库快照不代表可直接执行的生产迁移。

子数据与附件

涉及子数据写入必须阅读 子数据保存规则,包括差量更新、字段遗漏语义、身份校验、引用保护、事务与客户端 ID 往返;不能以摘要代替完整规则。

文件附件必须使用 MinIO 对象存储,同一字段的多个附件使用逗号分隔 URL。小程序拍照凭证与 Web 通用附件分别遵守各端 AGENTS.md。

编码与字段一致性

  • Minimal changes: Commits SHALL contain only what's needed. No unrelated refactoring or formatting.
  • Frontend (web-admin): pnpm, Prettier (single quotes, no semicolons, 2-space indent). Vue/Element Plus auto-imports — SHALL NOT manually import auto-imported APIs/components.
  • Backend: Python 3.9, FastAPI + SQLAlchemy + Pydantic v2. Routes stay thin; business logic goes in app/services/ and app/crud/. Config via pydantic-settings + .env files.
  • DB changes: SHALL maintain SQL in docs/sql/. Schema changes SHALL align with database-conventions public field rules.
  • Commit messages: SHALL be complete sentences describing "what changed and why". Follow Conventional Commits (feat|fix|docs|…).
  • Field consistency (CRUD ↔ Schema ↔ Frontend): When implementing CRUD for any entity, the _row_to_dict function is the single source of truth for all readable fields. The CreateBody/UpdateBody Pydantic schemas and the frontend formData initialization SHALL include every writable field present in _row_to_dict (excluding computed/read-only fields like id, createTime, updateTime, stockQty). 逐项核对 CRUD、CreateBody/UpdateBody 与前端 formData,并执行对应回归测试;仓库当前没有通用字段一致性检查脚本,不得宣称已通过不存在的检查。

权限

  • Role-menu: Selecting a child menu SHALL auto-include all ancestor menus (no orphan leaves).
  • Data scope: Per role — all / own dept / own dept and below / self only / custom. Custom uses sys_role_data_scope_detail with scope_type (dept/user) + scope_value.
  • Multi-role union: A user with multiple roles gets the union of menu permissions and the union of data scopes across all roles.
  • Dual menu trees: Web and miniprogram each have a separate top-level virtual root (parent_id=0). New menus SHALL be placed under the correct root.
  • Tenant management: Accessible ONLY by super_admin. All other system management runs within tenant context.

工作流:现有实现与后续约束

已有 backend/app/services/workflow_engine.py、backend/app/api/workflow.py 和 web-admin/src/views/system/workflow/ 的流程设计、待办、已办页面。以下为持续维护的设计约束,不能据此声称所有节点、策略或版本能力都已完备;每次修改应对照代码和测试确认支持范围。

  • Engine: 工作流子系统已存在于 Python 后端;继续按独立、可配置的审批/流程子系统演进。
  • Node types: Start, End, Approver, Conditional Branch (multi-branch supported). Extensible but SHALL NOT break published definitions.
  • Approver strategies: Specified users, specified roles, or SQL-based resolution. Per-node: "any one passes" or "all must pass".
  • Versioning: Each flow definition has a version. Running instances SHALL stick to their launch version; new versions only affect new launches.
  • Task centers: System SHALL provide "Pending Tasks" and "Completed Tasks" views.

规范和文档生命周期

需求依据为工程规范及对应变更,UI 权威为 Web UI 规范、小程序 UI 规范。工具适配文件只索引规范,不复制新的规则版本。

使用 OpenSpec 时遵守 openspec/config.yaml,proposal 的 Capabilities 须与 specs/<kebab-name>/spec.md 对应。实现和评审须对照 Requirement / Scenario。openspec/changes/ 下的变更不可因为日期久或目录整理就自动归档;只有完成验收并执行归档流程后,才按实际 openspec/specs/ 基线管理。

设计和实施计划遵循所用技能要求的路径(例如 docs/superpowers/specs/、docs/superpowers/plans/);文档索引记录状态与原路径,不为整理目录擅自移动或归档。历史 SQL、需求、计划与业务资料保持可追溯。