docs: 增加项目规范和邮件来源入口PRD
This commit is contained in:
282
docs/project/frontend-development-guidelines.md
Normal file
282
docs/project/frontend-development-guidelines.md
Normal file
@@ -0,0 +1,282 @@
|
||||
# TH Hotel 前端开发规范
|
||||
|
||||
## 1. 文档定位
|
||||
|
||||
本文整理 TH Hotel 当前前端开发约定,供本项目 UI 开发和其他 agent 协作参考。
|
||||
|
||||
本文是当前项目专属补充,不应整份复制到其他项目。可复用的通用前端规则应沉淀到 `docs/import/reusable/frontend-development-guidelines.md`。
|
||||
|
||||
前端只负责展示、交互、人工确认、调试入口和调用本项目后端。前端不得直接调用 OHIP、
|
||||
SuperAgent、AgentBus 或任何持有 Secret 的外部系统。
|
||||
|
||||
## 2. 技术栈
|
||||
|
||||
以 `client/package.json` 为准,当前前端技术栈如下:
|
||||
|
||||
| 类别 | 当前选择 |
|
||||
| --- | --- |
|
||||
| 运行时 | Node.js 22.13+ LTS |
|
||||
| 框架 | Vue 3.5.x |
|
||||
| 语言 | TypeScript ~6.0.x,Strict 模式 |
|
||||
| 构建 | Vite 8.x |
|
||||
| 组件写法 | Composition API,`<script setup lang="ts">` |
|
||||
| 路由 | Vue Router 5.x |
|
||||
| 客户端状态 | Pinia 3.x |
|
||||
| 服务端状态 | TanStack Vue Query 5.x |
|
||||
| UI 组件库 | PrimeVue 4.x |
|
||||
| 图标 | PrimeIcons |
|
||||
| 国际化 | vue-i18n 11.x |
|
||||
| Vue SFC 类型检查 | vue-tsc |
|
||||
| 测试 | Vitest 4.x、Vue Test Utils 2.x、jsdom |
|
||||
| Lint | ESLint 10.x、typescript-eslint 8.x、eslint-plugin-vue |
|
||||
|
||||
不引入通用 Admin Template。新增 UI 应延续现有设计语言和样式 token。
|
||||
|
||||
兼容性要求:
|
||||
|
||||
- Vite、ESLint 和 Vitest 的 Node.js 要求必须同时满足,当前统一使用 Node.js 22.13+ LTS。
|
||||
- TypeScript 版本必须与 `typescript-eslint` 支持范围一致;在确认 `typescript-eslint` 支持更高版本前,TypeScript 锁定为 `~6.0.x`,不得使用宽泛的 `^6.0.0`。
|
||||
- Vue SFC 项目必须配置 `vue-tsc` 做类型检查,不能只依赖 `tsc`。
|
||||
- 升级 Vue、Vite、TypeScript、ESLint、Vitest、PrimeVue、Pinia、Vue Router 或 Vue Query 前,必须先检查版本兼容性并更新本文。
|
||||
|
||||
## 3. 目录约定
|
||||
|
||||
当前前端目录:
|
||||
|
||||
```text
|
||||
client/src
|
||||
├── components
|
||||
│ ├── common
|
||||
│ └── reservation
|
||||
├── composables
|
||||
├── i18n
|
||||
│ └── locales
|
||||
├── layouts
|
||||
├── router
|
||||
├── services
|
||||
├── stores
|
||||
├── styles
|
||||
├── tests
|
||||
├── types
|
||||
└── views
|
||||
└── reservation
|
||||
```
|
||||
|
||||
目录规则:
|
||||
|
||||
- API 请求封装放入 `src/services`。
|
||||
- 手写类型定义放入 `src/types`。
|
||||
- 可复用组合逻辑放入 `src/composables`。
|
||||
- 路由定义放入 `src/router`。
|
||||
- Pinia Store 放入 `src/stores`。
|
||||
- i18n 入口和语言包放入 `src/i18n`。
|
||||
- 页面级组件放入 `src/views`。
|
||||
- 可复用业务组件放入 `src/components/<domain>`。
|
||||
- 通用布局放入 `src/layouts`。
|
||||
- 全局样式和设计 token 放入 `src/styles`。
|
||||
- 未来 OpenAPI 生成代码放入 `src/generated`,禁止手工修改。
|
||||
|
||||
## 4. 组件规范
|
||||
|
||||
- 页面和组件统一使用 Vue 3 Composition API。
|
||||
- `.vue` 文件使用 `<script setup lang="ts">`。
|
||||
- Props、Emits、响应式状态和服务返回值必须有明确类型。
|
||||
- 避免在模板中写复杂业务逻辑,复杂逻辑放入 computed、composable 或服务层。
|
||||
- 不在组件里直接拼接后端 URL,统一通过 services。
|
||||
- 不在组件里直接访问浏览器全局存储保存业务事实。
|
||||
- 不把中文或英文显示文案作为业务判断依据。
|
||||
- 不为未知的财务部、前台流程硬编码页面、状态或菜单。
|
||||
|
||||
## 5. 状态管理规则
|
||||
|
||||
Pinia 只保存客户端状态,例如:
|
||||
|
||||
- 当前用户上下文
|
||||
- 当前酒店
|
||||
- 当前部门
|
||||
- 语言和页面偏好
|
||||
- 轻量 UI 状态
|
||||
|
||||
服务端数据使用 TanStack Vue Query:
|
||||
|
||||
- 列表、详情、Timeline、Task、Preflight、SourceMessage 等后端数据通过 Query 获取。
|
||||
- Mutation 完成后按 query key 精准失效或更新缓存。
|
||||
- 不把服务端数据长期复制进 Pinia。
|
||||
- 不用 Pinia 绕过后端权限、状态机或校验。
|
||||
|
||||
## 6. API 请求规范
|
||||
|
||||
- 浏览器只能调用本项目后端。
|
||||
- 所有请求封装到 `src/services`。
|
||||
- 服务函数返回明确 TypeScript 类型。
|
||||
- 统一使用 `httpClient` 处理 JSON、错误和 Problem Detail。
|
||||
- 前端不直接调用 OHIP、SuperAgent、AgentBus、数据库或对象存储。
|
||||
- 前端不发送后端 Secret、replay access key、Provider API Key 或 Oracle 凭证。
|
||||
- 调试页面如果需要触发受控后端能力,应由后端提供 debug-only 包装接口,Secret 保留在后端。
|
||||
|
||||
## 7. 国际化规范
|
||||
|
||||
首期交付:
|
||||
|
||||
```text
|
||||
zh-CN
|
||||
en-US
|
||||
```
|
||||
|
||||
架构预留:
|
||||
|
||||
```text
|
||||
th-TH
|
||||
```
|
||||
|
||||
规则:
|
||||
|
||||
- 新增页面和组件不得硬编码中英文业务文案。
|
||||
- 系统固定文案必须使用稳定 i18n key。
|
||||
- 后端返回稳定业务代码和必要 `labelKey`,前端按 key 显示。
|
||||
- 前端不得把中文或英文文本作为业务判断依据。
|
||||
- 酒店配置名称、客人消息、姓名、备注、邮件正文和附件内容保持原文。
|
||||
- 日期、时间、数字和货币按当前语言、酒店时区和币种配置格式化。
|
||||
- API 仍传递结构化原始值,不传本地化展示字符串作为业务参数。
|
||||
|
||||
## 8. 类型与业务代码
|
||||
|
||||
- TypeScript 类型应贴近后端 API 契约。
|
||||
- 稳定业务代码使用 string union 或枚举型常量,避免散落 magic string。
|
||||
- 动态操作参数使用稳定 `fieldKey`。
|
||||
- 表单字段展示使用 `labelKey` 或 i18n key。
|
||||
- 不用 `label`、中文标题或英文标题做字段标识。
|
||||
- 接口字段变更时,同步更新 `src/types`、services、页面和测试。
|
||||
|
||||
## 9. UI 与交互规范
|
||||
|
||||
- UI 组件库使用 PrimeVue。
|
||||
- 避免引入大型 Admin Template。
|
||||
- 页面应优先表达业务主线,而不是堆叠技术字段。
|
||||
- Debug 页面可以显示技术 ID,但业务页面应优先展示可理解的业务状态和来源摘要。
|
||||
- 预检、人工复核、任务确认要清楚区分:
|
||||
- 外部 Provider 建议
|
||||
- 人工确认值
|
||||
- 最终执行结果
|
||||
- 邮件原文、附件详情和外部响应详情应通过受控详情接口读取,不默认塞进所有 Task 页面。
|
||||
- 涉及客户信息、付款信息和附件时,应默认最小展示。
|
||||
|
||||
## 10. 前端安全规范
|
||||
|
||||
- `VITE_*` 变量会暴露到浏览器构建产物,不能保存 Secret。
|
||||
- 前端不得保存数据库密码、OHIP 凭证、SuperAgent API Key、AgentBus Token、replay key。
|
||||
- 不在 LocalStorage、SessionStorage 或 URL 中保存敏感业务数据。
|
||||
- 错误提示不展示 Authorization、Cookie、Token、原始邮件全文或附件 URL。
|
||||
- 测试夹具不得使用真实客人、真实酒店或真实支付信息。
|
||||
|
||||
## 11. 配置规范
|
||||
|
||||
常用公开配置:
|
||||
|
||||
```text
|
||||
VITE_API_BASE_URL=http://localhost:8080
|
||||
VITE_APP_ENV=local
|
||||
VITE_DEFAULT_LOCALE=zh-CN
|
||||
VITE_ENABLE_MOCKS=false
|
||||
```
|
||||
|
||||
本地开发如需代理后端:
|
||||
|
||||
```text
|
||||
VITE_API_PROXY_TARGET=http://127.0.0.1:8081
|
||||
```
|
||||
|
||||
规则:
|
||||
|
||||
- 公开配置可以放 `VITE_*`。
|
||||
- Secret 一律不进入 `VITE_*`。
|
||||
- 生产需要运行时配置时,应由部署系统生成公开配置文件,例如 `/app-config.json`。
|
||||
- 需要秘密的外部调用一律经后端代理或适配器。
|
||||
|
||||
## 12. 路由规范
|
||||
|
||||
- Vue Router 管理部门级路由。
|
||||
- 新增业务路由前确认对应后端 API 和权限边界。
|
||||
- 平台 Shell 只保留已确认部门入口,不硬编码未知流程。
|
||||
- 详情页路由参数使用稳定 ID。
|
||||
- 页面刷新后必须能通过后端详情接口恢复必要状态,不依赖内存临时状态。
|
||||
|
||||
## 13. 表单与人工确认规范
|
||||
|
||||
- 人工确认表单优先使用后端返回的字段契约。
|
||||
- 保存草稿时使用稳定 `fieldKey`。
|
||||
- 不把显示文案作为提交字段名。
|
||||
- 表单应展示字段来源:Provider 建议、来源消息、人工修正、最终值。
|
||||
- 提交前前端可做基础格式校验,但最终业务校验在后端。
|
||||
- 发生版本冲突时,应提示用户刷新或重新确认,不静默覆盖。
|
||||
|
||||
## 14. Agent 前端开发 Skill 使用
|
||||
|
||||
当前项目后续如果由 Codex 或其他 agent 开发前端,涉及 UI、交互、视觉或浏览器验证时,应优先使用当前环境可用的前端相关 skill。Skill 只作为辅助,不能覆盖本项目 Vue、TypeScript、Vite、PrimeVue、Pinia、Vue Query、i18n、接口契约和安全边界。
|
||||
|
||||
当前项目建议:
|
||||
|
||||
- 新页面、复杂交互或业务页面信息架构:优先使用 `design-taste-frontend` 和 `ui-ux-pro-max`。
|
||||
- 设计 token、组件规范和样式体系:优先使用 `design-system`。
|
||||
- 已有页面视觉重构:优先使用 `redesign-existing-projects`。
|
||||
- 根据截图、设计稿或视觉参考还原页面:优先使用 `image-to-code`。
|
||||
- 浏览器验证、截图检查、点击路径和响应式检查:优先使用 `browser:control-in-app-browser`。
|
||||
- 需要生成插图、图片或占位视觉资产:可使用 `imagegen`。
|
||||
- `ui-styling` 可参考其可访问性、组件状态和样式组织原则,但本项目未确认使用 shadcn 或 Tailwind 前,不得因此引入 shadcn、Tailwind 或替换 PrimeVue。
|
||||
- `superpowers:brainstorming`、`superpowers:writing-plans`、`superpowers:test-driven-development`、`superpowers:verification-before-completion` 用于需求澄清、计划、测试和验收,不属于 UI 框架选择依据。
|
||||
|
||||
交付要求:
|
||||
|
||||
- 涉及 UI 或交互变更时,应说明使用了哪些 skill,或说明为什么未使用。
|
||||
- 涉及可视化结果时,应尽量提供浏览器截图、响应式检查或交互验证结果。
|
||||
- 如果 skill 建议与本项目规范冲突,以本项目规范、接口契约和用户明确要求为准。
|
||||
|
||||
## 15. 测试与检查命令
|
||||
|
||||
前端最低检查:
|
||||
|
||||
```bash
|
||||
cd client
|
||||
pnpm lint
|
||||
pnpm typecheck
|
||||
pnpm test
|
||||
pnpm build
|
||||
```
|
||||
|
||||
`pnpm typecheck` 应执行 `vue-tsc --noEmit` 或等价命令,确保 `.vue` 单文件组件也被类型检查覆盖。
|
||||
|
||||
聚焦开发时可运行:
|
||||
|
||||
```bash
|
||||
cd client
|
||||
pnpm test -- SomeSpecName.spec.ts
|
||||
```
|
||||
|
||||
如果命令尚未配置或因环境问题无法运行,必须明确说明,不能假装通过。
|
||||
|
||||
## 16. Git 与协作流程
|
||||
|
||||
- 改动前说明目标、范围和将修改的文件。
|
||||
- 每次只处理一个模块、一个页面或一个纵向切片。
|
||||
- 不修改与当前任务无关的用户变更。
|
||||
- 前后端接口变化前,先确认 API 契约和字段映射。
|
||||
- 修改后运行项目已配置的检查命令。
|
||||
- Git commit message 使用中文,清楚说明本次提交的业务或技术变更。
|
||||
|
||||
## 17. 前端提交前检查清单
|
||||
|
||||
- [ ] 是否只调用本项目后端?
|
||||
- [ ] 是否没有把 Secret 放入 `VITE_*`、源码、测试或 URL?
|
||||
- [ ] 新文案是否已进入 i18n?
|
||||
- [ ] 是否避免用中文或英文显示文本做业务判断?
|
||||
- [ ] API 请求是否放在 `src/services`?
|
||||
- [ ] 手写类型是否放在 `src/types`?
|
||||
- [ ] 可复用逻辑是否放在 `src/composables`?
|
||||
- [ ] 服务端数据是否使用 Vue Query,而不是长期塞进 Pinia?
|
||||
- [ ] 是否没有手工修改 `src/generated`?
|
||||
- [ ] 涉及 UI、交互或视觉变更时,是否使用或说明未使用合适的前端 / 设计 skill?
|
||||
- [ ] 涉及可视化结果时,是否做过浏览器、截图或响应式验证?
|
||||
- [ ] 是否运行了 `pnpm lint` 或说明了无法运行原因?
|
||||
- [ ] 是否运行了 `pnpm typecheck` 或说明了无法运行原因?
|
||||
- [ ] 是否运行了 `pnpm test` 或说明了无法运行原因?
|
||||
- [ ] 是否运行了 `pnpm build` 或说明了无法运行原因?
|
||||
Reference in New Issue
Block a user