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>
18 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. - Button icons: All
web-adminel-buttonwith visible text labels SHALL include a leading<el-icon>from@element-plus/icons-vue(explicit import). Seeopenspec/.../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: 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 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 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/.env.test(viaENV_FILE). - 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. - 进程重启:修改 bug 时,如果前端或后端需要重启,Agent 只告知用户,由用户自行重启。Agent 不得自行停止、启动或重启
web-admin开发服务与backend服务。