From 1bc075d5d60c538c0964aaad8aa4caaa57442ebf Mon Sep 17 00:00:00 2001 From: yelan Date: Mon, 31 Aug 2026 12:55:31 +0800 Subject: [PATCH] docs: add AGENTS.md development guidelines --- AGENTS.md | 39 ++++++++++++++ clinical-web/AGENTS.md | 116 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 155 insertions(+) create mode 100644 AGENTS.md create mode 100644 clinical-web/AGENTS.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..8544b3f --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,39 @@ +# 医签通项目开发规范 + +本文件适用于 `medical-sign` 仓库及其子目录。子目录中的 `AGENTS.md` 可以补充更具体的应用规范。 + +## 项目结构 + +- `clinical-web`:医护端、电子病历嵌入端和管理端,电脑端优先。 +- `patient-h5`:患者或家属使用的手机签署 H5,不是移动版电子病历。 +- `packages`:两个应用稳定共用的接口客户端、类型和基础逻辑;不单独部署。 +- 两个应用分别维护自己的 `package.json`、`node_modules` 和构建产物。 + +## 通用原则 + +- 以“患者 + 就诊 + 医嘱/项目 + 签署任务 + 文书版本 + 签署证据”为核心业务关系。 +- 解释医生、实际签署人和协助操作人员必须分别建模和记录。 +- 已签署的正式文书不可直接修改;追加内容应创建新的签署任务。 +- 前端不替代后端完成权限、身份和签署有效性校验。 +- 不在代码、日志或提交中写入 Token、密码、身份证号、完整病历等敏感信息。 +- 不把 `dist`、`node_modules`、本地 `.env` 和临时文件提交到仓库。 +- 未经明确要求,不执行 `git commit`、`git push` 或覆盖他人已有修改。 + +## 共享代码 + +- 只有在两个应用确实复用且接口已经稳定时,才将代码放入 `packages`。 +- 应用内只通过明确的公共导出使用共享包,不直接依赖共享包的内部文件。 +- 与单个应用强相关的页面、组件、Store 和接口,保留在对应应用中。 + +## 开发与验证 + +在对应应用目录执行其自己的脚本: + +```bash +npm run dev +npm run lint +npm run format:check +npm run build +``` + +修改接口、状态或跨页面组件时,应同时更新相应的 TypeScript 类型和 README/开发说明。 diff --git a/clinical-web/AGENTS.md b/clinical-web/AGENTS.md new file mode 100644 index 0000000..8b00d30 --- /dev/null +++ b/clinical-web/AGENTS.md @@ -0,0 +1,116 @@ +# clinical-web 开发规范 + +## 技术栈与边界 + +- 使用 Vue 3、TypeScript、Vite、Vue Router、Pinia、Element Plus 和 Axios。 +- 所有接口请求统一经过 `src/utils/request.ts` 的单例实例。 +- 开发环境默认使用 `/api`,由 `vite.config.ts` 代理到后端;不要在页面中直接拼接后端域名。 +- 当前除登录外的业务接口可以使用 Mock,但 Mock 数据必须遵守真实接口类型。 + +## 目录约定 + +```text +src/ +├─ api/ +│ ├─ auth.ts +│ ├─ workbench/ +│ │ ├─ home.ts +│ │ ├─ signing.ts +│ │ └─ types.ts +│ └─ management/ +│ ├─ documents.ts +│ ├─ reports.ts +│ ├─ users.ts +│ ├─ document-permissions.ts +│ ├─ settings.ts +│ └─ types.ts +├─ components/ +│ ├─ layout/ +│ └─ signing/ +├─ composables/ +├─ stores/ +├─ types/ +├─ utils/ +└─ views/ + ├─ auth/ + ├─ workbench/ + └─ management/ +``` + +- API 文件按页面业务域对应;管理端直接使用 `documents.ts`、`reports.ts` 等文件,不再额外套同名目录。 +- 每个具体 View 使用 `index.vue` 作为入口;当前页面专用组件放在同级 `components`。 +- 跨页面的领域组件放在 `src/components`,布局组件统一放在 `src/components/layout`。 +- API DTO 类型放在对应 API 业务域的 `types.ts`;页面展示和交互类型放在 View 的 `types.ts`;全局类型放在 `src/types/common.ts`。 + +## API 规范 + +- API 文件只负责请求、响应类型和必要的数据标准化。 +- 不在 API 文件中创建新的 Axios 实例,不在 API 层操作组件、路由或 `ElMessage`。 +- 所有请求通过 `request` 单例发送;接口函数必须提供明确的返回类型。 +- 接口地址使用相对路径,不重复写基础地址。 +- 业务接口的列表、详情、创建、更新和删除函数按资源命名,例如: + +```ts +import { request } from '@/utils/request' +import type { ReportOverviewResponse, ReportQuery } from './types' + +export function getReportOverview(params: ReportQuery) { + return request.get('/management/reports/overview', { params }) +} +``` + +- 响应包装、错误码和后端 DTO 与页面展示模型不一致时,在 API 边界或 composable 中转换,组件不负责猜测接口结构。 +- 登录 Token、用户信息和本地持久化只由 `stores/login.ts` 与 `utils/auth-storage.ts` 管理,页面不直接操作 `localStorage`。 + +## 页面与组件拆分 + +- `views/**/index.vue` 负责页面编排、接口调用、加载/错误状态、筛选条件和路由联动。 +- 当前页面专用组件负责展示和交互,通过类型化 `props` 接收数据,通过 `emit` 通知父组件。 +- 展示型组件不直接调用 API、不直接修改全局 Store;确有跨页面业务复用时,放入领域组件并明确其边界。 +- 组件只承担一个清晰职责。不要为了减少文件长度机械拆分小片段,也不要让页面入口堆积复杂表单和弹窗逻辑。 +- 复杂表单、弹窗流程、校验、提交和异步状态抽到 `composables/useXxx.ts`;弹窗组件负责表单渲染和事件呈现。 +- 签署任务新增流程由 `components/signing/NewSigningTaskDialog.vue` 和 `composables/useSigningTaskForm.ts` 共同维护,供签署工作台和文档库复用。 + +## 状态管理 + +- 页面只使用一次的表格数据、筛选条件、弹窗显隐和 loading,优先使用页面内的 `ref`、`reactive` 和 composable。 +- 只有跨页面共享、需要持久化或代表全局上下文的状态才进入 Pinia。 +- Store 按业务域拆分,并统一使用 Composition API 写法: + +```ts +export const useExampleStore = defineStore('example', () => { + const value = ref('') + + const isReady = computed(() => Boolean(value.value)) + + function setValue(nextValue: string) { + value.value = nextValue + } + + return { value, isReady, setValue } +}) +``` + +- 不使用 Pinia 的 `state`、`getters`、`actions` 配置式写法。 +- `stores/app.ts` 只管理院区、环境等应用上下文。 +- `stores/login.ts` 只管理登录态、用户信息、Token 和登录/退出流程。 +- 不把所有业务数据集中到 `app` Store;签署任务列表等页面数据默认留在页面或 composable 中。 +- 避免 Store 之间互相依赖,尤其不要让 `request.ts` 静态依赖业务 Store,防止循环依赖。 + +## 类型与命名 + +- 不使用无理由的 `any`;后端字段不确定时先定义 `unknown`,在边界处完成校验或标准化。 +- Vue 组件使用 PascalCase;API、composable、Store 和工具文件使用 kebab-case 或项目已有命名方式。 +- `useXxx` 表示 composable,`useXxxStore` 表示 Pinia Store。 +- 类型名描述业务含义,避免使用 `Data`、`Info` 等无语义名称。 + +## 提交前检查 + +```bash +npm run lint +npm run format:check +npx vue-tsc --noEmit +npm run build +``` + +如果构建被本机 `node_modules` 或已有 `dist` 的权限问题阻断,应保留错误信息并使用临时输出目录验证,不要删除或覆盖已有构建产物。