feat(admin): Add user management and upgrade to module permission system
Features - User Management (Phase 4.1): - Database: Add user_modules table for fine-grained module permissions - Database: Add 4 user permissions (view/create/edit/delete) to role_permissions - Backend: UserService (780 lines) - CRUD with tenant isolation - Backend: UserController + UserRoutes (648 lines) - 13 API endpoints - Backend: Batch import users from Excel - Frontend: UserListPage (412 lines) - list/filter/search/pagination - Frontend: UserFormPage (341 lines) - create/edit with module config - Frontend: UserDetailPage (393 lines) - details/tenant/module management - Frontend: 3 modal components (592 lines) - import/assign/configure - API: GET/POST/PUT/DELETE /api/admin/users/* endpoints Architecture Upgrade - Module Permission System: - Backend: Add getUserModules() method in auth.service - Backend: Login API returns modules array in user object - Frontend: AuthContext adds hasModule() method - Frontend: Navigation filters modules based on user.modules - Frontend: RouteGuard checks requiredModule instead of requiredVersion - Frontend: Remove deprecated version-based permission system - UX: Only show accessible modules in navigation (clean UI) - UX: Smart redirect after login (avoid 403 for regular users) Fixes: - Fix UTF-8 encoding corruption in ~100 docs files - Fix pageSize type conversion in userService (String to Number) - Fix authUser undefined error in TopNavigation - Fix login redirect logic with role-based access check - Update Git commit guidelines v1.2 with UTF-8 safety rules Database Changes: - CREATE TABLE user_modules (user_id, tenant_id, module_code, is_enabled) - ADD UNIQUE CONSTRAINT (user_id, tenant_id, module_code) - INSERT 4 permissions + role assignments - UPDATE PUBLIC tenant with 8 module subscriptions Technical: - Backend: 5 new files (~2400 lines) - Frontend: 10 new files (~2500 lines) - Docs: 1 development record + 2 status updates + 1 guideline update - Total: ~4900 lines of code Status: User management 100% complete, module permission system operational
This commit is contained in:
@@ -1,45 +1,45 @@
|
||||
# <EFBFBD>唳旿摨栞挽霈∟<EFBFBD><EFBFBD>?
|
||||
# 数据库设计规范
|
||||
|
||||
> **<EFBFBD><EFBFBD>𧋦嚗?* v2.0
|
||||
> **版本:** v2.0
|
||||
> **最后更新:** 2025-11-06
|
||||
> **数据库:** PostgreSQL 15+
|
||||
> **ORM嚗?* Prisma
|
||||
> **<EFBFBD><EFBFBD>鍂<EFBFBD><EFBFBD>凒嚗?* 撟喳蝱撅?+ <20>賢<EFBFBD>撅?+ 銝𡁜𦛚璅∪<E79285>撅?
|
||||
> **ORM:** Prisma
|
||||
> **适用范围:** 平台层 + 能力层 + 业务模块层
|
||||
|
||||
---
|
||||
|
||||
## 📋 核心原则
|
||||
|
||||
<EFBFBD>祈<EFBFBD><EFBFBD><EFBFBD>糓<EFBFBD><EFBFBD><EFBFBD>㗇芋<EFBFBD>埈㺭<EFBFBD>桀<EFBFBD>霈曇恣<EFBFBD><EFBFBD>抅蝖<EFBFBD>閫<EFBFBD><EFBFBD>嚗<EFBFBD><EFBFBD>憿颱艇<EFBFBD>潮<EFBFBD>摰<EFBFBD><EFBFBD>?
|
||||
本规范是所有模块数据库设计的基础规范,必须严格遵守。
|
||||
|
||||
**霈曇恣<EFBFBD>笔<EFBFBD>嚗?*
|
||||
- <EFBFBD>?<3F>萄儐蝚砌<E89D9A><E7A08C><EFBFBD><EFBFBD>嚗?NF嚗?
|
||||
- <EFBFBD>?雿輻鍂SERIAL雿靝蛹銝駁睸嚗<EFBFBD>㟲<EFBFBD>啗䌊憓痹<EFBFBD><EFBFBD>扯<EFBFBD><EFBFBD>游末嚗?
|
||||
- <EFBFBD>?<3F><><EFBFBD>㕑”<E39591><E2809D>鉄created_at<EFBFBD>吴pdated_at<EFBFBD>園𡢿<EFBFBD>?
|
||||
- <EFBFBD>?<3F>滩<EFBFBD>銵其蝙<E585B6>刻蔓<E588BB>𣳇膄嚗<E88684><E59A97><EFBFBD>羮eleted_at摮埈挾嚗?
|
||||
- <EFBFBD>?憭㚚睸蝥行<E89DA5>雿輻鍂ON DELETE CASCADE
|
||||
- <EFBFBD>?<3F>𤩺<EFBFBD>摮埈挾<E59F88>惩<EFBFBD>摮睃<E691AE>嚗<EFBFBD><E59A97><EFBFBD><EFBFBD>蝙<EFBFBD>灸crypt嚗?
|
||||
**设计原则:**
|
||||
- ✅ 遵循第三范式(3NF)
|
||||
- ✅ 使用SERIAL作为主键(整数自增,性能更好)
|
||||
- ✅ 所有表包含created_at和updated_at时间戳
|
||||
- ✅ 重要表使用软删除(保留deleted_at字段)
|
||||
- ✅ 外键约束使用ON DELETE CASCADE
|
||||
- ✅ 敏感字段加密存储(密码使用bcrypt)
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD><EFBFBD>儭?Schema<EFBFBD>𠉛氖蝑𣇉裦 潃?<3F><><EFBFBD>滩<EFBFBD>
|
||||
## 🏗️ Schema隔离策略 ⭐ 最重要
|
||||
|
||||
### 为什么需要Schema隔离
|
||||
|
||||
**<EFBFBD>詨<EFBFBD><EFBFBD>笔<EFBFBD>嚗?*
|
||||
1. <EFBFBD>?**璅∪<E79285><E288AA>祉<EFBFBD><E7A589>?*嚗𡁏<E59A97>銝芯<E98A9D><E88AAF>⊥芋<E28AA5>埈<EFBFBD><E59F88>祉<EFBFBD><E7A589><EFBFBD>chema
|
||||
2. <EFBFBD>?**<2A>舀<EFBFBD><E88880>祉<EFBFBD><E7A589>函蔡**嚗𡁜虾隞亙<E99A9E><E4BA99>砍紡<E7A08D>箸<EFBFBD>銝芣芋<E88AA3>㛖<EFBFBD><E39B96>唳旿
|
||||
3. <EFBFBD>?**<2A>舀<EFBFBD><E88880>祉<EFBFBD><E7A589><EFBFBD><EFBFBD>?*嚗𡁜虾隞亙<E99A9E><E4BA99>砌漱隞䀹<E99A9E>銝芣芋<E88AA3>?
|
||||
4. <EFBFBD>?**<2A><><EFBFBD><EFBFBD>𠉛氖**嚗𡁜虾隞乩蛹銝滚<E98A9D>Schema霈曄蔭銝滚<E98A9D><E6BB9A><EFBFBD><EFBFBD>
|
||||
5. <EFBFBD>?**<2A>踹<EFBFBD><E8B8B9>賢<EFBFBD><E8B3A2>脩<EFBFBD>**嚗帋<E59A97><E5B88B>峕芋<E5B395>堒虾隞交<E99A9E><E4BAA4>詨<EFBFBD><E8A9A8><EFBFBD>”<EFBFBD>?
|
||||
**核心原因:**
|
||||
1. ✅ **模块独立性**:每个业务模块有独立的Schema
|
||||
2. ✅ **支持独立部署**:可以单独导出某个模块的数据
|
||||
3. ✅ **支持独立销售**:可以单独交付某个模块
|
||||
4. ✅ **权限隔离**:可以为不同Schema设置不同权限
|
||||
5. ✅ **避免命名冲突**:不同模块可以有相同的表名
|
||||
|
||||
### Schema命名规范
|
||||
|
||||
```
|
||||
platform_schema # 撟喳蝱<EFBFBD>箇<EFBFBD>撅<EFBFBD><EFBFBD><EFBFBD>典<EFBFBD><EFBFBD>曹澈嚗?
|
||||
platform_schema # 平台基础层(全局共享)
|
||||
aia_schema # AI智能问答
|
||||
asl_schema # AI智能文献
|
||||
pkb_schema # 銝芯犖<EFBFBD>亥<EFBFBD>摨?
|
||||
pkb_schema # 个人知识库
|
||||
dc_schema # 数据清洗整理
|
||||
ssa_schema # 智能统计分析
|
||||
st_schema # 统计分析工具
|
||||
@@ -56,18 +56,18 @@ CREATE SCHEMA IF NOT EXISTS aia_schema;
|
||||
-- ...其他Schema
|
||||
```
|
||||
|
||||
### 頝沒chema靘肽<EFBFBD>閫<EFBFBD><EFBFBD> 潃?敹<>◆<EFBFBD>萄<EFBFBD>
|
||||
### 跨Schema依赖规则 ⭐ 必须遵守
|
||||
|
||||
**允许的依赖:**
|
||||
```sql
|
||||
-- <EFBFBD>?<3F><>捂嚗帋<E59A97><E5B88B>⊥芋<E28AA5>堒<EFBFBD><E5A092>私latform_schema
|
||||
-- ✅ 允许:业务模块引用platform_schema
|
||||
CREATE TABLE asl_schema.literature_projects (
|
||||
id SERIAL PRIMARY KEY,
|
||||
user_id INTEGER REFERENCES platform_schema.users(id) ON DELETE CASCADE,
|
||||
...
|
||||
);
|
||||
|
||||
-- <EFBFBD>?<3F><>捂嚗𡁻<E59A97>𡁶鍂<F0A181B6>賢<EFBFBD>撘閧鍂platform_schema
|
||||
-- ✅ 允许:通用能力引用platform_schema
|
||||
CREATE TABLE platform_schema.llm_usage (
|
||||
id SERIAL PRIMARY KEY,
|
||||
user_id INTEGER REFERENCES platform_schema.users(id) ON DELETE CASCADE,
|
||||
@@ -77,14 +77,14 @@ CREATE TABLE platform_schema.llm_usage (
|
||||
|
||||
**禁止的依赖:**
|
||||
```sql
|
||||
-- <EFBFBD>?蝳<>迫嚗帋<E59A97><E5B88B>⊥芋<E28AA5>𦯀<EFBFBD><F0A6AF80>港<EFBFBD><E6B8AF>詨<EFBFBD><E8A9A8>?
|
||||
-- ❌ 禁止:业务模块之间互相引用
|
||||
CREATE TABLE ssa_schema.analysis_projects (
|
||||
id SERIAL PRIMARY KEY,
|
||||
-- <EFBFBD>躰秤嚗<EFBFBD><EFBFBD><EFBFBD>賢<EFBFBD><EFBFBD>典<EFBFBD>隞碶<EFBFBD><EFBFBD>⊥芋<EFBFBD>?
|
||||
-- 错误!不能引用其他业务模块
|
||||
literature_project_id INTEGER REFERENCES asl_schema.literature_projects(id)
|
||||
);
|
||||
|
||||
-- <EFBFBD>?蝳<>迫嚗䮝latform_schema<EFBFBD>滚<EFBFBD>靘肽<EFBFBD>銝𡁜𦛚璅∪<EFBFBD>
|
||||
-- ❌ 禁止:platform_schema反向依赖业务模块
|
||||
CREATE TABLE platform_schema.users (
|
||||
id SERIAL PRIMARY KEY,
|
||||
-- 错误!platform_schema不能依赖业务模块
|
||||
@@ -92,104 +92,104 @@ CREATE TABLE platform_schema.users (
|
||||
);
|
||||
```
|
||||
|
||||
**甇<EFBFBD>&<EFBFBD>𡁏<EFBFBD>嚗?*
|
||||
**正确做法:**
|
||||
```
|
||||
頝冽芋<EFBFBD>埈㺭<EFBFBD>桀<EFBFBD><EFBFBD>𥪜銁摨𠉛鍂撅<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>銝滚銁<EFBFBD>唳旿摨枏<EFBFBD>嚗?
|
||||
跨模块数据关联在应用层处理,不在数据库层!
|
||||
|
||||
方式1:通过user_id关联
|
||||
- 两个模块都引用platform_schema.users
|
||||
- <EFBFBD>典<EFBFBD><EFBFBD>典<EFBFBD><EFBFBD>朞<EFBFBD>user_id<EFBFBD>亥砭銝支葵璅∪<EFBFBD><EFBFBD><EFBFBD>㺭<EFBFBD>?
|
||||
- 在应用层通过user_id查询两个模块的数据
|
||||
- 在应用层组装数据
|
||||
|
||||
<EFBFBD>孵<EFBFBD>2嚗𡁜<EFBFBD><EFBFBD>其<EFBFBD><EFBFBD>!D摮㛖泵銝?
|
||||
- <EFBFBD>刻”銝剖<EFBFBD><EFBFBD>典<EFBFBD>隞𡝗芋<EFBFBD>㛖<EFBFBD>銝𡁜𦛚ID嚗ĀARCHAR嚗?
|
||||
- 銝滚遣蝡见<EFBFBD><EFBFBD>桀<EFBFBD>蝟?
|
||||
- <EFBFBD>典<EFBFBD><EFBFBD>典<EFBFBD>撉諹<EFBFBD>ID<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
|
||||
方式2:存储业务ID字符串
|
||||
- 在表中存储其他模块的业务ID(VARCHAR)
|
||||
- 不建立外键关系
|
||||
- 在应用层验证ID的有效性
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📝 命名规范
|
||||
|
||||
### 銵典𦶢<EFBFBD>?
|
||||
### 表命名
|
||||
|
||||
**閫<EFBFBD><EFBFBD>嚗?*
|
||||
**规则:**
|
||||
- 小写字母
|
||||
- 銝见<EFBFBD>蝥踹<EFBFBD><EFBFBD>?
|
||||
- 下划线分隔
|
||||
- 复数形式
|
||||
- Schema<EFBFBD>滨<EFBFBD>嚗<EFBFBD>䰻霂X𧒄雿輻鍂嚗?
|
||||
- Schema前缀(查询时使用)
|
||||
|
||||
**蝷箔<EFBFBD>嚗?*
|
||||
**示例:**
|
||||
```sql
|
||||
-- <EFBFBD>?甇<>&
|
||||
-- ✅ 正确
|
||||
CREATE TABLE asl_schema.literature_projects (...);
|
||||
CREATE TABLE platform_schema.users (...);
|
||||
CREATE TABLE pkb_schema.knowledge_bases (...);
|
||||
|
||||
-- <EFBFBD>?<3F>躰秤
|
||||
-- ❌ 错误
|
||||
CREATE TABLE ASLSchema.LiteratureProject (...); -- 驼峰
|
||||
CREATE TABLE asl_schema.project (...); -- 单数
|
||||
CREATE TABLE literature-projects (...); -- 雿輻鍂餈𧼮<EFBFBD>蝚?
|
||||
CREATE TABLE literature-projects (...); -- 使用连字符
|
||||
```
|
||||
|
||||
### 字段命名
|
||||
|
||||
**閫<EFBFBD><EFBFBD>嚗?*
|
||||
**规则:**
|
||||
- 小写字母
|
||||
- 銝见<EFBFBD>蝥踹<EFBFBD><EFBFBD>?
|
||||
- 下划线分隔
|
||||
- 语义清晰
|
||||
|
||||
**蝷箔<EFBFBD>嚗?*
|
||||
**示例:**
|
||||
```sql
|
||||
-- <EFBFBD>?甇<>&
|
||||
-- ✅ 正确
|
||||
user_id
|
||||
created_at
|
||||
project_name
|
||||
is_active
|
||||
|
||||
-- <EFBFBD>?<3F>躰秤
|
||||
-- ❌ 错误
|
||||
userId -- 驼峰
|
||||
createdat -- 瘝⊥<EFBFBD>銝见<EFBFBD>蝥?
|
||||
prjName -- 蝻拙<EFBFBD>銝齿<EFBFBD><EFBFBD>?
|
||||
createdat -- 没有下划线
|
||||
prjName -- 缩写不清晰
|
||||
```
|
||||
|
||||
### 索引命名
|
||||
|
||||
**閫<EFBFBD><EFBFBD>嚗?* `idx_銵典<E98AB5>_摮埈挾<E59F88>崾
|
||||
**规则:** `idx_表名_字段名`
|
||||
|
||||
**蝷箔<EFBFBD>嚗?*
|
||||
**示例:**
|
||||
```sql
|
||||
-- <20>?甇<>&
|
||||
-- ✅ 正确
|
||||
CREATE INDEX idx_users_email ON platform_schema.users(email);
|
||||
CREATE INDEX idx_projects_user_id ON asl_schema.literature_projects(user_id);
|
||||
CREATE INDEX idx_projects_user_status ON asl_schema.literature_projects(user_id, status);
|
||||
|
||||
-- <20>?<3F>躰秤
|
||||
-- ❌ 错误
|
||||
CREATE INDEX user_email_idx ... -- 顺序错误
|
||||
CREATE INDEX index_on_email ... -- <EFBFBD>滨妍銝齿<EFBFBD><EFBFBD>?
|
||||
CREATE INDEX index_on_email ... -- 名称不清晰
|
||||
```
|
||||
|
||||
### 外键命名
|
||||
|
||||
**閫<EFBFBD><EFBFBD>嚗?* `fk_銵典<EFBFBD>_<EFBFBD>唾<EFBFBD>銵典<EFBFBD>`
|
||||
**规则:** `fk_表名_关联表名`
|
||||
|
||||
**蝷箔<EFBFBD>嚗?*
|
||||
**示例:**
|
||||
```sql
|
||||
-- <20>?甇<>&
|
||||
-- ✅ 正确
|
||||
CONSTRAINT fk_projects_users
|
||||
FOREIGN KEY (user_id) REFERENCES platform_schema.users(id);
|
||||
|
||||
CONSTRAINT fk_items_projects
|
||||
FOREIGN KEY (project_id) REFERENCES asl_schema.literature_projects(id);
|
||||
|
||||
-- <20>?<3F>躰秤
|
||||
CONSTRAINT user_fk ... -- <EFBFBD>滨妍銝齿<EFBFBD><EFBFBD>?
|
||||
-- ❌ 错误
|
||||
CONSTRAINT user_fk ... -- 名称不清晰
|
||||
CONSTRAINT foreign_key_users ... -- 太长
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD><EFBFBD> <20>𡁶鍂摮埈挾 潃?敹<>◆<EFBFBD><E29786>鉄
|
||||
## 📊 通用字段 ⭐ 必须包含
|
||||
|
||||
### 所有表必须包含
|
||||
|
||||
@@ -201,13 +201,13 @@ CREATE TABLE xxx_schema.table_name (
|
||||
-- 业务字段
|
||||
...
|
||||
|
||||
-- <EFBFBD>園𡢿<EFBFBD>喉<EFBFBD>敹<EFBFBD>◆嚗?
|
||||
-- 时间戳(必须)
|
||||
created_at TIMESTAMP DEFAULT NOW() NOT NULL,
|
||||
updated_at TIMESTAMP DEFAULT NOW() NOT NULL
|
||||
);
|
||||
```
|
||||
|
||||
### <EFBFBD>滩<EFBFBD>銵典<EFBFBD><EFBFBD><EFBFBD>鉄嚗<EFBFBD>蔓<EFBFBD>𣳇膄嚗?
|
||||
### 重要表应包含(软删除)
|
||||
|
||||
```sql
|
||||
CREATE TABLE xxx_schema.important_table (
|
||||
@@ -219,7 +219,7 @@ CREATE TABLE xxx_schema.important_table (
|
||||
-- 软删除字段(可选,重要表建议添加)
|
||||
deleted_at TIMESTAMP,
|
||||
|
||||
-- <EFBFBD>園𡢿<EFBFBD>喉<EFBFBD>敹<EFBFBD>◆嚗?
|
||||
-- 时间戳(必须)
|
||||
created_at TIMESTAMP DEFAULT NOW() NOT NULL,
|
||||
updated_at TIMESTAMP DEFAULT NOW() NOT NULL
|
||||
);
|
||||
@@ -228,7 +228,7 @@ CREATE TABLE xxx_schema.important_table (
|
||||
SELECT * FROM xxx_schema.important_table WHERE deleted_at IS NULL;
|
||||
```
|
||||
|
||||
### <EFBFBD>冽<EFBFBD><EFBFBD>唾<EFBFBD>銵典<EFBFBD>憿餃<EFBFBD><EFBFBD>?
|
||||
### 用户关联表必须包含
|
||||
|
||||
```sql
|
||||
CREATE TABLE xxx_schema.user_related_table (
|
||||
@@ -240,7 +240,7 @@ CREATE TABLE xxx_schema.user_related_table (
|
||||
-- 业务字段
|
||||
...
|
||||
|
||||
-- <EFBFBD>園𡢿<EFBFBD>喉<EFBFBD>敹<EFBFBD>◆嚗?
|
||||
-- 时间戳(必须)
|
||||
created_at TIMESTAMP DEFAULT NOW() NOT NULL,
|
||||
updated_at TIMESTAMP DEFAULT NOW() NOT NULL
|
||||
);
|
||||
@@ -250,7 +250,7 @@ CREATE TABLE xxx_schema.user_related_table (
|
||||
|
||||
## 🔍 索引设计规范
|
||||
|
||||
### 敹<EFBFBD>◆瘛餃<EFBFBD>蝝W<EFBFBD><EFBFBD><EFBFBD><EFBFBD>畾?
|
||||
### 必须添加索引的字段
|
||||
|
||||
**1. 主键**
|
||||
```sql
|
||||
@@ -266,7 +266,7 @@ CREATE INDEX idx_projects_user_id ON asl_schema.literature_projects(user_id);
|
||||
|
||||
**3. 常用查询字段**
|
||||
```sql
|
||||
-- status嚗<EFBFBD>𠶖<EFBFBD><EFBFBD><EFBFBD>畾蛛<EFBFBD>撣貊鍂鈭竝HERE嚗?
|
||||
-- status(状态字段,常用于WHERE)
|
||||
CREATE INDEX idx_projects_status ON asl_schema.literature_projects(status);
|
||||
|
||||
-- created_at(时间字段,常用于排序)
|
||||
@@ -281,22 +281,22 @@ CREATE UNIQUE INDEX idx_users_email ON platform_schema.users(email);
|
||||
|
||||
### 复合索引
|
||||
|
||||
**閫<EFBFBD><EFBFBD>嚗?*
|
||||
**规则:**
|
||||
- 高频组合查询使用复合索引
|
||||
- 最常查询的字段放在前面
|
||||
- 憭滚<E686AD>蝝W<E89D9D><EFBCB7><EFBFBD>憭?銝芸<E98A9D>畾?
|
||||
- 复合索引最多3个字段
|
||||
|
||||
**蝷箔<EFBFBD>嚗?*
|
||||
**示例:**
|
||||
```sql
|
||||
-- <20>?甇<>&嚗鮁ser_id + status 蝏<EFBFBD><EFBFBD><EFBFBD>亥砭
|
||||
-- ✅ 正确:user_id + status 组合查询
|
||||
CREATE INDEX idx_projects_user_status
|
||||
ON asl_schema.literature_projects(user_id, status);
|
||||
|
||||
-- <20>臭誑隡睃<E99AA1>隞乩<E99A9E><E4B9A9>亥砭嚗?
|
||||
-- 可以优化以下查询:
|
||||
-- WHERE user_id = ? AND status = ?
|
||||
-- WHERE user_id = ? 嚗<EFBFBD>蘨<EFBFBD>典<EFBFBD>蝻<EFBFBD>嚗?
|
||||
-- WHERE user_id = ? (只用前缀)
|
||||
|
||||
-- <20>?<3F>躰秤嚗𡁜<E59A97>畾菔<E795BE>憭?
|
||||
-- ❌ 错误:字段过多
|
||||
CREATE INDEX idx_projects_complex
|
||||
ON asl_schema.literature_projects(user_id, status, created_at, updated_at);
|
||||
```
|
||||
@@ -307,7 +307,7 @@ CREATE INDEX idx_projects_complex
|
||||
|
||||
### ON DELETE策略
|
||||
|
||||
**閫<EFBFBD><EFBFBD>嚗?*
|
||||
**规则:**
|
||||
```sql
|
||||
-- 用户删除时,级联删除关联数据
|
||||
FOREIGN KEY (user_id)
|
||||
@@ -319,15 +319,15 @@ FOREIGN KEY (project_id)
|
||||
REFERENCES asl_schema.literature_projects(id)
|
||||
ON DELETE CASCADE;
|
||||
|
||||
-- <20>寞<EFBFBD><E5AF9E><EFBFBD><EFBFBD>嚗帋<E59A97><E5B88B>賢<EFBFBD><E8B3A2>?
|
||||
-- 特殊情况:不能删除
|
||||
FOREIGN KEY (parent_id)
|
||||
REFERENCES xxx_schema.parent_table(id)
|
||||
ON DELETE RESTRICT; -- <20>匧<EFBFBD>霈啣<E99C88><E595A3>嗥<EFBFBD>甇W<E79487><EFBCB7>?
|
||||
ON DELETE RESTRICT; -- 有子记录时禁止删除
|
||||
```
|
||||
|
||||
### 外键索引
|
||||
|
||||
**閫<EFBFBD><EFBFBD>嚗?* <20><><EFBFBD>匧<EFBFBD><E58CA7>桀<EFBFBD>憿餅溶<E9A485>删揣撘?
|
||||
**规则:** 所有外键必须添加索引
|
||||
|
||||
```sql
|
||||
-- 创建外键
|
||||
@@ -342,11 +342,11 @@ CREATE INDEX idx_items_project_id ON asl_schema.literature_items(project_id);
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD>?<3F>扯<EFBFBD>隡睃<E99AA1>閫<EFBFBD><E996AB>
|
||||
## ⚡ 性能优化规范
|
||||
|
||||
### 大表分区(可选)
|
||||
|
||||
**<2A><>鍂<EFBFBD>箸艶嚗?* 撟游<E6929F><E6B8B8>?> 100銝<30>扇敶?
|
||||
**适用场景:** 年增长 > 100万记录
|
||||
|
||||
```sql
|
||||
-- 按月分区(如llm_usage表)
|
||||
@@ -388,13 +388,13 @@ WHERE created_at < NOW() - INTERVAL '1 year';
|
||||
|
||||
```sql
|
||||
-- 密码字段
|
||||
password VARCHAR(255) NOT NULL -- 雿輻鍂bcrypt<70>惩<EFBFBD>嚗<EFBFBD><E59A97><EFBFBD>典<EFBFBD>撣<EFBFBD><E692A3>?
|
||||
password VARCHAR(255) NOT NULL -- 使用bcrypt加密,存储哈希值
|
||||
|
||||
-- API Key字段
|
||||
api_key_encrypted TEXT NOT NULL -- 使用AES-256加密
|
||||
|
||||
-- 个人敏感信息
|
||||
phone_encrypted VARCHAR(255) -- <EFBFBD>𧢲㦤<EFBFBD>瑕<EFBFBD>撖?
|
||||
phone_encrypted VARCHAR(255) -- 手机号加密
|
||||
id_card_encrypted VARCHAR(255) -- 身份证号加密
|
||||
```
|
||||
|
||||
@@ -402,7 +402,7 @@ id_card_encrypted VARCHAR(255) -- 身份证号加密
|
||||
|
||||
```sql
|
||||
-- 日志中不记录敏感字段
|
||||
-- 撘<><E69298>?瘚贝<E7989A><E8B49D>臬<EFBFBD>雿輻鍂<E8BCBB>望<EFBFBD><E69C9B>唳旿
|
||||
-- 开发/测试环境使用脱敏数据
|
||||
UPDATE platform_schema.users
|
||||
SET
|
||||
email = CONCAT('user', id, '@example.com'),
|
||||
@@ -416,71 +416,71 @@ WHERE environment = 'development';
|
||||
|
||||
### 常用字段类型
|
||||
|
||||
| <EFBFBD>券<EFBFBD>?| <20>刻<EFBFBD>蝐餃<E89D90> | 霂湔<E99C82> |
|
||||
| 用途 | 推荐类型 | 说明 |
|
||||
|------|---------|------|
|
||||
| 主键 | SERIAL | 整数自增 |
|
||||
| 憭㚚睸 | INTEGER | 銝𦒘蜓<EFBFBD>桃掩<EFBFBD>衤<EFBFBD><EFBFBD>?|
|
||||
| <EFBFBD>剜<EFBFBD><EFBFBD>?| VARCHAR(N) | N<500嚗<EFBFBD><EFBFBD>憪枏<EFBFBD><EFBFBD><EFBFBD><EFBFBD>憸?|
|
||||
| <EFBFBD>踵<EFBFBD><EFBFBD>?| TEXT | <EFBFBD>𣳇鵭摨阡<EFBFBD><EFBFBD>塚<EFBFBD>憒<EFBFBD><EFBFBD>餈啜<EFBFBD><EFBFBD><EFBFBD>摰?|
|
||||
| 撣<EFBFBD><EFBFBD><EFBFBD>?| BOOLEAN | true/false |
|
||||
| <EFBFBD>交<EFBFBD><EFBFBD>園𡢿 | TIMESTAMP | 蝎曄&<EFBFBD>唳神蝘?|
|
||||
| 外键 | INTEGER | 与主键类型一致 |
|
||||
| 短文本 | VARCHAR(N) | N<500,如姓名、标题 |
|
||||
| 长文本 | TEXT | 无长度限制,如描述、内容 |
|
||||
| 布尔值 | BOOLEAN | true/false |
|
||||
| 日期时间 | TIMESTAMP | 精确到毫秒 |
|
||||
| 金额 | DECIMAL(10,2) | 避免精度问题 |
|
||||
| JSON | JSONB | 支持索引,性能更好 |
|
||||
|
||||
### 字段长度建议
|
||||
|
||||
```sql
|
||||
-- <20>剜<EFBFBD><E5899C>?
|
||||
-- 短文本
|
||||
name VARCHAR(100) -- 姓名
|
||||
title VARCHAR(200) -- 标题
|
||||
email VARCHAR(255) -- 邮箱
|
||||
phone VARCHAR(20) -- <EFBFBD>𧢲㦤<EFBFBD>?
|
||||
phone VARCHAR(20) -- 手机号
|
||||
|
||||
-- <20>嗆<EFBFBD><E59786><EFBFBD>銝?
|
||||
-- 状态枚举
|
||||
status VARCHAR(20) -- active, inactive, deleted
|
||||
role VARCHAR(20) -- user, admin
|
||||
|
||||
-- <20>踵<EFBFBD><E8B8B5>?
|
||||
-- 长文本
|
||||
description TEXT -- 描述
|
||||
content TEXT -- 内容
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD>?璉<><E79289>交<EFBFBD><E4BAA4>?
|
||||
## ✅ 检查清单
|
||||
|
||||
**设计新表时必须检查:**
|
||||
- [ ] 銵典<EFBFBD>蝚血<EFBFBD><EFBFBD>賢<EFBFBD>閫<EFBFBD><EFBFBD>嚗<EFBFBD><EFBFBD><EFBFBD>?銝见<E98A9D>蝥?憭齿㺭嚗?
|
||||
- [ ] 表名符合命名规范(小写+下划线+复数)
|
||||
- [ ] 使用正确的Schema(platform/aia/asl/pkb等)
|
||||
- [ ] <EFBFBD><EFBFBD>鉄id銝駁睸嚗𠄎ERIAL PRIMARY KEY嚗?
|
||||
- [ ] <EFBFBD><EFBFBD>鉄created_at<EFBFBD>吴pdated_at<EFBFBD>園𡢿<EFBFBD>?
|
||||
- [ ] 包含id主键(SERIAL PRIMARY KEY)
|
||||
- [ ] 包含created_at和updated_at时间戳
|
||||
- [ ] 用户关联表包含user_id外键
|
||||
- [ ] 所有外键都有ON DELETE策略
|
||||
- [ ] <EFBFBD><EFBFBD><EFBFBD>匧<EFBFBD><EFBFBD>桅<EFBFBD>瘛餃<EFBFBD>鈭<EFBFBD>揣撘?
|
||||
- [ ] 撣貊鍂<EFBFBD>亥砭摮埈挾瘛餃<EFBFBD>鈭<EFBFBD>揣撘?
|
||||
- [ ] 所有外键都添加了索引
|
||||
- [ ] 常用查询字段添加了索引
|
||||
- [ ] 外键约束符合跨Schema依赖规则
|
||||
- [ ] <EFBFBD>𤩺<EFBFBD>摮埈挾撌脣<EFBFBD>撖<EFBFBD><EFBFBD><EFBFBD>?
|
||||
- [ ] 敏感字段已加密存储
|
||||
|
||||
---
|
||||
|
||||
## 🔗 相关文档
|
||||
|
||||
**<EFBFBD>餉<EFBFBD>嚗?*
|
||||
- [<EFBFBD>唳旿摨枏<EFBFBD>撅<EFBFBD>閫<EFBFBD>㦛](./03-<2D>唳旿摨枏<E691A8>撅<EFBFBD>閫<EFBFBD>㦛.md) 潃?<3F>亦<EFBFBD><E4BAA6><EFBFBD><EFBFBD>农chema<EFBFBD>諹”
|
||||
**总览:**
|
||||
- [数据库全局视图](./03-数据库全局视图.md) ⭐ 查看所有Schema和表
|
||||
|
||||
**璅⊥踎嚗?*
|
||||
- [<EFBFBD>唳旿摨栞挽霈⊥芋<EFBFBD>瓢(../_templates/<EFBFBD>唳旿摨栞挽霈?璅⊥踎.md)
|
||||
**模板:**
|
||||
- [数据库设计模板](../_templates/数据库设计-模板.md)
|
||||
|
||||
**各模块设计:**
|
||||
- [撟喳蝱<EFBFBD>箇<EFBFBD>撅<EFBFBD>(../01-撟喳蝱<E596B3>箇<EFBFBD>撅?README.md)
|
||||
- [<EFBFBD>𡁶鍂<EFBFBD>賢<EFBFBD>撅<EFBFBD>(../02-<2D>𡁶鍂<F0A181B6>賢<EFBFBD>撅?README.md)
|
||||
- [平台基础层](../01-平台基础层/README.md)
|
||||
- [通用能力层](../02-通用能力层/README.md)
|
||||
- [业务模块层](../03-业务模块/README.md)
|
||||
|
||||
---
|
||||
|
||||
**最后更新:** 2025-11-06
|
||||
**维护人:** 技术架构师
|
||||
**<EFBFBD><EFBFBD>𧋦嚗?* v2.0
|
||||
**版本:** v2.0
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,32 +1,32 @@
|
||||
# API设计规范
|
||||
|
||||
> **<EFBFBD><EFBFBD>𧋦嚗?* v2.0
|
||||
> **版本:** v2.0
|
||||
> **最后更新:** 2025-11-06
|
||||
> **API憌擧聢嚗?* RESTful API
|
||||
> **<EFBFBD>箇<EFBFBD>URL嚗?* `http://localhost:3001/api/v1`
|
||||
> **<EFBFBD><EFBFBD>鍂<EFBFBD><EFBFBD>凒嚗?* 撟喳蝱撅?+ <20>賢<EFBFBD>撅?+ 銝𡁜𦛚璅∪<E79285>撅?
|
||||
> **API风格:** RESTful API
|
||||
> **基础URL:** `http://localhost:3001/api/v1`
|
||||
> **适用范围:** 平台层 + 能力层 + 业务模块层
|
||||
|
||||
---
|
||||
|
||||
## 📋 设计原则
|
||||
|
||||
### API First原则
|
||||
- <EFBFBD>?<3F><>挽霈,PI嚗<49><E59A97>摰䂿緵<E482BF>蠘<EFBFBD>
|
||||
- <EFBFBD>?API<EFBFBD>臬<EFBFBD><EFBFBD>𡒊垢<EFBFBD><EFBFBD><EFBFBD>蝥?
|
||||
- <EFBFBD>?API<EFBFBD>䀹凒<EFBFBD><EFBFBD>閬<EFBFBD><EFBFBD><EFBFBD>祆綉<EFBFBD>?
|
||||
- <EFBFBD>?<3F><><EFBFBD>𡅅PI<50>質<EFBFBD><E8B3AA>㗇<EFBFBD>獢?
|
||||
- ✅ 先设计API,再实现功能
|
||||
- ✅ API是前后端的契约
|
||||
- ✅ API变更需要版本控制
|
||||
- ✅ 所有API都要有文档
|
||||
|
||||
### RESTful设计
|
||||
- <EFBFBD>?雿輻鍂HTTP<54>刻<EFBFBD>銵函內<E587BD>滢<EFBFBD>嚗𠃑ET<45><54>OST<53><54>UT<55><54>ELETE嚗?
|
||||
- <EFBFBD>?URL銵函內韏<EFBFBD><EFBFBD>嚗䔶<EFBFBD>銵函內<EFBFBD>其<EFBFBD>
|
||||
- <EFBFBD>?雿輻鍂憭齿㺭<E9BDBF>滩<EFBFBD>銵函內韏<E585A7><E99F8F><EFBFBD><EFBFBD><EFBFBD>
|
||||
- <EFBFBD>?撋<><E6928B>韏<EFBFBD><E99F8F>銝滩<E98A9D>餈?撅?
|
||||
- <EFBFBD>?雿輻鍂HTTP<54>嗆<EFBFBD><E59786><EFBFBD>銵函內蝏𤘪<E89D8F>
|
||||
- ✅ 使用HTTP动词表示操作(GET、POST、PUT、DELETE)
|
||||
- ✅ URL表示资源,不表示动作
|
||||
- ✅ 使用复数名词表示资源集合
|
||||
- ✅ 嵌套资源不超过2层
|
||||
- ✅ 使用HTTP状态码表示结果
|
||||
|
||||
### 命名规范
|
||||
- <EFBFBD>?URL雿輻鍂撠誩<EFBFBD>摮埈<EFBFBD><EFBFBD>諹<EFBFBD>摮㛖泵嚗ɑebab-case嚗?
|
||||
- <EFBFBD>?<3F>亥砭<E4BAA5><E7A0AD>㺭雿輻鍂撽澆陸<E6BE86>賢<EFBFBD>嚗ẾamelCase嚗?
|
||||
- <EFBFBD>?JSON摮埈挾雿輻鍂撽澆陸<EFBFBD>賢<EFBFBD>嚗ẾamelCase嚗?
|
||||
- ✅ URL使用小写字母和连字符(kebab-case)
|
||||
- ✅ 查询参数使用驼峰命名(camelCase)
|
||||
- ✅ JSON字段使用驼峰命名(camelCase)
|
||||
|
||||
---
|
||||
|
||||
@@ -37,9 +37,9 @@
|
||||
```
|
||||
/api/v{version}/{module}/{resource}/{id?}/{action?}
|
||||
|
||||
蝷箔<EFBFBD>嚗?
|
||||
示例:
|
||||
/api/v1/literature/projects # 获取文献项目列表
|
||||
/api/v1/literature/projects/123 # <EFBFBD>瑕<EFBFBD>ID=123<EFBFBD><EFBFBD>★<EFBFBD>?
|
||||
/api/v1/literature/projects/123 # 获取ID=123的项目
|
||||
/api/v1/literature/projects/123/export # 导出项目(动作)
|
||||
```
|
||||
|
||||
@@ -50,19 +50,19 @@
|
||||
| 认证 | `/auth` | `/api/v1/auth/login` |
|
||||
| 用户 | `/users` | `/api/v1/users/me` |
|
||||
| AI问答 | `/chat` | `/api/v1/chat/conversations` |
|
||||
| <EFBFBD>箄<EFBFBD>雿?| `/agents` | `/api/v1/agents` |
|
||||
| 智能体 | `/agents` | `/api/v1/agents` |
|
||||
| AI文献 | `/literature` | `/api/v1/literature/projects` |
|
||||
| <EFBFBD>亥<EFBFBD>摨?| `/knowledge-bases` | `/api/v1/knowledge-bases` |
|
||||
| 知识库 | `/knowledge-bases` | `/api/v1/knowledge-bases` |
|
||||
| 数据清洗 | `/data-cleaning` | `/api/v1/data-cleaning/projects` |
|
||||
| 统计分析 | `/analysis` | `/api/v1/analysis/projects` |
|
||||
| 统计工具 | `/tools` | `/api/v1/tools` |
|
||||
| 稿件审查 | `/review` | `/api/v1/review/tasks` |
|
||||
| LLM网关 | `/llm` | `/api/v1/llm/chat` |
|
||||
| 蝞∠<EFBFBD>蝡?| `/admin` | `/api/v1/admin/users` |
|
||||
| 管理端 | `/admin` | `/api/v1/admin/users` |
|
||||
|
||||
### 资源命名
|
||||
|
||||
**<EFBFBD>?甇<>&蝷箔<E89DB7>嚗?*
|
||||
**✅ 正确示例:**
|
||||
```
|
||||
GET /api/v1/literature/projects # 获取列表
|
||||
GET /api/v1/literature/projects/:id # 获取详情
|
||||
@@ -72,10 +72,10 @@ DELETE /api/v1/literature/projects/:id # 删除
|
||||
|
||||
GET /api/v1/literature/projects/:id/items # 获取项目下的文献
|
||||
POST /api/v1/literature/projects/:id/items/import # 导入文献
|
||||
POST /api/v1/literature/projects/:id/screening/execute # <EFBFBD>扯<EFBFBD>蝑偦<EFBFBD>?
|
||||
POST /api/v1/literature/projects/:id/screening/execute # 执行筛选
|
||||
```
|
||||
|
||||
**<EFBFBD>?<3F>躰秤蝷箔<E89DB7>嚗?*
|
||||
**❌ 错误示例:**
|
||||
```
|
||||
POST /api/v1/literature/getProjects # 使用动词
|
||||
POST /api/v1/literature/createProject # 使用动词
|
||||
@@ -89,13 +89,13 @@ GET /api/v1/literatureProjectList # 驼峰命名
|
||||
|
||||
### 方法使用
|
||||
|
||||
| <EFBFBD>寞<EFBFBD> | <20>券<EFBFBD>?| <20>臬炏撟<E7828F><E6929F> | <20>臬炏摰匧<E691B0> |
|
||||
| 方法 | 用途 | 是否幂等 | 是否安全 |
|
||||
|------|------|---------|---------|
|
||||
| **GET** | <EFBFBD>瑕<EFBFBD>韏<EFBFBD><EFBFBD> | <20>?| <20>?|
|
||||
| **POST** | <EFBFBD>𥕦遣韏<EFBFBD><EFBFBD> | <20>?| <20>?|
|
||||
| **PUT** | 摰峕㟲<EFBFBD>湔鰵韏<EFBFBD><EFBFBD> | <20>?| <20>?|
|
||||
| **PATCH** | <EFBFBD>典<EFBFBD><EFBFBD>湔鰵韏<EFBFBD><EFBFBD> | <20>?| <20>?|
|
||||
| **DELETE** | <EFBFBD>𣳇膄韏<EFBFBD><EFBFBD> | <20>?| <20>?|
|
||||
| **GET** | 获取资源 | ✅ | ✅ |
|
||||
| **POST** | 创建资源 | ❌ | ❌ |
|
||||
| **PUT** | 完整更新资源 | ✅ | ❌ |
|
||||
| **PATCH** | 部分更新资源 | ❌ | ❌ |
|
||||
| **DELETE** | 删除资源 | ✅ | ❌ |
|
||||
|
||||
### 方法示例
|
||||
|
||||
@@ -109,7 +109,7 @@ GET /api/v1/literature/projects/123
|
||||
# 创建资源
|
||||
POST /api/v1/literature/projects
|
||||
Content-Type: application/json
|
||||
{ "name": "<EFBFBD>圈★<EFBFBD>?, "description": "..." }
|
||||
{ "name": "新项目", "description": "..." }
|
||||
|
||||
# 完整更新资源(所有字段)
|
||||
PUT /api/v1/literature/projects/123
|
||||
@@ -119,7 +119,7 @@ Content-Type: application/json
|
||||
# 部分更新资源(部分字段)
|
||||
PATCH /api/v1/literature/projects/123
|
||||
Content-Type: application/json
|
||||
{ "name": "<EFBFBD>芣凒<EFBFBD>啣<EFBFBD>蝘? }
|
||||
{ "name": "只更新名称" }
|
||||
|
||||
# 删除资源
|
||||
DELETE /api/v1/literature/projects/123
|
||||
@@ -135,15 +135,15 @@ DELETE /api/v1/literature/projects/123
|
||||
|--------|------|---------|
|
||||
| **200** | OK | 成功返回数据 |
|
||||
| **201** | Created | 成功创建资源 |
|
||||
| **204** | No Content | <EFBFBD>𣂼<EFBFBD>雿<EFBFBD><EFBFBD>餈𥪜<EFBFBD><EFBFBD>唳旿嚗<EFBFBD><EFBFBD><EFBFBD>𣳇膄嚗?|
|
||||
| **204** | No Content | 成功但无返回数据(如删除) |
|
||||
| **400** | Bad Request | 请求参数错误 |
|
||||
| **401** | Unauthorized | <EFBFBD>芾恕霂<EFBFBD><EFBFBD>瘝⊥<EFBFBD>Token<EFBFBD>巁oken餈<EFBFBD><EFBFBD>嚗?|
|
||||
| **403** | Forbidden | <EFBFBD>䭾<EFBFBD><EFBFBD>琜<EFBFBD>撌脰恕霂<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>銝滩雲嚗?|
|
||||
| **404** | Not Found | 韏<EFBFBD><EFBFBD>銝滚<EFBFBD><EFBFBD>?|
|
||||
| **409** | Conflict | 韏<EFBFBD><EFBFBD><EFBFBD>脩<EFBFBD>嚗<EFBFBD><EFBFBD><EFBFBD>滚<EFBFBD><EFBFBD>𥕦遣嚗?|
|
||||
| **422** | Unprocessable Entity | 霂凋<EFBFBD><EFBFBD>躰秤嚗<EFBFBD><EFBFBD>撉諹<EFBFBD>憭梯揖嚗?|
|
||||
| **401** | Unauthorized | 未认证(没有Token或Token过期) |
|
||||
| **403** | Forbidden | 无权限(已认证但权限不足) |
|
||||
| **404** | Not Found | 资源不存在 |
|
||||
| **409** | Conflict | 资源冲突(如重复创建) |
|
||||
| **422** | Unprocessable Entity | 语义错误(如验证失败) |
|
||||
| **429** | Too Many Requests | 请求过于频繁(限流) |
|
||||
| **500** | Internal Server Error | <EFBFBD>滚𦛚<EFBFBD>券<EFBFBD>霂?|
|
||||
| **500** | Internal Server Error | 服务器错误 |
|
||||
|
||||
### 状态码使用示例
|
||||
|
||||
@@ -154,7 +154,7 @@ res.status(200).json({ success: true, data: projects });
|
||||
// 201 Created - 成功创建资源
|
||||
res.status(201).json({ success: true, data: newProject });
|
||||
|
||||
// 204 No Content - <EFBFBD>𣂼<EFBFBD><EFBFBD>𣳇膄嚗<EFBFBD><EFBFBD><EFBFBD><EFBFBD>捆餈𥪜<EFBFBD>嚗?
|
||||
// 204 No Content - 成功删除(无内容返回)
|
||||
res.status(204).send();
|
||||
|
||||
// 400 Bad Request - 参数错误
|
||||
@@ -163,22 +163,22 @@ res.status(400).json({
|
||||
error: { code: 'INVALID_PARAMS', message: '参数错误' }
|
||||
});
|
||||
|
||||
// 401 Unauthorized - <EFBFBD>芾恕霂?
|
||||
// 401 Unauthorized - 未认证
|
||||
res.status(401).json({
|
||||
success: false,
|
||||
error: { code: 'UNAUTHORIZED', message: '请先登录' }
|
||||
});
|
||||
|
||||
// 403 Forbidden - <EFBFBD>䭾<EFBFBD><EFBFBD>?
|
||||
// 403 Forbidden - 无权限
|
||||
res.status(403).json({
|
||||
success: false,
|
||||
error: { code: 'FORBIDDEN', message: '无权访问' }
|
||||
});
|
||||
|
||||
// 404 Not Found - 韏<EFBFBD><EFBFBD>銝滚<EFBFBD><EFBFBD>?
|
||||
// 404 Not Found - 资源不存在
|
||||
res.status(404).json({
|
||||
success: false,
|
||||
error: { code: 'NOT_FOUND', message: '韏<EFBFBD><EFBFBD>銝滚<EFBFBD><EFBFBD>? }
|
||||
error: { code: 'NOT_FOUND', message: '资源不存在' }
|
||||
});
|
||||
|
||||
// 422 Unprocessable Entity - 验证失败
|
||||
@@ -196,9 +196,9 @@ res.status(422).json({
|
||||
|
||||
## 📝 响应格式规范
|
||||
|
||||
### 蝏煺<EFBFBD><EFBFBD>滚<EFBFBD><EFBFBD>澆<EFBFBD> 潃?敹<>◆<EFBFBD>萄<EFBFBD>
|
||||
### 统一响应格式 ⭐ 必须遵守
|
||||
|
||||
**<EFBFBD>𣂼<EFBFBD><EFBFBD>滚<EFBFBD>嚗?*
|
||||
**成功响应:**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
@@ -209,7 +209,7 @@ res.status(422).json({
|
||||
}
|
||||
```
|
||||
|
||||
**<EFBFBD>躰秤<EFBFBD>滚<EFBFBD>嚗?*
|
||||
**错误响应:**
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
@@ -255,11 +255,11 @@ res.status(422).json({
|
||||
"details": [
|
||||
{
|
||||
"field": "email",
|
||||
"message": "<EFBFBD>桃拳<EFBFBD>澆<EFBFBD>銝齿迤蝖?
|
||||
"message": "邮箱格式不正确"
|
||||
},
|
||||
{
|
||||
"field": "password",
|
||||
"message": "撖<EFBFBD><EFBFBD><EFBFBD>踹漲敹<EFBFBD>◆憭找<EFBFBD>6雿?
|
||||
"message": "密码长度必须大于6位"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -268,7 +268,7 @@ res.status(422).json({
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD><EFBFBD> 霈方<E99C88>銝擧<E98A9D><E693A7><EFBFBD><EFBFBD><EFBFBD>?
|
||||
## 🔑 认证与授权规范
|
||||
|
||||
### JWT认证
|
||||
|
||||
@@ -307,12 +307,12 @@ Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||||
|
||||
**3. Token过期处理**
|
||||
```http
|
||||
# Token餈<EFBFBD><EFBFBD>嚗諹<EFBFBD><EFBFBD>?01
|
||||
# Token过期,返回401
|
||||
{
|
||||
"success": false,
|
||||
"error": {
|
||||
"code": "TOKEN_EXPIRED",
|
||||
"message": "Token撌脰<EFBFBD><EFBFBD><EFBFBD><EFBFBD>霂琿<EFBFBD><EFBFBD>啁蒈敶?
|
||||
"message": "Token已过期,请重新登录"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -327,23 +327,23 @@ Content-Type: application/json
|
||||
|
||||
### 权限控制
|
||||
|
||||
| 蝡舐<EFBFBD>蝐餃<EFBFBD> | <20><>閬<EFBFBD>恕霂?| 閫坿𠧧閬<F0A0A7A7><E996AC> |
|
||||
| 端点类型 | 需要认证 | 角色要求 |
|
||||
|---------|---------|---------|
|
||||
| <EFBFBD>砍<EFBFBD>蝡舐<EFBFBD> | <20>?| <20>?|
|
||||
| <EFBFBD>冽<EFBFBD>蝡舐<EFBFBD> | <EFBFBD>?| user |
|
||||
| 蝞∠<EFBFBD>蝡舐<EFBFBD> | <EFBFBD>?| admin |
|
||||
| 公开端点 | ❌ | 无 |
|
||||
| 用户端点 | ✅ | user |
|
||||
| 管理端点 | ✅ | admin |
|
||||
|
||||
**蝷箔<EFBFBD>嚗?*
|
||||
**示例:**
|
||||
```typescript
|
||||
// <EFBFBD>砍<EFBFBD>蝡舐<EFBFBD>嚗<EFBFBD><EFBFBD><EFBFBD><EFBFBD>霈方<EFBFBD>嚗?
|
||||
// 公开端点(无需认证)
|
||||
POST /api/v1/auth/login
|
||||
POST /api/v1/auth/register
|
||||
|
||||
// <EFBFBD>冽<EFBFBD>蝡舐<EFBFBD>嚗<EFBFBD><EFBFBD>閬<EFBFBD>恕霂<EFBFBD><EFBFBD>user閫坿𠧧嚗?
|
||||
// 用户端点(需要认证,user角色)
|
||||
GET /api/v1/literature/projects
|
||||
POST /api/v1/literature/projects
|
||||
|
||||
// 蝞∠<EFBFBD>蝡舐<EFBFBD>嚗<EFBFBD><EFBFBD>閬<EFBFBD>恕霂<EFBFBD><EFBFBD>admin閫坿𠧧嚗?
|
||||
// 管理端点(需要认证,admin角色)
|
||||
GET /api/v1/admin/users
|
||||
POST /api/v1/admin/users/:id/disable
|
||||
```
|
||||
@@ -357,11 +357,11 @@ POST /api/v1/admin/users/:id/disable
|
||||
```
|
||||
GET /api/v1/literature/projects?page=1&pageSize=20&sortBy=createdAt&sortOrder=desc
|
||||
|
||||
Query<EFBFBD><EFBFBD>㺭嚗?
|
||||
- page: 憿萇<EFBFBD>嚗<EFBFBD><EFBFBD>霈?嚗?
|
||||
- pageSize: 瘥誯△<EFBFBD>圈<EFBFBD>嚗<EFBFBD><EFBFBD>霈?0嚗峕<E59A97>憭?00嚗?
|
||||
- sortBy: <EFBFBD>鍦<EFBFBD>摮埈挾嚗<EFBFBD><EFBFBD>霈勺reatedAt嚗?
|
||||
- sortOrder: <EFBFBD>鍦<EFBFBD><EFBFBD>孵<EFBFBD>嚗Òsc/desc嚗屸<EFBFBD>霈千esc嚗?
|
||||
Query参数:
|
||||
- page: 页码(默认1)
|
||||
- pageSize: 每页数量(默认10,最大100)
|
||||
- sortBy: 排序字段(默认createdAt)
|
||||
- sortOrder: 排序方向(asc/desc,默认desc)
|
||||
```
|
||||
|
||||
### 响应格式
|
||||
@@ -387,16 +387,16 @@ Query参数
|
||||
|
||||
## 🔍 筛选与搜索规范
|
||||
|
||||
### 蝑偦<EFBFBD>匧<EFBFBD><EFBFBD>?
|
||||
### 筛选参数
|
||||
|
||||
```
|
||||
GET /api/v1/literature/projects?status=active&keyword=骨质疏松
|
||||
|
||||
Query<EFBFBD><EFBFBD>㺭嚗?
|
||||
- status: <EFBFBD>嗆<EFBFBD><EFBFBD><EFBFBD><EFBFBD>㚁<EFBFBD>active/inactive嚗?
|
||||
- keyword: <EFBFBD>喲睸霂齿<EFBFBD>蝝g<EFBFBD><EFBFBD>𦦵揣name<EFBFBD>𩥇escription摮埈挾嚗?
|
||||
Query参数:
|
||||
- status: 状态筛选(active/inactive)
|
||||
- keyword: 关键词搜索(搜索name和description字段)
|
||||
- userId: 用户ID筛选(管理端)
|
||||
- startDate/endDate: <EFBFBD>交<EFBFBD><EFBFBD><EFBFBD>凒蝑偦<EFBFBD>?
|
||||
- startDate/endDate: 日期范围筛选
|
||||
```
|
||||
|
||||
### 搜索响应
|
||||
@@ -417,29 +417,29 @@ Query参数
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD>𩤃<EFBFBD> <20>躰秤<E8BAB0><E7A7A4>挽霈?
|
||||
## ⚠️ 错误码设计
|
||||
|
||||
### <EFBFBD><EFBFBD><EFBFBD><EFBFBD>躰秤<EFBFBD>?
|
||||
### 标准错误码
|
||||
|
||||
| <EFBFBD>躰秤<EFBFBD>?| HTTP<EFBFBD>嗆<EFBFBD>?| 霂湔<E99C82> |
|
||||
| 错误码 | HTTP状态 | 说明 |
|
||||
|--------|---------|------|
|
||||
| `VALIDATION_ERROR` | 422 | 参数验证失败 |
|
||||
| `UNAUTHORIZED` | 401 | <EFBFBD>芾恕霂?|
|
||||
| `UNAUTHORIZED` | 401 | 未认证 |
|
||||
| `TOKEN_EXPIRED` | 401 | Token过期 |
|
||||
| `FORBIDDEN` | 403 | <EFBFBD>䭾<EFBFBD><EFBFBD>?|
|
||||
| `NOT_FOUND` | 404 | 韏<EFBFBD><EFBFBD>銝滚<EFBFBD><EFBFBD>?|
|
||||
| `ALREADY_EXISTS` | 409 | 韏<EFBFBD><EFBFBD>撌脣<EFBFBD><EFBFBD>?|
|
||||
| `FORBIDDEN` | 403 | 无权限 |
|
||||
| `NOT_FOUND` | 404 | 资源不存在 |
|
||||
| `ALREADY_EXISTS` | 409 | 资源已存在 |
|
||||
| `QUOTA_EXCEEDED` | 429 | 配额超限 |
|
||||
| `INTERNAL_ERROR` | 500 | <EFBFBD>滚𦛚<EFBFBD>券<EFBFBD>霂?|
|
||||
| `INTERNAL_ERROR` | 500 | 服务器错误 |
|
||||
|
||||
### 銝𡁜𦛚<EFBFBD>躰秤<EFBFBD>?
|
||||
### 业务错误码
|
||||
|
||||
```typescript
|
||||
// 璅∪<EFBFBD><EFBFBD>孵<EFBFBD><EFBFBD>躰秤<EFBFBD><EFBFBD><EFBFBD><EFBFBD>滨<EFBFBD><EFBFBD>箏<EFBFBD>嚗?
|
||||
ASL_IMPORT_FAILED // AI<EFBFBD><EFBFBD>讃嚗𡁜紡<EFBFBD>亙仃韐?
|
||||
// 模块特定错误码(前缀区分)
|
||||
ASL_IMPORT_FAILED // AI文献:导入失败
|
||||
ASL_SCREENING_IN_PROGRESS // AI文献:筛选进行中
|
||||
PKB_QUOTA_EXCEEDED // 知识库:配额超限
|
||||
LLM_QUOTA_EXCEEDED // LLM嚗𡁻<EFBFBD>憸肽<EFBFBD><EFBFBD>?
|
||||
LLM_QUOTA_EXCEEDED // LLM:配额超限
|
||||
```
|
||||
|
||||
---
|
||||
@@ -452,7 +452,7 @@ LLM_QUOTA_EXCEEDED // LLM:配额超
|
||||
所有列表接口必须支持分页:
|
||||
- 默认pageSize=10
|
||||
- 最大pageSize=100
|
||||
- 蝳<EFBFBD>迫銝<EFBFBD>甈⊥<EFBFBD>扯<EFBFBD><EFBFBD>𧼮<EFBFBD><EFBFBD>冽㺭<EFBFBD>?
|
||||
- 禁止一次性返回全部数据
|
||||
```
|
||||
|
||||
### 2. 字段过滤
|
||||
@@ -460,13 +460,13 @@ LLM_QUOTA_EXCEEDED // LLM:配额超
|
||||
```
|
||||
GET /api/v1/users/me?fields=id,name,email
|
||||
|
||||
<EFBFBD>芾<EFBFBD><EFBFBD>鮋<EFBFBD>閬<EFBFBD><EFBFBD>摮埈挾嚗<EFBFBD><EFBFBD>撠烐㺭<EFBFBD>桐<EFBFBD>颲?
|
||||
只返回需要的字段,减少数据传输
|
||||
```
|
||||
|
||||
### 3. 缓存策略
|
||||
|
||||
```http
|
||||
# 霈曄蔭蝻枏<EFBFBD>憭?
|
||||
# 设置缓存头
|
||||
Cache-Control: public, max-age=300
|
||||
|
||||
# 使用ETag
|
||||
@@ -477,40 +477,40 @@ If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD>?璉<><E79289>交<EFBFBD><E4BAA4>?
|
||||
## ✅ 检查清单
|
||||
|
||||
**设计新API时必须检查:**
|
||||
- [ ] URL蝚血<EFBFBD>RESTful閫<EFBFBD><EFBFBD>嚗<EFBFBD>蝙<EFBFBD>典<EFBFBD>霂?憭齿㺭嚗?
|
||||
- [ ] 雿輻鍂甇<EFBFBD>&<EFBFBD><EFBFBD>TTP<EFBFBD>寞<EFBFBD>嚗𠃑ET/POST/PUT/DELETE嚗?
|
||||
- [ ] URL符合RESTful规范(使用名词+复数)
|
||||
- [ ] 使用正确的HTTP方法(GET/POST/PUT/DELETE)
|
||||
- [ ] 使用正确的HTTP状态码
|
||||
- [ ] <EFBFBD>滚<EFBFBD><EFBFBD>澆<EFBFBD>蝚血<EFBFBD>蝏煺<EFBFBD>閫<EFBFBD><EFBFBD>嚗ìuccess + data/error嚗?
|
||||
- [ ] 响应格式符合统一规范(success + data/error)
|
||||
- [ ] 需要认证的接口检查JWT Token
|
||||
- [ ] <EFBFBD><EFBFBD>閬<EFBFBD><EFBFBD><EFBFBD>鞟<EFBFBD><EFBFBD>亙藁璉<EFBFBD><EFBFBD>亦鍂<EFBFBD>瑁<EFBFBD><EFBFBD>?
|
||||
- [ ] 需要权限的接口检查用户角色
|
||||
- [ ] 列表接口支持分页
|
||||
- [ ] 列表接口支持排序
|
||||
- [ ] <EFBFBD>躰秤<EFBFBD>滚<EFBFBD><EFBFBD><EFBFBD>鉄<EFBFBD>𡒊&<EFBFBD><EFBFBD><EFBFBD>霂舐<EFBFBD><EFBFBD>屸<EFBFBD>霂臭縑<EFBFBD>?
|
||||
- [ ] 错误响应包含明确的错误码和错误信息
|
||||
- [ ] 所有API都有文档说明
|
||||
|
||||
---
|
||||
|
||||
## 🔗 相关文档
|
||||
|
||||
**<EFBFBD>餉<EFBFBD>嚗?*
|
||||
- [API頝舐眏<EFBFBD>餉<EFBFBD>](./04-API頝舐眏<EFBFBD>餉<EFBFBD>.md) 潃?<3F>亦<EFBFBD><E4BAA6><EFBFBD><EFBFBD>𡅅PI蝡舐<E89DA1>
|
||||
**总览:**
|
||||
- [API路由总览](./04-API路由总览.md) ⭐ 查看所有API端点
|
||||
|
||||
**璅⊥踎嚗?*
|
||||
**模板:**
|
||||
- [API设计模板](../_templates/API设计-模板.md)
|
||||
|
||||
**各模块设计:**
|
||||
- [撟喳蝱<EFBFBD>箇<EFBFBD>撅<EFBFBD>(../01-撟喳蝱<E596B3>箇<EFBFBD>撅?README.md)
|
||||
- [<EFBFBD>𡁶鍂<EFBFBD>賢<EFBFBD>撅<EFBFBD>(../02-<2D>𡁶鍂<F0A181B6>賢<EFBFBD>撅?README.md)
|
||||
- [平台基础层](../01-平台基础层/README.md)
|
||||
- [通用能力层](../02-通用能力层/README.md)
|
||||
- [业务模块层](../03-业务模块/README.md)
|
||||
|
||||
---
|
||||
|
||||
**最后更新:** 2025-11-06
|
||||
**维护人:** 技术架构师
|
||||
**<EFBFBD><EFBFBD>𧋦嚗?* v2.0
|
||||
**版本:** v2.0
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# 数据库全局视图
|
||||
|
||||
> **<EFBFBD>桃<EFBFBD>嚗?* <20>𣂷<EFBFBD><F0A382B7><EFBFBD><EFBFBD>农chema<6D>諹”<E8ABB9><E2809D>翰<EFBFBD>毺揣撘𤏪<E69298>靘蹂<E99D98><E8B982>交𪄳<E4BAA4>𣬚<EFBFBD>閫<EFBFBD><E996AB>撅<EFBFBD><E69285>唳旿<E594B3>嗆<EFBFBD>
|
||||
> **霂衣<EFBFBD>霈曇恣嚗?* 霂瑟䰻<E7919F>见<EFBFBD>璅∪<E79285><E288AA>?`01-<2D>唳旿摨栞挽霈?md`
|
||||
> **目的:** 提供所有Schema和表的快速索引,便于查找和理解全局数据架构
|
||||
> **详细设计:** 请查看各模块的 `01-数据库设计.md`
|
||||
> **数据库:** PostgreSQL 15+
|
||||
> **最后更新:** 2025-11-06
|
||||
|
||||
@@ -9,202 +9,202 @@
|
||||
|
||||
## 📊 Schema划分策略
|
||||
|
||||
### Schema<EFBFBD>𠉛氖<EFBFBD>笔<EFBFBD> 潃?
|
||||
### Schema隔离原则 ⭐
|
||||
|
||||
**銝箔<EFBFBD>銋<EFBFBD><EFBFBD>閬<EFBFBD>chema<EFBFBD>𠉛氖嚗?*
|
||||
1. <EFBFBD>?**璅∪<E79285><E288AA>祉<EFBFBD><E7A589>?*嚗𡁏<E59A97>銝芯<E98A9D><E88AAF>⊥芋<E28AA5>埈<EFBFBD><E59F88>祉<EFBFBD><E7A589><EFBFBD>chema
|
||||
2. <EFBFBD>?**<2A>舀<EFBFBD><E88880>祉<EFBFBD><E7A589>函蔡**嚗𡁜虾隞亙<E99A9E><E4BA99>砍紡<E7A08D>箸<EFBFBD>銝芣芋<E88AA3>㛖<EFBFBD><E39B96>唳旿
|
||||
3. <EFBFBD>?**<2A><><EFBFBD><EFBFBD>𠉛氖**嚗𡁜虾隞乩蛹銝滚<E98A9D>Schema霈曄蔭銝滚<E98A9D><E6BB9A><EFBFBD><EFBFBD>
|
||||
4. <EFBFBD>?**<2A>踹<EFBFBD><E8B8B9>賢<EFBFBD><E8B3A2>脩<EFBFBD>**嚗帋<E59A97><E5B88B>峕芋<E5B395>堒虾隞交<E99A9E><E4BAA4>詨<EFBFBD><E8A9A8><EFBFBD>”<EFBFBD>?
|
||||
**为什么需要Schema隔离:**
|
||||
1. ✅ **模块独立性**:每个业务模块有独立的Schema
|
||||
2. ✅ **支持独立部署**:可以单独导出某个模块的数据
|
||||
3. ✅ **权限隔离**:可以为不同Schema设置不同权限
|
||||
4. ✅ **避免命名冲突**:不同模块可以有相同的表名
|
||||
|
||||
**Schema<EFBFBD>賢<EFBFBD>閫<EFBFBD><EFBFBD>嚗?*
|
||||
**Schema命名规范:**
|
||||
```
|
||||
platform_schema # 撟喳蝱<EFBFBD>箇<EFBFBD>撅<EFBFBD><EFBFBD><EFBFBD>典<EFBFBD><EFBFBD>曹澈嚗?
|
||||
platform_schema # 平台基础层(全局共享)
|
||||
aia_schema # AI智能问答
|
||||
asl_schema # AI智能文献
|
||||
pkb_schema # 銝芯犖<EFBFBD>亥<EFBFBD>摨?
|
||||
pkb_schema # 个人知识库
|
||||
dc_schema # 数据清洗整理
|
||||
ssa_schema # 智能统计分析
|
||||
st_schema # 统计分析工具
|
||||
rvw_schema # 稿件审查系统
|
||||
admin_schema # 餈鞱𨯫蝞∠<EFBFBD>蝡荔<EFBFBD><EFBFBD>舫<EFBFBD>㚁<EFBFBD><EFBFBD>臬<EFBFBD>撟嗅<EFBFBD>platform_schema嚗?
|
||||
admin_schema # 运营管理端(可选,可合并到platform_schema)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📋 Schema一览表
|
||||
|
||||
| Schema | 霂湔<EFBFBD> | 銵冽㺭<E586BD>?| <20>嗆<EFBFBD>?| 霂衣<E99C82>霈曇恣 |
|
||||
| Schema | 说明 | 表数量 | 状态 | 详细设计 |
|
||||
|--------|------|--------|------|---------|
|
||||
| **platform_schema** | 撟喳蝱<EFBFBD>箇<EFBFBD>撅?| ~15銝?| <20>?雿輻鍂銝?| [<EFBFBD>亦<EFBFBD>](#platform_schema-撟喳蝱<EFBFBD>箇<EFBFBD>撅? |
|
||||
| **aia_schema** | AI<EFBFBD>箄<EFBFBD><EFBFBD>桃<EFBFBD> | ~8銝?| <20>?雿輻鍂銝?| [<5B>亦<EFBFBD>](#aia_schema-ai<EFBFBD>箄<EFBFBD><EFBFBD>桃<EFBFBD>) |
|
||||
| **pkb_schema** | 銝芯犖<EFBFBD>亥<EFBFBD>摨?| ~5銝?| <20>?雿輻鍂銝?| [<EFBFBD>亦<EFBFBD>](#pkb_schema-銝芯犖<EFBFBD>亥<EFBFBD>摨? |
|
||||
| **rvw_schema** | 蝔蹂辣摰⊥䰻蝟餌<EFBFBD> | ~6銝?| <20>?雿輻鍂銝?| [<5B>亦<EFBFBD>](#rvw_schema-蝔蹂辣摰⊥䰻蝟餌<EFBFBD>) |
|
||||
| **asl_schema** | AI<EFBFBD>箄<EFBFBD><EFBFBD><EFBFBD>讃 | ~10銝?| <20>?霈曇恣銝?| [ASL/01-<EFBFBD>唳旿摨栞挽霈((../03-銝𡁜𦛚璅∪<E79285>/ASL-AI<41>箄<EFBFBD><E7AE84><EFBFBD>讃/01-<2D>唳旿摨栞挽霈?md) |
|
||||
| **dc_schema** | <EFBFBD>唳旿皜<EFBFBD><EFBFBD><EFBFBD>渡<EFBFBD> | ~8銝?| <20>?閫<><E996AB>銝?| 敺<>挽霈?|
|
||||
| **ssa_schema** | <EFBFBD>箄<EFBFBD>蝏蠘恣<EFBFBD><EFBFBD><EFBFBD> | ~10銝?| <20>?閫<><E996AB>銝?| 敺<>挽霈?|
|
||||
| **st_schema** | 蝏蠘恣<EFBFBD><EFBFBD><EFBFBD>撌亙<EFBFBD> | ~5銝?| <20>?閫<><E996AB>銝?| 敺<>挽霈?|
|
||||
| **platform_schema** | 平台基础层 | ~15个 | ✅ 使用中 | [查看](#platform_schema-平台基础层) |
|
||||
| **aia_schema** | AI智能问答 | ~8个 | ✅ 使用中 | [查看](#aia_schema-ai智能问答) |
|
||||
| **pkb_schema** | 个人知识库 | ~5个 | ✅ 使用中 | [查看](#pkb_schema-个人知识库) |
|
||||
| **rvw_schema** | 稿件审查系统 | ~6个 | ✅ 使用中 | [查看](#rvw_schema-稿件审查系统) |
|
||||
| **asl_schema** | AI智能文献 | ~10个 | ⏳ 设计中 | [ASL/01-数据库设计](../03-业务模块/ASL-AI智能文献/01-数据库设计.md) |
|
||||
| **dc_schema** | 数据清洗整理 | ~8个 | ⏳ 规划中 | 待设计 |
|
||||
| **ssa_schema** | 智能统计分析 | ~10个 | ⏳ 规划中 | 待设计 |
|
||||
| **st_schema** | 统计分析工具 | ~5个 | ⏳ 规划中 | 待设计 |
|
||||
|
||||
**<EFBFBD>餉”<EFBFBD>堆<EFBFBD>** ~70銝迎<EFBFBD>憸<EFBFBD>摯嚗?
|
||||
**总表数:** ~70个(预估)
|
||||
|
||||
---
|
||||
|
||||
## 🔍 platform_schema(平台基础层)
|
||||
|
||||
**<EFBFBD>諹提嚗?* 摮睃<E691AE><E79D83>典<EFBFBD><E585B8>曹澈<E69BB9><E6BE88>像<EFBFBD>唳㺭<E594B3>殷<EFBFBD><E6AEB7><EFBFBD><EFBFBD>劐<EFBFBD><E58A90>⊥芋<E28AA5>烾<EFBFBD>靘肽<E99D98>
|
||||
**职责:** 存储全局共享的平台数据,所有业务模块都依赖
|
||||
|
||||
**霂衣<EFBFBD>霈曇恣嚗?* [UAM/01-<EFBFBD>唳旿摨栞挽霈((../01-撟喳蝱<E596B3>箇<EFBFBD>撅?01-<2D>冽<EFBFBD>銝擧<E98A9D><E693A7>𣂷葉敹?UAM)/01-<EFBFBD>唳旿摨栞挽霈?md)
|
||||
**详细设计:** [UAM/01-数据库设计](../01-平台基础层/01-用户与权限中心(UAM)/01-数据库设计.md)
|
||||
|
||||
### 核心表(用户与权限)
|
||||
|
||||
| 銵典<EFBFBD> | 霂湔<E99C82> | 霈啣<E99C88><E595A3>圈<EFBFBD>隡?| 霂衣<E99C82>霈曇恣 |
|
||||
| 表名 | 说明 | 记录数预估 | 详细设计 |
|
||||
|------|------|-----------|---------|
|
||||
| **users** | <EFBFBD>冽<EFBFBD><EFBFBD>箇<EFBFBD>靽⊥<EFBFBD> | 10銝?撟?| [UAM/01-<EFBFBD>唳旿摨栞挽霈((../01-撟喳蝱<E596B3>箇<EFBFBD>撅?01-<2D>冽<EFBFBD>銝擧<E98A9D><E693A7>𣂷葉敹?UAM)/01-<EFBFBD>唳旿摨栞挽霈?md) |
|
||||
| **users** | 用户基础信息 | 10万/年 | [UAM/01-数据库设计](../01-平台基础层/01-用户与权限中心(UAM)/01-数据库设计.md) |
|
||||
| **roles** | 角色定义 | <100 | 同上 |
|
||||
| **permissions** | 权限定义 | <500 | 同上 |
|
||||
| **user_roles** | <EFBFBD>冽<EFBFBD>-閫坿𠧧<E59DBF>唾<EFBFBD> | 10銝?撟?| <20>䔶<EFBFBD> |
|
||||
| **feature_flags** | Feature Flag<EFBFBD>滨蔭 潃?| <100 | <EFBFBD>䔶<EFBFBD> |
|
||||
| **user_feature_flags** | <EFBFBD>冽<EFBFBD>-Feature Flag<EFBFBD>唾<EFBFBD> 潃?| 10銝?撟?| <20>䔶<EFBFBD> |
|
||||
| **user_roles** | 用户-角色关联 | 10万/年 | 同上 |
|
||||
| **feature_flags** | Feature Flag配置 ⭐ | <100 | 同上 |
|
||||
| **user_feature_flags** | 用户-Feature Flag关联 ⭐ | 10万/年 | 同上 |
|
||||
|
||||
### LLM<EFBFBD>詨<EFBFBD>銵?
|
||||
### LLM相关表
|
||||
|
||||
| 銵典<EFBFBD> | 霂湔<E99C82> | 霈啣<E99C88><E595A3>圈<EFBFBD>隡?| 霂衣<E99C82>霈曇恣 |
|
||||
| 表名 | 说明 | 记录数预估 | 详细设计 |
|
||||
|------|------|-----------|---------|
|
||||
| **llm_models** | LLM璅∪<EFBFBD><EFBFBD>滨蔭 | <20 | [LLM蝵穃<EFBFBD>/01-<EFBFBD>唳旿摨栞挽霈((../02-<2D>𡁶鍂<F0A181B6>賢<EFBFBD>撅?01-LLM憭扳芋<E689B3>讠<EFBFBD><E8AEA0>?01-<2D>唳旿摨栞挽霈?md) |
|
||||
| **llm_usage** | LLM雿輻鍂霈啣<EFBFBD> 潃?| 1000銝?撟?| <20>䔶<EFBFBD> |
|
||||
| **llm_quotas** | LLM<EFBFBD>漤<EFBFBD>蝞∠<EFBFBD> | 10銝?撟?| <20>䔶<EFBFBD> |
|
||||
| **llm_models** | LLM模型配置 | <20 | [LLM网关/01-数据库设计](../02-通用能力层/01-LLM大模型网关/01-数据库设计.md) |
|
||||
| **llm_usage** | LLM使用记录 ⭐ | 1000万/年 | 同上 |
|
||||
| **llm_quotas** | LLM配额管理 | 10万/年 | 同上 |
|
||||
|
||||
### <EFBFBD>烐綉銝擧𠯫敹?
|
||||
### 监控与日志
|
||||
|
||||
| 銵典<EFBFBD> | 霂湔<E99C82> | 霈啣<E99C88><E595A3>圈<EFBFBD>隡?| 霂衣<E99C82>霈曇恣 |
|
||||
| 表名 | 说明 | 记录数预估 | 详细设计 |
|
||||
|------|------|-----------|---------|
|
||||
| **admin_logs** | 蝞∠<EFBFBD><EFBFBD>䀹<EFBFBD>雿𨀣𠯫敹?| 10銝?撟?| [<5B>烐綉銝擧𠯫敹?01-<2D>唳旿摨栞挽霈((../01-撟喳蝱<E596B3>箇<EFBFBD>撅?04-<2D>烐綉銝擧𠯫敹?01-<2D>唳旿摨栞挽霈?md) |
|
||||
| **error_logs** | <EFBFBD>躰秤<EFBFBD>亙<EFBFBD> | 100銝?撟?| <20>䔶<EFBFBD> |
|
||||
| **audit_logs** | 摰∟恣<EFBFBD>亙<EFBFBD> | 100銝?撟?| <20>䔶<EFBFBD> |
|
||||
| **admin_logs** | 管理员操作日志 | 10万/年 | [监控与日志/01-数据库设计](../01-平台基础层/04-监控与日志/01-数据库设计.md) |
|
||||
| **error_logs** | 错误日志 | 100万/年 | 同上 |
|
||||
| **audit_logs** | 审计日志 | 100万/年 | 同上 |
|
||||
|
||||
### 系统配置
|
||||
|
||||
| 銵典<EFBFBD> | 霂湔<E99C82> | 霈啣<E99C88><E595A3>圈<EFBFBD>隡?| 霂衣<E99C82>霈曇恣 |
|
||||
| 表名 | 说明 | 记录数预估 | 详细设计 |
|
||||
|------|------|-----------|---------|
|
||||
| **system_configs** | 蝟餌<EFBFBD><EFBFBD>滨蔭 | <100 | [蝟餌<EFBFBD><EFBFBD>滨蔭/01-<2D>唳旿摨栞挽霈((../01-撟喳蝱<E596B3>箇<EFBFBD>撅?05-蝟餌<E89D9F><E9A48C>滨蔭/01-<2D>唳旿摨栞挽霈?md) |
|
||||
| **system_configs** | 系统配置 | <100 | [系统配置/01-数据库设计](../01-平台基础层/05-系统配置/01-数据库设计.md) |
|
||||
| **prompt_templates** | Prompt模板 | <500 | 同上 |
|
||||
| **announcements** | 系统公告 | <1000 | 同上 |
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD><EFBFBD> aia_schema嚗㇁I<EFBFBD>箄<EFBFBD><EFBFBD>桃<EFBFBD>嚗?
|
||||
## 🤖 aia_schema(AI智能问答)
|
||||
|
||||
**<EFBFBD>諹提嚗?* 摮睃<E691AE>AI<41>箄<EFBFBD><E7AE84>桃<EFBFBD><E6A183>詨<EFBFBD><E8A9A8>唳旿嚗?2銝芣惣<E88AA3>賭<EFBFBD><E8B3AD><EFBFBD>笆霂嘥<E99C82><E598A5>莎<EFBFBD>
|
||||
**职责:** 存储AI智能问答相关数据(12个智能体、对话历史)
|
||||
|
||||
**<EFBFBD>嗆<EFBFBD><EFBFBD><EFBFBD>** <20>?撌脣<E6928C><E884A3>?
|
||||
**霂衣<EFBFBD>霈曇恣嚗?* [AIA/01-<EFBFBD>唳旿摨栞挽霈((../03-銝𡁜𦛚璅∪<E79285>/AIA-AI<41>箄<EFBFBD><E7AE84>桃<EFBFBD>/01-<2D>唳旿摨栞挽霈?md)嚗<><E59A97><EFBFBD>𥕦遣嚗?
|
||||
**状态:** ✅ 已实现
|
||||
**详细设计:** [AIA/01-数据库设计](../03-业务模块/AIA-AI智能问答/01-数据库设计.md)(待创建)
|
||||
|
||||
### <EFBFBD>詨<EFBFBD>銵?
|
||||
### 核心表
|
||||
|
||||
| 銵典<EFBFBD> | 霂湔<E99C82> | 霈啣<E99C88><E595A3>圈<EFBFBD>隡?|
|
||||
| 表名 | 说明 | 记录数预估 |
|
||||
|------|------|-----------|
|
||||
| **conversations** | 撖寡<EFBFBD>隡朞<EFBFBD> | 100銝?撟?|
|
||||
| **messages** | 撖寡<EFBFBD>瘨<EFBFBD><EFBFBD> | 1000銝?撟?|
|
||||
| **agents** | <EFBFBD>箄<EFBFBD>雿㯄<EFBFBD>蝵?| <20 |
|
||||
| **conversation_contexts** | 撖寡<EFBFBD>銝𠹺<EFBFBD><EFBFBD>?| 100銝?撟?|
|
||||
| **conversations** | 对话会话 | 100万/年 |
|
||||
| **messages** | 对话消息 | 1000万/年 |
|
||||
| **agents** | 智能体配置 | <20 |
|
||||
| **conversation_contexts** | 对话上下文 | 100万/年 |
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD><EFBFBD> pkb_schema嚗<EFBFBD>葵鈭箇䰻霂<EFBFBD><EFBFBD>嚗?
|
||||
## 📚 pkb_schema(个人知识库)
|
||||
|
||||
**<EFBFBD>諹提嚗?* 摮睃<E691AE>銝芯犖<E88AAF>亥<EFBFBD>摨瓐<E691A8><E79390><EFBFBD>獢<EFBFBD><E78DA2><EFBFBD>AG<41>桃<EFBFBD><E6A183>詨<EFBFBD><E8A9A8>唳旿
|
||||
**职责:** 存储个人知识库、文档、RAG问答相关数据
|
||||
|
||||
**<EFBFBD>嗆<EFBFBD><EFBFBD><EFBFBD>** <20>?撌脣<E6928C><E884A3>?
|
||||
**霂衣<EFBFBD>霈曇恣嚗?* [PKB/01-<EFBFBD>唳旿摨栞挽霈((../03-銝𡁜𦛚璅∪<E79285>/PKB-銝芯犖<E88AAF>亥<EFBFBD>摨?01-<2D>唳旿摨栞挽霈?md)嚗<><E59A97><EFBFBD>𥕦遣嚗?
|
||||
**状态:** ✅ 已实现
|
||||
**详细设计:** [PKB/01-数据库设计](../03-业务模块/PKB-个人知识库/01-数据库设计.md)(待创建)
|
||||
|
||||
### <EFBFBD>詨<EFBFBD>銵?
|
||||
### 核心表
|
||||
|
||||
| 銵典<EFBFBD> | 霂湔<E99C82> | 霈啣<E99C88><E595A3>圈<EFBFBD>隡?|
|
||||
| 表名 | 说明 | 记录数预估 |
|
||||
|------|------|-----------|
|
||||
| **knowledge_bases** | <EFBFBD>亥<EFBFBD>摨?| 30銝?撟?|
|
||||
| **documents** | <EFBFBD><EFBFBD>﹝ | 300銝?撟?|
|
||||
| **document_chunks** | <EFBFBD><EFBFBD>﹝<EFBFBD><EFBFBD><EFBFBD>嚗<EFBFBD><EFBFBD><EFBFBD>誩<EFBFBD>嚗?| 3000銝?撟?|
|
||||
| **kb_conversations** | <EFBFBD>亥<EFBFBD>摨枏笆霂?| 100銝?撟?|
|
||||
| **kb_messages** | <EFBFBD>亥<EFBFBD>摨枏笆霂脲<EFBFBD><EFBFBD>?| 1000銝?撟?|
|
||||
| **knowledge_bases** | 知识库 | 30万/年 |
|
||||
| **documents** | 文档 | 300万/年 |
|
||||
| **document_chunks** | 文档分块(向量化) | 3000万/年 |
|
||||
| **kb_conversations** | 知识库对话 | 100万/年 |
|
||||
| **kb_messages** | 知识库对话消息 | 1000万/年 |
|
||||
|
||||
---
|
||||
|
||||
## 📄 rvw_schema(稿件审查系统)
|
||||
|
||||
**<EFBFBD>諹提嚗?* 摮睃<E691AE>蝔蹂辣摰⊥䰻<E28AA5><E4B0BB><EFBFBD>隡唳𥁒<E594B3>羓㮾<E7BE93>單㺭<E596AE>?
|
||||
**职责:** 存储稿件审查、评估报告相关数据
|
||||
|
||||
**<EFBFBD>嗆<EFBFBD><EFBFBD><EFBFBD>** <20>?撌脣<E6928C><E884A3>堆<EFBFBD><E5A086>祉<EFBFBD>蝟餌<E89D9F>嚗?
|
||||
**霂衣<EFBFBD>霈曇恣嚗?* [RVW/01-<EFBFBD>唳旿摨栞挽霈((../03-銝𡁜𦛚璅∪<E79285>/RVW-蝔蹂辣摰⊥䰻蝟餌<E89D9F>/01-<2D>唳旿摨栞挽霈?md)嚗<><E59A97><EFBFBD>𥕦遣嚗?
|
||||
**状态:** ✅ 已实现(独立系统)
|
||||
**详细设计:** [RVW/01-数据库设计](../03-业务模块/RVW-稿件审查系统/01-数据库设计.md)(待创建)
|
||||
|
||||
### <EFBFBD>詨<EFBFBD>銵?
|
||||
### 核心表
|
||||
|
||||
| 銵典<EFBFBD> | 霂湔<E99C82> | 霈啣<E99C88><E595A3>圈<EFBFBD>隡?|
|
||||
| 表名 | 说明 | 记录数预估 |
|
||||
|------|------|-----------|
|
||||
| **review_tasks** | 摰⊥䰻隞餃𦛚 | 10銝?撟?|
|
||||
| **manuscripts** | 蝔蹂辣靽⊥<EFBFBD> | 10銝?撟?|
|
||||
| **review_results** | 摰⊥䰻蝏𤘪<EFBFBD> | 10銝?撟?|
|
||||
| **methodology_assessments** | <EFBFBD>寞<EFBFBD>摮西<EFBFBD>隡?| 10銝?撟?|
|
||||
| **guideline_assessments** | 蝔輻漲閫<EFBFBD><EFBFBD><EFBFBD>扯<EFBFBD>隡?| 10銝?撟?|
|
||||
| **review_tasks** | 审查任务 | 10万/年 |
|
||||
| **manuscripts** | 稿件信息 | 10万/年 |
|
||||
| **review_results** | 审查结果 | 10万/年 |
|
||||
| **methodology_assessments** | 方法学评估 | 10万/年 |
|
||||
| **guideline_assessments** | 稿约规范性评估 | 10万/年 |
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD><EFBFBD> asl_schema嚗㇁I<EFBFBD>箄<EFBFBD><EFBFBD><EFBFBD>讃嚗?
|
||||
## 📖 asl_schema(AI智能文献)
|
||||
|
||||
**<EFBFBD>諹提嚗?* 摮睃<E691AE><E79D83><EFBFBD>讃蝑偦<E89D91>剹<EFBFBD><E589B9><EFBFBD><EFBFBD>硔<EFBFBD><E7A194><EFBFBD><EFBFBD>鞟㮾<E99E9F>單㺭<E596AE>?
|
||||
**职责:** 存储文献筛选、提取、分析相关数据
|
||||
|
||||
**<EFBFBD>嗆<EFBFBD><EFBFBD><EFBFBD>** <20>?霈曇恣銝哨<E98A9D>P0隡睃<E99AA1>蝥改<E89DA5>
|
||||
**霂衣<EFBFBD>霈曇恣嚗?* [ASL/01-<EFBFBD>唳旿摨栞挽霈((../03-銝𡁜𦛚璅∪<E79285>/ASL-AI<41>箄<EFBFBD><E7AE84><EFBFBD>讃/01-<2D>唳旿摨栞挽霈?md)
|
||||
**状态:** ⏳ 设计中(P0优先级)
|
||||
**详细设计:** [ASL/01-数据库设计](../03-业务模块/ASL-AI智能文献/01-数据库设计.md)
|
||||
|
||||
### <EFBFBD>詨<EFBFBD>銵剁<EFBFBD>憸<EFBFBD><EFBFBD>嚗?
|
||||
### 核心表(预览)
|
||||
|
||||
| 銵典<EFBFBD> | 霂湔<E99C82> | 霈啣<E99C88><E595A3>圈<EFBFBD>隡?|
|
||||
| 表名 | 说明 | 记录数预估 |
|
||||
|------|------|-----------|
|
||||
| **literature_projects** | <EFBFBD><EFBFBD>讃憿寧𤌍 | 10銝?撟?|
|
||||
| **literature_items** | <EFBFBD><EFBFBD>讃<EFBFBD>∠𤌍 | 1000銝?撟?|
|
||||
| **pico_configs** | PICO蝥喳<EFBFBD><EFBFBD>㘾膄<EFBFBD><EFBFBD><EFBFBD> | 10銝?撟?|
|
||||
| **screening_results** | 蝑偦<EFBFBD>厩<EFBFBD><EFBFBD>?| 1000銝?撟?|
|
||||
| **screening_history** | 蝑偦<EFBFBD>匧<EFBFBD><EFBFBD>莎<EFBFBD><EFBFBD>臬<EFBFBD>皞荔<EFBFBD> | 1000銝?撟?|
|
||||
| **extraction_tasks** | <EFBFBD>𣂼<EFBFBD>隞餃𦛚 | 100銝?撟?|
|
||||
| **extraction_results** | <EFBFBD>𣂼<EFBFBD>蝏𤘪<EFBFBD> | 100銝?撟?|
|
||||
| **literature_projects** | 文献项目 | 10万/年 |
|
||||
| **literature_items** | 文献条目 | 1000万/年 |
|
||||
| **pico_configs** | PICO纳入排除标准 | 10万/年 |
|
||||
| **screening_results** | 筛选结果 | 1000万/年 |
|
||||
| **screening_history** | 筛选历史(可回溯) | 1000万/年 |
|
||||
| **extraction_tasks** | 提取任务 | 100万/年 |
|
||||
| **extraction_results** | 提取结果 | 100万/年 |
|
||||
|
||||
---
|
||||
|
||||
## 🧹 dc_schema(数据清洗整理)
|
||||
|
||||
**<EFBFBD>諹提嚗?* 摮睃<E691AE><E79D83>唳旿皜<E697BF><E79A9C>隞餃𦛚<E9A483><F0A69B9A>TL<54>滨蔭<E6BBA8><E894AD>ER蝏𤘪<E89D8F>
|
||||
**职责:** 存储数据清洗任务、ETL配置、NER结果
|
||||
|
||||
**<EFBFBD>嗆<EFBFBD><EFBFBD><EFBFBD>** <20>?閫<><E996AB>銝哨<E98A9D>P1隡睃<E99AA1>蝥改<E89DA5>
|
||||
**霂衣<EFBFBD>霈曇恣嚗?* 敺<>挽霈?
|
||||
**状态:** ⏳ 规划中(P1优先级)
|
||||
**详细设计:** 待设计
|
||||
|
||||
### <EFBFBD>詨<EFBFBD>銵剁<EFBFBD>憸<EFBFBD><EFBFBD>嚗?
|
||||
### 核心表(预览)
|
||||
|
||||
| 銵典<EFBFBD> | 霂湔<E99C82> | 霈啣<E99C88><E595A3>圈<EFBFBD>隡?|
|
||||
| 表名 | 说明 | 记录数预估 |
|
||||
|------|------|-----------|
|
||||
| **cleaning_projects** | 皜<EFBFBD><EFBFBD>憿寧𤌍 | 10銝?撟?|
|
||||
| **data_sources** | <EFBFBD>唳旿皞?| 100銝?撟?|
|
||||
| **etl_configs** | ETL<EFBFBD>滨蔭 | 10銝?撟?|
|
||||
| **ner_tasks** | NER隞餃𦛚 | 100銝?撟?|
|
||||
| **ner_results** | NER蝏𤘪<EFBFBD> | 1000銝?撟?|
|
||||
| **cleaning_projects** | 清洗项目 | 10万/年 |
|
||||
| **data_sources** | 数据源 | 100万/年 |
|
||||
| **etl_configs** | ETL配置 | 10万/年 |
|
||||
| **ner_tasks** | NER任务 | 100万/年 |
|
||||
| **ner_results** | NER结果 | 1000万/年 |
|
||||
|
||||
---
|
||||
|
||||
## 🔗 跨Schema依赖关系
|
||||
|
||||
### 靘肽<EFBFBD>閫<EFBFBD><EFBFBD> 潃?<3F>滩<EFBFBD>
|
||||
### 依赖规则 ⭐ 重要
|
||||
|
||||
**允许的依赖:**
|
||||
```
|
||||
<EFBFBD>?銝𡁜𦛚璅∪<E79285> <20>?platform_schema嚗<EFBFBD><EFBFBD>霈詨<EFBFBD><EFBFBD>殷<EFBFBD>
|
||||
<EFBFBD>?<3F>𡁶鍂<F0A181B6>賢<EFBFBD> <20>?platform_schema嚗<EFBFBD><EFBFBD>霈詨<EFBFBD><EFBFBD>殷<EFBFBD>
|
||||
<EFBFBD>?銝𡁜𦛚璅∪<E79285>銋钅𡢿嚗<F0A1A2BF><E59A97>甇Y凒<EFBCB9>乩<EFBFBD>韏吔<E99F8F>
|
||||
<EFBFBD>?platform_schema <EFBFBD>?銝𡁜𦛚璅∪<E79285>嚗<EFBFBD><E59A97><EFBFBD>睲<EFBFBD>韏吔<E99F8F>
|
||||
✅ 业务模块 → platform_schema(允许外键)
|
||||
✅ 通用能力 → platform_schema(允许外键)
|
||||
❌ 业务模块之间(禁止直接依赖)
|
||||
❌ platform_schema → 业务模块(反向依赖)
|
||||
```
|
||||
|
||||
### 靘肽<EFBFBD><EFBFBD>喟頂<EFBFBD>?
|
||||
### 依赖关系图
|
||||
|
||||
```
|
||||
platform_schema.users (1)
|
||||
<EFBFBD>?(N) <EFBFBD><EFBFBD><EFBFBD>劐<EFBFBD><EFBFBD>⊥芋<EFBFBD>烾<EFBFBD>靘肽<EFBFBD><EFBFBD>冽<EFBFBD>銵?
|
||||
↓ (N) 所有业务模块都依赖用户表
|
||||
├── aia_schema.conversations
|
||||
├── asl_schema.literature_projects
|
||||
├── pkb_schema.knowledge_bases
|
||||
@@ -215,67 +215,67 @@ platform_schema.users (1)
|
||||
|
||||
platform_schema.llm_usage (独立)
|
||||
- 记录所有模块的LLM调用
|
||||
- <EFBFBD>朞<EFBFBD>module摮埈挾<EFBFBD>箏<EFBFBD>嚗?AIA', 'ASL', 'PKB'蝑?
|
||||
- 通过module字段区分:'AIA', 'ASL', 'PKB'等
|
||||
```
|
||||
|
||||
### 外键示例
|
||||
|
||||
```sql
|
||||
-- <EFBFBD>?<3F><>捂嚗帋<E59A97><E5B88B>⊥芋<E28AA5>堒<EFBFBD><E5A092>私latform_schema
|
||||
-- ✅ 允许:业务模块引用platform_schema
|
||||
CREATE TABLE asl_schema.literature_projects (
|
||||
id SERIAL PRIMARY KEY,
|
||||
user_id INTEGER REFERENCES platform_schema.users(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
-- <EFBFBD>?蝳<>迫嚗帋<E59A97><E5B88B>⊥芋<E28AA5>𦯀<EFBFBD><F0A6AF80>港<EFBFBD><E6B8AF>詨<EFBFBD><E8A9A8>?
|
||||
-- ❌ 禁止:业务模块之间互相引用
|
||||
CREATE TABLE ssa_schema.analysis_projects (
|
||||
id SERIAL PRIMARY KEY,
|
||||
-- <EFBFBD>躰秤嚗帋<EFBFBD><EFBFBD>賢<EFBFBD><EFBFBD>典<EFBFBD>隞碶<EFBFBD><EFBFBD>⊥芋<EFBFBD>?
|
||||
-- 错误:不能引用其他业务模块
|
||||
literature_project_id INTEGER REFERENCES asl_schema.literature_projects(id)
|
||||
);
|
||||
|
||||
-- <EFBFBD>?甇<>&<EFBFBD>𡁏<EFBFBD>嚗𡁻<E59A97>朞<EFBFBD>user_id<EFBFBD>唾<EFBFBD>
|
||||
-- ✅ 正确做法:通过user_id关联
|
||||
-- 在应用层处理跨模块关联,不在数据库层
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD><EFBFBD> <20>唳旿<E594B3>讐<EFBFBD>霈∴<E99C88>憸<EFBFBD>摯嚗?
|
||||
## 📊 数据量统计(预估)
|
||||
|
||||
### 按Schema统计
|
||||
|
||||
| Schema | 銵冽㺭<EFBFBD>?| 撟游<E6929F><E6B8B8>輯扇敶閙㺭 | 摮睃<E691AE>憸<EFBFBD>摯嚗?撟湛<E6929F> |
|
||||
| Schema | 表数量 | 年增长记录数 | 存储预估(5年) |
|
||||
|--------|--------|------------|---------------|
|
||||
| platform_schema | 15 | 1000銝?| 50GB |
|
||||
| aia_schema | 8 | 1100銝?| 30GB |
|
||||
| pkb_schema | 5 | 3300銝?| 200GB嚗<EFBFBD><EFBFBD><EFBFBD>𧶏<EFBFBD> |
|
||||
| rvw_schema | 6 | 50銝?| 5GB |
|
||||
| asl_schema | 10 | 2100銝?| 50GB |
|
||||
| dc_schema | 8 | 1100銝?| 100GB |
|
||||
| ssa_schema | 10 | 500銝?| 50GB |
|
||||
| st_schema | 5 | 100銝?| 10GB |
|
||||
| **<EFBFBD>餉恣** | **~70** | **~4000銝?撟?* | **~500GB嚗?撟湛<E6929F>** |
|
||||
| platform_schema | 15 | 1000万 | 50GB |
|
||||
| aia_schema | 8 | 1100万 | 30GB |
|
||||
| pkb_schema | 5 | 3300万 | 200GB(向量) |
|
||||
| rvw_schema | 6 | 50万 | 5GB |
|
||||
| asl_schema | 10 | 2100万 | 50GB |
|
||||
| dc_schema | 8 | 1100万 | 100GB |
|
||||
| ssa_schema | 10 | 500万 | 50GB |
|
||||
| st_schema | 5 | 100万 | 10GB |
|
||||
| **总计** | **~70** | **~4000万/年** | **~500GB(5年)** |
|
||||
|
||||
### 大表监控(年增长>100万)
|
||||
|
||||
| 銵典<EFBFBD> | Schema | 撟游<EFBFBD><EFBFBD>?| 蝝W<E89D9D>蝑𣇉裦 |
|
||||
| 表名 | Schema | 年增长 | 索引策略 |
|
||||
|------|--------|--------|---------|
|
||||
| llm_usage | platform | 1000銝?| <20>㗇<EFBFBD><E39787><EFBFBD>躹 |
|
||||
| messages | aia | 1000銝?| <20>実reated_at蝝W<EFBFBD> |
|
||||
| document_chunks | pkb | 3000銝?| <20>煾<EFBFBD>蝝W<E89D9D> |
|
||||
| literature_items | asl | 1000銝?| <20>纺roject_id蝝W<EFBFBD> |
|
||||
| screening_results | asl | 1000銝?| 憭滚<E686AD>蝝W<E89D9D> |
|
||||
| llm_usage | platform | 1000万 | 按月分区 |
|
||||
| messages | aia | 1000万 | 按created_at索引 |
|
||||
| document_chunks | pkb | 3000万 | 向量索引 |
|
||||
| literature_items | asl | 1000万 | 按project_id索引 |
|
||||
| screening_results | asl | 1000万 | 复合索引 |
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD><EFBFBD> 敹恍<E695B9><E6818D>䰻<EFBFBD>暹<EFBFBD><E69AB9>?
|
||||
## 🔍 快速查找指南
|
||||
|
||||
### <EFBFBD>箸艶1嚗𡁏<EFBFBD>閬<EFBFBD><EFBFBD><EFBFBD>烐<EFBFBD>銝芣芋<EFBFBD>?
|
||||
### 场景1:我要开发某个模块
|
||||
1. 在上面的表格中找到对应的Schema
|
||||
2. 点击"详细设计"链接
|
||||
3. <EFBFBD>亦<EFBFBD>霂交芋<EFBFBD>㛖<EFBFBD>摰峕㟲銵函<EFBFBD><EFBFBD>?
|
||||
3. 查看该模块的完整表结构
|
||||
|
||||
### <EFBFBD>箸艶2嚗𡁏<EFBFBD>閬<EFBFBD>䰻<EFBFBD>𧢲<EFBFBD>銝芾”<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
|
||||
### 场景2:我要查看某个表的结构
|
||||
1. 先确定表属于哪个Schema(根据功能判断)
|
||||
2. 转到对应模块的数据库设计文档
|
||||
3. 搜索表名
|
||||
@@ -286,53 +286,53 @@ CREATE TABLE ssa_schema.analysis_projects (
|
||||
3. 在应用层处理跨模块关联,不在数据库层
|
||||
|
||||
### 场景4:我要查看全局数据架构
|
||||
1. <EFBFBD><EFBFBD>粉<EFBFBD>祆<EFBFBD>獢<EFBFBD><EFBFBD>敹恍<EFBFBD>煺<EFBFBD>閫<EFBFBD><EFBFBD><EFBFBD>农chema嚗?
|
||||
2. <EFBFBD>亦<EFBFBD>[<5B>嗆<EFBFBD>霈曇恣<E69B87>冽艶<E586BD>霄(../00-蝟餌<E89D9F><E9A48C>颱<EFBFBD>霈曇恣/08-<2D>嗆<EFBFBD>霈曇恣<E69B87>冽艶<E586BD>?md)
|
||||
1. 阅读本文档(快速了解所有Schema)
|
||||
2. 查看[架构设计全景图](../00-系统总体设计/08-架构设计全景图.md)
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ 重要提醒
|
||||
|
||||
### Schema<EFBFBD>𠉛氖<EFBFBD><EFBFBD>釣<EFBFBD>譍<EFBFBD>憿?
|
||||
### Schema隔离的注意事项
|
||||
|
||||
**<EFBFBD>?甇<>&<EFBFBD>𡁏<EFBFBD>嚗?*
|
||||
- 銝𡁜𦛚璅∪<EFBFBD><EFBFBD>芸<EFBFBD><EFBFBD>?`platform_schema.users`
|
||||
- 頝冽芋<EFBFBD>埈㺭<EFBFBD>桀<EFBFBD><EFBFBD>𥪜銁摨𠉛鍂撅<EFBFBD><EFBFBD><EFBFBD>?
|
||||
- 雿輻鍂 `user_id + 銝𡁜𦛚ID` <EFBFBD><EFBFBD>䲮撘?
|
||||
**✅ 正确做法:**
|
||||
- 业务模块只引用 `platform_schema.users`
|
||||
- 跨模块数据关联在应用层处理
|
||||
- 使用 `user_id + 业务ID` 的方式
|
||||
|
||||
**<EFBFBD>?<3F>躰秤<E8BAB0>𡁏<EFBFBD>嚗?*
|
||||
**❌ 错误做法:**
|
||||
- 业务模块之间直接外键关联
|
||||
- <EFBFBD>?`platform_schema` 銝剖<EFBFBD><EFBFBD>其<EFBFBD><EFBFBD>⊥㺭<EFBFBD>?
|
||||
- 在 `platform_schema` 中存储业务数据
|
||||
- 不同模块使用相同的表名(虽然Schema隔离了,但容易混淆)
|
||||
|
||||
### 性能优化建议
|
||||
|
||||
1. **憭扯”敹<EFBFBD>◆<EFBFBD><EFBFBD>△<EFBFBD>亥砭**嚗<><E59A97> `llm_usage`<EFBFBD><EFBFBD>messages`嚗?
|
||||
2. **<EFBFBD>剔<EFBFBD>摮埈挾敹<EFBFBD>◆<EFBFBD>删揣撘?*嚗<><E59A97> `user_id`<EFBFBD><EFBFBD>created_at`嚗?
|
||||
3. **<EFBFBD><EFBFBD><EFBFBD>銵典<EFBFBD><EFBFBD>?*嚗<><E59A97><EFBFBD>?<3F>匧僑嚗<E58391><E59A97> `llm_usage`嚗?
|
||||
1. **大表必须分页查询**(如 `llm_usage`、`messages`)
|
||||
2. **热点字段必须加索引**(如 `user_id`、`created_at`)
|
||||
3. **考虑表分区**(按月/按年,如 `llm_usage`)
|
||||
4. **定期归档历史数据**(如1年前的日志)
|
||||
|
||||
---
|
||||
|
||||
## 🔗 相关文档
|
||||
|
||||
**閫<EFBFBD><EFBFBD>嚗?*
|
||||
- [<EFBFBD>唳旿摨栞挽霈∟<EFBFBD><EFBFBD><EFBFBD>(./01-<2D>唳旿摨栞挽霈∟<E99C88><E2889F>?md) 潃?敹<>粉
|
||||
- [<EFBFBD>唳旿摨𤘪沲<EFBFBD><EFBFBD>秩<EFBFBD>筕(../00-蝟餌<E89D9F><E9A48C>颱<EFBFBD>霈曇恣/03-<2D>唳旿摨𤘪沲<F0A498AA><E6B2B2>秩<EFBFBD>?md)
|
||||
**规范:**
|
||||
- [数据库设计规范](./01-数据库设计规范.md) ⭐ 必读
|
||||
- [数据库架构说明](../00-系统总体设计/03-数据库架构说明.md)
|
||||
|
||||
**璅∪<EFBFBD>霈曇恣嚗?*
|
||||
- [撟喳蝱<EFBFBD>箇<EFBFBD>撅<EFBFBD>(../01-撟喳蝱<E596B3>箇<EFBFBD>撅?README.md)
|
||||
- [<EFBFBD>𡁶鍂<EFBFBD>賢<EFBFBD>撅<EFBFBD>(../02-<2D>𡁶鍂<F0A181B6>賢<EFBFBD>撅?README.md)
|
||||
**模块设计:**
|
||||
- [平台基础层](../01-平台基础层/README.md)
|
||||
- [通用能力层](../02-通用能力层/README.md)
|
||||
- [业务模块层](../03-业务模块/README.md)
|
||||
|
||||
**璅⊥踎嚗?*
|
||||
- [<EFBFBD>唳旿摨栞挽霈⊥芋<EFBFBD>瓢(../_templates/<EFBFBD>唳旿摨栞挽霈?璅⊥踎.md)
|
||||
**模板:**
|
||||
- [数据库设计模板](../_templates/数据库设计-模板.md)
|
||||
|
||||
---
|
||||
|
||||
**最后更新:** 2025-11-06
|
||||
**维护人:** 技术架构师
|
||||
**<EFBFBD><EFBFBD>𧋦嚗?* v1.0
|
||||
**版本:** v1.0
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# API路由总览
|
||||
|
||||
> **<EFBFBD>桃<EFBFBD>嚗?* <20>𣂷<EFBFBD><F0A382B7><EFBFBD><EFBFBD>𡅅PI蝡舐<E89DA1><E88890><EFBFBD>翰<EFBFBD>毺揣撘𤏪<E69298>靘蹂<E99D98><E8B982>交𪄳<E4BAA4>屸<EFBFBD><E5B1B8>滩楝<E6BBA9>勗<EFBFBD>蝒?
|
||||
> **霂衣<EFBFBD>霈曇恣嚗?* 霂瑟䰻<E7919F>见<EFBFBD>璅∪<E79285><E288AA>?`02-API霈曇恣.md`
|
||||
> **<EFBFBD>箇<EFBFBD>URL嚗?* `http://localhost:3001/api/v1`
|
||||
> **目的:** 提供所有API端点的快速索引,便于查找和避免路由冲突
|
||||
> **详细设计:** 请查看各模块的 `02-API设计.md`
|
||||
> **基础URL:** `http://localhost:3001/api/v1`
|
||||
> **最后更新:** 2025-11-06
|
||||
|
||||
---
|
||||
@@ -13,9 +13,9 @@
|
||||
```
|
||||
/api/v{version}/{module}/{resource}/{id?}/{action?}
|
||||
|
||||
蝷箔<EFBFBD>嚗?
|
||||
示例:
|
||||
/api/v1/literature/projects # 获取文献项目列表
|
||||
/api/v1/literature/projects/123 # <EFBFBD>瑕<EFBFBD>ID=123<EFBFBD><EFBFBD>★<EFBFBD>?
|
||||
/api/v1/literature/projects/123 # 获取ID=123的项目
|
||||
/api/v1/literature/projects/123/export # 导出项目
|
||||
```
|
||||
|
||||
@@ -23,350 +23,350 @@
|
||||
|
||||
| 模块代码 | 路由前缀 | 说明 |
|
||||
|---------|---------|------|
|
||||
| 撟喳蝱<EFBFBD>箇<EFBFBD>撅?| `/auth`, `/users`, `/admin` | 霈方<EFBFBD><EFBFBD><EFBFBD>鍂<EFBFBD>瑯<EFBFBD><EFBFBD>恣<EFBFBD>?|
|
||||
| 平台基础层 | `/auth`, `/users`, `/admin` | 认证、用户、管理 |
|
||||
| LLM网关 | `/llm` | LLM调用 |
|
||||
| AIA | `/chat`, `/agents` | AI智能问答 |
|
||||
| ASL | `/literature` | AI智能文献 |
|
||||
| PKB | `/knowledge-bases`, `/kb` | 銝芯犖<EFBFBD>亥<EFBFBD>摨?|
|
||||
| PKB | `/knowledge-bases`, `/kb` | 个人知识库 |
|
||||
| DC | `/data-cleaning` | 数据清洗 |
|
||||
| SSA | `/analysis` | 智能统计分析 |
|
||||
| ST | `/tools` | 统计工具 |
|
||||
| RVW | `/review` | 稿件审查 |
|
||||
| ADMIN | `/admin` | 餈鞱𨯫蝞∠<EFBFBD>蝡?|
|
||||
| ADMIN | `/admin` | 运营管理端 |
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD><EFBFBD> 霈方<E99C88>銝𡒊鍂<F0A1928A>瑞恣<E7919E><E681A3><EFBFBD>/api/v1/auth, /api/v1/users嚗?
|
||||
## 🔐 认证与用户管理(/api/v1/auth, /api/v1/users)
|
||||
|
||||
**<EFBFBD>嗆<EFBFBD><EFBFBD><EFBFBD>** <20>?撌脣<E6928C><E884A3>?
|
||||
**霂衣<EFBFBD>霈曇恣嚗?* [UAM/02-API霈曇恣](../01-撟喳蝱<EFBFBD>箇<EFBFBD>撅?01-<2D>冽<EFBFBD>銝擧<E98A9D><E693A7>𣂷葉敹?UAM)/02-API霈曇恣.md)嚗<EFBFBD><EFBFBD><EFBFBD>𥕦遣嚗?
|
||||
**状态:** ✅ 已实现
|
||||
**详细设计:** [UAM/02-API设计](../01-平台基础层/01-用户与权限中心(UAM)/02-API设计.md)(待创建)
|
||||
|
||||
### 认证相关
|
||||
|
||||
| 端点 | 方法 | 说明 | 认证 |
|
||||
|------|------|------|------|
|
||||
| `/api/v1/auth/register` | POST | <EFBFBD>冽<EFBFBD>瘜典<EFBFBD> | <EFBFBD>?|
|
||||
| `/api/v1/auth/login` | POST | <EFBFBD>冽<EFBFBD><EFBFBD>餃<EFBFBD> | <EFBFBD>?|
|
||||
| `/api/v1/auth/logout` | POST | <EFBFBD>冽<EFBFBD><EFBFBD>餃枂 | <EFBFBD>?|
|
||||
| `/api/v1/auth/refresh` | POST | <EFBFBD>瑟鰵Token | <EFBFBD>?|
|
||||
| `/api/v1/auth/profile` | GET | <EFBFBD>瑕<EFBFBD>敶枏<EFBFBD><EFBFBD>冽<EFBFBD>靽⊥<EFBFBD> | <EFBFBD>?|
|
||||
| `/api/v1/auth/profile` | PUT | <EFBFBD>湔鰵敶枏<EFBFBD><EFBFBD>冽<EFBFBD>靽⊥<EFBFBD> | <EFBFBD>?|
|
||||
| `/api/v1/auth/register` | POST | 用户注册 | ❌ |
|
||||
| `/api/v1/auth/login` | POST | 用户登录 | ❌ |
|
||||
| `/api/v1/auth/logout` | POST | 用户登出 | ✅ |
|
||||
| `/api/v1/auth/refresh` | POST | 刷新Token | ✅ |
|
||||
| `/api/v1/auth/profile` | GET | 获取当前用户信息 | ✅ |
|
||||
| `/api/v1/auth/profile` | PUT | 更新当前用户信息 | ✅ |
|
||||
|
||||
### 用户管理
|
||||
|
||||
| 端点 | 方法 | 说明 | 认证 |
|
||||
|------|------|------|------|
|
||||
| `/api/v1/users` | GET | <EFBFBD>冽<EFBFBD><EFBFBD>𡑒”嚗<EFBFBD><EFBFBD>憿蛛<EFBFBD> | <EFBFBD>?ADMIN |
|
||||
| `/api/v1/users/:id` | GET | <EFBFBD>冽<EFBFBD>霂行<EFBFBD> | <EFBFBD>?ADMIN |
|
||||
| `/api/v1/users/:id` | PUT | <EFBFBD>湔鰵<EFBFBD>冽<EFBFBD> | <EFBFBD>?ADMIN |
|
||||
| `/api/v1/users/:id` | DELETE | <EFBFBD>𣳇膄<EFBFBD>冽<EFBFBD> | <EFBFBD>?ADMIN |
|
||||
| `/api/v1/users` | GET | 用户列表(分页) | ✅ ADMIN |
|
||||
| `/api/v1/users/:id` | GET | 用户详情 | ✅ ADMIN |
|
||||
| `/api/v1/users/:id` | PUT | 更新用户 | ✅ ADMIN |
|
||||
| `/api/v1/users/:id` | DELETE | 删除用户 | ✅ ADMIN |
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD><EFBFBD> LLM憭扳芋<EFBFBD>讠<EFBFBD><EFBFBD>喉<EFBFBD>/api/v1/llm嚗?
|
||||
## 🤖 LLM大模型网关(/api/v1/llm)
|
||||
|
||||
**<EFBFBD>嗆<EFBFBD><EFBFBD><EFBFBD>** <20>?敺<><E695BA><EFBFBD>堆<EFBFBD>P0隡睃<E99AA1>蝥改<E89DA5>
|
||||
**霂衣<EFBFBD>霈曇恣嚗?* [LLM蝵穃<EFBFBD>/02-API霈曇恣](../02-<EFBFBD>𡁶鍂<EFBFBD>賢<EFBFBD>撅?01-LLM憭扳芋<E689B3>讠<EFBFBD><E8AEA0>?02-API霈曇恣.md)
|
||||
**状态:** ❌ 待实现(P0优先级)
|
||||
**详细设计:** [LLM网关/02-API设计](../02-通用能力层/01-LLM大模型网关/02-API设计.md)
|
||||
|
||||
### LLM调用
|
||||
|
||||
| 端点 | 方法 | 说明 | 认证 |
|
||||
|------|------|------|------|
|
||||
| `/api/v1/llm/chat` | POST | LLM撖寡<EFBFBD>嚗<EFBFBD><EFBFBD>瘚<EFBFBD><EFBFBD>嚗?| <20>?|
|
||||
| `/api/v1/llm/chat/stream` | POST | LLM撖寡<EFBFBD>嚗<EFBFBD><EFBFBD>撘莅SE嚗?| <20>?|
|
||||
| `/api/v1/llm/quota` | GET | <EFBFBD>亥砭敶枏<EFBFBD><EFBFBD>冽<EFBFBD><EFBFBD>漤<EFBFBD> | <EFBFBD>?|
|
||||
| `/api/v1/llm/usage` | GET | <EFBFBD>亥砭雿輻鍂蝏蠘恣 | <EFBFBD>?|
|
||||
| `/api/v1/llm/models` | GET | <EFBFBD>瑕<EFBFBD><EFBFBD>舐鍂璅∪<EFBFBD><EFBFBD>𡑒” | <EFBFBD>?|
|
||||
| `/api/v1/llm/chat` | POST | LLM对话(非流式) | ✅ |
|
||||
| `/api/v1/llm/chat/stream` | POST | LLM对话(流式SSE) | ✅ |
|
||||
| `/api/v1/llm/quota` | GET | 查询当前用户配额 | ✅ |
|
||||
| `/api/v1/llm/usage` | GET | 查询使用统计 | ✅ |
|
||||
| `/api/v1/llm/models` | GET | 获取可用模型列表 | ✅ |
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD>俥 AI<EFBFBD>箄<EFBFBD><EFBFBD>桃<EFBFBD>嚗?api/v1/chat, /api/v1/agents嚗?
|
||||
## 💬 AI智能问答(/api/v1/chat, /api/v1/agents)
|
||||
|
||||
**<EFBFBD>嗆<EFBFBD><EFBFBD><EFBFBD>** <20>?撌脣<E6928C><E884A3>?
|
||||
**霂衣<EFBFBD>霈曇恣嚗?* [AIA/02-API霈曇恣](../03-銝𡁜𦛚璅∪<EFBFBD>/AIA-AI<EFBFBD>箄<EFBFBD><EFBFBD>桃<EFBFBD>/02-API霈曇恣.md)嚗<EFBFBD><EFBFBD><EFBFBD>𥕦遣嚗?
|
||||
**状态:** ✅ 已实现
|
||||
**详细设计:** [AIA/02-API设计](../03-业务模块/AIA-AI智能问答/02-API设计.md)(待创建)
|
||||
|
||||
### 对话管理
|
||||
|
||||
| 端点 | 方法 | 说明 | 认证 |
|
||||
|------|------|------|------|
|
||||
| `/api/v1/chat/conversations` | GET | 撖寡<EFBFBD><EFBFBD>𡑒” | <EFBFBD>?|
|
||||
| `/api/v1/chat/conversations` | POST | <EFBFBD>𥕦遣撖寡<EFBFBD> | <EFBFBD>?|
|
||||
| `/api/v1/chat/conversations/:id` | GET | 撖寡<EFBFBD>霂行<EFBFBD> | <EFBFBD>?|
|
||||
| `/api/v1/chat/conversations/:id` | DELETE | <EFBFBD>𣳇膄撖寡<EFBFBD> | <EFBFBD>?|
|
||||
| `/api/v1/chat/conversations/:id/messages` | GET | 撖寡<EFBFBD>瘨<EFBFBD><EFBFBD><EFBFBD>𡑒” | <EFBFBD>?|
|
||||
| `/api/v1/chat/conversations/:id/messages` | POST | <EFBFBD>煾<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?| <20>?|
|
||||
| `/api/v1/chat/conversations` | GET | 对话列表 | ✅ |
|
||||
| `/api/v1/chat/conversations` | POST | 创建对话 | ✅ |
|
||||
| `/api/v1/chat/conversations/:id` | GET | 对话详情 | ✅ |
|
||||
| `/api/v1/chat/conversations/:id` | DELETE | 删除对话 | ✅ |
|
||||
| `/api/v1/chat/conversations/:id/messages` | GET | 对话消息列表 | ✅ |
|
||||
| `/api/v1/chat/conversations/:id/messages` | POST | 发送消息 | ✅ |
|
||||
|
||||
### <EFBFBD>箄<EFBFBD>雿梶恣<EFBFBD>?
|
||||
### 智能体管理
|
||||
|
||||
| 端点 | 方法 | 说明 | 认证 |
|
||||
|------|------|------|------|
|
||||
| `/api/v1/agents` | GET | <EFBFBD>箄<EFBFBD>雿枏<EFBFBD>銵剁<EFBFBD>12銝迎<EFBFBD> | <EFBFBD>?|
|
||||
| `/api/v1/agents/:id` | GET | <EFBFBD>箄<EFBFBD>雿栞祕<EFBFBD>?| <20>?|
|
||||
| `/api/v1/agents` | GET | 智能体列表(12个) | ✅ |
|
||||
| `/api/v1/agents/:id` | GET | 智能体详情 | ✅ |
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD><EFBFBD> AI<EFBFBD>箄<EFBFBD><EFBFBD><EFBFBD>讃嚗?api/v1/literature嚗?
|
||||
## 📖 AI智能文献(/api/v1/literature)
|
||||
|
||||
**<EFBFBD>嗆<EFBFBD><EFBFBD><EFBFBD>** <20>?霈曇恣銝哨<E98A9D>P0隡睃<E99AA1>蝥改<E89DA5>
|
||||
**霂衣<EFBFBD>霈曇恣嚗?* [ASL/02-API霈曇恣](../03-銝𡁜𦛚璅∪<EFBFBD>/ASL-AI<EFBFBD>箄<EFBFBD><EFBFBD><EFBFBD>讃/02-API霈曇恣.md)
|
||||
**状态:** ⏳ 设计中(P0优先级)
|
||||
**详细设计:** [ASL/02-API设计](../03-业务模块/ASL-AI智能文献/02-API设计.md)
|
||||
|
||||
### 项目管理
|
||||
|
||||
| 端点 | 方法 | 说明 | 认证 |
|
||||
|------|------|------|------|
|
||||
| `/api/v1/literature/projects` | GET | <EFBFBD><EFBFBD>讃憿寧𤌍<EFBFBD>𡑒” | <EFBFBD>?|
|
||||
| `/api/v1/literature/projects` | POST | <EFBFBD>𥕦遣<EFBFBD><EFBFBD>讃憿寧𤌍 | <EFBFBD>?|
|
||||
| `/api/v1/literature/projects/:id` | GET | 憿寧𤌍霂行<EFBFBD> | <EFBFBD>?|
|
||||
| `/api/v1/literature/projects/:id` | PUT | <EFBFBD>湔鰵憿寧𤌍 | <EFBFBD>?|
|
||||
| `/api/v1/literature/projects/:id` | DELETE | <EFBFBD>𣳇膄憿寧𤌍 | <EFBFBD>?|
|
||||
| `/api/v1/literature/projects` | GET | 文献项目列表 | ✅ |
|
||||
| `/api/v1/literature/projects` | POST | 创建文献项目 | ✅ |
|
||||
| `/api/v1/literature/projects/:id` | GET | 项目详情 | ✅ |
|
||||
| `/api/v1/literature/projects/:id` | PUT | 更新项目 | ✅ |
|
||||
| `/api/v1/literature/projects/:id` | DELETE | 删除项目 | ✅ |
|
||||
|
||||
### 文献筛选(标题摘要初筛)⭐
|
||||
|
||||
| 端点 | 方法 | 说明 | 认证 |
|
||||
|------|------|------|------|
|
||||
| `/api/v1/literature/projects/:id/items/import` | POST | 撖澆<EFBFBD>CSV<EFBFBD><EFBFBD>辣 | <EFBFBD>?|
|
||||
| `/api/v1/literature/projects/:id/pico` | POST | <EFBFBD>滨蔭PICO<EFBFBD><EFBFBD><EFBFBD> | <EFBFBD>?|
|
||||
| `/api/v1/literature/projects/:id/pico` | GET | <EFBFBD>瑕<EFBFBD>PICO<EFBFBD>滨蔭 | <EFBFBD>?|
|
||||
| `/api/v1/literature/projects/:id/screening/title` | POST | <EFBFBD>扯<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>䁅<EFBFBD><EFBFBD>萘<EFBFBD> | <EFBFBD>?|
|
||||
| `/api/v1/literature/projects/:id/screening/status` | GET | <EFBFBD>亥砭蝑偦<EFBFBD>㕑<EFBFBD>摨?| <20>?|
|
||||
| `/api/v1/literature/projects/:id/screening/results` | GET | <EFBFBD>瑕<EFBFBD>蝑偦<EFBFBD>厩<EFBFBD><EFBFBD>?| <20>?|
|
||||
| `/api/v1/literature/projects/:id/screening/export` | POST | 撖澆枂Excel | <EFBFBD>?|
|
||||
| `/api/v1/literature/projects/:id/items/import` | POST | 导入CSV文件 | ✅ |
|
||||
| `/api/v1/literature/projects/:id/pico` | POST | 配置PICO标准 | ✅ |
|
||||
| `/api/v1/literature/projects/:id/pico` | GET | 获取PICO配置 | ✅ |
|
||||
| `/api/v1/literature/projects/:id/screening/title` | POST | 执行标题摘要初筛 | ✅ |
|
||||
| `/api/v1/literature/projects/:id/screening/status` | GET | 查询筛选进度 | ✅ |
|
||||
| `/api/v1/literature/projects/:id/screening/results` | GET | 获取筛选结果 | ✅ |
|
||||
| `/api/v1/literature/projects/:id/screening/export` | POST | 导出Excel | ✅ |
|
||||
|
||||
### <EFBFBD><EFBFBD>讃蝑偦<EFBFBD>㚁<EFBFBD><EFBFBD>冽<EFBFBD>憭滨<EFBFBD>嚗?
|
||||
### 文献筛选(全文复筛)
|
||||
|
||||
| 端点 | 方法 | 说明 | 认证 |
|
||||
|------|------|------|------|
|
||||
| `/api/v1/literature/projects/:id/screening/fulltext` | POST | <EFBFBD>扯<EFBFBD><EFBFBD>冽<EFBFBD>蝑偦<EFBFBD>?| <20>?|
|
||||
| `/api/v1/literature/projects/:id/screening/fulltext/status` | GET | <EFBFBD>亥砭餈𥕦漲 | <EFBFBD>?|
|
||||
| `/api/v1/literature/projects/:id/screening/fulltext` | POST | 执行全文筛选 | ✅ |
|
||||
| `/api/v1/literature/projects/:id/screening/fulltext/status` | GET | 查询进度 | ✅ |
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD><EFBFBD> 銝芯犖<E88AAF>亥<EFBFBD>摨橒<E691A8>/api/v1/knowledge-bases嚗?
|
||||
## 📚 个人知识库(/api/v1/knowledge-bases)
|
||||
|
||||
**<EFBFBD>嗆<EFBFBD><EFBFBD><EFBFBD>** <20>?撌脣<E6928C><E884A3>?
|
||||
**霂衣<EFBFBD>霈曇恣嚗?* [PKB/02-API霈曇恣](../03-銝𡁜𦛚璅∪<EFBFBD>/PKB-銝芯犖<E88AAF>亥<EFBFBD>摨?02-API霈曇恣.md)嚗<EFBFBD><EFBFBD><EFBFBD>𥕦遣嚗?
|
||||
**状态:** ✅ 已实现
|
||||
**详细设计:** [PKB/02-API设计](../03-业务模块/PKB-个人知识库/02-API设计.md)(待创建)
|
||||
|
||||
### <EFBFBD>亥<EFBFBD>摨梶恣<EFBFBD>?
|
||||
### 知识库管理
|
||||
|
||||
| 端点 | 方法 | 说明 | 认证 |
|
||||
|------|------|------|------|
|
||||
| `/api/v1/knowledge-bases` | GET | <EFBFBD>亥<EFBFBD>摨枏<EFBFBD>銵?| <20>?|
|
||||
| `/api/v1/knowledge-bases` | POST | <EFBFBD>𥕦遣<EFBFBD>亥<EFBFBD>摨?| <20>?|
|
||||
| `/api/v1/knowledge-bases/:id` | GET | <EFBFBD>亥<EFBFBD>摨栞祕<EFBFBD>?| <20>?|
|
||||
| `/api/v1/knowledge-bases/:id` | PUT | <EFBFBD>湔鰵<EFBFBD>亥<EFBFBD>摨?| <20>?|
|
||||
| `/api/v1/knowledge-bases/:id` | DELETE | <EFBFBD>𣳇膄<EFBFBD>亥<EFBFBD>摨?| <20>?|
|
||||
| `/api/v1/knowledge-bases` | GET | 知识库列表 | ✅ |
|
||||
| `/api/v1/knowledge-bases` | POST | 创建知识库 | ✅ |
|
||||
| `/api/v1/knowledge-bases/:id` | GET | 知识库详情 | ✅ |
|
||||
| `/api/v1/knowledge-bases/:id` | PUT | 更新知识库 | ✅ |
|
||||
| `/api/v1/knowledge-bases/:id` | DELETE | 删除知识库 | ✅ |
|
||||
|
||||
### 文档管理
|
||||
|
||||
| 端点 | 方法 | 说明 | 认证 |
|
||||
|------|------|------|------|
|
||||
| `/api/v1/knowledge-bases/:id/documents` | GET | <EFBFBD><EFBFBD>﹝<EFBFBD>𡑒” | <EFBFBD>?|
|
||||
| `/api/v1/knowledge-bases/:id/documents` | POST | 銝𠹺<EFBFBD><EFBFBD><EFBFBD>﹝ | <EFBFBD>?|
|
||||
| `/api/v1/knowledge-bases/:id/documents/:docId` | GET | <EFBFBD><EFBFBD>﹝霂行<EFBFBD> | <EFBFBD>?|
|
||||
| `/api/v1/knowledge-bases/:id/documents/:docId` | DELETE | <EFBFBD>𣳇膄<EFBFBD><EFBFBD>﹝ | <EFBFBD>?|
|
||||
| `/api/v1/knowledge-bases/:id/documents` | GET | 文档列表 | ✅ |
|
||||
| `/api/v1/knowledge-bases/:id/documents` | POST | 上传文档 | ✅ |
|
||||
| `/api/v1/knowledge-bases/:id/documents/:docId` | GET | 文档详情 | ✅ |
|
||||
| `/api/v1/knowledge-bases/:id/documents/:docId` | DELETE | 删除文档 | ✅ |
|
||||
|
||||
### RAG问答
|
||||
|
||||
| 端点 | 方法 | 说明 | 认证 |
|
||||
|------|------|------|------|
|
||||
| `/api/v1/knowledge-bases/:id/chat` | POST | <EFBFBD>亥<EFBFBD>摨㯄䔮蝑?| <20>?|
|
||||
| `/api/v1/knowledge-bases/:id/search` | GET | 霂凋<EFBFBD>璉<EFBFBD>蝝?| <20>?|
|
||||
| `/api/v1/knowledge-bases/:id/chat` | POST | 知识库问答 | ✅ |
|
||||
| `/api/v1/knowledge-bases/:id/search` | GET | 语义检索 | ✅ |
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD>完 <20>唳旿皜<E697BF><E79A9C><EFBFBD>渡<EFBFBD>嚗?api/v1/data-cleaning嚗?
|
||||
## 🧹 数据清洗整理(/api/v1/data-cleaning)
|
||||
|
||||
**<EFBFBD>嗆<EFBFBD><EFBFBD><EFBFBD>** <20>?閫<><E996AB>銝哨<E98A9D>P1隡睃<E99AA1>蝥改<E89DA5>
|
||||
**霂衣<EFBFBD>霈曇恣嚗?* 敺<>挽霈?
|
||||
**状态:** ⏳ 规划中(P1优先级)
|
||||
**详细设计:** 待设计
|
||||
|
||||
### 清洗项目
|
||||
|
||||
| 端点 | 方法 | 说明 | 认证 |
|
||||
|------|------|------|------|
|
||||
| `/api/v1/data-cleaning/projects` | GET | 皜<EFBFBD><EFBFBD>憿寧𤌍<EFBFBD>𡑒” | <EFBFBD>?|
|
||||
| `/api/v1/data-cleaning/projects` | POST | <EFBFBD>𥕦遣皜<EFBFBD><EFBFBD>憿寧𤌍 | <EFBFBD>?|
|
||||
| `/api/v1/data-cleaning/projects/:id` | GET | 憿寧𤌍霂行<EFBFBD> | <EFBFBD>?|
|
||||
| `/api/v1/data-cleaning/projects` | GET | 清洗项目列表 | ✅ |
|
||||
| `/api/v1/data-cleaning/projects` | POST | 创建清洗项目 | ✅ |
|
||||
| `/api/v1/data-cleaning/projects/:id` | GET | 项目详情 | ✅ |
|
||||
|
||||
### ETL配置
|
||||
|
||||
| 端点 | 方法 | 说明 | 认证 |
|
||||
|------|------|------|------|
|
||||
| `/api/v1/data-cleaning/projects/:id/etl` | POST | <EFBFBD>滨蔭ETL閫<EFBFBD><EFBFBD> | <EFBFBD>?|
|
||||
| `/api/v1/data-cleaning/projects/:id/execute` | POST | <EFBFBD>扯<EFBFBD>皜<EFBFBD><EFBFBD>隞餃𦛚 | <EFBFBD>?|
|
||||
| `/api/v1/data-cleaning/projects/:id/etl` | POST | 配置ETL规则 | ✅ |
|
||||
| `/api/v1/data-cleaning/projects/:id/execute` | POST | 执行清洗任务 | ✅ |
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD><EFBFBD> <20>箄<EFBFBD>蝏蠘恣<E8A098><E681A3><EFBFBD>嚗?api/v1/analysis嚗?
|
||||
## 📊 智能统计分析(/api/v1/analysis)
|
||||
|
||||
**<EFBFBD>嗆<EFBFBD><EFBFBD><EFBFBD>** <20>?閫<><E996AB>銝哨<E98A9D>P2隡睃<E99AA1>蝥改<E89DA5>
|
||||
**霂衣<EFBFBD>霈曇恣嚗?* 敺<>挽霈?
|
||||
**状态:** ⏳ 规划中(P2优先级)
|
||||
**详细设计:** 待设计
|
||||
|
||||
### 分析项目
|
||||
|
||||
| 端点 | 方法 | 说明 | 认证 |
|
||||
|------|------|------|------|
|
||||
| `/api/v1/analysis/projects` | GET | <EFBFBD><EFBFBD><EFBFBD>憿寧𤌍<EFBFBD>𡑒” | <EFBFBD>?|
|
||||
| `/api/v1/analysis/projects` | POST | <EFBFBD>𥕦遣<EFBFBD><EFBFBD><EFBFBD>憿寧𤌍 | <EFBFBD>?|
|
||||
| `/api/v1/analysis/projects/:id/execute` | POST | <EFBFBD>扯<EFBFBD><EFBFBD><EFBFBD><EFBFBD> | <EFBFBD>?|
|
||||
| `/api/v1/analysis/projects` | GET | 分析项目列表 | ✅ |
|
||||
| `/api/v1/analysis/projects` | POST | 创建分析项目 | ✅ |
|
||||
| `/api/v1/analysis/projects/:id/execute` | POST | 执行分析 | ✅ |
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD>圲 蝏蠘恣<E8A098><E681A3><EFBFBD>撌亙<E6928C>嚗?api/v1/tools嚗?
|
||||
## 🔧 统计分析工具(/api/v1/tools)
|
||||
|
||||
**<EFBFBD>嗆<EFBFBD><EFBFBD><EFBFBD>** <20>?閫<><E996AB>銝哨<E98A9D>P2隡睃<E99AA1>蝥改<E89DA5>
|
||||
**霂衣<EFBFBD>霈曇恣嚗?* 敺<>挽霈?
|
||||
**状态:** ⏳ 规划中(P2优先级)
|
||||
**详细设计:** 待设计
|
||||
|
||||
### 工具调用
|
||||
|
||||
| 端点 | 方法 | 说明 | 认证 |
|
||||
|------|------|------|------|
|
||||
| `/api/v1/tools` | GET | 撌亙<EFBFBD><EFBFBD>𡑒”嚗?00+嚗?| <20>?|
|
||||
| `/api/v1/tools/:id` | GET | 撌亙<EFBFBD>霂行<EFBFBD> | <EFBFBD>?|
|
||||
| `/api/v1/tools/:id/execute` | POST | <EFBFBD>扯<EFBFBD>撌亙<EFBFBD> | <EFBFBD>?|
|
||||
| `/api/v1/tools` | GET | 工具列表(100+) | ✅ |
|
||||
| `/api/v1/tools/:id` | GET | 工具详情 | ✅ |
|
||||
| `/api/v1/tools/:id/execute` | POST | 执行工具 | ✅ |
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD><EFBFBD> 蝔蹂辣摰⊥䰻蝟餌<E89D9F>嚗?api/v1/review嚗?
|
||||
## 📄 稿件审查系统(/api/v1/review)
|
||||
|
||||
**<EFBFBD>嗆<EFBFBD><EFBFBD><EFBFBD>** <20>?撌脣<E6928C><E884A3>堆<EFBFBD><E5A086>祉<EFBFBD>蝟餌<E89D9F>嚗?
|
||||
**霂衣<EFBFBD>霈曇恣嚗?* [RVW/02-API霈曇恣](../03-銝𡁜𦛚璅∪<EFBFBD>/RVW-蝔蹂辣摰⊥䰻蝟餌<E89D9F>/02-API霈曇恣.md)嚗<EFBFBD><EFBFBD><EFBFBD>𥕦遣嚗?
|
||||
**状态:** ✅ 已实现(独立系统)
|
||||
**详细设计:** [RVW/02-API设计](../03-业务模块/RVW-稿件审查系统/02-API设计.md)(待创建)
|
||||
|
||||
### 审查任务
|
||||
|
||||
| 端点 | 方法 | 说明 | 认证 |
|
||||
|------|------|------|------|
|
||||
| `/api/v1/review/tasks` | GET | 摰⊥䰻隞餃𦛚<EFBFBD>𡑒” | <EFBFBD>?|
|
||||
| `/api/v1/review/tasks` | POST | <EFBFBD>𥕦遣摰⊥䰻隞餃𦛚 | <EFBFBD>?|
|
||||
| `/api/v1/review/tasks/:id` | GET | 隞餃𦛚霂行<EFBFBD> | <EFBFBD>?|
|
||||
| `/api/v1/review/tasks/:id/execute` | POST | <EFBFBD>扯<EFBFBD>摰⊥䰻 | <EFBFBD>?|
|
||||
| `/api/v1/review/tasks/:id/report` | GET | <EFBFBD><EFBFBD><EFBFBD><EFBFBD>亙<EFBFBD>嚗㇊DF嚗?| <20>?|
|
||||
| `/api/v1/review/tasks` | GET | 审查任务列表 | ✅ |
|
||||
| `/api/v1/review/tasks` | POST | 创建审查任务 | ✅ |
|
||||
| `/api/v1/review/tasks/:id` | GET | 任务详情 | ✅ |
|
||||
| `/api/v1/review/tasks/:id/execute` | POST | 执行审查 | ✅ |
|
||||
| `/api/v1/review/tasks/:id/report` | GET | 生成报告(PDF) | ✅ |
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD><EFBFBD>儭?餈鞱𨯫蝞∠<E89D9E>蝡荔<E89DA1>/api/v1/admin嚗?
|
||||
## 🛠️ 运营管理端(/api/v1/admin)
|
||||
|
||||
**<EFBFBD>嗆<EFBFBD><EFBFBD><EFBFBD>** <20>?閫<><E996AB>銝哨<E98A9D>P1隡睃<E99AA1>蝥改<E89DA5>
|
||||
**霂衣<EFBFBD>霈曇恣嚗?* [ADMIN/02-API霈曇恣](../03-銝𡁜𦛚璅∪<EFBFBD>/ADMIN-餈鞱𨯫蝞∠<EFBFBD>蝡?02-API霈曇恣.md)
|
||||
**状态:** ⏳ 规划中(P1优先级)
|
||||
**详细设计:** [ADMIN/02-API设计](../03-业务模块/ADMIN-运营管理端/02-API设计.md)
|
||||
|
||||
### <EFBFBD>冽<EFBFBD>蝞∠<EFBFBD> 潃?
|
||||
### 用户管理 ⭐
|
||||
|
||||
| 端点 | 方法 | 说明 | 认证 |
|
||||
|------|------|------|------|
|
||||
| `/api/v1/admin/users` | GET | <EFBFBD>冽<EFBFBD><EFBFBD>𡑒” | <EFBFBD>?ADMIN |
|
||||
| `/api/v1/admin/users/:id` | GET | <EFBFBD>冽<EFBFBD>霂行<EFBFBD> | <EFBFBD>?ADMIN |
|
||||
| `/api/v1/admin/users/:id` | PUT | <EFBFBD>湔鰵<EFBFBD>冽<EFBFBD> | <EFBFBD>?ADMIN |
|
||||
| `/api/v1/admin/users/:id/plan` | PUT | 靽格㺿憟烾<EFBFBD> | <EFBFBD>?ADMIN |
|
||||
| `/api/v1/admin/users/:id/disable` | POST | 蝳<EFBFBD>鍂<EFBFBD>冽<EFBFBD> | <EFBFBD>?ADMIN |
|
||||
| `/api/v1/admin/users` | GET | 用户列表 | ✅ ADMIN |
|
||||
| `/api/v1/admin/users/:id` | GET | 用户详情 | ✅ ADMIN |
|
||||
| `/api/v1/admin/users/:id` | PUT | 更新用户 | ✅ ADMIN |
|
||||
| `/api/v1/admin/users/:id/plan` | PUT | 修改套餐 | ✅ ADMIN |
|
||||
| `/api/v1/admin/users/:id/disable` | POST | 禁用用户 | ✅ ADMIN |
|
||||
|
||||
### Feature Flag蝞∠<EFBFBD> 潃?
|
||||
### Feature Flag管理 ⭐
|
||||
|
||||
| 端点 | 方法 | 说明 | 认证 |
|
||||
|------|------|------|------|
|
||||
| `/api/v1/admin/feature-flags` | GET | Flag<EFBFBD>𡑒” | <EFBFBD>?ADMIN |
|
||||
| `/api/v1/admin/feature-flags` | POST | <EFBFBD>𥕦遣Flag | <EFBFBD>?ADMIN |
|
||||
| `/api/v1/admin/feature-flags/:id` | PUT | <EFBFBD>湔鰵Flag | <EFBFBD>?ADMIN |
|
||||
| `/api/v1/admin/users/:id/flags` | GET | <EFBFBD>冽<EFBFBD>Flag | <EFBFBD>?ADMIN |
|
||||
| `/api/v1/admin/users/:id/flags` | PUT | <EFBFBD>湔鰵<EFBFBD>冽<EFBFBD>Flag | <EFBFBD>?ADMIN |
|
||||
| `/api/v1/admin/feature-flags` | GET | Flag列表 | ✅ ADMIN |
|
||||
| `/api/v1/admin/feature-flags` | POST | 创建Flag | ✅ ADMIN |
|
||||
| `/api/v1/admin/feature-flags/:id` | PUT | 更新Flag | ✅ ADMIN |
|
||||
| `/api/v1/admin/users/:id/flags` | GET | 用户Flag | ✅ ADMIN |
|
||||
| `/api/v1/admin/users/:id/flags` | PUT | 更新用户Flag | ✅ ADMIN |
|
||||
|
||||
### LLM璅∪<EFBFBD>蝞∠<EFBFBD> 潃?
|
||||
### LLM模型管理 ⭐
|
||||
|
||||
| 端点 | 方法 | 说明 | 认证 |
|
||||
|------|------|------|------|
|
||||
| `/api/v1/admin/llm/models` | GET | 璅∪<EFBFBD><EFBFBD>𡑒” | <EFBFBD>?ADMIN |
|
||||
| `/api/v1/admin/llm/models` | POST | 瘛餃<EFBFBD>璅∪<EFBFBD> | <EFBFBD>?ADMIN |
|
||||
| `/api/v1/admin/llm/models/:id` | PUT | <EFBFBD>湔鰵璅∪<EFBFBD> | <EFBFBD>?ADMIN |
|
||||
| `/api/v1/admin/llm/usage` | GET | LLM雿輻鍂蝏蠘恣 | <EFBFBD>?ADMIN |
|
||||
| `/api/v1/admin/llm/cost-analysis` | GET | <EFBFBD>鞉𧋦<EFBFBD><EFBFBD><EFBFBD> | <EFBFBD>?ADMIN |
|
||||
| `/api/v1/admin/llm/models` | GET | 模型列表 | ✅ ADMIN |
|
||||
| `/api/v1/admin/llm/models` | POST | 添加模型 | ✅ ADMIN |
|
||||
| `/api/v1/admin/llm/models/:id` | PUT | 更新模型 | ✅ ADMIN |
|
||||
| `/api/v1/admin/llm/usage` | GET | LLM使用统计 | ✅ ADMIN |
|
||||
| `/api/v1/admin/llm/cost-analysis` | GET | 成本分析 | ✅ ADMIN |
|
||||
|
||||
### Prompt管理
|
||||
|
||||
| 端点 | 方法 | 说明 | 认证 |
|
||||
|------|------|------|------|
|
||||
| `/api/v1/admin/prompts` | GET | Prompt<EFBFBD>𡑒” | <EFBFBD>?ADMIN |
|
||||
| `/api/v1/admin/prompts` | POST | <EFBFBD>𥕦遣Prompt | <EFBFBD>?ADMIN |
|
||||
| `/api/v1/admin/prompts/:id` | PUT | <EFBFBD>湔鰵Prompt | <EFBFBD>?ADMIN |
|
||||
| `/api/v1/admin/prompts` | GET | Prompt列表 | ✅ ADMIN |
|
||||
| `/api/v1/admin/prompts` | POST | 创建Prompt | ✅ ADMIN |
|
||||
| `/api/v1/admin/prompts/:id` | PUT | 更新Prompt | ✅ ADMIN |
|
||||
|
||||
### 日志查询
|
||||
|
||||
| 端点 | 方法 | 说明 | 认证 |
|
||||
|------|------|------|------|
|
||||
| `/api/v1/admin/logs` | GET | <EFBFBD>亙<EFBFBD><EFBFBD>𡑒” | <EFBFBD>?ADMIN |
|
||||
| `/api/v1/admin/logs/errors` | GET | <EFBFBD>躰秤<EFBFBD>亙<EFBFBD> | <EFBFBD>?ADMIN |
|
||||
| `/api/v1/admin/logs/operations` | GET | <EFBFBD>滢<EFBFBD><EFBFBD>亙<EFBFBD> | <EFBFBD>?ADMIN |
|
||||
| `/api/v1/admin/logs` | GET | 日志列表 | ✅ ADMIN |
|
||||
| `/api/v1/admin/logs/errors` | GET | 错误日志 | ✅ ADMIN |
|
||||
| `/api/v1/admin/logs/operations` | GET | 操作日志 | ✅ ADMIN |
|
||||
|
||||
### 数据报表
|
||||
|
||||
| 端点 | 方法 | 说明 | 认证 |
|
||||
|------|------|------|------|
|
||||
| `/api/v1/admin/reports/overview` | GET | <EFBFBD>餉<EFBFBD><EFBFBD>唳旿 | <EFBFBD>?ADMIN |
|
||||
| `/api/v1/admin/reports/users` | GET | <EFBFBD>冽<EFBFBD>瘣餉<EFBFBD>摨?| <20>?ADMIN |
|
||||
| `/api/v1/admin/reports/features` | GET | <EFBFBD>蠘<EFBFBD>雿輻鍂<EFBFBD>?| <20>?ADMIN |
|
||||
| `/api/v1/admin/reports/llm` | GET | LLM蝏蠘恣 | <EFBFBD>?ADMIN |
|
||||
| `/api/v1/admin/reports/overview` | GET | 总览数据 | ✅ ADMIN |
|
||||
| `/api/v1/admin/reports/users` | GET | 用户活跃度 | ✅ ADMIN |
|
||||
| `/api/v1/admin/reports/features` | GET | 功能使用率 | ✅ ADMIN |
|
||||
| `/api/v1/admin/reports/llm` | GET | LLM统计 | ✅ ADMIN |
|
||||
|
||||
---
|
||||
|
||||
## 📊 路由统计
|
||||
|
||||
### <EFBFBD>㗇芋<EFBFBD>㛖<EFBFBD>霈?
|
||||
### 按模块统计
|
||||
|
||||
| 璅∪<EFBFBD> | 蝡舐<E89DA1><E88890>圈<EFBFBD> | <20>嗆<EFBFBD>?|
|
||||
| 模块 | 端点数量 | 状态 |
|
||||
|------|---------|------|
|
||||
| 霈方<EFBFBD>銝𡒊鍂<EFBFBD>?| 10 | <20>?撌脣<E6928C><E884A3>?|
|
||||
| LLM蝵穃<EFBFBD> | 5 | <EFBFBD>?敺<><E695BA><EFBFBD>?|
|
||||
| AI<EFBFBD>箄<EFBFBD><EFBFBD>桃<EFBFBD> | 8 | <EFBFBD>?撌脣<E6928C><E884A3>?|
|
||||
| AI<EFBFBD>箄<EFBFBD><EFBFBD><EFBFBD>讃 | 15 | <EFBFBD>?霈曇恣銝?|
|
||||
| 銝芯犖<EFBFBD>亥<EFBFBD>摨?| 10 | <20>?撌脣<E6928C><E884A3>?|
|
||||
| <EFBFBD>唳旿皜<EFBFBD><EFBFBD> | 5 | <EFBFBD>?閫<><E996AB>銝?|
|
||||
| <EFBFBD>箄<EFBFBD>蝏蠘恣<EFBFBD><EFBFBD><EFBFBD> | 3 | <20>?閫<><E996AB>銝?|
|
||||
| 蝏蠘恣撌亙<EFBFBD> | 3 | <EFBFBD>?閫<><E996AB>銝?|
|
||||
| 蝔蹂辣摰⊥䰻 | 5 | <EFBFBD>?撌脣<E6928C><E884A3>?|
|
||||
| 餈鞱𨯫蝞∠<EFBFBD>蝡?| 20 | <20>?閫<><E996AB>銝?|
|
||||
| 认证与用户 | 10 | ✅ 已实现 |
|
||||
| LLM网关 | 5 | ❌ 待实现 |
|
||||
| AI智能问答 | 8 | ✅ 已实现 |
|
||||
| AI智能文献 | 15 | ⏳ 设计中 |
|
||||
| 个人知识库 | 10 | ✅ 已实现 |
|
||||
| 数据清洗 | 5 | ⏳ 规划中 |
|
||||
| 智能统计分析 | 3 | ⏳ 规划中 |
|
||||
| 统计工具 | 3 | ⏳ 规划中 |
|
||||
| 稿件审查 | 5 | ✅ 已实现 |
|
||||
| 运营管理端 | 20 | ⏳ 规划中 |
|
||||
| **总计** | **~85** | - |
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD>𩤃<EFBFBD> 頝舐眏<E88890>脩<EFBFBD>璉<EFBFBD><E79289>?
|
||||
## ⚠️ 路由冲突检查
|
||||
|
||||
### 潜在冲突
|
||||
|
||||
**<EFBFBD>?<3F>踹<EFBFBD><E8B8B9>脩<EFBFBD>嚗?*
|
||||
**❌ 避免冲突:**
|
||||
```
|
||||
# <EFBFBD>躰秤嚗𡁏芋<EFBFBD>堒<EFBFBD>蝘啣<EFBFBD>蝒?
|
||||
# 错误:模块名称冲突
|
||||
/api/v1/admin/users # 管理端的用户管理
|
||||
/api/v1/users # 平台层的用户管理
|
||||
|
||||
# 甇<EFBFBD>&嚗𡁏<EFBFBD>蝖桀躹<EFBFBD>?
|
||||
# 正确:明确区分
|
||||
/api/v1/auth/profile # 当前用户信息
|
||||
/api/v1/admin/users # 管理端用户CRUD
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD><EFBFBD> 敹恍<E695B9><E6818D>䰻<EFBFBD>暹<EFBFBD><E69AB9>?
|
||||
## 🔍 快速查找指南
|
||||
|
||||
### 场景1:查找某个模块的所有API
|
||||
1. <EFBFBD>其<EFBFBD><EFBFBD>Y<EFBFBD>銵冽聢銝剜𪄳<EFBFBD>啣笆摨娍芋<EFBFBD>?
|
||||
1. 在上面的表格中找到对应模块
|
||||
2. 点击"详细设计"链接
|
||||
3. 查看该模块的完整API文档
|
||||
|
||||
### 场景2:设计新API端点
|
||||
1. <EFBFBD>亦<EFBFBD><EFBFBD>祆<EFBFBD>獢<EFBFBD><EFBFBD>蝖桐<EFBFBD>頝舐眏銝滚<EFBFBD>蝒?
|
||||
1. 查看本文档,确保路由不冲突
|
||||
2. 参考[API设计规范](./02-API设计规范.md)
|
||||
3. 使用[API设计模板](../_templates/API设计-模板.md)
|
||||
|
||||
### 场景3:查看全局API架构
|
||||
1. 阅读本文档(快速了解所有端点)
|
||||
2. <EFBFBD>亦<EFBFBD>[<5B>嗆<EFBFBD>霈曇恣<E69B87>冽艶<E586BD>霄(../00-蝟餌<E89D9F><E9A48C>颱<EFBFBD>霈曇恣/08-<2D>嗆<EFBFBD>霈曇恣<E69B87>冽艶<E586BD>?md)
|
||||
2. 查看[架构设计全景图](../00-系统总体设计/08-架构设计全景图.md)
|
||||
|
||||
---
|
||||
|
||||
## 🔗 相关文档
|
||||
|
||||
**閫<EFBFBD><EFBFBD>嚗?*
|
||||
- [API霈曇恣閫<EFBFBD><EFBFBD>](./02-API霈曇恣閫<EFBFBD><EFBFBD>.md) 潃?敹<>粉
|
||||
- [霈方<EFBFBD>銝擧<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(./02-API霈曇恣閫<E681A3><E996AB>.md#霈方<EFBFBD>銝擧<EFBFBD><EFBFBD>?
|
||||
**规范:**
|
||||
- [API设计规范](./02-API设计规范.md) ⭐ 必读
|
||||
- [认证与授权规范](./02-API设计规范.md#认证与授权)
|
||||
|
||||
**璅⊥踎嚗?*
|
||||
**模板:**
|
||||
- [API设计模板](../_templates/API设计-模板.md)
|
||||
|
||||
**数据库:**
|
||||
@@ -376,7 +376,7 @@
|
||||
|
||||
**最后更新:** 2025-11-06
|
||||
**维护人:** 技术架构师
|
||||
**<EFBFBD><EFBFBD>𧋦嚗?* v1.0
|
||||
**版本:** v1.0
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
# 代码规范
|
||||
|
||||
> **鐗堟湰锛?* v1.0
|
||||
> **鍒涘缓鏃ユ湡锛?* 2025-10-10
|
||||
> **閫傜敤鑼冨洿锛?* 鍓嶇<E98D93>锛圧eact/TypeScript锛? 鍚庣<E98D9A>锛圢ode.js/TypeScript锛?
|
||||
> **版本:** v1.0
|
||||
> **创建日期:** 2025-10-10
|
||||
> **适用范围:** 前端(React/TypeScript)+ 后端(Node.js/TypeScript)
|
||||
|
||||
---
|
||||
|
||||
## 📋 目录
|
||||
@@ -17,26 +18,29 @@
|
||||
|
||||
---
|
||||
|
||||
## 馃専 骞冲彴鑳藉姏浣跨敤瑙勮寖锛?025-11-16 鏂板<EFBFBD>锛?
|
||||
> **猸?閲嶈<E996B2>鎻愮ず**锛氬钩鍙板凡鎻愪緵瀹屾暣鐨勫熀纭€璁炬柦鏈嶅姟
|
||||
> **璇︾粏瑙勮寖**锛歔浜戝師鐢熷紑鍙戣<E98D99>鑼僝(./08-浜戝師鐢熷紑鍙戣<E98D99>鑼?md)
|
||||
## 🌟 平台能力使用规范(2025-11-16 新增)
|
||||
|
||||
> **⭐ 重要提示**:平台已提供完整的基础设施服务
|
||||
> **详细规范**:[云原生开发规范](./08-云原生开发规范.md)
|
||||
> **详细文档**:[平台基础设施规划](../09-架构实施/04-平台基础设施规划.md)
|
||||
|
||||
### 蹇呴』澶嶇敤鐨勫钩鍙版湇鍔?
|
||||
**涓氬姟妯″潡锛圓SL/AIA/PKB/DC绛夛級绂佹<E7BB82>閲嶅<E996B2>瀹炵幇浠ヤ笅鍔熻兘锛?*
|
||||
### 必须复用的平台服务
|
||||
|
||||
| 鏈嶅姟 | 瀵煎叆鏂瑰紡 | 鐢ㄩ€?|
|
||||
**业务模块(ASL/AIA/PKB/DC等)禁止重复实现以下功能:**
|
||||
|
||||
| 服务 | 导入方式 | 用途 |
|
||||
|------|---------|------|
|
||||
| **存储服务** | `import { storage } from '@/common/storage'` | 文件上传下载 |
|
||||
| **鏃ュ織绯荤粺** | `import { logger } from '@/common/logging'` | 鏍囧噯鍖栨棩蹇?|
|
||||
| **寮傛<EFBFBD>浠诲姟** | `import { jobQueue } from '@/common/jobs'` | 闀挎椂闂翠换鍔?|
|
||||
| **缂撳瓨鏈嶅姟** | `import { cache } from '@/common/cache'` | 鍒嗗竷寮忕紦瀛?|
|
||||
| **鏁版嵁搴?* | `import { prisma } from '@/config/database'` | 鏁版嵁搴撴搷浣?|
|
||||
| **日志系统** | `import { logger } from '@/common/logging'` | 标准化日志 |
|
||||
| **异步任务** | `import { jobQueue } from '@/common/jobs'` | 长时间任务 |
|
||||
| **缓存服务** | `import { cache } from '@/common/cache'` | 分布式缓存 |
|
||||
| **数据库** | `import { prisma } from '@/config/database'` | 数据库操作 |
|
||||
| **LLM能力** | `import { LLMFactory } from '@/common/llm'` | LLM调用 |
|
||||
|
||||
---
|
||||
|
||||
### 鉁?姝g‘绀轰緥锛氫娇鐢ㄥ钩鍙版湇鍔?
|
||||
### ✅ 正确示例:使用平台服务
|
||||
|
||||
```typescript
|
||||
// backend/src/modules/asl/services/literatureService.ts
|
||||
import { storage } from '@/common/storage'
|
||||
@@ -54,7 +58,8 @@ export class LiteratureService {
|
||||
// 2. 使用平台日志系统
|
||||
logger.info('PDF uploaded', { projectId, url })
|
||||
|
||||
// 3. 浣跨敤骞冲彴鏁版嵁搴? const literature = await prisma.aslLiterature.create({
|
||||
// 3. 使用平台数据库
|
||||
const literature = await prisma.aslLiterature.create({
|
||||
data: { projectId, pdfUrl: url, pdfFileSize: pdfBuffer.length }
|
||||
})
|
||||
|
||||
@@ -65,7 +70,8 @@ export class LiteratureService {
|
||||
}
|
||||
|
||||
async startScreening(projectId: string, literatureIds: string[]) {
|
||||
// 5. 浣跨敤骞冲彴寮傛<EFBFBD>浠诲姟锛堥暱鏃堕棿浠诲姟蹇呴』寮傛<EFBFBD>锛? const job = await jobQueue.push('asl:screening', {
|
||||
// 5. 使用平台异步任务(长时间任务必须异步)
|
||||
const job = await jobQueue.push('asl:screening', {
|
||||
projectId,
|
||||
literatureIds
|
||||
})
|
||||
@@ -78,44 +84,54 @@ export class LiteratureService {
|
||||
|
||||
---
|
||||
|
||||
### 鉂?閿欒<E996BF>绀轰緥锛氶噸澶嶅疄鐜板钩鍙拌兘鍔?
|
||||
### ❌ 错误示例:重复实现平台能力
|
||||
|
||||
```typescript
|
||||
// 鉂?閿欒<E996BF>锛氬湪涓氬姟妯″潡涓<E6BDA1>嚜宸卞疄鐜板瓨鍌?// backend/src/modules/asl/storage/LocalStorage.ts 鈫?涓嶅簲璇ュ瓨鍦<E793A8>紒
|
||||
// ❌ 错误:在业务模块中自己实现存储
|
||||
// backend/src/modules/asl/storage/LocalStorage.ts ← 不应该存在!
|
||||
import fs from 'fs'
|
||||
|
||||
export class LocalStorage {
|
||||
async upload(file: Buffer) {
|
||||
await fs.writeFile('./uploads/file.pdf', file) // 鉂?閲嶅<E996B2>瀹炵幇
|
||||
await fs.writeFile('./uploads/file.pdf', file) // ❌ 重复实现
|
||||
return '/uploads/file.pdf'
|
||||
}
|
||||
}
|
||||
|
||||
// 鉂?閿欒<E996BF>锛氬湪涓氬姟妯″潡涓<E6BDA1>嚜宸卞疄鐜版棩蹇?// backend/src/modules/asl/logger/logger.ts 鈫?涓嶅簲璇ュ瓨鍦<E793A8>紒
|
||||
// ❌ 错误:在业务模块中自己实现日志
|
||||
// backend/src/modules/asl/logger/logger.ts ← 不应该存在!
|
||||
import winston from 'winston'
|
||||
|
||||
export const logger = winston.createLogger({...}) // 鉂?閲嶅<E996B2>瀹炵幇
|
||||
export const logger = winston.createLogger({...}) // ❌ 重复实现
|
||||
|
||||
// 鉂?閿欒<E996BF>锛氭瘡娆℃柊寤烘暟鎹<E69A9F>簱杩炴帴
|
||||
// ❌ 错误:每次新建数据库连接
|
||||
import { PrismaClient } from '@prisma/client'
|
||||
|
||||
export function getUser() {
|
||||
const prisma = new PrismaClient() // 鉂?杩炴帴娉勬紡
|
||||
const prisma = new PrismaClient() // ❌ 连接泄漏
|
||||
return prisma.user.findMany()
|
||||
}
|
||||
```
|
||||
|
||||
**为什么错误?**
|
||||
- 鉂?閲嶅<E996B2>浠g爜锛岄毦浠ョ淮鎶?- 鉂?涓嶅悓妯″潡瀹炵幇涓嶄竴鑷?- 鉂?鏃犳硶缁熶竴鍒囨崲鐜<E5B4B2><E9909C>锛堟湰鍦?浜戠<E6B59C>锛?- 鉂?娴<>垂寮€鍙戞椂闂?- 鉂?浜戠<E6B59C>閮ㄧ讲浼氬け璐ワ紙Serverless闄愬埗锛?
|
||||
- ❌ 重复代码,难以维护
|
||||
- ❌ 不同模块实现不一致
|
||||
- ❌ 无法统一切换环境(本地/云端)
|
||||
- ❌ 浪费开发时间
|
||||
- ❌ 云端部署会失败(Serverless限制)
|
||||
|
||||
---
|
||||
|
||||
### 文件上传规范
|
||||
|
||||
```typescript
|
||||
// 鉁?姝g‘锛氫娇鐢ㄥ瓨鍌ㄦ娊璞″眰
|
||||
// ✅ 正确:使用存储抽象层
|
||||
const url = await storage.upload('asl/pdf/123.pdf', buffer)
|
||||
|
||||
// 鉂?閿欒<E996BF>锛氱洿鎺ユ搷浣滄枃浠剁郴缁?fs.writeFileSync('./uploads/123.pdf', buffer) // Serverless瀹瑰櫒閲嶅惎浼氫涪澶?
|
||||
// 鉂?閿欒<E996BF>锛氱‖缂栫爜瀛樺偍璺<E5818D>緞
|
||||
// ❌ 错误:直接操作文件系统
|
||||
fs.writeFileSync('./uploads/123.pdf', buffer) // Serverless容器重启会丢失
|
||||
|
||||
// ❌ 错误:硬编码存储路径
|
||||
const filePath = 'D:/uploads/123.pdf' // Windows路径,Linux无法运行
|
||||
```
|
||||
|
||||
@@ -124,7 +140,7 @@ const filePath = 'D:/uploads/123.pdf' // Windows路径,Linux无法运行
|
||||
### 异步任务规范
|
||||
|
||||
```typescript
|
||||
// 鉁?姝g‘锛氶暱鏃堕棿浠诲姟锛?10绉掞級蹇呴』寮傛<E5AFAE>澶勭悊
|
||||
// ✅ 正确:长时间任务(>10秒)必须异步处理
|
||||
app.post('/screening/start', async (req, res) => {
|
||||
const job = await jobQueue.push('asl:screening', data)
|
||||
res.send({ jobId: job.id }) // 立即返回,不等待完成
|
||||
@@ -136,26 +152,29 @@ app.get('/screening/jobs/:id', async (req, res) => {
|
||||
res.send({ status: job.status, progress: job.progress })
|
||||
})
|
||||
|
||||
// 鉂?閿欒<E996BF>锛氬悓姝ョ瓑寰呴暱鏃堕棿浠诲姟
|
||||
// ❌ 错误:同步等待长时间任务
|
||||
app.post('/screening/start', async (req, res) => {
|
||||
const results = await processAllLiteratures(data) // 鍙<EFBFBD>兘闇€瑕?0鍒嗛挓
|
||||
const results = await processAllLiteratures(data) // 可能需要10分钟
|
||||
res.send({ results }) // Serverless 30秒超时!
|
||||
})
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 鏁版嵁搴撹繛鎺ヨ<EFBFBD>鑼?
|
||||
### 数据库连接规范
|
||||
|
||||
```typescript
|
||||
// 鉁?姝g‘锛氫娇鐢ㄥ叏灞€Prisma瀹炰緥
|
||||
// ✅ 正确:使用全局Prisma实例
|
||||
import { prisma } from '@/config/database'
|
||||
|
||||
export async function getUsers() {
|
||||
return await prisma.user.findMany()
|
||||
}
|
||||
|
||||
// 鉂?閿欒<E996BF>锛氭瘡娆℃柊寤哄疄渚?export async function getUsers() {
|
||||
const prisma = new PrismaClient() // 杩炴帴鏁拌€楀敖锛? return await prisma.user.findMany()
|
||||
// ❌ 错误:每次新建实例
|
||||
export async function getUsers() {
|
||||
const prisma = new PrismaClient() // 连接数耗尽!
|
||||
return await prisma.user.findMany()
|
||||
}
|
||||
```
|
||||
|
||||
@@ -164,44 +183,52 @@ export async function getUsers() {
|
||||
### 日志规范
|
||||
|
||||
```typescript
|
||||
// 鉁?姝g‘锛氫娇鐢ㄥ钩鍙版棩蹇楃郴缁?import { logger } from '@/common/logging'
|
||||
// ✅ 正确:使用平台日志系统
|
||||
import { logger } from '@/common/logging'
|
||||
|
||||
logger.info('Operation successful', { userId, action: 'upload' })
|
||||
logger.error('Operation failed', { error: err.message, userId })
|
||||
|
||||
// 鉂?閿欒<E996BF>锛氫娇鐢╟onsole.log
|
||||
console.log('Operation successful') // 鏃犳硶闆嗕腑鏀堕泦锛岄毦浠ユ煡璇?
|
||||
// 鉂?閿欒<E996BF>锛氬啓鏈<E59593>湴鏃ュ織鏂囦欢
|
||||
fs.appendFileSync('./app.log', 'Operation successful') // Serverless涓嶆敮鎸?```
|
||||
// ❌ 错误:使用console.log
|
||||
console.log('Operation successful') // 无法集中收集,难以查询
|
||||
|
||||
// ❌ 错误:写本地日志文件
|
||||
fs.appendFileSync('./app.log', 'Operation successful') // Serverless不支持
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 通用规范
|
||||
|
||||
### 代码风格
|
||||
- 鉁?浣跨敤ESLint鍜孭rettier缁熶竴浠g爜椋庢牸
|
||||
- 鉁?缂╄繘锛?涓<EFBFBD>┖鏍?- 鉁?瀛楃<EFBFBD>涓诧細浼樺厛浣跨敤鍗曞紩鍙?`'`
|
||||
- 鉁?琛屽熬锛氫笉鍔犲垎鍙凤紙闄ら潪蹇呰<EFBFBD>锛?- 鉁?鍗曡<EFBFBD>鏈€澶ч暱搴︼細100瀛楃<EFBFBD>
|
||||
- 鉁?浣跨敤灏鹃殢閫楀彿锛堝<EFBFBD>璞°€佹暟缁勶級
|
||||
- ✅ 使用ESLint和Prettier统一代码风格
|
||||
- ✅ 缩进:2个空格
|
||||
- ✅ 字符串:优先使用单引号 `'`
|
||||
- ✅ 行尾:不加分号(除非必要)
|
||||
- ✅ 单行最大长度:100字符
|
||||
- ✅ 使用尾随逗号(对象、数组)
|
||||
|
||||
### 文件组织
|
||||
- 鉁?涓€涓<EFBFBD>枃浠朵竴涓<EFBFBD>粍浠?绫?- 鉁?鐩稿叧鏂囦欢鏀惧湪鍚屼竴鐩<EFBFBD>綍
|
||||
- 鉁?浣跨敤barrel exports锛坕ndex.ts锛?- 鉁?娴嬭瘯鏂囦欢涓庢簮鏂囦欢鍚岀洰褰?
|
||||
- ✅ 一个文件一个组件/类
|
||||
- ✅ 相关文件放在同一目录
|
||||
- ✅ 使用barrel exports(index.ts)
|
||||
- ✅ 测试文件与源文件同目录
|
||||
|
||||
```
|
||||
src/
|
||||
├── components/
|
||||
鈹? 鈹溾攢鈹€ Button/
|
||||
鈹? 鈹? 鈹溾攢鈹€ Button.tsx
|
||||
鈹? 鈹? 鈹溾攢鈹€ Button.test.tsx
|
||||
鈹? 鈹? 鈹溾攢鈹€ Button.styles.ts
|
||||
鈹? 鈹? 鈹斺攢鈹€ index.ts # export { Button } from './Button'
|
||||
│ ├── Button/
|
||||
│ │ ├── Button.tsx
|
||||
│ │ ├── Button.test.tsx
|
||||
│ │ ├── Button.styles.ts
|
||||
│ │ └── index.ts # export { Button } from './Button'
|
||||
```
|
||||
|
||||
### 代码注释
|
||||
- 鉁?澶嶆潅閫昏緫蹇呴』娉ㄩ噴
|
||||
- 鉁?鍏<>叡API蹇呴』娉ㄩ噴
|
||||
- 鉁?閬垮厤鏃犵敤娉ㄩ噴
|
||||
- 鉁?浣跨敤JSDoc鏍煎紡
|
||||
- ✅ 复杂逻辑必须注释
|
||||
- ✅ 公共API必须注释
|
||||
- ✅ 避免无用注释
|
||||
- ✅ 使用JSDoc格式
|
||||
|
||||
---
|
||||
|
||||
@@ -209,7 +236,7 @@ src/
|
||||
|
||||
### 类型定义
|
||||
|
||||
**鉁?鎺ㄨ崘锛?*
|
||||
**✅ 推荐:**
|
||||
```typescript
|
||||
// 使用interface定义对象结构
|
||||
interface User {
|
||||
@@ -228,14 +255,16 @@ enum UserRole {
|
||||
}
|
||||
```
|
||||
|
||||
**鉂?閬垮厤锛?*
|
||||
**❌ 避免:**
|
||||
```typescript
|
||||
// 不要使用any
|
||||
function process(data: any) { // 鉂? // ...
|
||||
function process(data: any) { // ❌
|
||||
// ...
|
||||
}
|
||||
|
||||
// 应该明确类型
|
||||
function process(data: ProcessData) { // 鉁? // ...
|
||||
function process(data: ProcessData) { // ✅
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
@@ -274,7 +303,7 @@ import type { Project, ProjectStatus } from './types'
|
||||
|
||||
### 组件定义
|
||||
|
||||
**鉁?鎺ㄨ崘锛氬嚱鏁扮粍浠?+ Hooks**
|
||||
**✅ 推荐:函数组件 + Hooks**
|
||||
```tsx
|
||||
import { useState } from 'react'
|
||||
|
||||
@@ -314,14 +343,15 @@ export function Button({
|
||||
}
|
||||
```
|
||||
|
||||
**鉂?閬垮厤锛氱被缁勪欢**
|
||||
**❌ 避免:类组件**
|
||||
```tsx
|
||||
// 除非有特殊需求,否则不使用类组件
|
||||
class Button extends React.Component { ... } // 鉂?```
|
||||
class Button extends React.Component { ... } // ❌
|
||||
```
|
||||
|
||||
### Hooks规范
|
||||
|
||||
**鉁?鎺ㄨ崘锛氳嚜瀹氫箟Hooks**
|
||||
**✅ 推荐:自定义Hooks**
|
||||
```typescript
|
||||
// useProjects.ts
|
||||
import { useState, useEffect } from 'react'
|
||||
@@ -373,7 +403,8 @@ function ProjectList() {
|
||||
### 组件组织
|
||||
|
||||
```tsx
|
||||
// 鉁?鎺ㄨ崘鐨勭粍浠剁粨鏋?import { useState, useEffect, useMemo, useCallback } from 'react'
|
||||
// ✅ 推荐的组件结构
|
||||
import { useState, useEffect, useMemo, useCallback } from 'react'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { SomeComponent } from '@/components'
|
||||
import { useCustomHook } from '@/hooks'
|
||||
@@ -389,19 +420,23 @@ export function Component({ prop1, prop2 }: ComponentProps) {
|
||||
const [state, setState] = useState()
|
||||
const { data } = useCustomHook()
|
||||
|
||||
// 2. 娲剧敓鐘舵€侊紙useMemo锛? const computedValue = useMemo(() => {
|
||||
// 2. 派生状态(useMemo)
|
||||
const computedValue = useMemo(() => {
|
||||
return heavyComputation(data)
|
||||
}, [data])
|
||||
|
||||
// 3. 浜嬩欢澶勭悊锛坲seCallback锛? const handleClick = useCallback(() => {
|
||||
// 3. 事件处理(useCallback)
|
||||
const handleClick = useCallback(() => {
|
||||
// 处理逻辑
|
||||
}, [])
|
||||
|
||||
// 4. Effects
|
||||
useEffect(() => {
|
||||
// 鍓<EFBFBD>綔鐢? }, [])
|
||||
// 副作用
|
||||
}, [])
|
||||
|
||||
// 5. 鏃╂湡杩斿洖锛圠oading/Error锛? if (!data) return <Loading />
|
||||
// 5. 早期返回(Loading/Error)
|
||||
if (!data) return <Loading />
|
||||
|
||||
// 6. 渲染
|
||||
return (
|
||||
@@ -414,7 +449,7 @@ export function Component({ prop1, prop2 }: ComponentProps) {
|
||||
|
||||
### 条件渲染
|
||||
|
||||
**鉁?鎺ㄨ崘锛?*
|
||||
**✅ 推荐:**
|
||||
```tsx
|
||||
// 简单条件:使用 &&
|
||||
{isLoggedIn && <UserMenu />}
|
||||
@@ -433,14 +468,14 @@ function renderContent() {
|
||||
return <div>{renderContent()}</div>
|
||||
```
|
||||
|
||||
**鉂?閬垮厤锛?*
|
||||
**❌ 避免:**
|
||||
```tsx
|
||||
// 避免复杂的嵌套三元运算符
|
||||
{condition1 ? (
|
||||
condition2 ? <A /> : <B />
|
||||
) : (
|
||||
condition3 ? <C /> : <D />
|
||||
)} // 鉂?闅句互鐞嗚В
|
||||
)} // ❌ 难以理解
|
||||
```
|
||||
|
||||
---
|
||||
@@ -452,11 +487,11 @@ return <div>{renderContent()}</div>
|
||||
```
|
||||
backend/src/
|
||||
├── routes/ # 路由定义
|
||||
鈹? 鈹溾攢鈹€ auth.routes.ts
|
||||
鈹? 鈹斺攢鈹€ project.routes.ts
|
||||
│ ├── auth.routes.ts
|
||||
│ └── project.routes.ts
|
||||
├── services/ # 业务逻辑
|
||||
鈹? 鈹溾攢鈹€ auth.service.ts
|
||||
鈹? 鈹斺攢鈹€ project.service.ts
|
||||
│ ├── auth.service.ts
|
||||
│ └── project.service.ts
|
||||
├── controllers/ # 控制器(可选)
|
||||
├── models/ # Prisma模型
|
||||
├── utils/ # 工具函数
|
||||
@@ -536,7 +571,8 @@ export async function projectRoutes(server: FastifyInstance) {
|
||||
}
|
||||
```
|
||||
|
||||
### Service灞?
|
||||
### Service层
|
||||
|
||||
```typescript
|
||||
// services/project.service.ts
|
||||
import { prisma } from '../lib/prisma'
|
||||
@@ -544,7 +580,8 @@ import type { CreateProjectDto, UpdateProjectDto } from '../types'
|
||||
|
||||
export class ProjectService {
|
||||
/**
|
||||
* 鑾峰彇鐢ㄦ埛鐨勯」鐩<EFBFBD>垪琛? */
|
||||
* 获取用户的项目列表
|
||||
*/
|
||||
async getProjects(userId: string, options: PaginationOptions) {
|
||||
const { page, pageSize } = options
|
||||
|
||||
@@ -675,7 +712,8 @@ async function getProject(id: string) {
|
||||
}
|
||||
```
|
||||
|
||||
### 閿欒<EFBFBD>澶勭悊涓<EFBFBD>棿浠?
|
||||
### 错误处理中间件
|
||||
|
||||
```typescript
|
||||
// middleware/error-handler.ts
|
||||
import { FastifyError, FastifyReply, FastifyRequest } from 'fastify'
|
||||
@@ -689,7 +727,8 @@ export async function errorHandler(
|
||||
// 记录错误
|
||||
request.log.error(error)
|
||||
|
||||
// 鑷<EFBFBD>畾涔夐敊璇? if (error instanceof AppError) {
|
||||
// 自定义错误
|
||||
if (error instanceof AppError) {
|
||||
return reply.code(error.statusCode).send({
|
||||
success: false,
|
||||
error: {
|
||||
@@ -744,22 +783,23 @@ export async function errorHandler(
|
||||
### 变量命名
|
||||
|
||||
```typescript
|
||||
// 鉁?鎺ㄨ崘
|
||||
// ✅ 推荐
|
||||
const userName = 'John' // camelCase
|
||||
const USER_ROLE = 'admin' // 常量用UPPER_SNAKE_CASE
|
||||
const isLoading = false // 布尔值用is/has/can前缀
|
||||
const hasPermission = true
|
||||
const canEdit = false
|
||||
|
||||
// 鉂?閬垮厤
|
||||
// ❌ 避免
|
||||
const user_name = 'John' // 不用snake_case
|
||||
const loading = false // 布尔值缺少is前缀
|
||||
const x = 10 // 鏃犳剰涔夌殑鍙橀噺鍚?```
|
||||
const x = 10 // 无意义的变量名
|
||||
```
|
||||
|
||||
### 函数命名
|
||||
|
||||
```typescript
|
||||
// 鉁?鎺ㄨ崘
|
||||
// ✅ 推荐
|
||||
function getUser() { } // get: 获取数据
|
||||
function fetchProjects() { } // fetch: 异步获取
|
||||
function createProject() { } // create: 创建
|
||||
@@ -767,20 +807,24 @@ function updateProject() { } // update: 更新
|
||||
function deleteProject() { } // delete: 删除
|
||||
function handleClick() { } // handle: 事件处理
|
||||
function validateEmail() { } // validate: 验证
|
||||
function formatDate() { } // format: 鏍煎紡鍖?
|
||||
// 鉂?閬垮厤
|
||||
function data() { } // 涓嶆竻妤氬姛鑳?function doSomething() { } // 澶<>ā绯?function process() { } // 涓嶆槑纭?```
|
||||
function formatDate() { } // format: 格式化
|
||||
|
||||
// ❌ 避免
|
||||
function data() { } // 不清楚功能
|
||||
function doSomething() { } // 太模糊
|
||||
function process() { } // 不明确
|
||||
```
|
||||
|
||||
### 组件命名
|
||||
|
||||
```typescript
|
||||
// 鉁?鎺ㄨ崘
|
||||
// ✅ 推荐
|
||||
<Button /> // 基础组件
|
||||
<UserProfile /> // 业务组件
|
||||
<ProjectList /> // 列表组件
|
||||
<CreateProjectModal /> // 弹窗组件
|
||||
|
||||
// 鉂?閬垮厤
|
||||
// ❌ 避免
|
||||
<button /> // 不用小写
|
||||
<user_profile /> // 不用snake_case
|
||||
<ListProjects /> // 动词不要在前
|
||||
@@ -794,9 +838,11 @@ function data() { } // 不清楚功
|
||||
|
||||
```typescript
|
||||
/**
|
||||
* 鍒涘缓鏂伴」鐩? * @param userId - 鐢ㄦ埛ID
|
||||
* 创建新项目
|
||||
* @param userId - 用户ID
|
||||
* @param data - 项目数据
|
||||
* @returns 鍒涘缓鐨勯」鐩<EFBFBD><EFBFBD>璞? * @throws {ValidationError} 褰撴暟鎹<E69A9F>獙璇佸け璐ユ椂
|
||||
* @returns 创建的项目对象
|
||||
* @throws {ValidationError} 当数据验证失败时
|
||||
*/
|
||||
async function createProject(
|
||||
userId: string,
|
||||
@@ -809,18 +855,21 @@ async function createProject(
|
||||
### 代码注释
|
||||
|
||||
```typescript
|
||||
// 鉁?濂界殑娉ㄩ噴锛氳В閲婁负浠€涔?// 浣跨敤setTimeout閬垮厤闃诲<E99783>UI娓叉煋
|
||||
// ✅ 好的注释:解释为什么
|
||||
// 使用setTimeout避免阻塞UI渲染
|
||||
setTimeout(() => {
|
||||
processLargeData()
|
||||
}, 0)
|
||||
|
||||
// 绛夊緟Dify澶勭悊鏂囨。锛屾渶澶氶噸璇?0娆?for (let i = 0; i < 10; i++) {
|
||||
// 等待Dify处理文档,最多重试10次
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const status = await checkStatus()
|
||||
if (status === 'completed') break
|
||||
await sleep(2000)
|
||||
}
|
||||
|
||||
// 鉂?鍧忕殑娉ㄩ噴锛氶噸澶嶄唬鐮?// 璁剧疆loading涓簍rue
|
||||
// ❌ 坏的注释:重复代码
|
||||
// 设置loading为true
|
||||
setLoading(true)
|
||||
|
||||
// 调用API
|
||||
@@ -845,10 +894,10 @@ await api.getData()
|
||||
|
||||
| 类型 | 说明 |
|
||||
|------|------|
|
||||
| feat | 鏂板姛鑳?|
|
||||
| feat | 新功能 |
|
||||
| fix | Bug修复 |
|
||||
| docs | 文档更新 |
|
||||
| style | 浠g爜鏍煎紡锛堜笉褰卞搷鍔熻兘锛?|
|
||||
| style | 代码格式(不影响功能) |
|
||||
| refactor | 重构 |
|
||||
| perf | 性能优化 |
|
||||
| test | 测试相关 |
|
||||
@@ -863,8 +912,11 @@ git commit -m "fix(project): 修复项目删除权限问题"
|
||||
git commit -m "docs(api): 更新API文档"
|
||||
git commit -m "refactor(chat): 优化消息组件结构"
|
||||
|
||||
# 涓嶅ソ鐨勬彁浜?git commit -m "update" # 鉂?澶<>ā绯?git commit -m "fix bug" # 鉂?娌℃湁璇存槑鏄<E6A791>粈涔坆ug
|
||||
git commit -m "瀹屾垚鍔熻兘" # 鉂?娌℃湁璇存槑鏄<E6A791>粈涔堝姛鑳?```
|
||||
# 不好的提交
|
||||
git commit -m "update" # ❌ 太模糊
|
||||
git commit -m "fix bug" # ❌ 没有说明是什么bug
|
||||
git commit -m "完成功能" # ❌ 没有说明是什么功能
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -907,30 +959,36 @@ module.exports = {
|
||||
|
||||
---
|
||||
|
||||
## 浠g爜Review妫€鏌ユ竻鍗?
|
||||
## 代码Review检查清单
|
||||
|
||||
### 功能
|
||||
- [ ] 功能是否完整实现
|
||||
- [ ] 是否有遗漏的边界情况
|
||||
- [ ] 错误处理是否完善
|
||||
|
||||
### 代码质量
|
||||
- [ ] 浠g爜鏄<EFBFBD>惁鏄撹<EFBFBD>鏄撶悊瑙?- [ ] 鏄<>惁鏈夐噸澶嶄唬鐮?- [ ] 鍑芥暟鏄<E69A9F>惁杩囬暱锛堝缓璁?50琛岋級
|
||||
- [ ] 代码是否易读易理解
|
||||
- [ ] 是否有重复代码
|
||||
- [ ] 函数是否过长(建议<50行)
|
||||
- [ ] 是否遵守命名规范
|
||||
|
||||
### 性能
|
||||
- [ ] 是否有性能问题
|
||||
- [ ] 是否有不必要的重渲染
|
||||
- [ ] 鏁版嵁搴撴煡璇㈡槸鍚︿紭鍖?
|
||||
- [ ] 数据库查询是否优化
|
||||
|
||||
### 安全
|
||||
- [ ] 是否有SQL注入风险
|
||||
- [ ] 是否有XSS风险
|
||||
- [ ] 权限验证是否完善
|
||||
|
||||
### 测试
|
||||
- [ ] 鏄<EFBFBD>惁鏈夊崟鍏冩祴璇?- [ ] 娴嬭瘯瑕嗙洊鐜囨槸鍚﹁冻澶?
|
||||
- [ ] 是否有单元测试
|
||||
- [ ] 测试覆盖率是否足够
|
||||
|
||||
---
|
||||
|
||||
**鏂囨。缁存姢锛?* 瑙勮寖鏇存柊闇€鍚屾<E98D9A>姝ゆ枃妗?
|
||||
**文档维护:** 规范更新需同步此文档
|
||||
**最后更新:** 2025-10-10
|
||||
**维护者:** 技术负责人
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,42 +1,47 @@
|
||||
# 鈭穃<EFBFBD><EFBFBD>笔<EFBFBD><EFBFBD>𤏸<EFBFBD><EFBFBD>?
|
||||
> **<2A><>﹝<EFBFBD><EFB99D>𧋦嚗?* V1.1
|
||||
> **<EFBFBD>𥕦遣<EFBFBD>交<EFBFBD>嚗?* 2025-11-16
|
||||
# 云原生开发规范
|
||||
|
||||
> **文档版本:** V1.1
|
||||
> **创建日期:** 2025-11-16
|
||||
> **最后更新:** 2025-12-13 🏆 **Postgres-Only 架构规范新增**
|
||||
> **<EFBFBD><EFBFBD>鍂撖寡情嚗?* <20><><EFBFBD>匧<EFBFBD><E58CA7>睲犖<E79DB2>?
|
||||
> **撘箏<EFBFBD><EFBFBD>改<EFBFBD>** <20>?敹<>◆<EFBFBD>萄<EFBFBD>
|
||||
> **适用对象:** 所有开发人员
|
||||
> **强制性:** ✅ 必须遵守
|
||||
> **维护者:** 架构团队
|
||||
|
||||
---
|
||||
|
||||
## 📋 文档说明
|
||||
|
||||
<EFBFBD>祆<EFBFBD>獢<EFBFBD><EFBFBD>銋劐<EFBFBD><EFBFBD>毺<EFBFBD><EFBFBD>臬<EFBFBD>嚗𠄎erverless SAE + RDS + OSS嚗劐<EFBFBD><EFBFBD>?*隞<><E99A9E>閫<EFBFBD><E996AB>**嚗峕<E59A97><E5B395>劐<EFBFBD><E58A90>⊥芋<E28AA5>梹<EFBFBD>ASL<53><4C>IA<49><41>KB蝑㚁<E89D91>敹<EFBFBD>◆<EFBFBD>萄<EFBFBD><E89084>?
|
||||
**<EFBFBD><EFBFBD>粉<EFBFBD>園𡢿**嚗?0 <20><><EFBFBD>
|
||||
**璉<EFBFBD><EFBFBD>仿<EFBFBD><EFBFBD>?*嚗𡁏<E59A97>甈∩誨<E288A9><E8AAA8><EFBFBD>鈭文<E988AD>
|
||||
本文档定义云原生环境(Serverless SAE + RDS + OSS)下的**代码规范**,所有业务模块(ASL、AIA、PKB等)必须遵守。
|
||||
|
||||
**阅读时间**:10 分钟
|
||||
**检查频率**:每次代码提交前
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD><EFBFBD> <20>詨<EFBFBD><E8A9A8>笔<EFBFBD>嚗𡁜<E59A97><F0A1819C>典像<E585B8>啗<EFBFBD><E59597>?
|
||||
> **潃?<3F>滩<EFBFBD><E6BBA9>鞟內嚗?025-11-16 <20>湔鰵嚗?*嚗𡁜像<F0A1819C>啣歇<E595A3>𣂷<EFBFBD>摰峕㟲<E5B395><E39FB2>抅蝖<E68A85>霈暹鴌<E69AB9>滚𦛚
|
||||
## 🌟 核心原则:复用平台能力
|
||||
|
||||
> **⭐ 重要提示(2025-11-16 更新)**:平台已提供完整的基础设施服务
|
||||
> **详细文档**:[平台基础设施规划](../09-架构实施/04-平台基础设施规划.md)
|
||||
|
||||
### 平台已提供的服务
|
||||
|
||||
**业务模块(ASL/AIA/PKB/DC等)应该复用以下平台能力,禁止重复实现:**
|
||||
|
||||
| <EFBFBD>滚𦛚 | 撖澆<E69296><E6BE86>孵<EFBFBD> | <20>券<EFBFBD>?| <20><>﹝ |
|
||||
| 服务 | 导入方式 | 用途 | 文档 |
|
||||
|------|---------|------|------|
|
||||
| **摮睃<EFBFBD><EFBFBD>滚𦛚** | `import { storage } from '@/common/storage'` | <EFBFBD><EFBFBD>辣銝𠹺<EFBFBD>銝贝蝸 | <20>?撟喳蝱蝥?|
|
||||
| **<EFBFBD>亙<EFBFBD>蝟餌<EFBFBD>** | `import { logger } from '@/common/logging'` | <EFBFBD><EFBFBD><EFBFBD><EFBFBD>𡝗𠯫敹?| <20>?撟喳蝱蝥?|
|
||||
| **撘<EFBFBD>郊隞餃𦛚** | `import { jobQueue } from '@/common/jobs'` | <EFBFBD>踵𧒄<EFBFBD>港遙<EFBFBD>?| <20>?撟喳蝱蝥?|
|
||||
| **蝻枏<EFBFBD><EFBFBD>滚𦛚** | `import { cache } from '@/common/cache'` | <EFBFBD><EFBFBD><EFBFBD>撘讐<EFBFBD>摮?| <20>?撟喳蝱蝥?|
|
||||
| **<EFBFBD><EFBFBD> <20>剔<EFBFBD>蝏凋<E89D8F>** | `import { CheckpointService } from '@/common/jobs'` | 隞餃𦛚<EFBFBD>剔<EFBFBD>蝞∠<EFBFBD> | <20>?撟喳蝱蝥改<E89DA5><E694B9>堆<EFBFBD> |
|
||||
| **<EFBFBD>唳旿摨?* | `import { prisma } from '@/config/database'` | <EFBFBD>唳旿摨𤘪<EFBFBD>雿?| <20>?撟喳蝱蝥?|
|
||||
| **LLM<EFBFBD>賢<EFBFBD>** | `import { LLMFactory } from '@/common/llm'` | LLM靚<EFBFBD>鍂 | <20>?撟喳蝱蝥?|
|
||||
| **存储服务** | `import { storage } from '@/common/storage'` | 文件上传下载 | ✅ 平台级 |
|
||||
| **日志系统** | `import { logger } from '@/common/logging'` | 标准化日志 | ✅ 平台级 |
|
||||
| **异步任务** | `import { jobQueue } from '@/common/jobs'` | 长时间任务 | ✅ 平台级 |
|
||||
| **缓存服务** | `import { cache } from '@/common/cache'` | 分布式缓存 | ✅ 平台级 |
|
||||
| **🏆 断点续传** | `import { CheckpointService } from '@/common/jobs'` | 任务断点管理 | ✅ 平台级(新) |
|
||||
| **数据库** | `import { prisma } from '@/config/database'` | 数据库操作 | ✅ 平台级 |
|
||||
| **LLM能力** | `import { LLMFactory } from '@/common/llm'` | LLM调用 | ✅ 平台级 |
|
||||
|
||||
### 示例:正确使用平台服务
|
||||
|
||||
### 蝷箔<E89DB7>嚗𡁏迤蝖桐蝙<E6A190>典像<E585B8>唳<EFBFBD><E594B3>?
|
||||
```typescript
|
||||
// <EFBFBD>?甇<>&嚗𡁶凒<F0A181B6>亙紡<E4BA99>亙像<E4BA99>唳<EFBFBD><E594B3>?import { storage } from '@/common/storage'
|
||||
// ✅ 正确:直接导入平台服务
|
||||
import { storage } from '@/common/storage'
|
||||
import { logger } from '@/common/logging'
|
||||
import { jobQueue } from '@/common/jobs'
|
||||
import { prisma } from '@/config/database'
|
||||
@@ -50,7 +55,8 @@ export class LiteratureService {
|
||||
// 2. 使用平台日志系统
|
||||
logger.info('PDF uploaded', { projectId, url })
|
||||
|
||||
// 3. 雿輻鍂撟喳蝱<EFBFBD>唳旿摨? const literature = await prisma.aslLiterature.create({
|
||||
// 3. 使用平台数据库
|
||||
const literature = await prisma.aslLiterature.create({
|
||||
data: { projectId, pdfUrl: url }
|
||||
})
|
||||
|
||||
@@ -59,26 +65,36 @@ export class LiteratureService {
|
||||
}
|
||||
```
|
||||
|
||||
### <EFBFBD>?<3F>躰秤嚗𡁻<E59A97>憭滚<E686AD><E6BB9A>啣像<E595A3>啗<EFBFBD><E59597>?
|
||||
### ❌ 错误:重复实现平台能力
|
||||
|
||||
```typescript
|
||||
// <EFBFBD>?<3F>躰秤嚗𡁜銁銝𡁜𦛚璅∪<E79285>銝剛䌊撌勗<E6928C><E58B97>啣<EFBFBD><E595A3>?// backend/src/modules/asl/storage/LocalStorage.ts <20>?銝滚<E98A9D>霂亙<E99C82><E4BA99>剁<EFBFBD>
|
||||
// ❌ 错误:在业务模块中自己实现存储
|
||||
// backend/src/modules/asl/storage/LocalStorage.ts ← 不应该存在!
|
||||
export class LocalStorage {
|
||||
async upload(file: Buffer) {
|
||||
await fs.writeFile('./uploads/file.pdf', file) // <EFBFBD>?<3F>滚<EFBFBD>摰䂿緵
|
||||
await fs.writeFile('./uploads/file.pdf', file) // ❌ 重复实现
|
||||
}
|
||||
}
|
||||
|
||||
// <EFBFBD>?<3F>躰秤嚗𡁜銁銝𡁜𦛚璅∪<E79285>銝剛䌊撌勗<E6928C><E58B97>唳𠯫敹?// backend/src/modules/asl/logger/logger.ts <20>?銝滚<E98A9D>霂亙<E99C82><E4BA99>剁<EFBFBD>
|
||||
export const logger = winston.createLogger({...}) // <20>?<3F>滚<EFBFBD>摰䂿緵
|
||||
// ❌ 错误:在业务模块中自己实现日志
|
||||
// backend/src/modules/asl/logger/logger.ts ← 不应该存在!
|
||||
export const logger = winston.createLogger({...}) // ❌ 重复实现
|
||||
```
|
||||
|
||||
**<EFBFBD>笔<EFBFBD>**嚗?- <20>?<3F>滚<EFBFBD>隞<EFBFBD><E99A9E>嚗屸𠗕隞亦輕<E4BAA6>?- <20>?銝滚<E98A9D>璅∪<E79285>摰䂿緵銝滢<E98A9D><E6BBA2>?- <20>?<3F>䭾<EFBFBD>蝏煺<E89D8F><E785BA><EFBFBD>揢<EFBFBD>臬<EFBFBD>嚗<EFBFBD>𧋦<EFBFBD>?鈭𤑳垢嚗?- <20>?瘚芾晶撘<E699B6><E69298>烐𧒄<E78390>?
|
||||
**原因**:
|
||||
- ❌ 重复代码,难以维护
|
||||
- ❌ 不同模块实现不一致
|
||||
- ❌ 无法统一切换环境(本地/云端)
|
||||
- ❌ 浪费开发时间
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD>?<3F>刻<EFBFBD><E588BB>𡁏<EFBFBD>嚗㇄O嚗?
|
||||
### 1. <20><>辣摮睃<E691AE> <20>?
|
||||
## ✅ 推荐做法(DO)
|
||||
|
||||
### 1. 文件存储 ✅
|
||||
|
||||
```typescript
|
||||
// <EFBFBD>?甇<>&嚗帋蝙<E5B88B>典<EFBFBD><E585B8>冽𡂝鞊∪<E99E8A>
|
||||
// ✅ 正确:使用存储抽象层
|
||||
import { storage } from '@/common/storage/StorageFactory'
|
||||
|
||||
export async function uploadFile(file: Buffer, filename: string) {
|
||||
@@ -87,7 +103,8 @@ export async function uploadFile(file: Buffer, filename: string) {
|
||||
return url
|
||||
}
|
||||
|
||||
// <EFBFBD>?甇<>&嚗鍃xcel <20>湔𦻖隞𤾸<E99A9E>摮䁅圾<E48185>?import * as xlsx from 'xlsx'
|
||||
// ✅ 正确:Excel 直接从内存解析
|
||||
import * as xlsx from 'xlsx'
|
||||
|
||||
export async function importExcel(buffer: Buffer) {
|
||||
const workbook = xlsx.read(buffer, { type: 'buffer' }) // 内存解析
|
||||
@@ -96,35 +113,42 @@ export async function importExcel(buffer: Buffer) {
|
||||
}
|
||||
```
|
||||
|
||||
**<EFBFBD><EFBFBD>眏**嚗?- 摰孵膥<E5ADB5>滚鍳銝滢<E98A9D>銝W仃<EFBCB7><E4BB83>辣
|
||||
- <EFBFBD>砍𧑐撘<EFBFBD><EFBFBD>穃<EFBFBD><EFBFBD>煺漣<EFBFBD>臬<EFBFBD>隞<EFBFBD><EFBFBD>銝<EFBFBD><EFBFBD>?- <20>芸𢆡<E88AB8>寞旿<E5AF9E>臬<EFBFBD><E887AC>㗛<EFBFBD><E3979B><EFBFBD>揢摮睃<E691AE><E79D83>孵<EFBFBD>
|
||||
**理由**:
|
||||
- 容器重启不会丢失文件
|
||||
- 本地开发和生产环境代码一致
|
||||
- 自动根据环境变量切换存储方式
|
||||
|
||||
---
|
||||
|
||||
### 2. <EFBFBD>唳旿摨栞<EFBFBD><EFBFBD>?<3F>?
|
||||
### 2. 数据库连接 ✅
|
||||
|
||||
```typescript
|
||||
// <EFBFBD>?甇<>&嚗帋蝙<E5B88B>典<EFBFBD>撅<EFBFBD> Prisma Client
|
||||
// ✅ 正确:使用全局 Prisma Client
|
||||
import { prisma } from '@/config/database'
|
||||
|
||||
export async function createProject(data: any) {
|
||||
return await prisma.aslScreeningProject.create({ data })
|
||||
}
|
||||
|
||||
// <EFBFBD>?甇<>&嚗𡁏鸌<F0A1818F>𤩺<EFBFBD>雿靝蝙<E99D9D>其<EFBFBD><E585B6>?export async function importLiteratures(literatures: any[]) {
|
||||
// ✅ 正确:批量操作使用事务
|
||||
export async function importLiteratures(literatures: any[]) {
|
||||
return await prisma.$transaction(async (tx) => {
|
||||
return await tx.aslLiterature.createMany({ data: literatures })
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
**<EFBFBD><EFBFBD>眏**嚗?- <20>典<EFBFBD>摰硺<E691B0>憭滨鍂餈墧𦻖
|
||||
**理由**:
|
||||
- 全局实例复用连接
|
||||
- 避免连接数耗尽
|
||||
- 鈭见𦛚靽肽<EFBFBD><EFBFBD>唳旿銝<EFBFBD><EFBFBD>湔<EFBFBD>?
|
||||
- 事务保证数据一致性
|
||||
|
||||
---
|
||||
|
||||
### 3. <EFBFBD>臬<EFBFBD><EFBFBD>㗛<EFBFBD><EFBFBD>滨蔭 <20>?
|
||||
### 3. 环境变量配置 ✅
|
||||
|
||||
```typescript
|
||||
// <EFBFBD>?甇<>&嚗𡁶<E59A97>銝<EFBFBD><E98A9D>滨蔭蝞∠<E89D9E>
|
||||
// ✅ 正确:统一配置管理
|
||||
// backend/src/config/env.ts
|
||||
export const config = {
|
||||
llm: {
|
||||
@@ -140,19 +164,22 @@ export const config = {
|
||||
}
|
||||
}
|
||||
|
||||
// <EFBFBD>?甇<>&嚗帋蝙<E5B88B>券<EFBFBD>蝵桀笆鞊?import { config } from '@/config/env'
|
||||
// ✅ 正确:使用配置对象
|
||||
import { config } from '@/config/env'
|
||||
const apiKey = config.llm.apiKey
|
||||
```
|
||||
|
||||
**<EFBFBD><EFBFBD>眏**嚗?- <20>滨蔭<E6BBA8><E894AD>葉蝞∠<E89D9E>
|
||||
**理由**:
|
||||
- 配置集中管理
|
||||
- 类型安全
|
||||
- 便于切换环境
|
||||
|
||||
---
|
||||
|
||||
### 4. <EFBFBD>踵𧒄<EFBFBD>港遙<EFBFBD>∪<EFBFBD><EFBFBD>?<3F>?
|
||||
### 4. 长时间任务处理 ✅
|
||||
|
||||
```typescript
|
||||
// <EFBFBD>?甇<>&嚗𡁜<E59A97>甇乩遙<E4B9A9>?+ 餈𥕦漲頧株砭
|
||||
// ✅ 正确:异步任务 + 进度轮询
|
||||
export async function startScreening(req, res) {
|
||||
// 1. 创建任务记录
|
||||
const task = await prisma.aslScreeningTask.create({
|
||||
@@ -166,8 +193,9 @@ export async function startScreening(req, res) {
|
||||
// 2. 立即返回任务ID
|
||||
res.send({ success: true, taskId: task.id })
|
||||
|
||||
// 3. <EFBFBD>𤾸蝱撘<EFBFBD>郊<EFBFBD>扯<EFBFBD>嚗<EFBFBD><EFBFBD><EFBFBD>餃<EFBFBD>霂瑟<EFBFBD>嚗? processScreeningAsync(task.id).catch(err => {
|
||||
console.error('蝑偦<E89D91>劐遙<E58A90>∪仃韐?', err)
|
||||
// 3. 后台异步执行(不阻塞请求)
|
||||
processScreeningAsync(task.id).catch(err => {
|
||||
console.error('筛选任务失败:', err)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -184,16 +212,20 @@ export async function getTaskProgress(req, res) {
|
||||
}
|
||||
```
|
||||
|
||||
**<EFBFBD><EFBFBD>眏**嚗?- <20>踹<EFBFBD>霂瑟<E99C82>頞<EFBFBD>𧒄嚗𠄎AE暺䁅恕30蝘𡜐<E89D98>
|
||||
**理由**:
|
||||
- 避免请求超时(SAE默认30秒)
|
||||
- 用户体验更好
|
||||
- 支持批量任务
|
||||
|
||||
**<EFBFBD>?摰峕㟲摰噼殿<E599BC><E6AEBF><EFBFBD>?*嚗?霂西<E99C82> [Postgres-Only撘<79>郊隞餃𦛚憭<F0A69B9A><E686AD><EFBFBD><EFBFBD><EFBFBD>](../02-<2D>𡁶鍂<F0A181B6>賢<EFBFBD>撅?Postgres-Only撘<79>郊隞餃𦛚憭<F0A69B9A><E686AD><EFBFBD><EFBFBD><EFBFBD>.md)嚗<>抅鈭𥟠C Tool C摰峕㟲摰噼殿嚗?
|
||||
**✨ 完整实践参考**:
|
||||
详见 [Postgres-Only异步任务处理指南](../02-通用能力层/Postgres-Only异步任务处理指南.md)(基于DC Tool C完整实践)
|
||||
|
||||
---
|
||||
|
||||
### 5. <EFBFBD>亙<EFBFBD>颲枏枂 <20>?
|
||||
### 5. 日志输出 ✅
|
||||
|
||||
```typescript
|
||||
// <EFBFBD>?甇<>&嚗帋蝙<E5B88B>?logger 颲枏枂<EFBFBD>?stdout
|
||||
// ✅ 正确:使用 logger 输出到 stdout
|
||||
import pino from 'pino'
|
||||
|
||||
const logger = pino({
|
||||
@@ -209,7 +241,7 @@ export async function uploadFile(req, res) {
|
||||
// ... 上传逻辑
|
||||
}
|
||||
|
||||
// <EFBFBD>?甇<>&嚗𡁶<E59A97><F0A181B6><EFBFBD><EFBFBD><EFBFBD>亙<EFBFBD>
|
||||
// ✅ 正确:结构化日志
|
||||
logger.error({
|
||||
error: err.message,
|
||||
stack: err.stack,
|
||||
@@ -217,13 +249,17 @@ logger.error({
|
||||
}, 'Upload failed')
|
||||
```
|
||||
|
||||
**<EFBFBD><EFBFBD>眏**嚗?- SAE <20>芸𢆡<E88AB8><F0A286A1><EFBFBD> stdout <20>亙<EFBFBD>
|
||||
- 蝏𤘪<EFBFBD><EFBFBD>碶噶鈭擧䰻霂W<EFBFBD><EFBFBD>?- <20><>葉<EFBFBD>亦<EFBFBD>嚗䔶<E59A97>隡帋腺憭?
|
||||
**理由**:
|
||||
- SAE 自动采集 stdout 日志
|
||||
- 结构化便于查询分析
|
||||
- 集中查看,不会丢失
|
||||
|
||||
---
|
||||
|
||||
### 6. <EFBFBD>躰秤憭<EFBFBD><EFBFBD> <20>?
|
||||
### 6. 错误处理 ✅
|
||||
|
||||
```typescript
|
||||
// <EFBFBD>?甇<>&嚗𡁶<E59A97>銝<EFBFBD><E98A9D>躰秤憭<E7A7A4><E686AD>
|
||||
// ✅ 正确:统一错误处理
|
||||
export async function uploadPdf(req, res) {
|
||||
try {
|
||||
const file = await req.file()
|
||||
@@ -246,14 +282,17 @@ export async function uploadPdf(req, res) {
|
||||
}
|
||||
```
|
||||
|
||||
**<EFBFBD><EFBFBD>眏**嚗?- <20>冽<EFBFBD><E586BD>见<EFBFBD><E8A781>见末<E8A781>躰秤靽⊥<E99DBD>
|
||||
**理由**:
|
||||
- 用户看到友好错误信息
|
||||
- 日志记录详细错误
|
||||
- 銝齿𠂔<EFBFBD>脣<EFBFBD><EFBFBD>典<EFBFBD><EFBFBD>?
|
||||
- 不暴露内部实现
|
||||
|
||||
---
|
||||
|
||||
### 7. 銝湔𧒄<EFBFBD><EFBFBD>辣憭<EFBFBD><EFBFBD> <20>?
|
||||
### 7. 临时文件处理 ✅
|
||||
|
||||
```typescript
|
||||
// <EFBFBD>?甇<>&嚗?tmp <20>桀<EFBFBD><E6A180>典<EFBFBD>蝡见朖<E8A781>𣳇膄
|
||||
// ✅ 正确:/tmp 目录用完立即删除
|
||||
import fs from 'fs/promises'
|
||||
import path from 'path'
|
||||
|
||||
@@ -261,7 +300,7 @@ export async function extractPdfText(ossKey: string): Promise<string> {
|
||||
const tmpPath = path.join('/tmp', `${Date.now()}.pdf`)
|
||||
|
||||
try {
|
||||
// 1. 隞?OSS 銝贝蝸<EFBFBD>?/tmp
|
||||
// 1. 从 OSS 下载到 /tmp
|
||||
await storage.download(ossKey, tmpPath)
|
||||
|
||||
// 2. 提取文本
|
||||
@@ -279,43 +318,51 @@ export async function extractPdfText(ossKey: string): Promise<string> {
|
||||
}
|
||||
```
|
||||
|
||||
**<EFBFBD><EFBFBD>眏**嚗?- /tmp 摰寥<E691B0><E5AFA5>厰<EFBFBD>嚗?12MB嚗?- 摰孵膥<E5ADB5>滚鍳隡𡁏<E99AA1>蝛?- <20>踹<EFBFBD>蝤<EFBFBD><E89DA4><EFBFBD>䭾說
|
||||
**理由**:
|
||||
- /tmp 容量有限(512MB)
|
||||
- 容器重启会清空
|
||||
- 避免磁盘占满
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD><EFBFBD> Postgres-Only <EFBFBD>嗆<EFBFBD>閫<EFBFBD><EFBFBD>嚗?025-12-13 <EFBFBD>啣<EFBFBD>嚗?
|
||||
## 🏆 Postgres-Only 架构规范(2025-12-13 新增)
|
||||
|
||||
### 核心理念
|
||||
|
||||
**Platform-Only 璅∪<EFBFBD>**嚗𡁏<E59A97><F0A1818F>劐遙<E58A90>∠恣<E288A0><E681A3>縑<EFBFBD>舐<EFBFBD>銝<EFBFBD>摮睃<E691AE><E79D83>?`platform_schema.job.data`嚗䔶<EFBFBD><EFBFBD>∟”<EFBFBD>芸<EFBFBD><EFBFBD>其<EFBFBD><EFBFBD>∩縑<EFBFBD>胯<EFBFBD>?
|
||||
### 隞餃𦛚蝞∠<E89D9E><E288A0><EFBFBD>迤蝖桀<E89D96>瘜?
|
||||
#### <EFBFBD>?DO: 雿輻鍂 job.data 摮睃<E691AE>隞餃𦛚蝞∠<E89D9E>靽⊥<E99DBD>
|
||||
**Platform-Only 模式**:所有任务管理信息统一存储在 `platform_schema.job.data`,业务表只存储业务信息。
|
||||
|
||||
### 任务管理的正确做法
|
||||
|
||||
#### ✅ DO: 使用 job.data 存储任务管理信息
|
||||
|
||||
```typescript
|
||||
// <EFBFBD>?甇<>&嚗帋遙<E5B88B>⊥<EFBFBD><E28AA5><EFBFBD><EFBFBD><EFBFBD>剔<EFBFBD>靽⊥<E99DBD>摮睃<E691AE><E79D83>?job.data
|
||||
// ✅ 正确:任务拆分和断点信息存储在 job.data
|
||||
import { jobQueue } from '@/common/jobs';
|
||||
import { CheckpointService } from '@/common/jobs/CheckpointService';
|
||||
|
||||
// <EFBFBD>券<EFBFBD><EFBFBD>遙<EFBFBD>⊥𧒄嚗<EFBFBD><EFBFBD><EFBFBD>怠<EFBFBD><EFBFBD>港縑<EFBFBD>?await jobQueue.push('asl:screening:batch', {
|
||||
// 推送任务时,包含完整信息
|
||||
await jobQueue.push('asl:screening:batch', {
|
||||
// 业务信息
|
||||
taskId: 'xxx',
|
||||
projectId: 'yyy',
|
||||
literatureIds: [...],
|
||||
|
||||
// <EFBFBD>?隞餃𦛚<E9A483><F0A69B9A><EFBFBD>靽⊥<E99DBD>嚗<EFBFBD><E59A97><EFBFBD>典銁 job.data嚗? batchIndex: 3,
|
||||
// ✅ 任务拆分信息(存储在 job.data)
|
||||
batchIndex: 3,
|
||||
totalBatches: 20,
|
||||
startIndex: 150,
|
||||
endIndex: 200,
|
||||
|
||||
// <EFBFBD>?餈𥕦漲餈質葵
|
||||
// ✅ 进度追踪
|
||||
processedCount: 0,
|
||||
successCount: 0,
|
||||
failedCount: 0,
|
||||
});
|
||||
|
||||
// Worker 銝凋蝙<EFBFBD>?CheckpointService
|
||||
// Worker 中使用 CheckpointService
|
||||
const checkpointService = new CheckpointService(prisma);
|
||||
|
||||
// 靽嘥<EFBFBD><EFBFBD>剔<EFBFBD><EFBFBD>?job.data
|
||||
// 保存断点到 job.data
|
||||
await checkpointService.saveCheckpoint(job.id, {
|
||||
currentBatchIndex: 5,
|
||||
currentIndex: 250,
|
||||
@@ -323,39 +370,52 @@ await checkpointService.saveCheckpoint(job.id, {
|
||||
totalBatches: 20
|
||||
});
|
||||
|
||||
// <EFBFBD>㰘蝸<EFBFBD>剔<EFBFBD>隞?job.data
|
||||
// 加载断点从 job.data
|
||||
const checkpoint = await checkpointService.loadCheckpoint(job.id);
|
||||
if (checkpoint) {
|
||||
resumeFrom = checkpoint.currentIndex;
|
||||
}
|
||||
```
|
||||
|
||||
#### <EFBFBD>?DON'T: <EFBFBD>其<EFBFBD><EFBFBD>∟”銝剖<EFBFBD><EFBFBD>其遙<EFBFBD>∠恣<EFBFBD><EFBFBD>縑<EFBFBD>?
|
||||
#### ❌ DON'T: 在业务表中存储任务管理信息
|
||||
|
||||
```typescript
|
||||
// <EFBFBD>?<3F>躰秤嚗𡁜銁銝𡁜𦛚銵函<E98AB5> Schema 銝剜溶<E5899C>牐遙<E78990>∠恣<E288A0><E681A3><EFBFBD>畾?model AslScreeningTask {
|
||||
// ❌ 错误:在业务表的 Schema 中添加任务管理字段
|
||||
model AslScreeningTask {
|
||||
id String @id
|
||||
projectId String
|
||||
|
||||
// <EFBFBD>?銝滩<E98A9D>瘛餃<E7989B>餈嗘<E9A488>摮埈挾嚗? totalBatches Int // <20>?摨磰砲<E7A3B0>?job.data 銝? processedBatches Int // <20>?摨磰砲<E7A3B0>?job.data 銝? currentIndex Int // <20>?摨磰砲<E7A3B0>?job.data 銝? checkpointData Json? // <20>?摨磰砲<E7A3B0>?job.data 銝?}
|
||||
// ❌ 不要添加这些字段!
|
||||
totalBatches Int // ← 应该在 job.data 中
|
||||
processedBatches Int // ← 应该在 job.data 中
|
||||
currentIndex Int // ← 应该在 job.data 中
|
||||
checkpointData Json? // ← 应该在 job.data 中
|
||||
}
|
||||
|
||||
// <EFBFBD>?<3F>躰秤嚗朞䌊撌勗<E6928C><E58B97>唳鱏<E594B3>寞<EFBFBD><E5AF9E>?class MyCheckpointService {
|
||||
// ❌ 错误:自己实现断点服务
|
||||
class MyCheckpointService {
|
||||
async save(taskId: string) {
|
||||
await prisma.aslScreeningTask.update({
|
||||
where: { id: taskId },
|
||||
data: { checkpointData: {...} } // <EFBFBD>?銝滩<E98A9D>餈蹱甅<E8B9B1>𡄯<EFBFBD>
|
||||
data: { checkpointData: {...} } // ❌ 不要这样做!
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**为什么不对?**
|
||||
- <EFBFBD>?瘥譍葵璅∪<E79285><E288AA>質<EFBFBD>瘛餃<E7989B><E9A483>詨<EFBFBD><E8A9A8><EFBFBD><EFBFBD>畾蛛<E795BE>隞<EFBFBD><E99A9E><EFBFBD>滚<EFBFBD>嚗?- <20>?餈嘥<E9A488> DRY <20>笔<EFBFBD>
|
||||
- <EFBFBD>?餈嘥<E9A488> 3 撅<>沲<EFBFBD><E6B2B2><EFBFBD><EFBFBD>?- <20>?蝏湔擪<E6B994>圈𠗕嚗<F0A09795>耨<EFBFBD>寥<EFBFBD>餉<EFBFBD><E9A489><EFBFBD>閬<EFBFBD>㺿憭𡁜<E686AD>嚗?
|
||||
- ❌ 每个模块都要添加相同的字段(代码重复)
|
||||
- ❌ 违反 DRY 原则
|
||||
- ❌ 违反 3 层架构原则
|
||||
- ❌ 维护困难(修改逻辑需要改多处)
|
||||
|
||||
### 智能阈值判断的规范
|
||||
|
||||
#### <EFBFBD>?DO: 摰䂿緵<EFBFBD>箄<EFBFBD><EFBFBD>峕芋撘誩<EFBFBD><EFBFBD>?
|
||||
#### ✅ DO: 实现智能双模式处理
|
||||
|
||||
```typescript
|
||||
const QUEUE_THRESHOLD = 50; // <EFBFBD>刻<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
|
||||
const QUEUE_THRESHOLD = 50; // 推荐阈值
|
||||
|
||||
export async function startTask(items: any[]) {
|
||||
const useQueue = items.length >= QUEUE_THRESHOLD;
|
||||
|
||||
@@ -366,68 +426,84 @@ export async function startTask(items: any[]) {
|
||||
await jobQueue.push('task:batch', {...});
|
||||
}
|
||||
} else {
|
||||
// <EFBFBD>湔𦻖璅∪<EFBFBD>嚗𡁜<EFBFBD>隞餃𦛚嚗?50<35>∴<EFBFBD>
|
||||
processDirectly(items); // 敹恍<EFBFBD>笔<EFBFBD>摨? }
|
||||
// 直接模式:小任务(<50条)
|
||||
processDirectly(items); // 快速响应
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**銝箔<EFBFBD>銋<EFBFBD><EFBFBD><EFBFBD>瑕<EFBFBD>嚗?*
|
||||
- <EFBFBD>?撠譍遙<E8AD8D>∪翰<E288AA>笔<EFBFBD>摨䈑<E691A8><E48891>𣳇<EFBFBD><F0A3B387>堒辣餈<E8BEA3><E9A488>
|
||||
- <EFBFBD>?憭找遙<E689BE>⊿<EFBFBD><E28ABF>舫<EFBFBD>嚗<EFBFBD>𣈲<EFBFBD><F0A388B2>鱏<EFBFBD>寧賒隡𩤃<E99AA1>
|
||||
- <EFBFBD>?<3F>扯<EFBFBD>銝𤾸虾<F0A4BEB8>䭾<EFBFBD>批像銵?
|
||||
#### <20>?DON'T: <20><><EFBFBD>劐遙<E58A90>⊿<EFBFBD>韏圈<E99F8F><E59C88>?
|
||||
**为什么这样做?**
|
||||
- ✅ 小任务快速响应(无队列延迟)
|
||||
- ✅ 大任务高可靠(支持断点续传)
|
||||
- ✅ 性能与可靠性平衡
|
||||
|
||||
#### ❌ DON'T: 所有任务都走队列
|
||||
|
||||
```typescript
|
||||
// <EFBFBD>?<3F>躰秤嚗𡁜朖雿?<3F>∟扇敶蓥<E695B6>雿輻鍂<E8BCBB>笔<EFBFBD>
|
||||
// ❌ 错误:即使1条记录也使用队列
|
||||
export async function startTask(items: any[]) {
|
||||
// 无论多少数据,都推送到队列
|
||||
await jobQueue.push('task:batch', items); // <EFBFBD>?撠譍遙<E8AD8D>∩<EFBFBD><E288A9>匧辣餈?}
|
||||
await jobQueue.push('task:batch', items); // ❌ 小任务会有延迟
|
||||
}
|
||||
```
|
||||
|
||||
**为什么不对?**
|
||||
- <EFBFBD>?撠譍遙<E8AD8D>∪<EFBFBD>摨娍<E691A8>嚗<EFBFBD><E59A97><EFBFBD>埈<EFBFBD>頧株砭<E6A0AA>湧<EFBFBD>嚗?- <20>?瘚芾晶<E88ABE>笔<EFBFBD>韏<EFBFBD><E99F8F>
|
||||
- <EFBFBD>?<3F>冽<EFBFBD>雿㯄<E99BBF>撌?
|
||||
### <20><><EFBFBD>潭綫<E6BDAD>𣂼<EFBFBD>?
|
||||
| 隞餃𦛚蝐餃<E89D90> | <20>刻<EFBFBD><E588BB><EFBFBD><EFBFBD>?| <20><>眏 |
|
||||
- ❌ 小任务响应慢(队列有轮询间隔)
|
||||
- ❌ 浪费队列资源
|
||||
- ❌ 用户体验差
|
||||
|
||||
### 阈值推荐值
|
||||
|
||||
| 任务类型 | 推荐阈值 | 理由 |
|
||||
|---------|---------|------|
|
||||
| <EFBFBD><EFBFBD>讃蝑偦<EFBFBD>?| 50蝭?| <20>閧<EFBFBD>~7蝘𡜐<E89D98>50蝭㻬5<E3BBAC><35><EFBFBD> |
|
||||
| <EFBFBD>唳旿<EFBFBD>𣂼<EFBFBD> | 50<35>?| <20>閙辺~5-10蝘𡜐<E89D98>50<35>﹚5<EFB99A><35><EFBFBD> |
|
||||
| 蝏蠘恣璅∪<EFBFBD> | 30銝?| <20>蓥葵~10蝘𡜐<E89D98>30銝泠5<E6B3A0><35><EFBFBD> |
|
||||
| 暺䁅恕 | 50<EFBFBD>?| <20>𡁶鍂<F0A181B6>刻<EFBFBD><E588BB>?|
|
||||
| 文献筛选 | 50篇 | 单篇~7秒,50篇~5分钟 |
|
||||
| 数据提取 | 50条 | 单条~5-10秒,50条~5分钟 |
|
||||
| 统计模型 | 30个 | 单个~10秒,30个~5分钟 |
|
||||
| 默认 | 50条 | 通用推荐值 |
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD>?蝳<>迫<EFBFBD>𡁏<EFBFBD>嚗㇄ON'T嚗?
|
||||
### 1. <20>砍𧑐<E7A08D><F0A79190>辣摮睃<E691AE> <20>?
|
||||
## ❌ 禁止做法(DON'T)
|
||||
|
||||
### 1. 本地文件存储 ❌
|
||||
|
||||
```typescript
|
||||
// <EFBFBD>?蝳<>迫嚗𡁏𧋦<F0A1818F>唳<EFBFBD>隞嗥頂蝏笔<E89D8F><E7AC94>?import fs from 'fs'
|
||||
// ❌ 禁止:本地文件系统存储
|
||||
import fs from 'fs'
|
||||
|
||||
export async function uploadFile(req, res) {
|
||||
const file = await req.file()
|
||||
const buffer = await file.toBuffer()
|
||||
|
||||
// <EFBFBD>?<3F>躰秤嚗𡁜捆<F0A1819C>券<EFBFBD><E588B8>臭腺憭? fs.writeFileSync('./uploads/file.pdf', buffer)
|
||||
// ❌ 错误:容器重启丢失
|
||||
fs.writeFileSync('./uploads/file.pdf', buffer)
|
||||
|
||||
res.send({ url: '/uploads/file.pdf' })
|
||||
}
|
||||
|
||||
// <EFBFBD>?蝳<>迫嚗帋<E59A97>韏𡝗𧋦<F0A19D97>啗楝敺?const uploadDir = '/var/app/uploads'
|
||||
// ❌ 禁止:依赖本地路径
|
||||
const uploadDir = '/var/app/uploads'
|
||||
const filePath = path.join(uploadDir, filename)
|
||||
```
|
||||
|
||||
**<EFBFBD>桅<EFBFBD>**嚗?- 摰孵膥<E5ADB5>滚鍳<E6BB9A>𡝗<EFBFBD>摰孵<E691B0><E5ADB5><EFBFBD>辣銝W仃
|
||||
**问题**:
|
||||
- 容器重启或扩容后文件丢失
|
||||
- 多实例间无法共享文件
|
||||
- 磁盘空间有限
|
||||
|
||||
**甇<EFBFBD>&<EFBFBD>𡁏<EFBFBD>**嚗帋蝙<E5B88B>?`storage.upload()` 銝𠹺<EFBFBD><EFBFBD>?OSS
|
||||
**正确做法**:使用 `storage.upload()` 上传到 OSS
|
||||
|
||||
---
|
||||
|
||||
### 2. <EFBFBD><EFBFBD><EFBFBD>蝻枏<EFBFBD> <20>?
|
||||
### 2. 内存缓存 ❌
|
||||
|
||||
```typescript
|
||||
// <EFBFBD>?蝳<>迫嚗𡁜<E59A97>摮条<E691AE>摮矋<E691AE>憭𡁜<E686AD>靘衤<E99D98><E8A1A4>曹澈嚗?const cache = new Map<string, any>()
|
||||
// ❌ 禁止:内存缓存(多实例不共享)
|
||||
const cache = new Map<string, any>()
|
||||
|
||||
export async function getProject(id: string) {
|
||||
// <EFBFBD>?<3F>躰秤嚗𡁏<E59A97>摰孵<E691B0><E5ADB5>嗡<EFBFBD>摰硺<E691B0>霂颱<E99C82><E9A2B1>啁<EFBFBD>摮? if (cache.has(id)) {
|
||||
// ❌ 错误:扩容后其他实例读不到缓存
|
||||
if (cache.has(id)) {
|
||||
return cache.get(id)
|
||||
}
|
||||
|
||||
@@ -436,32 +512,42 @@ export async function getProject(id: string) {
|
||||
return project
|
||||
}
|
||||
|
||||
// <EFBFBD>?蝳<>迫嚗𡁜<E59A97>撅<EFBFBD><E69285>㗛<EFBFBD>摮睃<E691AE><E79D83>嗆<EFBFBD>?let taskStatus = {} // 憭𡁜<E686AD>靘衤<E99D98><E8A1A4>峕郊
|
||||
// ❌ 禁止:全局变量存储状态
|
||||
let taskStatus = {} // 多实例不同步
|
||||
```
|
||||
|
||||
**<EFBFBD>桅<EFBFBD>**嚗?- 憭𡁜<E686AD>靘钅𡢿<E99285>唳旿銝滚<E98A9D>甇?- <20>拙捆<E68B99>𡒊<EFBFBD>摮睃仃<E79D83>?- <20><><EFBFBD><EFBFBD>删鍂銝滚虾<E6BB9A>?
|
||||
**甇<>&<EFBFBD>𡁏<EFBFBD>**嚗帋蝙<E5B88B>?Redis <20>𡝗㺭<F0A19D97>桀<EFBFBD>
|
||||
**问题**:
|
||||
- 多实例间数据不同步
|
||||
- 扩容后缓存失效
|
||||
- 内存占用不可控
|
||||
|
||||
**正确做法**:使用 Redis 或数据库
|
||||
|
||||
---
|
||||
|
||||
### 3. 蝖祉<EFBFBD><EFBFBD><EFBFBD><EFBFBD>蝵?<3F>?
|
||||
### 3. 硬编码配置 ❌
|
||||
|
||||
```typescript
|
||||
// <EFBFBD>?蝳<>迫嚗𡁶′蝻𣇉<E89DBB>
|
||||
// ❌ 禁止:硬编码
|
||||
const LLM_API_KEY = 'sk-xxx'
|
||||
const DB_HOST = '192.168.1.100'
|
||||
const OSS_BUCKET = 'my-bucket'
|
||||
|
||||
// <EFBFBD>?蝳<>迫嚗𡁜<E59A97>甇餌垢<E9A48C>?app.listen(3001)
|
||||
// ❌ 禁止:写死端口
|
||||
app.listen(3001)
|
||||
|
||||
// <EFBFBD>?蝳<>迫嚗𡁜<E59A97>甇餃<E79487><E9A483>?const baseUrl = 'https://api.example.com'
|
||||
// ❌ 禁止:写死域名
|
||||
const baseUrl = 'https://api.example.com'
|
||||
```
|
||||
|
||||
**<EFBFBD>桅<EFBFBD>**嚗?- <20>䭾<EFBFBD><E4ADBE><EFBFBD>揢<EFBFBD>臬<EFBFBD>
|
||||
**问题**:
|
||||
- 无法切换环境
|
||||
- 安全风险(密钥泄露)
|
||||
- 部署困难
|
||||
|
||||
**甇<EFBFBD>&<EFBFBD>𡁏<EFBFBD>**嚗?```typescript
|
||||
// <20>?雿輻鍂<E8BCBB>臬<EFBFBD><E887AC>㗛<EFBFBD>
|
||||
**正确做法**:
|
||||
```typescript
|
||||
// ✅ 使用环境变量
|
||||
const apiKey = process.env.LLM_API_KEY
|
||||
const port = process.env.PORT || 3001
|
||||
app.listen(port)
|
||||
@@ -469,99 +555,124 @@ app.listen(port)
|
||||
|
||||
---
|
||||
|
||||
### 4. <EFBFBD>峕郊<EFBFBD>蹂遙<EFBFBD>?<3F>?
|
||||
### 4. 同步长任务 ❌
|
||||
|
||||
```typescript
|
||||
// <20>?蝳<>迫嚗𡁜<E59A97>甇亙<E79487><E4BA99><EFBFBD>鵭隞餃𦛚
|
||||
// ❌ 禁止:同步处理长任务
|
||||
export async function screenLiteratures(req, res) {
|
||||
const literatures = await prisma.aslLiterature.findMany({...})
|
||||
|
||||
// <EFBFBD>?<3F>躰秤嚗?00蝭<30>虾<EFBFBD>質<EFBFBD>餈?0蝘? for (const lit of literatures) {
|
||||
await llmScreening(lit) // 瘥讐<E798A5>2-3蝘? }
|
||||
// ❌ 错误:100篇可能超过30秒
|
||||
for (const lit of literatures) {
|
||||
await llmScreening(lit) // 每篇2-3秒
|
||||
}
|
||||
|
||||
res.send({ success: true }) // 可能已经超时
|
||||
}
|
||||
|
||||
// <EFBFBD>?蝳<>迫嚗𡁏瓷<F0A1818F>㕑<EFBFBD><E39591>嗡<EFBFBD><E597A1>?const result = await axios.get(url) // <20>航<EFBFBD>瘞訾<E7989E>蝑匧<E89D91>
|
||||
// ❌ 禁止:没有超时保护
|
||||
const result = await axios.get(url) // 可能永久等待
|
||||
```
|
||||
|
||||
**<EFBFBD>桅<EFBFBD>**嚗?- SAE 霂瑟<E99C82>頞<EFBFBD>𧒄 30 蝘?- <20>滨垢蝑匧<E89D91><E58CA7>園𡢿餈<F0A1A2BF>鵭
|
||||
**问题**:
|
||||
- SAE 请求超时 30 秒
|
||||
- 前端等待时间过长
|
||||
- 无法显示进度
|
||||
|
||||
**甇<EFBFBD>&<EFBFBD>𡁏<EFBFBD>**嚗𡁜<E59A97>甇乩遙<E4B9A9>?+ 餈𥕦漲頧株砭嚗<E7A0AD><E59A97> DO 蝚?<3F>∴<EFBFBD>
|
||||
**正确做法**:异步任务 + 进度轮询(见 DO 第4条)
|
||||
|
||||
---
|
||||
|
||||
### 5. <EFBFBD>砍𧑐<EFBFBD>亙<EFBFBD><EFBFBD><EFBFBD>辣 <20>?
|
||||
### 5. 本地日志文件 ❌
|
||||
|
||||
```typescript
|
||||
// <20>?蝳<>迫嚗𡁜<E59A97><F0A1819C>交𧋦<E4BAA4>唳<EFBFBD>隞?import fs from 'fs'
|
||||
// ❌ 禁止:写入本地文件
|
||||
import fs from 'fs'
|
||||
|
||||
export function logError(error: Error) {
|
||||
// <EFBFBD>?<3F>躰秤嚗𡁜捆<F0A1819C>券<EFBFBD><E588B8>臭腺憭梧<E686AD><E6A2A7>䭾<EFBFBD><E4ADBE><EFBFBD>葉<EFBFBD>亦<EFBFBD>
|
||||
// ❌ 错误:容器重启丢失,无法集中查看
|
||||
fs.appendFileSync('/var/log/app.log', error.message + '\n')
|
||||
}
|
||||
|
||||
// <EFBFBD>?蝳<>迫嚗帋蝙<E5B88B>?console.log <EFBFBD>䔶<EFBFBD><EFBFBD>?logger
|
||||
console.log('User logged in') // <EFBFBD>删<EFBFBD><EFBFBD><EFBFBD><EFBFBD>嚗屸𠗕隞交䰻霂?```
|
||||
// ❌ 禁止:使用 console.log 而不用 logger
|
||||
console.log('User logged in') // 无结构化,难以查询
|
||||
```
|
||||
|
||||
**<EFBFBD>桅<EFBFBD>**嚗?- 摰孵膥<E5ADB5>滚鍳<E6BB9A>亙<EFBFBD>銝W仃
|
||||
- 憭𡁜<E686AD>靘𧢲𠯫敹堒<E695B9><E5A092>?- <20>䭾<EFBFBD><E4ADBE><EFBFBD>葉<EFBFBD><E89189><EFBFBD>
|
||||
**问题**:
|
||||
- 容器重启日志丢失
|
||||
- 多实例日志分散
|
||||
- 无法集中分析
|
||||
|
||||
**甇<EFBFBD>&<EFBFBD>𡁏<EFBFBD>**嚗?```typescript
|
||||
// <20>?颲枏枂<E69E8F>?stdout嚗䔶蝙<E494B6>?logger
|
||||
**正确做法**:
|
||||
```typescript
|
||||
// ✅ 输出到 stdout,使用 logger
|
||||
logger.info({ userId, action: 'login' }, 'User logged in')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 6. <EFBFBD>啣遣<EFBFBD>唳旿摨栞<EFBFBD><EFBFBD>?<3F>?
|
||||
### 6. 新建数据库连接 ❌
|
||||
|
||||
```typescript
|
||||
// <20>?蝳<>迫嚗𡁏<E59A97>甈∟窈瘙<E7AA88>鰵撱箄<E692B1><E7AE84>?import { PrismaClient } from '@prisma/client'
|
||||
// ❌ 禁止:每次请求新建连接
|
||||
import { PrismaClient } from '@prisma/client'
|
||||
|
||||
export async function getProjects(req, res) {
|
||||
// <EFBFBD>?<3F>躰秤嚗𡁏<E59A97>甈⊥鰵撱綽<E692B1>餈墧𦻖<E5A2A7>唳𠂔憓? const prisma = new PrismaClient()
|
||||
// ❌ 错误:每次新建,连接数暴增
|
||||
const prisma = new PrismaClient()
|
||||
const projects = await prisma.aslScreeningProject.findMany()
|
||||
await prisma.$disconnect()
|
||||
|
||||
res.send(projects)
|
||||
}
|
||||
|
||||
// <EFBFBD>?蝳<>迫嚗𡁶凒<F0A181B6>乩蝙<E4B9A9>?pg <20>硋<EFBFBD>隞㚚店<E39A9A>?import { Pool } from 'pg'
|
||||
// ❌ 禁止:直接使用 pg 或其他驱动
|
||||
import { Pool } from 'pg'
|
||||
const pool = new Pool({ connectionString: process.env.DATABASE_URL })
|
||||
```
|
||||
|
||||
**<EFBFBD>桅<EFBFBD>**嚗?- 餈墧𦻖<E5A2A7>啣翰<E595A3>蠘<EFBFBD>堒偷嚗㇌DS<44>𣂼<EFBFBD> 400 餈墧𦻖嚗?- <20>扯<EFBFBD>雿𦒘<E99BBF>嚗<EFBFBD><E59A97><EFBFBD>亙遣蝡贝<E89DA1>埈𧒄嚗?- 韏<><E99F8F>瘚芾晶
|
||||
**问题**:
|
||||
- 连接数快速耗尽(RDS限制 400 连接)
|
||||
- 性能低下(连接建立耗时)
|
||||
- 资源浪费
|
||||
|
||||
**甇<EFBFBD>&<EFBFBD>𡁏<EFBFBD>**嚗?```typescript
|
||||
// <20>?雿輻鍂<E8BCBB>典<EFBFBD> Prisma Client
|
||||
**正确做法**:
|
||||
```typescript
|
||||
// ✅ 使用全局 Prisma Client
|
||||
import { prisma } from '@/config/database'
|
||||
const projects = await prisma.aslScreeningProject.findMany()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 7. 敹賜裦<EFBFBD>躰秤 <20>?
|
||||
### 7. 忽略错误 ❌
|
||||
|
||||
```typescript
|
||||
// <20>?蝳<>迫嚗𡁶征<F0A181B6>?catch
|
||||
// ❌ 禁止:空的 catch
|
||||
try {
|
||||
await storage.upload(key, buffer)
|
||||
} catch (error) {
|
||||
// <EFBFBD>?<3F>躰秤鋡怠<E98BA1><E680A0>㚁<EFBFBD><E39A81>䭾<EFBFBD><E4ADBE>埝䰻
|
||||
// ❌ 错误被吞掉,无法排查
|
||||
}
|
||||
|
||||
// <EFBFBD>?蝳<>迫嚗帋<E59A97>憭<EFBFBD><E686AD> Promise rejection
|
||||
// ❌ 禁止:不处理 Promise rejection
|
||||
processAsync(taskId) // 没有 .catch()
|
||||
|
||||
// <EFBFBD>?蝳<>迫嚗朞<E59A97><E69C9E>墧芋蝟𢠃<E89D9F>霂?catch (error) {
|
||||
// ❌ 禁止:返回模糊错误
|
||||
catch (error) {
|
||||
res.status(500).send({ error: 'Something went wrong' })
|
||||
// 用户不知道什么错了,如何解决
|
||||
}
|
||||
```
|
||||
|
||||
**<EFBFBD>桅<EFBFBD>**嚗?- <20>躰秤<E8BAB0>䭾<EFBFBD>餈質葵
|
||||
- <20>冽<EFBFBD>雿㯄<E99BBF>撌?- <20>埝䰻<E59F9D>圈𠗕
|
||||
**问题**:
|
||||
- 错误无法追踪
|
||||
- 用户体验差
|
||||
- 排查困难
|
||||
|
||||
**甇<EFBFBD>&<EFBFBD>𡁏<EFBFBD>**嚗?```typescript
|
||||
// <20>?霈啣<E99C88><E595A3>亙<EFBFBD> + <20>见末<E8A781>躰秤靽⊥<E99DBD>
|
||||
**正确做法**:
|
||||
```typescript
|
||||
// ✅ 记录日志 + 友好错误信息
|
||||
try {
|
||||
await storage.upload(key, buffer)
|
||||
} catch (error) {
|
||||
@@ -578,39 +689,57 @@ try {
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD><EFBFBD> 隞<><E99A9E>摰⊥䰻璉<E4B0BB><E79289>交<EFBFBD><E4BAA4>?
|
||||
<EFBFBD>?*<2A>𣂷漱隞<E6BCB1><E99A9E><EFBFBD>?*嚗諹窈<E8ABB9>鞾★璉<E29885><E79289>伐<EFBFBD>
|
||||
## 🔍 代码审查检查清单
|
||||
|
||||
在**提交代码前**,请逐项检查:
|
||||
|
||||
### 文件存储
|
||||
- [ ] <20>臬炏雿輻鍂 `storage.upload()` <20>屸<EFBFBD> `fs.writeFile()`嚗?- [ ] Excel <20>臬炏隞𤾸<E99A9E>摮䁅圾<E48185>琜<EFBFBD><E7909C>屸<EFBFBD>靽嘥<E99DBD><E598A5>唳𧋦<E594B3>堆<EFBFBD>
|
||||
- [ ] 是否使用 `storage.upload()` 而非 `fs.writeFile()`?
|
||||
- [ ] Excel 是否从内存解析,而非保存到本地?
|
||||
- [ ] PDF 提取后是否立即删除临时文件?
|
||||
|
||||
### <EFBFBD>唳旿摨?- [ ] <20>臬炏雿輻鍂<E8BCBB>典<EFBFBD> `prisma` 摰硺<E691B0>嚗?- [ ] <20>臬炏<E887AC>踹<EFBFBD><E8B8B9>典儐<E585B8>臭葉<E887AD>扯<EFBFBD><E689AF>閙辺<E99699>亥砭嚗<E7A0AD><E59A97>摨磰砲<E7A3B0>寥<EFBFBD><E5AFA5>滢<EFBFBD>嚗?- [ ] <20>寥<EFBFBD><E5AFA5>滢<EFBFBD><E6BBA2>臬炏雿輻鍂鈭见𦛚嚗?
|
||||
### 数据库
|
||||
- [ ] 是否使用全局 `prisma` 实例?
|
||||
- [ ] 是否避免在循环中执行单条查询?(应该批量操作)
|
||||
- [ ] 批量操作是否使用事务?
|
||||
|
||||
### 配置管理
|
||||
- [ ] <20>臬炏<E887AC><E7828F><EFBFBD>厰<EFBFBD>蝵桅<E89DB5>隞?`process.env` 霂餃<E99C82>嚗?- [ ] <20>臬炏瘝⊥<E7989D>蝖祉<E89D96><E7A589><EFBFBD><EFBFBD> IP<49><50><EFBFBD><EFBFBD>溻<EFBFBD><E6BABB><EFBFBD><EFBFBD>伐<EFBFBD>
|
||||
- [ ] 是否所有配置都从 `process.env` 读取?
|
||||
- [ ] 是否没有硬编码的 IP、域名、密钥?
|
||||
- [ ] `.env.example` 是否已更新?
|
||||
|
||||
### <EFBFBD>踵𧒄<EFBFBD>港遙<EFBFBD>?- [ ] 頞<><E9A09E> 10 蝘垍<E89D98>隞餃𦛚<E9A483>臬炏<E887AC>嫣蛹撘<E89BB9>郊嚗?- [ ] <20>臬炏<E887AC>𣂷<EFBFBD>鈭<EFBFBD><E988AD>摨行䰻霂X𦻖<EFBCB8><F0A6BB96><EFBFBD>
|
||||
- [ ] <20>滨垢<E6BBA8>臬炏<E887AC>㕑蔭霂X<E99C82> WebSocket <20>瑕<EFBFBD>餈𥕦漲嚗?
|
||||
### 长时间任务
|
||||
- [ ] 超过 10 秒的任务是否改为异步?
|
||||
- [ ] 是否提供了进度查询接口?
|
||||
- [ ] 前端是否有轮询或 WebSocket 获取进度?
|
||||
|
||||
### 日志
|
||||
- [ ] <20>臬炏雿輻鍂 `logger` <20>屸<EFBFBD> `console.log`嚗?- [ ] <20>亙<EFBFBD><E4BA99>臬炏蝏𤘪<E89D8F><F0A498AA>吔<EFBFBD>JSON<4F>澆<EFBFBD>嚗㚁<E59A97>
|
||||
- [ ] 是否使用 `logger` 而非 `console.log`?
|
||||
- [ ] 日志是否结构化(JSON格式)?
|
||||
- [ ] 是否记录了关键操作(userId、action)?
|
||||
|
||||
### 错误处理
|
||||
- [ ] <20><><EFBFBD>?async <20>賣㺭<E8B3A3>臬炏<E887AC>?try-catch嚗?- [ ] <20>臬炏霈啣<E99C88>鈭<EFBFBD>祕蝏<E7A595><E89D8F>霂舀𠯫敹梹<E695B9>
|
||||
- [ ] <20>臬炏餈𥪜<E9A488>鈭<EFBFBD><E988AD>憟賜<E6869F><E8B39C>躰秤靽⊥<E99DBD>嚗?
|
||||
- [ ] 所有 async 函数是否有 try-catch?
|
||||
- [ ] 是否记录了详细错误日志?
|
||||
- [ ] 是否返回了友好的错误信息?
|
||||
|
||||
### 临时文件
|
||||
- [ ] `/tmp` 目录使用后是否立即删除?
|
||||
- [ ] <20>臬炏<E887AC>?`finally` <20>𦯀葉皜<E89189><E79A9C>嚗?- [ ] <20>臬炏<E887AC>踹<EFBFBD><E8B8B9>踵<EFBFBD>靘肽<E99D98> `/tmp`嚗?
|
||||
- [ ] 是否在 `finally` 块中清理?
|
||||
- [ ] 是否避免长期依赖 `/tmp`?
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD>㴓 敹恍<E695B9>蠘䌊璉<E48C8A>嚗?<3F><><EFBFBD>嚗?
|
||||
**餈鞱<E9A488>隞乩<E99A9E><E4B9A9>賭誘嚗峕<E59A97><E5B395>乩誨<E4B9A9><E8AAA8>葉<EFBFBD>臬炏<E887AC>㕑<EFBFBD>閫?*嚗?
|
||||
## 🎯 快速自检(5分钟)
|
||||
|
||||
**运行以下命令,检查代码中是否有违规**:
|
||||
|
||||
```bash
|
||||
# 检查是否有本地文件存储
|
||||
grep -r "fs.writeFile\|fs.appendFile" backend/src/modules/
|
||||
|
||||
# 璉<EFBFBD><EFBFBD>交糓<EFBFBD>行<EFBFBD>蝖祉<EFBFBD><EFBFBD><EFBFBD><EFBFBD>蝵?grep -r "sk-\|http://\|192.168" backend/src/modules/
|
||||
# 检查是否有硬编码配置
|
||||
grep -r "sk-\|http://\|192.168" backend/src/modules/
|
||||
|
||||
# 检查是否有新建 Prisma 连接
|
||||
grep -r "new PrismaClient" backend/src/modules/
|
||||
@@ -619,14 +748,15 @@ grep -r "new PrismaClient" backend/src/modules/
|
||||
grep -r "console.log" backend/src/modules/
|
||||
```
|
||||
|
||||
**憸<EFBFBD><EFBFBD>蝏𤘪<EFBFBD>**嚗𡁏<E59A97><F0A1818F>㗇<EFBFBD><E39787>亙<EFBFBD>霂亥<E99C82><E4BAA5>?**0 銝芸龪<E88AB8>?*
|
||||
**预期结果**:所有检查应该返回 **0 个匹配**
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>獢?
|
||||
- [鈭穃<E988AD><E7A983>罸<EFBFBD>蝵脫沲<E884AB><E6B2B2><EFBFBD><EFBFBD>㻩(../09-<2D>嗆<EFBFBD>摰墧鴌/03-鈭穃<E988AD><E7A983>罸<EFBFBD>蝵脫沲<E884AB><E6B2B2><EFBFBD><EFBFBD>?md) - <20><>鉄摰峕㟲隞<E39FB2><E99A9E>蝷箔<E89DB7>
|
||||
## 📚 参考文档
|
||||
|
||||
- [云原生部署架构指南](../09-架构实施/03-云原生部署架构指南.md) - 包含完整代码示例
|
||||
- [前后端模块化架构设计-V2](../00-系统总体设计/前后端模块化架构设计-V2.md) - 架构总纲
|
||||
- [<EFBFBD>唳旿摨栞挽霈∟<EFBFBD><EFBFBD><EFBFBD>(./01-<2D>唳旿摨栞挽霈∟<E99C88><E2889F>?md)
|
||||
- [数据库设计规范](./01-数据库设计规范.md)
|
||||
- [API设计规范](./02-API设计规范.md)
|
||||
- [代码规范](./05-代码规范.md)
|
||||
- [Git提交规范](./06-Git提交规范.md)
|
||||
@@ -635,13 +765,14 @@ grep -r "console.log" backend/src/modules/
|
||||
|
||||
## 📝 更新日志
|
||||
|
||||
| <EFBFBD>交<EFBFBD> | <20><>𧋦 | <20>䀹凒<E480B9><E58792>捆 | 蝏湔擪<E6B994>?|
|
||||
| 日期 | 版本 | 变更内容 | 维护者 |
|
||||
|------|------|---------|--------|
|
||||
| 2025-11-16 | V1.0 | <EFBFBD>𥕦遣<EFBFBD><EFBFBD>﹝嚗<EFBFBD><EFBFBD>銋劐<EFBFBD><EFBFBD>毺<EFBFBD>撘<EFBFBD><EFBFBD>𤏸<EFBFBD><EFBFBD>?| <20>嗆<EFBFBD><E59786>a<EFBFBD> |
|
||||
| 2025-11-16 | V1.0 | 创建文档,定义云原生开发规范 | 架构团队 |
|
||||
|
||||
---
|
||||
|
||||
**文档维护者:** 架构团队
|
||||
**最后更新:** 2025-11-16
|
||||
**<EFBFBD><EFBFBD>﹝<EFBFBD>嗆<EFBFBD><EFBFBD><EFBFBD>** <20>?撌脣<E6928C><E884A3>?
|
||||
**撘箏<EFBFBD><EFBFBD>扯<EFBFBD>嚗?* <20>?<3F><><EFBFBD>劐誨<E58A90><E8AAA8><EFBFBD>鈭文<E988AD>敹<EFBFBD>◆璉<E29786><E79289>?
|
||||
**文档状态:** ✅ 已完成
|
||||
**强制执行:** ✅ 所有代码提交前必须检查
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# <EFBFBD>唳旿摨枏<EFBFBD><EFBFBD>𤏸<EFBFBD><EFBFBD>?
|
||||
# 数据库开发规范
|
||||
|
||||
> 版本: v1.0
|
||||
> 更新日期: 2026-01-11
|
||||
@@ -14,27 +14,27 @@
|
||||
⚠️ 黄金法则:任何数据库操作前,必须先备份!
|
||||
```
|
||||
|
||||
### 1.2 蝳<EFBFBD>迫雿輻鍂<EFBFBD><EFBFBD>暒<EFBFBD>拙𦶢隞?
|
||||
### 1.2 禁止使用的危险命令
|
||||
|
||||
| 命令 | 危险等级 | 说明 |
|
||||
|------|----------|------|
|
||||
| `prisma db push --force-reset` | <EFBFBD>𣞁 **<EFBFBD><EFBFBD><EFBFBD>** | 隡𡁜<EFBFBD><EFBFBD>斗<EFBFBD><EFBFBD>㗇㺭<EFBFBD>桀<EFBFBD><EFBFBD>鱲risma蝞∠<EFBFBD><EFBFBD><EFBFBD>笆鞊?|
|
||||
| `prisma migrate reset` | <EFBFBD>𣞁 **<EFBFBD><EFBFBD><EFBFBD>** | <EFBFBD>滨蔭<EFBFBD>港葵<EFBFBD>唳旿摨?|
|
||||
| `DROP DATABASE` | <EFBFBD>𣞁 **<EFBFBD><EFBFBD><EFBFBD>** | <EFBFBD>𣳇膄<EFBFBD>港葵<EFBFBD>唳旿摨?|
|
||||
| `TRUNCATE TABLE` | <EFBFBD><EFBFBD> 擃?| 皜<>征銵冽㺭<E586BD>?|
|
||||
| `prisma db push --force-reset` | 🔴 **极高** | 会删除所有数据和非Prisma管理的对象 |
|
||||
| `prisma migrate reset` | 🔴 **极高** | 重置整个数据库 |
|
||||
| `DROP DATABASE` | 🔴 **极高** | 删除整个数据库 |
|
||||
| `TRUNCATE TABLE` | 🟠 高 | 清空表数据 |
|
||||
|
||||
### 1.3 <EFBFBD>刻<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>典𦶢隞?
|
||||
### 1.3 推荐的安全命令
|
||||
|
||||
| <EFBFBD>賭誘 | <20>券<EFBFBD>?| 摰匧<E691B0><E58CA7>?|
|
||||
| 命令 | 用途 | 安全性 |
|
||||
|------|------|--------|
|
||||
| `prisma migrate dev` | 撘<EFBFBD><EFBFBD>𤑳㴓憓<EFBFBD><EFBFBD>蝘?| <20>?摰匧<E691B0> |
|
||||
| `prisma migrate deploy` | <EFBFBD>煺漣<EFBFBD>臬<EFBFBD>餈<EFBFBD>宏 | <20>?摰匧<E691B0> |
|
||||
| `prisma db push` (<EFBFBD>?--force-reset) | <EFBFBD>峕郊schema<EFBFBD>唳㺭<EFBFBD>桀<EFBFBD> | <20>𩤃<EFBFBD> 靚冽<E99D9A>雿輻鍂 |
|
||||
| `prisma generate` | <EFBFBD><EFBFBD><EFBFBD>摰X<EFBFBD>蝡?| <20>?摰匧<E691B0> |
|
||||
| `prisma migrate dev` | 开发环境迁移 | ✅ 安全 |
|
||||
| `prisma migrate deploy` | 生产环境迁移 | ✅ 安全 |
|
||||
| `prisma db push` (无 --force-reset) | 同步schema到数据库 | ⚠️ 谨慎使用 |
|
||||
| `prisma generate` | 生成客户端 | ✅ 安全 |
|
||||
|
||||
---
|
||||
|
||||
## 2. <EFBFBD>唳旿摨枏<EFBFBD>隞質<EFBFBD><EFBFBD>?
|
||||
## 2. 数据库备份规范
|
||||
|
||||
### 2.1 备份命令
|
||||
|
||||
@@ -51,11 +51,11 @@ docker exec ai-clinical-postgres pg_dump -U postgres -d ai_clinical_research > "
|
||||
|
||||
| 时机 | 是否必须 |
|
||||
|------|----------|
|
||||
| <EFBFBD>扯<EFBFBD>隞颱<EFBFBD> `prisma migrate` <EFBFBD>?| <20>?敹<>◆ |
|
||||
| <EFBFBD>扯<EFBFBD> `prisma db push` <EFBFBD>?| <20>?敹<>◆ |
|
||||
| <EFBFBD>函蔡<EFBFBD>啁<EFBFBD>鈭抒㴓憓<EFBFBD><EFBFBD> | <20>?敹<>◆ |
|
||||
| 瘥𤩺𠯫<EFBFBD>芸𢆡憭<EFBFBD>遢 | <20>?<3F>刻<EFBFBD> |
|
||||
| <EFBFBD>滚之<EFBFBD>蠘<EFBFBD><EFBFBD>穃<EFBFBD><EFBFBD>?| <20>?敹<>◆ |
|
||||
| 执行任何 `prisma migrate` 前 | ✅ 必须 |
|
||||
| 执行 `prisma db push` 前 | ✅ 必须 |
|
||||
| 部署到生产环境前 | ✅ 必须 |
|
||||
| 每日自动备份 | ✅ 推荐 |
|
||||
| 重大功能发布前 | ✅ 必须 |
|
||||
|
||||
### 2.3 备份文件管理
|
||||
|
||||
@@ -87,7 +87,7 @@ graph TD
|
||||
### 3.2 具体步骤
|
||||
|
||||
```bash
|
||||
# 1. 憭<EFBFBD>遢<EFBFBD>唳旿摨?
|
||||
# 1. 备份数据库
|
||||
docker exec ai-clinical-postgres pg_dump -U postgres -d ai_clinical_research > backup_before_migration.sql
|
||||
|
||||
# 2. 修改 schema.prisma
|
||||
@@ -100,36 +100,36 @@ cat prisma/migrations/xxx_describe_your_change/migration.sql
|
||||
|
||||
# 5. 测试
|
||||
|
||||
# 6. 憒<EFBFBD><EFBFBD>憭梯揖嚗峕<EFBFBD>憭滚<EFBFBD>隞?
|
||||
# 6. 如果失败,恢复备份
|
||||
cat backup_before_migration.sql | docker exec -i ai-clinical-postgres psql -U postgres -d ai_clinical_research
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Prisma 銝擧㺭<EFBFBD>桀<EFBFBD>銝滢<EFBFBD><EFBFBD>湧䔮憸?
|
||||
## 4. Prisma 与数据库不一致问题
|
||||
|
||||
### 4.1 Prisma 不管理的对象
|
||||
|
||||
隞乩<EFBFBD><EFBFBD>唳旿摨枏笆鞊∩<EFBFBD><EFBFBD>?`schema.prisma` 銝剖<EFBFBD>銋㚁<EFBFBD><EFBFBD><EFBFBD>閬<EFBFBD><EFBFBD><EFBFBD>祉恣<EFBFBD><EFBFBD><EFBFBD>
|
||||
以下数据库对象不在 `schema.prisma` 中定义,需要单独管理:
|
||||
|
||||
| 对象 | 类型 | 来源 | 恢复脚本 |
|
||||
|------|------|------|----------|
|
||||
| `platform_schema.job_common` | 銵?| pg-boss 餈鞱<EFBFBD><EFBFBD>嗅<EFBFBD>撱?| `restore_job_common.sql` |
|
||||
| `platform_schema.create_queue()` | <EFBFBD>賣㺭 | pg-boss <EFBFBD>嘥<EFBFBD><EFBFBD>?| `restore_pgboss_functions.sql` |
|
||||
| `platform_schema.delete_queue()` | <EFBFBD>賣㺭 | pg-boss <EFBFBD>嘥<EFBFBD><EFBFBD>?| `restore_pgboss_functions.sql` |
|
||||
| `platform_schema.job_common` | 表 | pg-boss 运行时创建 | `restore_job_common.sql` |
|
||||
| `platform_schema.create_queue()` | 函数 | pg-boss 初始化 | `restore_pgboss_functions.sql` |
|
||||
| `platform_schema.delete_queue()` | 函数 | pg-boss 初始化 | `restore_pgboss_functions.sql` |
|
||||
|
||||
### 4.2 <EFBFBD>W<EFBFBD><EFBFBD>?Prisma 蝞∠<EFBFBD><EFBFBD><EFBFBD>笆鞊?
|
||||
### 4.2 恢复非 Prisma 管理的对象
|
||||
|
||||
```bash
|
||||
# 憒<EFBFBD><EFBFBD>霂臬<EFBFBD>鈭?pg-boss <20>詨<EFBFBD>撖寡情嚗峕<E59A97>銵䕘<E98AB5>
|
||||
# 如果误删了 pg-boss 相关对象,执行:
|
||||
npx prisma db execute --file restore_job_common.sql --schema prisma/schema.prisma
|
||||
npx prisma db execute --file restore_pgboss_functions.sql --schema prisma/schema.prisma
|
||||
```
|
||||
|
||||
### 4.3 璉<EFBFBD><EFBFBD>交㺭<EFBFBD>桀<EFBFBD>銝?Prisma 銝<EFBFBD><EFBFBD>湔<EFBFBD>?
|
||||
### 4.3 检查数据库与 Prisma 一致性
|
||||
|
||||
```bash
|
||||
# <EFBFBD>亦<EFBFBD><EFBFBD>唳旿摨㮖葉<EFBFBD><EFBFBD>遆<EFBFBD>?
|
||||
# 查看数据库中的函数
|
||||
SELECT routine_name FROM information_schema.routines WHERE routine_schema = 'platform_schema';
|
||||
|
||||
# 查看数据库中的表
|
||||
@@ -140,29 +140,29 @@ SELECT table_name FROM information_schema.tables WHERE table_schema = 'platform_
|
||||
|
||||
---
|
||||
|
||||
## 5. 憭?Schema <EFBFBD>嗆<EFBFBD>閫<EFBFBD><EFBFBD>
|
||||
## 5. 多 Schema 架构规范
|
||||
|
||||
### 5.1 Schema 命名规范
|
||||
|
||||
| Schema | <EFBFBD>券<EFBFBD>?| 蝷箔<E89DB7>銵?|
|
||||
| Schema | 用途 | 示例表 |
|
||||
|--------|------|--------|
|
||||
| `platform_schema` | 平台基础设施 | users, tenants, app_cache |
|
||||
| `admin_schema` | 运营管理 | admin_operation_logs |
|
||||
| `aia_schema` | AI智能问答 | conversations, messages |
|
||||
| `asl_schema` | <EFBFBD><EFBFBD>讃蝑偦<EFBFBD>?| screening_projects, literatures |
|
||||
| `asl_schema` | 文献筛选 | screening_projects, literatures |
|
||||
| `dc_schema` | 数据清洗 | dc_templates, dc_extraction_tasks |
|
||||
| `pkb_schema` | 銝芯犖<EFBFBD>亥<EFBFBD>摨?| knowledge_bases, documents |
|
||||
| `pkb_schema` | 个人知识库 | knowledge_bases, documents |
|
||||
| `iit_schema` | IIT项目 | projects, audit_logs |
|
||||
| `rvw_schema` | 论文预审 | review_tasks |
|
||||
| `capability_schema` | 通用能力 | prompt_templates |
|
||||
| `public` | <EFBFBD>扳㺭<EFBFBD>?<3F>澆捆 | users (<EFBFBD>?, admin_logs |
|
||||
| `public` | 旧数据/兼容 | users (旧), admin_logs |
|
||||
|
||||
### 5.2 銵典𦶢<EFBFBD>滩<EFBFBD><EFBFBD>?
|
||||
### 5.2 表命名规范
|
||||
|
||||
```
|
||||
{schema_name}.{module_prefix}_{entity_name}
|
||||
|
||||
蝷箔<EFBFBD>嚗?
|
||||
示例:
|
||||
- dc_schema.dc_templates
|
||||
- dc_schema.dc_extraction_tasks
|
||||
- asl_schema.screening_projects
|
||||
@@ -170,12 +170,12 @@ SELECT table_name FROM information_schema.tables WHERE table_schema = 'platform_
|
||||
|
||||
---
|
||||
|
||||
## 6. 憭㚚睸銝擧㺭<EFBFBD>桀<EFBFBD><EFBFBD>湔<EFBFBD>?
|
||||
## 6. 外键与数据完整性
|
||||
|
||||
### 6.1 頝?Schema 憭㚚睸
|
||||
### 6.1 跨 Schema 外键
|
||||
|
||||
```prisma
|
||||
// <EFBFBD>?甇<>&嚗𡁏<E59A97>蝖格<E89D96>摰𡁜<E691B0>蝟?
|
||||
// ✅ 正确:明确指定关系
|
||||
model ReviewTask {
|
||||
userId String @map("user_id")
|
||||
user PublicUser @relation(fields: [userId], references: [id])
|
||||
@@ -191,9 +191,9 @@ model PublicUser {
|
||||
}
|
||||
```
|
||||
|
||||
### 6.2 憭㚚睸<EFBFBD><EFBFBD><EFBFBD>璉<EFBFBD><EFBFBD>?
|
||||
### 6.2 外键指向检查
|
||||
|
||||
<EFBFBD>其蝙<EFBFBD>?`prisma db push` <EFBFBD>𠬍<EFBFBD>璉<EFBFBD><EFBFBD>亙<EFBFBD><EFBFBD>格糓<EFBFBD>行迤蝖殷<EFBFBD>
|
||||
在使用 `prisma db push` 后,检查外键是否正确:
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
@@ -213,7 +213,7 @@ WHERE tc.constraint_type = 'FOREIGN KEY';
|
||||
|
||||
```bash
|
||||
# 1. 停止应用
|
||||
# 2. 隞𤾸<EFBFBD>隞賣<EFBFBD>憭?
|
||||
# 2. 从备份恢复
|
||||
cat backup_xxx.sql | docker exec -i ai-clinical-postgres psql -U postgres -d ai_clinical_research
|
||||
|
||||
# 3. 验证数据
|
||||
@@ -222,13 +222,13 @@ npx tsx verify_system.ts
|
||||
# 4. 重启应用
|
||||
```
|
||||
|
||||
### 7.2 Schema 銝滢<EFBFBD><EFBFBD>湔<EFBFBD>憭?
|
||||
### 7.2 Schema 不一致恢复
|
||||
|
||||
```bash
|
||||
# 1. 璉<EFBFBD><EFBFBD>亙榆撘?
|
||||
# 1. 检查差异
|
||||
npx tsx compare_schema_db.ts
|
||||
|
||||
# 2. <EFBFBD>W<EFBFBD>蝻箏仃<EFBFBD><EFBFBD>笆鞊?
|
||||
# 2. 恢复缺失的对象
|
||||
npx prisma db execute --file restore_xxx.sql --schema prisma/schema.prisma
|
||||
|
||||
# 3. 验证
|
||||
@@ -236,37 +236,37 @@ npx prisma db execute --file restore_xxx.sql --schema prisma/schema.prisma
|
||||
|
||||
---
|
||||
|
||||
## 8. 撘<EFBFBD><EFBFBD>𤑳㴓憓?vs <20>煺漣<E785BA>臬<EFBFBD>
|
||||
## 8. 开发环境 vs 生产环境
|
||||
|
||||
### 8.1 撘<EFBFBD><EFBFBD>𤑳㴓憓?
|
||||
### 8.1 开发环境
|
||||
|
||||
- 可以使用 `prisma migrate dev`
|
||||
- 可以使用 `prisma db push`(谨慎)
|
||||
- 摰𡁏<EFBFBD><EFBFBD>峕郊<EFBFBD>煺漣<EFBFBD>唳旿摨梶<EFBFBD><EFBFBD>?
|
||||
- 定期同步生产数据库结构
|
||||
|
||||
### 8.2 生产环境
|
||||
|
||||
- **只能**使用 `prisma migrate deploy`
|
||||
- **蝳<EFBFBD>迫**雿輻鍂隞颱<E99A9E> `--force` <EFBFBD>?`--reset` <EFBFBD><EFBFBD>㺭
|
||||
- **禁止**使用任何 `--force` 或 `--reset` 参数
|
||||
- 变更前必须有回滚计划
|
||||
- 敹<EFBFBD>◆<EFBFBD>㗇<EFBFBD><EFBFBD>啣<EFBFBD>隞?
|
||||
- 必须有最新备份
|
||||
|
||||
---
|
||||
|
||||
## 9. 璉<EFBFBD><EFBFBD>交<EFBFBD><EFBFBD>?
|
||||
## 9. 检查清单
|
||||
|
||||
### 9.1 <EFBFBD>唳旿摨枏<EFBFBD><EFBFBD>游<EFBFBD>璉<EFBFBD><EFBFBD>?
|
||||
### 9.1 数据库变更前检查
|
||||
|
||||
- [ ] 已备份数据库
|
||||
- [ ] 撌脣恣<EFBFBD>?schema.prisma <EFBFBD>䀹凒
|
||||
- [ ] 撌脫<EFBFBD><EFBFBD>交糓<EFBFBD>血蔣<EFBFBD>漤<EFBFBD> Prisma 蝞∠<E89D9E><E288A0><EFBFBD>笆鞊?
|
||||
- [ ] 撌脣<EFBFBD>憭<EFBFBD><EFBFBD>皛𡁏䲮獢?
|
||||
- [ ] 撌脣銁撘<EFBFBD><EFBFBD>𤑳㴓憓<EFBFBD><EFBFBD>霂?
|
||||
- [ ] 已审查 schema.prisma 变更
|
||||
- [ ] 已检查是否影响非 Prisma 管理的对象
|
||||
- [ ] 已准备回滚方案
|
||||
- [ ] 已在开发环境测试
|
||||
|
||||
### 9.2 <EFBFBD>函蔡<EFBFBD>擧<EFBFBD><EFBFBD>?
|
||||
### 9.2 部署后检查
|
||||
|
||||
- [ ] 应用正常启动
|
||||
- [ ] <EFBFBD>唳旿摨栞<EFBFBD><EFBFBD>交迤撣?
|
||||
- [ ] 数据库连接正常
|
||||
- [ ] pg-boss 队列正常工作
|
||||
- [ ] 核心功能测试通过
|
||||
|
||||
@@ -278,14 +278,14 @@ npx prisma db execute --file restore_xxx.sql --schema prisma/schema.prisma
|
||||
|
||||
```
|
||||
backend/
|
||||
<EFBFBD>鎿<EFBFBD><EFBFBD><EFBFBD> verify_system.ts # 蝟餌<EFBFBD>摰峕㟲<EFBFBD>折<EFBFBD>霂?
|
||||
├── verify_system.ts # 系统完整性验证
|
||||
├── compare_schema_db.ts # Schema与数据库对比
|
||||
<EFBFBD>鎿<EFBFBD><EFBFBD><EFBFBD> check_iit_asl_data.ts # 璉<EFBFBD><EFBFBD>交芋<EFBFBD>埈㺭<EFBFBD>?
|
||||
<EFBFBD>鎿<EFBFBD><EFBFBD><EFBFBD> restore_job_common.sql # <EFBFBD>W<EFBFBD> job_common 銵?
|
||||
├── check_iit_asl_data.ts # 检查模块数据
|
||||
├── restore_job_common.sql # 恢复 job_common 表
|
||||
└── restore_pgboss_functions.sql # 恢复 pg-boss 函数
|
||||
```
|
||||
|
||||
### 10.2 敹恍<EFBFBD>罸<EFBFBD>霂<EFBFBD>𦶢隞?
|
||||
### 10.2 快速验证命令
|
||||
|
||||
```bash
|
||||
# 设置环境变量
|
||||
@@ -294,27 +294,27 @@ $env:DATABASE_URL="postgresql://postgres:postgres123@localhost:5432/ai_clinical_
|
||||
# 验证系统
|
||||
npx tsx verify_system.ts
|
||||
|
||||
# 璉<EFBFBD><EFBFBD>交㺭<EFBFBD>?
|
||||
# 检查数据
|
||||
npx tsx check_iit_asl_data.ts
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD><EFBFBD><EFBFBD>嚗帋<EFBFBD><EFBFBD><EFBFBD><EFBFBD>靘?
|
||||
## 附录:事故案例
|
||||
|
||||
### 獢<EFBFBD><EFBFBD>1嚗?026-01-11 <EFBFBD>唳旿摨㯄<EFBFBD>蝵桐<EFBFBD><EFBFBD>?
|
||||
### 案例1:2026-01-11 数据库重置事故
|
||||
|
||||
**<EFBFBD>笔<EFBFBD>**嚗帋蝙<E5B88B>?`prisma db push --force-reset` 撖潸稲<EFBFBD>?Prisma 蝞∠<EFBFBD><EFBFBD><EFBFBD>笆鞊∩腺憭?
|
||||
**原因**:使用 `prisma db push --force-reset` 导致非 Prisma 管理的对象丢失
|
||||
|
||||
**敶勗<EFBFBD>**嚗?
|
||||
- pg-boss <EFBFBD>賣㺭銝W仃嚗屸<EFBFBD><EFBFBD>埈<EFBFBD>瘜閙釣<EFBFBD>?
|
||||
- job_common 銵其腺憭?
|
||||
- <EFBFBD>冽<EFBFBD><EFBFBD>唳旿銝W仃嚗<EFBFBD>歇<EFBFBD>朞<EFBFBD> seed <EFBFBD>W<EFBFBD>嚗?
|
||||
**影响**:
|
||||
- pg-boss 函数丢失,队列无法注册
|
||||
- job_common 表丢失
|
||||
- 用户数据丢失(已通过 seed 恢复)
|
||||
|
||||
**<EFBFBD>躰悌**嚗?
|
||||
**教训**:
|
||||
1. 永远不要使用 `--force-reset`
|
||||
2. <EFBFBD>滢<EFBFBD><EFBFBD>滚<EFBFBD>憿餃<EFBFBD>隞?
|
||||
3. 鈭<EFBFBD>圾 Prisma <EFBFBD><EFBFBD>恣<EFBFBD><EFBFBD>器<EFBFBD>?
|
||||
2. 操作前必须备份
|
||||
3. 了解 Prisma 的管理边界
|
||||
|
||||
详见:`docs/08-项目管理/2026-01-11-数据库事故总结.md`
|
||||
|
||||
@@ -323,4 +323,3 @@ npx tsx check_iit_asl_data.ts
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
# 模块认证规范
|
||||
|
||||
> <EFBFBD>祆<EFBFBD>獢<EFBFBD><EFBFBD>銋劐<EFBFBD>銝𡁜𦛚璅∪<EFBFBD>憒<EFBFBD><EFBFBD>甇<EFBFBD>&雿輻鍂撟喳蝱霈方<EFBFBD><EFBFBD>賢<EFBFBD>嚗𣬚&靽脲<EFBFBD><EFBFBD>?API <20>賣迤蝖格𡉼撣血<E692A3>撉諹<E69289><E8ABB9>冽<EFBFBD>頨思遢<E6809D>?
|
||||
> 本文档定义了业务模块如何正确使用平台认证能力,确保所有 API 都正确携带和验证用户身份。
|
||||
|
||||
## 1. 架构概览
|
||||
|
||||
```
|
||||
<EFBFBD>𢞖<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
|
||||
<EFBFBD>? <EFBFBD>滨垢 <EFBFBD>?
|
||||
<EFBFBD>? <20>𢞖<EFBFBD><F0A29E96><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>? <20>?
|
||||
<EFBFBD>? <20>? common/api/axios.ts <EFBFBD>?撣西恕霂<E68195><E99C82> axios 摰硺<EFBFBD> <EFBFBD>? <20>?
|
||||
<EFBFBD>? <20>? framework/auth/api.ts <EFBFBD>?Token 蝞∠<EFBFBD> (getAccessToken)<EFBFBD>? <20>?
|
||||
<EFBFBD>? <20>婙<EFBFBD><E5A999><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>? <20>?
|
||||
<EFBFBD>婙<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
|
||||
<EFBFBD>?
|
||||
<EFBFBD>?Authorization: Bearer <token>
|
||||
<EFBFBD>?
|
||||
<EFBFBD>𢞖<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
|
||||
<EFBFBD>? <EFBFBD>𡒊垢 <EFBFBD>?
|
||||
<EFBFBD>? <20>𢞖<EFBFBD><F0A29E96><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>? <20>?
|
||||
<EFBFBD>? <20>? common/auth/auth.middleware.ts <EFBFBD>? <20>?
|
||||
<EFBFBD>? <20>? - authenticate: 撉諹<EFBFBD> JWT Token <EFBFBD>? <20>?
|
||||
<EFBFBD>? <20>? - requirePermission: <EFBFBD><EFBFBD><EFBFBD>璉<EFBFBD><EFBFBD>? <EFBFBD>? <20>?
|
||||
<EFBFBD>? <20>? - requireRoles: 閫坿𠧧璉<EFBFBD><EFBFBD>? <EFBFBD>? <20>?
|
||||
<EFBFBD>? <20>婙<EFBFBD><E5A999><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>? <20>?
|
||||
<EFBFBD>婙<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ 前端 │
|
||||
│ ┌─────────────────────────────────────────────────────┐ │
|
||||
│ │ common/api/axios.ts ← 带认证的 axios 实例 │ │
|
||||
│ │ framework/auth/api.ts ← Token 管理 (getAccessToken)│ │
|
||||
│ └─────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
│ Authorization: Bearer <token>
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ 后端 │
|
||||
│ ┌─────────────────────────────────────────────────────┐ │
|
||||
│ │ common/auth/auth.middleware.ts │ │
|
||||
│ │ - authenticate: 验证 JWT Token │ │
|
||||
│ │ - requirePermission: 权限检查 │ │
|
||||
│ │ - requireRoles: 角色检查 │ │
|
||||
│ └─────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## 2. 前端规范
|
||||
@@ -34,12 +34,12 @@
|
||||
// 导入带认证的 apiClient
|
||||
import apiClient from '../../../common/api/axios';
|
||||
|
||||
// 雿輻鍂<EFBFBD>孵<EFBFBD>銝?axios 摰<><E691B0><EFBFBD>詨<EFBFBD>嚗諹䌊<E8ABB9>冽𡉼撣?JWT Token
|
||||
// 使用方式与 axios 完全相同,自动携带 JWT Token
|
||||
const response = await apiClient.get('/api/v2/xxx');
|
||||
const response = await apiClient.post('/api/v2/xxx', data);
|
||||
```
|
||||
|
||||
### 2.2 雿輻鍂<EFBFBD>毺<EFBFBD> fetch嚗<68><E59A97><EFBFBD>见𢆡瘛餃<E7989B> Token嚗?
|
||||
### 2.2 使用原生 fetch(需手动添加 Token)
|
||||
|
||||
```typescript
|
||||
import { getAccessToken } from '../../../framework/auth/api';
|
||||
@@ -56,12 +56,12 @@ function getAuthHeaders(): HeadersInit {
|
||||
return headers;
|
||||
}
|
||||
|
||||
// <EFBFBD><EFBFBD><EFBFBD>?fetch 霂瑟<EFBFBD>雿輻鍂 getAuthHeaders()
|
||||
// 所有 fetch 请求使用 getAuthHeaders()
|
||||
const response = await fetch(url, {
|
||||
headers: getAuthHeaders(),
|
||||
});
|
||||
|
||||
// <EFBFBD><EFBFBD>辣銝𠹺<EFBFBD>嚗<EFBFBD><EFBFBD>霈曄蔭 Content-Type嚗?
|
||||
// 文件上传(不设置 Content-Type)
|
||||
const token = getAccessToken();
|
||||
const headers: HeadersInit = {};
|
||||
if (token) {
|
||||
@@ -76,22 +76,22 @@ const response = await fetch(url, {
|
||||
|
||||
## 3. 后端规范
|
||||
|
||||
### 3.1 頝舐眏瘛餃<EFBFBD>霈方<EFBFBD>銝剝𡢿隞?
|
||||
### 3.1 路由添加认证中间件
|
||||
|
||||
```typescript
|
||||
// 撖澆<EFBFBD>霈方<EFBFBD>銝剝𡢿隞?
|
||||
// 导入认证中间件
|
||||
import { authenticate, requirePermission } from '../../../common/auth/auth.middleware.js';
|
||||
|
||||
// 瘛餃<EFBFBD><EFBFBD>啗楝<EFBFBD>?
|
||||
// 添加到路由
|
||||
fastify.get('/xxx', { preHandler: [authenticate] }, handler);
|
||||
|
||||
// <EFBFBD><EFBFBD>閬<EFBFBD>鸌摰𡁏<EFBFBD><EFBFBD>?
|
||||
// 需要特定权限
|
||||
fastify.post('/xxx', {
|
||||
preHandler: [authenticate, requirePermission('module:action')]
|
||||
}, handler);
|
||||
```
|
||||
|
||||
### 3.2 <EFBFBD>批<EFBFBD><EFBFBD>刻繮<EFBFBD>𣇉鍂<EFBFBD>?ID
|
||||
### 3.2 控制器获取用户 ID
|
||||
|
||||
```typescript
|
||||
/**
|
||||
@@ -105,7 +105,7 @@ function getUserId(request: FastifyRequest): string {
|
||||
return userId;
|
||||
}
|
||||
|
||||
// <EFBFBD>冽綉<EFBFBD>嗅膥<EFBFBD>寞<EFBFBD>銝凋蝙<EFBFBD>?
|
||||
// 在控制器方法中使用
|
||||
async function myHandler(request: FastifyRequest, reply: FastifyReply) {
|
||||
const userId = getUserId(request);
|
||||
// ... 使用 userId
|
||||
@@ -117,7 +117,7 @@ async function myHandler(request: FastifyRequest, reply: FastifyReply) {
|
||||
```typescript
|
||||
interface DecodedToken {
|
||||
userId: string; // 用户ID
|
||||
phone: string; // <EFBFBD>𧢲㦤<EFBFBD>?
|
||||
phone: string; // 手机号
|
||||
role: string; // 角色
|
||||
tenantId: string; // 租户ID
|
||||
tenantCode?: string; // 租户Code
|
||||
@@ -126,69 +126,68 @@ interface DecodedToken {
|
||||
}
|
||||
```
|
||||
|
||||
## 4. 璉<EFBFBD><EFBFBD>交<EFBFBD><EFBFBD>?
|
||||
## 4. 检查清单
|
||||
|
||||
### 4.1 <EFBFBD>唳芋<EFBFBD>堒<EFBFBD><EFBFBD>烐<EFBFBD><EFBFBD>交<EFBFBD><EFBFBD>?
|
||||
### 4.1 新模块开发检查清单
|
||||
|
||||
- [ ] **前端 API 文件**
|
||||
- [ ] 雿輻鍂 `apiClient` <EFBFBD>𡝗溶<EFBFBD>?`getAuthHeaders()`
|
||||
- [ ] <EFBFBD><EFBFBD>辣銝𠹺<EFBFBD><EFBFBD>閧𡠺憭<EFBFBD><EFBFBD>嚗<EFBFBD><EFBFBD>霈曄蔭 Content-Type嚗?
|
||||
- [ ] 使用 `apiClient` 或添加 `getAuthHeaders()`
|
||||
- [ ] 文件上传单独处理(不设置 Content-Type)
|
||||
- [ ] 导出函数不包含测试用 userId 参数
|
||||
|
||||
- [ ] **后端路由文件**
|
||||
- [ ] 撖澆<EFBFBD> `authenticate` 銝剝𡢿隞?
|
||||
- [ ] 导入 `authenticate` 中间件
|
||||
- [ ] 所有需要认证的路由添加 `preHandler: [authenticate]`
|
||||
- [ ] <EFBFBD>砍<EFBFBD> API嚗<EFBFBD><EFBFBD>璅⊥踎<EFBFBD>𡑒”嚗匧虾銝齿溶<EFBFBD>㰘恕霂?
|
||||
- [ ] 公开 API(如模板列表)可不添加认证
|
||||
|
||||
- [ ] **<EFBFBD>𡒊垢<EFBFBD>批<EFBFBD><EFBFBD>冽<EFBFBD>隞?*
|
||||
- [ ] **后端控制器文件**
|
||||
- [ ] 添加 `getUserId()` 辅助函数
|
||||
- [ ] 蝘駁膄<EFBFBD><EFBFBD><EFBFBD>?`MOCK_USER_ID` <EFBFBD>𣇉′蝻𣇉<EFBFBD>暺䁅恕<EFBFBD>?
|
||||
- [ ] 移除所有 `MOCK_USER_ID` 或硬编码默认值
|
||||
- [ ] 使用 `getUserId(request)` 获取用户 ID
|
||||
|
||||
### 4.2 撌脣<EFBFBD><EFBFBD>鞉芋<EFBFBD>㛖𠶖<EFBFBD>?
|
||||
### 4.2 已完成模块状态
|
||||
|
||||
| 璅∪<EFBFBD> | <20>滨垢 API | <20>𡒊垢頝舐眏 | <20>𡒊垢<F0A1928A>批<EFBFBD><E689B9>?| <20>嗆<EFBFBD>?|
|
||||
| 模块 | 前端 API | 后端路由 | 后端控制器 | 状态 |
|
||||
|------|---------|---------|-----------|------|
|
||||
| RVW | <EFBFBD>?apiClient | <EFBFBD>?authenticate | <EFBFBD>?getUserId | <EFBFBD>?|
|
||||
| PKB | <EFBFBD>?<3F>行⏛<E8A18C>?| <20>?authenticate | <EFBFBD>?getUserId | <EFBFBD>?|
|
||||
| ASL | <EFBFBD>?getAuthHeaders | <EFBFBD>?authenticate | <EFBFBD>?getUserId | <EFBFBD>?|
|
||||
| DC Tool B | <EFBFBD>?getAuthHeaders | <EFBFBD>?authenticate | <EFBFBD>?getUserId | <EFBFBD>?|
|
||||
| DC Tool C | <EFBFBD>?apiClient | <EFBFBD>?authenticate | <EFBFBD>?getUserId | <EFBFBD>?|
|
||||
| IIT | N/A (隡<EFBFBD><EFBFBD>敺桐縑) | N/A | <EFBFBD>?隡<><E99AA1>敺桐縑userId | <EFBFBD>?|
|
||||
| Prompt蝞∠<EFBFBD> | <EFBFBD>?getAuthHeaders | <EFBFBD>?authenticate | <EFBFBD>?getUserId | <EFBFBD>?|
|
||||
| RVW | ✅ apiClient | ✅ authenticate | ✅ getUserId | ✅ |
|
||||
| PKB | ✅ 拦截器 | ✅ authenticate | ✅ getUserId | ✅ |
|
||||
| ASL | ✅ getAuthHeaders | ✅ authenticate | ✅ getUserId | ✅ |
|
||||
| DC Tool B | ✅ getAuthHeaders | ✅ authenticate | ✅ getUserId | ✅ |
|
||||
| DC Tool C | ✅ apiClient | ✅ authenticate | ✅ getUserId | ✅ |
|
||||
| IIT | N/A (企业微信) | N/A | ✅ 企业微信userId | ✅ |
|
||||
| Prompt管理 | ✅ getAuthHeaders | ✅ authenticate | ✅ getUserId | ✅ |
|
||||
|
||||
## 5. 撣貉<EFBFBD><EFBFBD>躰秤<EFBFBD>諹圾<EFBFBD>單䲮獢?
|
||||
## 5. 常见错误和解决方案
|
||||
|
||||
### 5.1 401 Unauthorized
|
||||
|
||||
**<EFBFBD>笔<EFBFBD>**: <EFBFBD>滨垢瘝⊥<EFBFBD><EFBFBD>箏蒂 JWT Token <EFBFBD>?Token 餈<EFBFBD><EFBFBD>
|
||||
**原因**: 前端没有携带 JWT Token 或 Token 过期
|
||||
|
||||
**解决**:
|
||||
1. 璉<EFBFBD><EFBFBD>亙<EFBFBD>蝡?API <20>臬炏雿輻鍂 `apiClient` <EFBFBD>?`getAuthHeaders()`
|
||||
2. 璉<EFBFBD><EFBFBD>?localStorage 銝剜糓<EFBFBD>行<EFBFBD> `accessToken`
|
||||
1. 检查前端 API 是否使用 `apiClient` 或 `getAuthHeaders()`
|
||||
2. 检查 localStorage 中是否有 `accessToken`
|
||||
3. 如果 Token 过期,尝试刷新或重新登录
|
||||
|
||||
### 5.2 User not authenticated
|
||||
|
||||
**<EFBFBD>笔<EFBFBD>**: <EFBFBD>𡒊垢頝舐眏瘝⊥<EFBFBD>瘛餃<EFBFBD> `authenticate` 銝剝𡢿隞?
|
||||
**原因**: 后端路由没有添加 `authenticate` 中间件
|
||||
|
||||
**解决**: 在路由定义中添加 `preHandler: [authenticate]`
|
||||
|
||||
### 5.3 TypeError: Cannot read property 'userId' of undefined
|
||||
|
||||
**<EFBFBD>笔<EFBFBD>**: 雿輻鍂鈭<EFBFBD><EFBFBD>霂舐<EFBFBD>撅墧<EFBFBD>批<EFBFBD>嚗Ǒrequest.user.id` <20>屸<EFBFBD> `request.user.userId`嚗?
|
||||
**原因**: 使用了错误的属性名(`request.user.id` 而非 `request.user.userId`)
|
||||
|
||||
**解决**: 使用 `(request as any).user?.userId`
|
||||
|
||||
## 6. <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>隞?
|
||||
## 6. 参考文件
|
||||
|
||||
- 前端 axios 实例: `frontend-v2/src/common/api/axios.ts`
|
||||
- 前端 Token 管理: `frontend-v2/src/framework/auth/api.ts`
|
||||
- <20>𡒊垢霈方<E99C88>銝剝𡢿隞? `backend/src/common/auth/auth.middleware.ts`
|
||||
- 后端认证中间件: `backend/src/common/auth/auth.middleware.ts`
|
||||
- 后端 JWT 服务: `backend/src/common/auth/jwt.service.ts`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
# 04-寮€鍙戣<EFBFBD>鑼?
|
||||
> **鐩<>爣锛?* 缁熶竴鍥㈤槦寮€鍙戣<E98D99>鑼冿紝鎻愰珮浠g爜璐ㄩ噺鍜屽崗浣滄晥鐜?
|
||||
> **閫傜敤鑼冨洿锛?* 骞冲彴灞?+ 鑳藉姏灞?+ 涓氬姟妯″潡灞?
|
||||
> **寮哄埗绛夌骇锛?* 猸愨瓙猸愨瓙猸?蹇呴』閬靛畧
|
||||
# 04-开发规范
|
||||
|
||||
> **目标:** 统一团队开发规范,提高代码质量和协作效率
|
||||
> **适用范围:** 平台层 + 能力层 + 业务模块层
|
||||
> **强制等级:** ⭐⭐⭐⭐⭐ 必须遵守
|
||||
|
||||
---
|
||||
|
||||
## 📋 规范文档列表
|
||||
|
||||
### 1. 鏁版嵁搴撹<EFBFBD>璁¤<EFBFBD>鑼?猸愨瓙猸愨瓙猸?**鏂囦欢锛?* `01-鏁版嵁搴撹<E690B4>璁¤<E79281>鑼?md` 鈴?寰呭垱寤猴紙浠?`01-璁捐<E79281>鏂囨。/鏁版嵁搴撹<E690B4>璁℃枃妗?md` 鎻愬彇锛?
|
||||
**鏍稿績鍐呭<EFBFBD>锛?*
|
||||
### 1. 数据库设计规范 ⭐⭐⭐⭐⭐
|
||||
**文件:** `01-数据库设计规范.md` ⏳ 待创建(从 `01-设计文档/数据库设计文档.md` 提取)
|
||||
|
||||
**核心内容:**
|
||||
- Schema隔离策略(platform_schema、asl_schema等)
|
||||
- 表命名规范(小写+下划线)
|
||||
- 字段命名规范
|
||||
@@ -16,41 +19,55 @@
|
||||
- 外键约束规范
|
||||
- 通用字段(created_at、updated_at等)
|
||||
|
||||
**蹇<EFBFBD>€熷弬鑰冿細** [鏁版嵁搴撳叏灞€瑙嗗浘](./03-鏁版嵁搴撳叏灞€瑙嗗浘.md) 猸?宸插垱寤?
|
||||
**快速参考:** [数据库全局视图](./03-数据库全局视图.md) ⭐ 已创建
|
||||
|
||||
---
|
||||
|
||||
### 2. API璁捐<EFBFBD>瑙勮寖 猸愨瓙猸愨瓙猸?**鏂囦欢锛?* `02-API璁捐<E79281>瑙勮寖.md` 鈴?寰呭垱寤猴紙浠?`01-璁捐<E79281>鏂囨。/API璁捐<E79281>瑙勮寖.md` 鎻愬彇锛?
|
||||
**鏍稿績鍐呭<EFBFBD>锛?*
|
||||
### 2. API设计规范 ⭐⭐⭐⭐⭐
|
||||
**文件:** `02-API设计规范.md` ⏳ 待创建(从 `01-设计文档/API设计规范.md` 提取)
|
||||
|
||||
**核心内容:**
|
||||
- RESTful API设计原则
|
||||
- URL鍛藉悕瑙勮寖锛坄/api/v1/妯″潡/璧勬簮`锛?- HTTP鏂规硶浣跨敤瑙勮寖
|
||||
- URL命名规范(`/api/v1/模块/资源`)
|
||||
- HTTP方法使用规范
|
||||
- 请求/响应格式规范
|
||||
- 閿欒<EFBFBD>鐮佽<EFBFBD>璁?- 璁よ瘉鍜屾潈闄?
|
||||
**蹇<>€熷弬鑰冿細** [API璺<EFBFBD>敱鎬昏<EFBFBD>](./04-API璺<49>敱鎬昏<E98EAC>.md) 猸?宸插垱寤?
|
||||
- 错误码设计
|
||||
- 认证和权限
|
||||
|
||||
**快速参考:** [API路由总览](./04-API路由总览.md) ⭐ 已创建
|
||||
|
||||
---
|
||||
|
||||
### 3. 鏁版嵁搴撳叏灞€瑙嗗浘 猸愨瓙猸愨瓙猸?鉁?鏂板<E98F82>
|
||||
**鏂囦欢锛?* `03-鏁版嵁搴撳叏灞€瑙嗗浘.md`
|
||||
### 3. 数据库全局视图 ⭐⭐⭐⭐⭐ ✅ 新增
|
||||
**文件:** `03-数据库全局视图.md`
|
||||
|
||||
**鐢ㄩ€旓細** 鎻愪緵鎵€鏈塖chema鍜岃〃鐨勫揩閫熺储寮?
|
||||
**鏍稿績鍐呭<E98D90>锛?*
|
||||
- Schema鍒掑垎绛栫暐锛?涓猄chema锛?- 鎵€鏈夎〃鐨勬€昏<E282AC>鍜岃烦杞<E783A6>摼鎺?- 璺⊿chema渚濊禆鍏崇郴
|
||||
- 鏁版嵁閲忛<EFBFBD>浼?
|
||||
**浣跨敤鍦烘櫙锛?*
|
||||
**用途:** 提供所有Schema和表的快速索引
|
||||
|
||||
**核心内容:**
|
||||
- Schema划分策略(8个Schema)
|
||||
- 所有表的总览和跳转链接
|
||||
- 跨Schema依赖关系
|
||||
- 数据量预估
|
||||
|
||||
**使用场景:**
|
||||
- 查看全局数据架构
|
||||
- 快速定位某个表属于哪个Schema
|
||||
- 浜嗚В璺ㄦā鍧楁暟鎹<EFBFBD>叧绯?
|
||||
- 了解跨模块数据关系
|
||||
|
||||
---
|
||||
|
||||
### 4. API璺<EFBFBD>敱鎬昏<EFBFBD> 猸愨瓙猸愨瓙猸?鉁?鏂板<E98F82>
|
||||
**鏂囦欢锛?* `04-API璺<EFBFBD>敱鎬昏<EFBFBD>.md`
|
||||
### 4. API路由总览 ⭐⭐⭐⭐⭐ ✅ 新增
|
||||
**文件:** `04-API路由总览.md`
|
||||
|
||||
**鐢ㄩ€旓細** 鎻愪緵鎵€鏈堿PI绔<EFBFBD>偣鐨勫揩閫熺储寮?
|
||||
**鏍稿績鍐呭<E98D90>锛?*
|
||||
**用途:** 提供所有API端点的快速索引
|
||||
|
||||
**核心内容:**
|
||||
- 路由命名规范
|
||||
- 所有模块的API端点总览
|
||||
- 璺<EFBFBD>敱鍐茬獊妫€鏌?- 绔<>偣缁熻<E7BC81>锛垀85涓<35>級
|
||||
- 路由冲突检查
|
||||
- 端点统计(~85个)
|
||||
|
||||
**浣跨敤鍦烘櫙锛?*
|
||||
**使用场景:**
|
||||
- 查看全局API架构
|
||||
- 避免路由冲突
|
||||
- 快速查找某个功能的API端点
|
||||
@@ -58,29 +75,36 @@
|
||||
---
|
||||
|
||||
### 5. 代码规范 ⭐⭐⭐⭐
|
||||
**鏂囦欢锛?* `05-浠g爜瑙勮寖.md` 鈫?閲嶅懡鍚嶈嚜 `浠g爜瑙勮寖.md`锛堝凡瀛樺湪锛?18琛岋級
|
||||
**文件:** `05-代码规范.md` → 重命名自 `代码规范.md`(已存在,818行)
|
||||
|
||||
**鏍稿績鍐呭<EFBFBD>锛?*
|
||||
**核心内容:**
|
||||
- TypeScript编码规范
|
||||
- React组件规范
|
||||
- 鏂囦欢鍜岀洰褰曞懡鍚?- 浠g爜娉ㄩ噴瑙勮寖
|
||||
- 文件和目录命名
|
||||
- 代码注释规范
|
||||
- 错误处理规范
|
||||
- 日志记录规范
|
||||
|
||||
**已有内容,包含:**
|
||||
- ESLint配置
|
||||
- Prettier配置
|
||||
- 璇︾粏鐨勭紪鐮佽<EFBFBD>鑼?
|
||||
- 详细的编码规范
|
||||
|
||||
---
|
||||
|
||||
### 6. Git鎻愪氦瑙勮寖 猸愨瓙猸愨瓙猸?鉁?宸插畬鎴?**鏂囦欢锛?* `06-Git鎻愪氦瑙勮寖.md`
|
||||
### 6. Git提交规范 ⭐⭐⭐⭐⭐ ✅ 已完成
|
||||
**文件:** `06-Git提交规范.md`
|
||||
|
||||
**鏍稿績鍐呭<EFBFBD>锛?*
|
||||
- 杩滅▼浠撳簱閰嶇疆锛圙itee锛?- Commit Message鏍煎紡瑙勮寖
|
||||
**核心内容:**
|
||||
- 远程仓库配置(Gitee)
|
||||
- Commit Message格式规范
|
||||
- 分支管理策略
|
||||
- 涓<EFBFBD>枃缂栫爜闂<EFBFBD><EFBFBD>瑙e喅鏂规<EFBFBD> 猸?閲嶈<E996B2>
|
||||
- Git鍘嗗彶閲嶅啓涓庣淮鎶?- PR/MR瑙勮寖鍜屼唬鐮佸<E990AE>鏌ユ祦绋?- 甯歌<E794AF>闂<EFBFBD><E99782>涓庢渶浣冲疄璺?
|
||||
**鍖呭惈瀹炵敤宸ュ叿锛?*
|
||||
- 中文编码问题解决方案 ⭐ 重要
|
||||
- Git历史重写与维护
|
||||
- PR/MR规范和代码审查流程
|
||||
- 常见问题与最佳实践
|
||||
|
||||
**包含实用工具:**
|
||||
- `fix-git-commit-messages.ps1` 脚本使用说明
|
||||
- Git 别名配置
|
||||
- 中文乱码修复完整流程
|
||||
@@ -89,19 +113,22 @@
|
||||
```
|
||||
<type>(<scope>): <subject>
|
||||
|
||||
feat: 鏂板姛鑳? fix: Bug淇<EFBFBD><EFBFBD> docs: 鏂囨。
|
||||
feat: 新功能 fix: Bug修复 docs: 文档
|
||||
style: 格式 refactor: 重构 perf: 优化
|
||||
test: 测试 chore: 构建 ci: CI/CD
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 7. 娴嬭瘯瑙勮寖 猸愨瓙猸?**鏂囦欢锛?* `07-娴嬭瘯瑙勮寖.md` 鈴?寰呭垱寤?
|
||||
**鏍稿績鍐呭<EFBFBD>锛?*
|
||||
### 7. 测试规范 ⭐⭐⭐
|
||||
**文件:** `07-测试规范.md` ⏳ 待创建
|
||||
|
||||
**核心内容:**
|
||||
- 单元测试规范
|
||||
- 集成测试规范
|
||||
- E2E测试规范
|
||||
- 娴嬭瘯瑕嗙洊鐜囪<EFBFBD>姹?
|
||||
- 测试覆盖率要求
|
||||
|
||||
**测试覆盖率要求:**
|
||||
- 核心业务逻辑:≥80%
|
||||
- 工具函数:≥90%
|
||||
@@ -109,63 +136,83 @@ test: 测试 chore: 构建 ci: CI/CD
|
||||
|
||||
---
|
||||
|
||||
## 馃幆 瑙勮寖浼樺厛绾?
|
||||
## 🎯 规范优先级
|
||||
|
||||
### P0 - 必须遵守
|
||||
- 鉁?鏁版嵁搴撹<E690B4>璁¤<E79281>鑼?- 鉁?API璁捐<E79281>瑙勮寖
|
||||
- 鉁?Git鎻愪氦瑙勮寖锛圕ommit Message锛?
|
||||
- ✅ 数据库设计规范
|
||||
- ✅ API设计规范
|
||||
- ✅ Git提交规范(Commit Message)
|
||||
|
||||
### P1 - 强烈建议
|
||||
- 鉁?浠g爜瑙勮寖锛圱ypeScript/React锛?- 鉁?閿欒<E996BF>澶勭悊瑙勮寖
|
||||
- 鉁?鏃ュ織璁板綍瑙勮寖
|
||||
- ✅ 代码规范(TypeScript/React)
|
||||
- ✅ 错误处理规范
|
||||
- ✅ 日志记录规范
|
||||
|
||||
### P2 - 建议遵守
|
||||
- 鈿?娴嬭瘯瑙勮寖
|
||||
- 鈿?鏂囨。娉ㄩ噴瑙勮寖
|
||||
- 鈿?鎬ц兘浼樺寲瑙勮寖
|
||||
- ⚪ 测试规范
|
||||
- ⚪ 文档注释规范
|
||||
- ⚪ 性能优化规范
|
||||
|
||||
---
|
||||
|
||||
## 馃攳 蹇<>€熸煡鎵?
|
||||
**鎴戣<E98EB4>璁捐<E79281>鏁版嵁搴撹〃锛?* 鈫?`01-鏁版嵁搴撹<E690B4>璁¤<E79281>鑼?md`
|
||||
**鎴戣<EFBFBD>璁捐<EFBFBD>API鎺ュ彛锛?* 鈫?`02-API璁捐<E79281>瑙勮寖.md`
|
||||
**鎴戣<EFBFBD>鏌ョ湅鍏ㄥ眬鏁版嵁鏋舵瀯锛?* 鈫?`03-鏁版嵁搴撳叏灞€瑙嗗浘.md` 鉁?
|
||||
**鎴戣<EFBFBD>鏌ョ湅鍏ㄥ眬API璺<EFBFBD>敱锛?* 鈫?`04-API璺<49>敱鎬昏<E98EAC>.md` 鉁?
|
||||
**鎴戣<EFBFBD>缂栧啓浠g爜锛?* 鈫?`05-浠g爜瑙勮寖.md` 鉁?
|
||||
**鎴戣<EFBFBD>鎻愪氦浠g爜锛?* 鈫?`06-Git鎻愪氦瑙勮寖.md` 鉁?
|
||||
**鎴戣<EFBFBD>瑙e喅涓<EFBFBD>枃涔辩爜锛?* 鈫?`06-Git鎻愪氦瑙勮寖.md` (绗?鑺? 鉁?
|
||||
**鎴戣<EFBFBD>閰嶇疆杩滅▼浠撳簱锛?* 鈫?`06-Git鎻愪氦瑙勮寖.md` (绗?鑺? 鉁?
|
||||
**鎴戣<EFBFBD>缂栧啓娴嬭瘯锛?* 鈫?`07-娴嬭瘯瑙勮寖.md`
|
||||
## 🔍 快速查找
|
||||
|
||||
**我要设计数据库表:** → `01-数据库设计规范.md`
|
||||
**我要设计API接口:** → `02-API设计规范.md`
|
||||
**我要查看全局数据架构:** → `03-数据库全局视图.md` ✅
|
||||
**我要查看全局API路由:** → `04-API路由总览.md` ✅
|
||||
**我要编写代码:** → `05-代码规范.md` ✅
|
||||
**我要提交代码:** → `06-Git提交规范.md` ✅
|
||||
**我要解决中文乱码:** → `06-Git提交规范.md` (第4节) ✅
|
||||
**我要配置远程仓库:** → `06-Git提交规范.md` (第1节) ✅
|
||||
**我要编写测试:** → `07-测试规范.md`
|
||||
|
||||
---
|
||||
|
||||
## 鈿狅笍 杩濆弽瑙勮寖鐨勫悗鏋?
|
||||
## ⚠️ 违反规范的后果
|
||||
|
||||
### 数据库设计不规范
|
||||
- 鉂?Schema娣蜂贡锛屾ā鍧楄€﹀悎
|
||||
- 鉂?鏃犳硶瀹炵幇妯″潡鐙<E6BDA1>珛閮ㄧ讲
|
||||
- 鉂?鏁版嵁杩佺Щ鍥伴毦
|
||||
- ❌ Schema混乱,模块耦合
|
||||
- ❌ 无法实现模块独立部署
|
||||
- ❌ 数据迁移困难
|
||||
|
||||
### API璁捐<EFBFBD>涓嶈<EFBFBD>鑼?- 鉂?鍓嶅悗绔<E68297><E7BB94>鎺ュ洶闅?- 鉂?API鏂囨。娣蜂贡
|
||||
- 鉂?鐗堟湰鍗囩骇鍥伴毦
|
||||
### API设计不规范
|
||||
- ❌ 前后端对接困难
|
||||
- ❌ API文档混乱
|
||||
- ❌ 版本升级困难
|
||||
|
||||
### 代码不规范
|
||||
- ❌ 代码可读性差
|
||||
- ❌ 维护成本高
|
||||
- ❌ Bug率上升
|
||||
|
||||
### 浠g爜涓嶈<E6B693>鑼?- 鉂?浠g爜鍙<E7889C><E98D99>鎬у樊
|
||||
- 鉂?缁存姢鎴愭湰楂?- 鉂?Bug鐜囦笂鍗?
|
||||
---
|
||||
|
||||
## 📝 规范更新流程
|
||||
|
||||
1. 鎻愬嚭瑙勮寖鍙樻洿闇€姹傦紙Issue鎴朠R锛?2. 鍥㈤槦璁ㄨ<E79281>鍜岃瘎瀹?3. 鏇存柊瑙勮寖鏂囨。
|
||||
1. 提出规范变更需求(Issue或PR)
|
||||
2. 团队讨论和评审
|
||||
3. 更新规范文档
|
||||
4. 通知全员
|
||||
5. 閫愭<EFBFBD>杩佺Щ鏃т唬鐮?
|
||||
5. 逐步迁移旧代码
|
||||
|
||||
---
|
||||
|
||||
## 🔗 相关工具
|
||||
|
||||
**代码检查:**
|
||||
- ESLint锛圝avaScript/TypeScript锛?- Prettier锛堜唬鐮佹牸寮忓寲锛?- Stylelint锛圕SS锛?
|
||||
- ESLint(JavaScript/TypeScript)
|
||||
- Prettier(代码格式化)
|
||||
- Stylelint(CSS)
|
||||
|
||||
**提交检查:**
|
||||
- Husky锛圙it Hooks锛?- Commitlint锛圕ommit Message妫€鏌ワ級
|
||||
- Husky(Git Hooks)
|
||||
- Commitlint(Commit Message检查)
|
||||
|
||||
**数据库:**
|
||||
- Prisma锛圤RM + Migration锛?- pgAdmin锛堟暟鎹<E69A9F>簱绠$悊锛?
|
||||
- Prisma(ORM + Migration)
|
||||
- pgAdmin(数据库管理)
|
||||
|
||||
---
|
||||
|
||||
**最后更新:** 2025-11-06
|
||||
|
||||
Reference in New Issue
Block a user