Files
zkxw/AGENTS.md
T
zlwuandCursor ac8e471aca fix: align sample registration, freight scope, and OA datetime display
Let customer-service quick register write storage, certificate, and insurance separately without extra menu or data-scope checks. List freight by document data scope like the web admin, allow protocol staff outside the collection region, and pad OA datetimes to seconds so PC date pickers can show historical minute values.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-20 17:30:30 +08:00

18 KiB
Raw Blame History

AGENTS.md — zkxw (陇耘鲜达)

Two-package monorepo: Python backend + Vue 3 admin frontend. Named "sanqiang" internally.

Repository Layout

backend/          FastAPI backend (Python 3.9, venv)
web-admin/        Vue 3 admin panel (pnpm, Vite 7, Element Plus, Tailwind CSS 4)
docs/             UI specs, SQL schemas, requirements docs
openspec/         OpenSpec: `config.yaml`; active changes under `openspec/changes/*/`
.cursorrules      Detailed UI conventions and constraints (Chinese)

OpenSpec engineering standards

Full specs: openspec/changes/zkxw-engineering-standards/specs/*/spec.md. Below are the key SHALL items every coding session MUST follow.

UI Conventions (web-admin + miniprogram)

  • Visual authority: web-admin SHALL follow docs/web-admin-ui-spec-fresh-mint.md (Fresh Mint palette, --primary #10b981). miniprogram SHALL follow docs/miniprogram-ui-spec-sanqiang.md (三墙 palette, brand green #0a9f6d).
  • No cross-app color mixing: web-admin SHALL NOT use #0a9f6d as primary; miniprogram SHALL NOT use #10b981 as primary.
  • Tree path display: Dropdown/tree nodes show node name only; input fields, table columns, exports, and view dialogs SHALL show full ancestor path. Separator: / (space-slash-space). See web-admin/src/utils/tree-path.ts.
  • Dialog forms: label-position="top". No backdrop blur (backdrop-filter: none). Use .dialog-form-layout with max-height: calc(100vh - 100px), only body scrolls.
  • Dialog grid: Default 2-column (.form-grid-2). Max 5 columns. Full-width fields use .form-col-span-2 (grid-column: 1 / -1). Narrow viewport SHALL fallback to fewer columns.
  • List panel heading: panel-top → h2.title-bar-heading SHALL show primary-color vertical bar via ::before. Ambiguous titles (e.g. "租户" containing "户") SHALL be registered in App.vue panelTitleBarTextRules.
  • Miniprogram media: Thumbnails 1:1 aspectFill; carousel 4:3 aspectFill; detail images widthFix. Min tap target 44×44px.
  • Sidebar menu icons: First-level menu items SHALL show icons before the name; second-level and deeper items SHALL NOT show icons (text only). Implemented via level === 0 check in SidebarSubmenu.vue.
  • Tab bar (WorkTab) icons: Tab bar tabs SHALL NOT show icons — only text titles. meta.icon is for sidebar only.
  • Form field annotations: Field hints (e.g. "数值越小越靠前") SHALL appear as small text after the label via <template #label>字段名<span class="form-label-tip">注释</span></template>, NOT beside the input control. Style class: .form-label-tip (12px, --mint-text-muted).
  • Attachment upload card layout: Upload trigger SHALL be a card (140×96px, dashed border #a7f3d0) inline as the first item in the same flex row as uploaded attachment cards; select file → immediate upload via fetchUploadAttachment; preview/download/delete on cards; hint below the row. Authority: ProtocolFormDialog.vue «协议附件». See openspec/changes/zkxw-engineering-standards/specs/ui-conventions/spec.md §「附件上传卡片化布局」for full Vue template + SCSS + interaction rules.
  • Button icons: All web-admin el-button with visible text labels SHALL include a leading <el-icon> from @element-plus/icons-vue (explicit import). See openspec/.../ui-conventions/spec.md §「按钮须携带图标」.
  • Sort fields (sort_order/orderNum): web-admin 列表、新增弹窗、编辑弹窗中默认不展示排序字段。后续根据功能需要自行添加。
  • Status/conclusion/type fields as Tags: All status, conclusion, and type fields in table columns and view dialogs SHALL render as <el-tag> with semantic colors. Tables: use <el-tag :type="..." size="small"> in column templates. SystemViewDialog: use tagType property on ViewField. Semantic colors: success=正常/启用/已完成/通过, warning=进行中/待确认/已过期, danger=异常/已作废/拒绝/不通过/质检待执行/质检待结论, info=待生效/停用/默认, primary=特殊分类/来源类型. SHALL NOT use plain text or custom <span class="tag">. See openspec/.../ui-conventions/spec.md "状态、结论与类型字段使用 Tag 标签展示".
  • Template pages — new pages SHALL match these exactly:
    • Standard list: src/views/system/unit/index.vue
    • Complex list: src/views/system/order/index.vue
    • Product list + view dialog: src/views/system/product/index.vue
    • Tree master data: src/views/system/category/index.vue
    • User CRUD: src/views/system/user/index.vue
  • UI pattern index — before implementing a new page, developers SHALL select a pattern code (P01–P27) per docs/web-admin-ui-pattern-index.md and OpenSpec ui-conventions §「界面模式索引与参考页选型」; PRs SHALL cite pattern code and reference page path.

API Conventions (backend)

  • 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.

Database Conventions

  • 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.

Architecture Conventions

  • Monorepo structure: Python backend (backend/) + Vue 3 web-admin (web-admin/) + uni-app miniprogram (miniprogram/). Shared backend and tenant model.
  • File attachments: SHALL use object storage (MinIO). Multiple attachments in one field SHALL be comma-separated URLs.
  • Authoritative docs: docs/中科兴皖需求V0.3.md (requirements), docs/web-admin-ui-spec-fresh-mint.md (web UI), docs/miniprogram-ui-spec-sanqiang.md (miniprogram UI).

Coding Conventions

  • 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). Run python scripts/check_field_consistency.py after implementation to verify. See docs/dev-field-consistency.md for details.

Permission Conventions

  • 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.

Workflow Conventions (target design, not yet implemented)

  • Engine: SHALL be implemented in Python backend as an independent, configurable approval/flow subsystem.
  • 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.

Backend (backend/)

Stack

FastAPI · SQLAlchemy · Pydantic v2 · MySQL (pymysql) · Redis · MinIO · JWT auth · Alembic migrations

Commands

source venv/bin/activate
pip install -r requirements.txt
cp .env.example .env.local   # fill in DB, Redis, MinIO, etc.
./start-local.sh              # uvicorn --reload on 127.0.0.1:8000
./start-prod.sh start         # production on :8111 (reads .env.production, PID-managed)
./start-prod.sh status|stop|restart|logs
./start-test.sh start         # test on :8112 (reads .env.test, PID-managed)
./start-test.sh activate      # source .venv/bin/activate (interactive shell)
./start-test.sh status|stop|restart|logs

Entrypoint & Structure

  • Entrypoint: app/main.py → app.main:app
  • app/api/ — Route files: public.py (no auth), menu.py, admin.py. Register new routers in app/api/__init__.py and app/main.py.
  • app/core/ — Config (config.py), DB (database.py), auth (auth.py, security.py), middleware (api_crypto_middleware.py, api_request_log_middleware.py), RSA login crypto (login_crypto.py)
  • app/models/ — SQLAlchemy models (models.py, base.py)
  • app/schemas/ — Pydantic schemas per domain (auth, order, product, user, etc.)
  • app/crud/ — Database CRUD operations (base.py has generic base)
  • app/services/ — Business logic layer
  • app/tasks/ — APScheduler scheduled tasks
  • scripts/ — SQL migrations and one-off scripts

Key Patterns

  • API prefix: /api (set via API_V1_PREFIX in config). Routes: /api/public/*, /api/admin/*, /api/supplier/*, /api/client/*, /api/deliver/*
  • Auth: JWT + RSA-encrypted login. Login RSA key auto-generated or set via LOGIN_RSA_PRIVATE_KEY_PEM env var.
  • API encryption middleware: symmetric crypto layer controlled by API_ENCRYPT_* env vars. Excluded paths listed in API_ENCRYPT_EXCLUDE_PATHS.
  • Config: pydantic-settings (app/core/config.py), reads from .env / .env.local / .env.production / .env.test (via ENV_FILE).
  • Database init / schema baseline: docs/sql/zkxw.sql(从当前库导出的全量 SQL)。Default admin: admin / 111111, role super_admin.
  • Swagger docs at /docs, ReDoc at /redoc.
  • Tests: minimal, only tests/test_api_crypto.py. Run with pytest.

Frontend (web-admin/)

Stack

Vue 3 · TypeScript (strict: false, noImplicitAny: false) · Vite 7 · Element Plus · Tailwind CSS 4 · Pinia · vue-router (hash mode) · SCSS · Axios · pnpm

Commands

pnpm install                  # if fails: pnpm install --ignore-scripts
pnpm dev                      # Vite dev server (port from .env.development)
pnpm build                    # production build
pnpm build:typecheck          # typecheck + build (vue-tsc --noEmit)
pnpm lint                     # ESLint check
pnpm fix                      # ESLint --fix
pnpm lint:prettier            # Prettier format all
pnpm lint:stylelint           # Stylelint fix SCSS/Vue
pnpm commit                   # cz-git interactive commit
pnpm clean:dev                # strip demo data for fresh start

Entrypoint & Structure

  • Entrypoint: src/main.ts
  • src/views/system/ — Main business pages: category/, order/, product/, tenant/, unit/, user/
  • src/api/ — Axios API modules: auth.ts, admin.ts, business.ts, system.ts, chinaRegion.ts
  • src/store/modules/ — Pinia stores: user.ts, menu.ts, setting.ts, table.ts, worktab.ts
  • src/router/modules/ — Route modules: index.ts, sqxp.ts, exception.ts
  • src/utils/tree-path.ts — Tree path utilities (buildTreePathLabelFromFlat, etc.). Separator: / (spaced slash).

Path Aliases (tsconfig + vite)

@/* → src/*, @views/*, @imgs/*, @icons/*, @utils/*, @stores/*, @plugins/*, @styles/*

Key Patterns

  • Auto-imports: unplugin-auto-import + unplugin-vue-components — Vue, vue-router, pinia, @vueuse/core APIs and Element Plus components are auto-imported. Don't manually import them.
  • Element Plus: auto-imported resolvers — use components directly, no manual imports.
  • Tailwind CSS 4: via @tailwindcss/vite plugin.
  • SCSS: global mixin/data injected via vite.config.ts additionalData (uses @styles/core/el-light.scss and @styles/core/mixin.scss).
  • API proxy: dev server proxies /api → VITE_API_PROXY_URL (localhost:8000). Also /web and /mini proxies configured.
  • Env files: .env.development (local), .env.production (prod). Uses VITE_* prefix.
  • API encryption: VITE_API_ENCRYPT_ENABLED toggles request/response crypto in dev. Production has it on.
  • Hash routing: URLs use /#/ format.
  • Access mode: VITE_ACCESS_MODE=frontend (fixed frontend menu mode).

Code Style

  • Prettier: single quotes, no semicolons, 2-space indent, trailing comma: none, vueIndentScriptAndStyle: true
  • ESLint: extends recommended + typescript + vue essential + prettier. @typescript-eslint/no-explicit-any is OFF.
  • Stylelint: SCSS + Vue + recess-order property sorting.
  • Commit: Conventional commits via cz-git + commitlint. Types: feat|fix|docs|style|refactor|perf|test|build|ci|revert|chore|wip.
  • Husky + lint-staged: pre-commit auto-runs ESLint, Prettier, Stylelint on staged files.

UI Design Authority

The .cursorrules file and docs/ are the authoritative source for all UI decisions.

  • Web admin UI spec: docs/web-admin-ui-spec-fresh-mint.md + docs/fresh-mint-green.html
  • Template pages (match these exactly for new pages):
    • Standard list: src/views/system/unit/index.vue (/#/demo/unit)
    • Complex list: src/views/system/order/index.vue (/#/demo/order)
    • Product list + view dialog: src/views/system/product/index.vue
    • Tree master data: src/views/system/category/index.vue
    • User CRUD: src/views/system/user/index.vue
    • Console/dashboard: src/views/dashboard/console/index.vue
  • Color tokens (web-admin): Primary #10b981, dark #059669, bg #ecfdf5. Fresh Mint palette. Do NOT use miniprogram colors in web-admin.
  • Tree display: dropdown shows node name; selected/input/table shows full path (spaced slash separator).

Knowledge Graph (代码知识图谱)

项目已生成代码知识图谱,用于理解模块间依赖关系、追踪修改影响范围。

图谱位置

项目 报告 可视化 数据
后端 backend/graphify-out/GRAPH_REPORT.md backend/graphify-out/graph.html backend/graphify-out/graph.json
前端 web-admin/graphify-out/GRAPH_REPORT.md web-admin/graphify-out/graph.html web-admin/graphify-out/graph.json

使用方式

  • 浏览器:直接打开 */graphify-out/graph.html 查看交互式图谱
  • AI Agent 查询:已配置 MCP 服务(graphify),可通过工具调用查询图谱
  • 手动更新:./scripts/update-graph.sh [backend|frontend|all]

Agent 更新规则

完成代码修改后(新建文件、修改函数签名、新增/删除 import、重构模块),Agent SHALL 执行 ./scripts/update-graph.sh 增量更新图谱,确保图谱与代码保持同步。如果只修改了单个项目(backend 或 web-admin),只需更新对应项目即可。

Important Constraints

  • Language: User communication in Chinese (简体中文) when user writes in Chinese.
  • Minimal changes: Don't expand scope, don't refactor unrelated code. Match surrounding naming/type/import style.
  • Cross-app colors: Web admin uses Fresh Mint (#10b981), miniprogram uses 三墙 (#0a9f6d). Don't mix.
  • No backdrop blur on modals: backdrop-filter: none.
  • Dialog forms: label-position="top".
  • Table action column: fixed="right", min-width ≥ 260px.
  • Table column widths: All el-table-column SHALL use min-width (not width) for proportional scaling when viewport resizes.
  • Toolbar: "已选 N 项" first, then primary action button (only one type="primary" per toolbar row), no space-between push.
  • Database changes: always pair with schema SQL in docs/sql/ and evaluate API/TypeScript type impact.
  • 进程重启:修改 bug 时,如果前端或后端需要重启,Agent 只告知用户,由用户自行重启。Agent 不得自行停止、启动或重启 web-admin 开发服务与 backend 服务。