17 KiB
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-adminSHALL followdocs/web-admin-ui-spec-fresh-mint.md(Fresh Mint palette,--primary #10b981).miniprogramSHALL followdocs/miniprogram-ui-spec-sanqiang.md(三墙 palette, brand green#0a9f6d). - No cross-app color mixing:
web-adminSHALL NOT use#0a9f6das primary;miniprogramSHALL NOT use#10b981as 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). Seeweb-admin/src/utils/tree-path.ts. - Dialog forms:
label-position="top". No backdrop blur (backdrop-filter: none). Use.dialog-form-layoutwithmax-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-headingSHALL show primary-color vertical bar via::before. Ambiguous titles (e.g. "租户" containing "户") SHALL be registered inApp.vuepanelTitleBarTextRules. - Miniprogram media: Thumbnails 1:1
aspectFill; carousel 4:3aspectFill; detail imageswidthFix. 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 === 0check inSidebarSubmenu.vue. - Tab bar (WorkTab) icons: Tab bar tabs SHALL NOT show icons — only text titles.
meta.iconis 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 viafetchUploadAttachment; preview/download/delete on cards; hint below the row. Authority:ProtocolFormDialog.vue«协议附件». Seeopenspec/changes/zkxw-engineering-standards/specs/ui-conventions/spec.md§「附件上传卡片化布局」for full Vue template + SCSS + interaction rules. - 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: usetagTypeproperty onViewField. Semantic colors:success=正常/启用/已完成/通过,warning=进行中/待确认/已过期,danger=异常/已作废/拒绝/不通过,info=待执行/待生效/停用/默认,primary=特殊分类/来源类型. SHALL NOT use plain text or custom<span class="tag">. Seeopenspec/.../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
- Standard list:
- UI pattern index — before implementing a new page, developers SHALL select a pattern code (P01–P27) per
docs/web-admin-ui-pattern-index.mdand OpenSpecui-conventions§「界面模式索引与参考页选型」; PRs SHALL cite pattern code and reference page path.
API Conventions (backend)
- Cell-storage sample cross-table key: Matching
biz_protocol_sampleto downstream rows (sample reception, QC work orders, etc.) SHALL usetenant_no+sample_codeonly—notcollection_protocol_idorprotocol_sample_id(protocol may change; sample code does not). Seeopenspec/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 settenant_noto 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 DESCwhen no custom sort is specified. - Route registration: New route modules SHALL be registered in
app/api/__init__.pyANDapp/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):
idVARCHAR(64) UUID,tenant_no,order_num,remark,create_by,create_dept_id,create_time,update_by,update_time,del_flag(default0). - Field order:
id→ business fields → public fields (tenant_nothroughdel_flag). - Soft delete: SHALL NOT physically delete business data. Delete = set
del_flag=1. Queries SHALL excludedel_flag=1by default. - Primary key:
idSHALL beVARCHAR(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/andapp/crud/. Config viapydantic-settings+.envfiles. - DB changes: SHALL maintain SQL in
docs/sql/. Schema changes SHALL align withdatabase-conventionspublic 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_dictfunction is the single source of truth for all readable fields. The CreateBody/UpdateBody Pydantic schemas and the frontendformDatainitialization SHALL include every writable field present in_row_to_dict(excluding computed/read-only fields likeid,createTime,updateTime,stockQty). Runpython scripts/check_field_consistency.pyafter implementation to verify. Seedocs/dev-field-consistency.mdfor 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_detailwithscope_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 (reads .env.production, PID-managed)
./start-prod.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 inapp/api/__init__.pyandapp/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.pyhas generic base)app/services/— Business logic layerapp/tasks/— APScheduler scheduled tasksscripts/— SQL migrations and one-off scripts
Key Patterns
- API prefix:
/api(set viaAPI_V1_PREFIXin 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_PEMenv var. - API encryption middleware: symmetric crypto layer controlled by
API_ENCRYPT_*env vars. Excluded paths listed inAPI_ENCRYPT_EXCLUDE_PATHS. - Config: pydantic-settings (
app/core/config.py), reads from.env/.env.local/.env.production. - Database init / schema baseline:
docs/sql/zkxw.sql(从当前库导出的全量 SQL)。Default admin:admin/111111, rolesuper_admin. - Swagger docs at
/docs, ReDoc at/redoc. - Tests: minimal, only
tests/test_api_crypto.py. Run withpytest.
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.tssrc/store/modules/— Pinia stores:user.ts,menu.ts,setting.ts,table.ts,worktab.tssrc/router/modules/— Route modules:index.ts,sqxp.ts,exception.tssrc/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/viteplugin. - SCSS: global mixin/data injected via
vite.config.tsadditionalData(uses@styles/core/el-light.scssand@styles/core/mixin.scss). - API proxy: dev server proxies
/api→VITE_API_PROXY_URL(localhost:8000). Also/weband/miniproxies configured. - Env files:
.env.development(local),.env.production(prod). UsesVITE_*prefix. - API encryption:
VITE_API_ENCRYPT_ENABLEDtoggles 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-anyis 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
- Standard list:
- 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-columnSHALL usemin-width(notwidth) for proportional scaling when viewport resizes. - Toolbar: "已选 N 项" first, then primary action button (only one
type="primary"per toolbar row), nospace-betweenpush. - Database changes: always pair with schema SQL in
docs/sql/and evaluate API/TypeScript type impact.