feat(aia): Complete AIA V2.0 with universal streaming capabilities

Major Changes:
- Add StreamingService with OpenAI Compatible format
- Upgrade Chat component V2 with Ant Design X integration
- Implement AIA module with 12 intelligent agents
- Update API routes to unified /api/v1 prefix
- Update system documentation

Backend (~1300 lines):
- common/streaming: OpenAI Compatible adapter
- modules/aia: 12 agents, conversation service, streaming integration
- Update route versions (RVW, PKB to v1)

Frontend (~3500 lines):
- modules/aia: AgentHub + ChatWorkspace (100% prototype restoration)
- shared/Chat: AIStreamChat, ThinkingBlock, useAIStream Hook
- Update API endpoints to v1

Documentation:
- AIA module status guide
- Universal capabilities catalog
- System overview updates
- All module documentation sync

Tested: Stream response verified, authentication working
Status: AIA V2.0 core completed (85%)
This commit is contained in:
2026-01-14 19:15:01 +08:00
parent 3d35e9c58b
commit 1b53ab9d52
386 changed files with 52096 additions and 65238 deletions

View File

@@ -1,45 +1,45 @@
# 数据库设计规范
# <EFBFBD>唳旿摨栞挽霈∟<EFBFBD><EFBFBD>?
> **版本:** v2.0
> **<EFBFBD><EFBFBD>𧋦嚗?* v2.0
> **<2A><><EFBFBD>擧凒<E693A7><EFBFBD>** 2025-11-06
> **<2A>唳旿摨橒<E691A8>** PostgreSQL 15+
> **ORM** Prisma
> **适用范围:** 平台层 + 能力层 + 业务模块层
> **ORM嚗?* Prisma
> **<EFBFBD><EFBFBD><EFBFBD><EFBFBD>凒嚗?* 撟喳蝱撅?+ <20><EFBFBD>撅?+ 銝𡁜𦛚璅<E79285>撅?
---
## <20><> <20><EFBFBD><E8A9A8><EFBFBD>
本规范是所有模块数据库设计的基础规范,必须严格遵守。
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>㗇芋<EFBFBD>埈㺭<EFBFBD><EFBFBD>霈曇恣<EFBFBD><EFBFBD>抅蝖<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>憿颱艇<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
**设计原则:**
- ✅ 遵循第三范式3NF
- ✅ 使用SERIAL作为主键(整数自增,性能更好)
- ✅ 所有表包含created_at和updated_at时间戳
- ✅ 重要表使用软删除保留deleted_at字段)
- ✅ 外键约束使用ON DELETE CASCADE
- ✅ 敏感字段加密存储密码使用bcrypt
**霈曇恣<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嚗?
---
## 🏗️ Schema隔离策略 ⭐ 最重要
## <EFBFBD><EFBFBD>儭?Schema<EFBFBD>𠉛氖蝑𣇉裦 潃?<3F><><EFBFBD><EFBFBD>
### 銝箔<E98A9D><EFBFBD><E98A8B><EFBFBD>chema<6D>𠉛氖
**核心原因:**
1. **模块独立性**每个业务模块有独立的Schema
2. **支持独立部署**:可以单独导出某个模块的数据
3. **支持独立销售**:可以单独交付某个模块
4. **权限隔离**可以为不同Schema设置不同权限
5. **避免命名冲突**:不同模块可以有相同的表名
**<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>?
### Schema<6D><EFBFBD><EFBFBD><E996AB>
```
platform_schema # 平台基础层(全局共享)
platform_schema # 撟喳蝱<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>曹澈嚗?
aia_schema # AI<41><EFBFBD><E7AE84><EFBFBD>
asl_schema # AI<41><EFBFBD><E7AE84><EFBFBD>
pkb_schema # 个人知识库
pkb_schema # 銝芯犖<EFBFBD><EFBFBD>摨?
dc_schema # <20>唳旿皜<E697BF><E79A9C><EFBFBD><EFBFBD>
ssa_schema # <20><EFBFBD>蝏蠘恣<E8A098><E681A3><EFBFBD>
st_schema # 蝏蠘恣<E8A098><E681A3><EFBFBD>撌亙<E6928C>
@@ -56,18 +56,18 @@ CREATE SCHEMA IF NOT EXISTS aia_schema;
-- ...<2E><EFBFBD>Schema
```
### 跨Schema依赖规则 ⭐ 必须遵守
### 頝沒chema靘肽<EFBFBD><EFBFBD><EFBFBD> 潃?敹<><EFBFBD><EFBFBD>
**<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>韏吔<EFBFBD>**
```sql
-- ✅ 允许业务模块引用platform_schema
-- <EFBFBD>?<3F><>捂嚗帋<E59A97><E5B88B>⊥芋<E28AA5><EFBFBD><E5A092>latform_schema
CREATE TABLE asl_schema.literature_projects (
id SERIAL PRIMARY KEY,
user_id INTEGER REFERENCES platform_schema.users(id) ON DELETE CASCADE,
...
);
-- ✅ 允许:通用能力引用platform_schema
-- <EFBFBD>?<3F><>捂嚗𡁻<E59A97>𡁶鍂<F0A181B6><EFBFBD>撘閧鍂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 (
**蝳<><EFBFBD><E8BFAB><EFBFBD>韏吔<E99F8F>**
```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)
);
-- ❌ 禁止platform_schema反向依赖业务模块
-- <EFBFBD>?蝳<>迫嚗䮝latform_schema<EFBFBD><EFBFBD>靘肽<EFBFBD>銝𡁜𦛚璅<EFBFBD>
CREATE TABLE platform_schema.users (
id SERIAL PRIMARY KEY,
-- <20>躰秤嚗<E7A7A4>latform_schema銝滩<E98A9D>靘肽<E99D98>銝𡁜𦛚璅<E79285>
@@ -92,104 +92,104 @@ CREATE TABLE platform_schema.users (
);
```
**正确做法:**
**<EFBFBD><EFBFBD>𡁏<EFBFBD>嚗?*
```
跨模块数据关联在应用层处理,不在数据库层!
頝冽芋<EFBFBD>埈㺭<EFBFBD><EFBFBD><EFBFBD>𥪜銁摨𠉛鍂撅<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>銝滚銁<EFBFBD>唳旿摨枏<EFBFBD>嚗?
<EFBFBD><EFBFBD>1嚗𡁻<EFBFBD><EFBFBD>user_id<EFBFBD><EFBFBD>
- 銝支葵璅<E79285><E288AA><EFBFBD><E8B3A2>私latform_schema.users
- 在应用层通过user_id查询两个模块的数据
- <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>user_id<EFBFBD>亥砭銝支葵璅<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
- <20><EFBFBD><E585B8><EFBFBD><EFBFBD><E89D8F><EFBFBD>唳旿
方式2存储业务ID字符串
- 在表中存储其他模块的业务IDVARCHAR
- 不建立外键关系
- 在应用层验证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>?
```
---
## <20><> <20><EFBFBD><EFBFBD><E996AB>
### 表命名
### 銵典𦶢<EFBFBD>?
**规则:**
**<EFBFBD><EFBFBD>嚗?*
- 撠誩<E692A0>摮埈<E691AE>
- 下划线分隔
- 銝见<EFBFBD>蝥踹<EFBFBD><EFBFBD>?
- 憭齿㺭敶<E695B6>
- Schema前缀(查询时使用)
- Schema<EFBFBD><EFBFBD><EFBFBD>䰻霂𧒄雿輻鍂嚗?
**示例:**
**蝷箔<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 (...); -- <20>閙㺭
CREATE TABLE literature-projects (...); -- 使用连字符
CREATE TABLE literature-projects (...); -- 雿輻鍂餈𧼮<EFBFBD>蝚?
```
### 摮埈挾<E59F88><EFBFBD>
**规则:**
**<EFBFBD><EFBFBD>嚗?*
- 撠誩<E692A0>摮埈<E691AE>
- 下划线分隔
- 銝见<EFBFBD>蝥踹<EFBFBD><EFBFBD>?
- 霂凋<E99C82><EFBFBD>
**示例:**
**蝷箔<EFBFBD>嚗?*
```sql
-- ✅ 正确
-- <EFBFBD>?甇<>
user_id
created_at
project_name
is_active
-- ❌ 错误
-- <EFBFBD>?<3F>躰秤
userId -- 撽澆陸
createdat -- 没有下划线
prjName -- 缩写不清晰
createdat -- 瘝⊥<EFBFBD>銝见<EFBFBD>蝥?
prjName -- 蝻拙<EFBFBD>銝齿<EFBFBD><EFBFBD>?
```
### 蝝<E89D9D><EFBCB7><EFBFBD>
**规则:** `idx_表名_字段名`
**<EFBFBD><EFBFBD>嚗?* `idx_銵典<E98AB5>_摮埈挾<E59F88>
**示例:**
**蝷箔<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 ... -- 憿箏<E686BF><E7AE8F>躰秤
CREATE INDEX index_on_email ... -- 名称不清晰
CREATE INDEX index_on_email ... -- <EFBFBD>滨妍銝齿<EFBFBD><EFBFBD>?
```
### 憭㚚睸<E39A9A><EFBFBD>
**规则:** `fk_表名_关联表名`
**<EFBFBD><EFBFBD>嚗?* `fk_銵典<EFBFBD>_<EFBFBD><EFBFBD>銵典<EFBFBD>`
**示例:**
**蝷箔<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);
-- ❌ 错误
CONSTRAINT user_fk ... -- 名称不清晰
-- <20>?<3F>躰秤
CONSTRAINT user_fk ... -- <EFBFBD>滨妍銝齿<EFBFBD><EFBFBD>?
CONSTRAINT foreign_key_users ... -- 憭芷鵭
```
---
## 📊 通用字段 ⭐ 必须包含
## <EFBFBD><EFBFBD> <20>𡁶鍂摮埈挾 潃?敹<><EFBFBD><E29786>
### <20><><EFBFBD>㕑”敹<E2809D><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 (
-- 頧臬<E9A0A7><E887AC><EFBFBD>畾蛛<E795BE><E89B9B><EFBFBD><EFBFBD><E39A81><EFBFBD>銵典遣霈格溶<E6A0BC>𩤃<EFBFBD>
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 (
## <20><><E89D9D>霈曇恣閫<E681A3><E996AB>
### 必须添加索引的字段
### <EFBFBD>◆瘛餃<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>畾?
**1. 銝駁睸**
```sql
@@ -266,7 +266,7 @@ CREATE INDEX idx_projects_user_id ON asl_schema.literature_projects(user_id);
**3. 撣貊鍂<E8B28A>亥砭摮埈挾**
```sql
-- status状态字段常用于WHERE
-- status<EFBFBD>𠶖<EFBFBD><EFBFBD><EFBFBD>畾蛛<EFBFBD>撣貊鍂鈭竝HERE嚗?
CREATE INDEX idx_projects_status ON asl_schema.literature_projects(status);
-- created_at嚗<74>𧒄<EFBFBD><EFBFBD>畾蛛<E795BE>撣貊鍂鈭擧<E988AD>摨𧶏<E691A8>
@@ -281,22 +281,22 @@ CREATE UNIQUE INDEX idx_users_email ON platform_schema.users(email);
### 憭滚<E686AD><E89D9D>
**规则:**
**<EFBFBD><EFBFBD>嚗?*
- 擃㗛<E69383><EFBFBD><E89D8F><EFBFBD>亥砭雿輻鍂憭滚<E686AD><E89D9D>
- <20><>撣豢䰻霂<E99C82>摮埈挾<E59F88>曉銁<E69B89>漤𢒰
- 复合索引最多3个字段
- 憭滚<E686AD><E89D9D><EFBCB7><EFBFBD>憭?銝芸<E98A9D>畾?
**示例:**
**蝷箔<EFBFBD>嚗?*
```sql
-- ✅ 正确user_id + status 组合查询
-- <20>?甇<>嚗鮁ser_id + status <EFBFBD><EFBFBD><EFBFBD>亥砭
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 = ? (只用前缀)
-- WHERE user_id = ? <EFBFBD><EFBFBD><EFBFBD><EFBFBD>嚗?
-- ❌ 错误:字段过多
-- <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
-- <20><EFBFBD><E586BD>𣳇膄<F0A3B387><EFBFBD>蝥扯<E89DA5><E689AF>𣳇膄<F0A3B387><EFBFBD><E594BE>唳旿
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; -- 有子记录时禁止删除
ON DELETE RESTRICT; -- <20><EFBFBD>霈啣<E99C88><E595A3><EFBFBD><E79487><EFBCB7>?
```
### 憭㚚睸蝝<E89D9D>
**规则:** 所有外键必须添加索引
**<EFBFBD><EFBFBD>嚗?* <20><><EFBFBD><EFBFBD><E58CA7><EFBFBD>憿餅溶<E9A485>删揣撘?
```sql
-- <20>𥕦遣憭㚚睸
@@ -342,11 +342,11 @@ CREATE INDEX idx_items_project_id ON asl_schema.literature_items(project_id);
---
## ⚡ 性能优化规范
## <EFBFBD>?<3F><EFBFBD>隡睃<E99AA1><EFBFBD><E996AB>
### 憭扯”<E689AF><E2809D>躹嚗<E8BAB9><EFBFBD><EFBFBD>
**适用场景:** 年增长 > 100万记录
**<EFBFBD><EFBFBD><EFBFBD>箸艶嚗?* 撟游<E6929F><E6B8B8>?> 100銝<30>扇敶?
```sql
-- <20><EFBFBD><E39787><EFBFBD>躹嚗<E8BAB9><E59A97>llm_usage銵剁<E98AB5>
@@ -388,13 +388,13 @@ WHERE created_at < NOW() - INTERVAL '1 year';
```sql
-- 撖<><E69296>摮埈挾
password VARCHAR(255) NOT NULL -- 使用bcrypt加密存储哈希值
password VARCHAR(255) NOT NULL -- 雿輻鍂bcrypt<70><EFBFBD><EFBFBD><E59A97><EFBFBD><EFBFBD><EFBFBD><E692A3>?
-- API Key摮埈挾
api_key_encrypted TEXT NOT NULL -- 雿輻鍂AES-256<35><EFBFBD>
-- 銝芯犖<E88AAF>𤩺<EFBFBD>靽⊥<E99DBD>
phone_encrypted VARCHAR(255) -- 手机号加密
phone_encrypted VARCHAR(255) -- <EFBFBD>𧢲㦤<EFBFBD><EFBFBD>撖?
id_card_encrypted VARCHAR(255) -- 頨思遢霂<E981A2><EFBFBD><EFBFBD>
```
@@ -402,7 +402,7 @@ id_card_encrypted VARCHAR(255) -- 身份证号加密
```sql
-- <20><EFBFBD>銝凋<E98A9D>霈啣<E99C88><E595A3>𤩺<EFBFBD>摮埈挾
-- 开发/测试环境使用脱敏数据
-- 撘<><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';
### 撣貊鍂摮埈挾蝐餃<E89D90>
| 用途 | 推荐类型 | 说明 |
| <EFBFBD><EFBFBD>?| <20><EFBFBD>蝐餃<E89D90> | 霂湔<E99C82> |
|------|---------|------|
| 銝駁睸 | SERIAL | <20>湔㺭<E6B994><EFBFBD> |
| 外键 | INTEGER | 与主键类型一致 |
| 短文本 | VARCHAR(N) | N<500,如姓名、标题 |
| 长文本 | TEXT | 无长度限制,如描述、内容 |
| 布尔值 | BOOLEAN | true/false |
| 日期时间 | TIMESTAMP | 精确到毫秒 |
| 憭㚚睸 | 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>唳神蝘?|
| <20><EFBFBD> | DECIMAL(10,2) | <20><EFBFBD>蝎曉漲<E69B89><EFBFBD> |
| JSON | JSONB | <20><EFBFBD><E89D9D>嚗峕<E59A97><EFBFBD><E689AF>游末 |
### 摮埈挾<E59F88>踹漲撱箄悅
```sql
-- 短文本
-- <20><EFBFBD><E5899C>?
name VARCHAR(100) -- 憪枏<E686AA>
title VARCHAR(200) -- <20><><EFBFBD>
email VARCHAR(255) -- <20>桃拳
phone VARCHAR(20) -- 手机号
phone VARCHAR(20) -- <EFBFBD>𧢲㦤<EFBFBD>?
-- 状态枚举
-- <20><EFBFBD><E59786><EFBFBD>銝?
status VARCHAR(20) -- active, inactive, deleted
role VARCHAR(20) -- user, admin
-- 长文本
-- <20><EFBFBD><E8B8B5>?
description TEXT -- <20>讛膩
content TEXT -- <20><>
```
---
## ✅ 检查清单
## <EFBFBD>?璉<><E79289><EFBFBD><E4BAA4>?
**霈曇恣<E69B87>啗”<E59597><EFBFBD>憿餅<E686BF><E9A485><EFBFBD>**
- [ ] 表名符合命名规范(小写+下划线+复数)
- [ ] 銵典<EFBFBD>蝚血<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?銝见<E98A9D>蝥?憭齿㺭嚗?
- [ ] 雿輻鍂甇<E98D82><EFBFBD><EFBC86>chema嚗īlatform/aia/asl/pkb蝑㚁<E89D91>
- [ ] 包含id主键SERIAL PRIMARY KEY
- [ ] 包含created_at和updated_at时间戳
- [ ] <EFBFBD><EFBFBD>鉄id銝駁睸嚗𠄎ERIAL PRIMARY KEY嚗?
- [ ] <EFBFBD><EFBFBD>created_at<EFBFBD>pdated_at<EFBFBD>園𡢿<EFBFBD>?
- [ ] <20><EFBFBD><E586BD><EFBFBD>銵典<E98AB5><E585B8>哎ser_id憭㚚睸
- [ ] <20><><EFBFBD><EFBFBD><E58CA7><EFBFBD><E6A185>伨N DELETE蝑𣇉裦
- [ ] 所有外键都添加了索引
- [ ] 常用查询字段添加了索引
- [ ] <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>瘛餃<EFBFBD><EFBFBD>揣撘?
- [ ] 撣貊鍂<EFBFBD>亥砭摮埈挾瘛餃<EFBFBD><EFBFBD>揣撘?
- [ ] 憭㚚睸蝥行<E89DA5>蝚血<E89D9A>頝沒chema靘肽<E99D98><EFBFBD><E996AB>
- [ ] 敏感字段已加密存储
- [ ] <EFBFBD>𤩺<EFBFBD>摮埈挾撌脣<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
---
## <20><> <20><EFBFBD><E8A9A8><EFBFBD>
**总览:**
- [数据库全局视图](./03-数据库全局视图.md) ⭐ 查看所有Schema和表
**<EFBFBD><EFBFBD>嚗?*
- [<EFBFBD>唳旿摨枏<EFBFBD><EFBFBD><EFBFBD>](./03-<2D>唳旿摨枏<E691A8><EFBFBD><EFBFBD>㦛.md) 潃?<3F><EFBFBD><E4BAA6><EFBFBD><EFBFBD>chema<EFBFBD>諹”
**模板:**
- [数据库设计模板](../_templates/数据库设计-模板.md)
**璅⊥踎嚗?*
- [<EFBFBD>唳旿摨栞挽霈⊥芋<EFBFBD>瓢(../_templates/<EFBFBD>唳旿摨栞挽霈?璅⊥踎.md)
**<EFBFBD><EFBFBD><EFBFBD>𡑒挽霈∴<EFBFBD>**
- [平台基础层](../01-平台基础层/README.md)
- [通用能力层](../02-通用能力层/README.md)
- [撟喳蝱<EFBFBD><EFBFBD><EFBFBD>(../01-撟喳蝱<E596B3><EFBFBD>撅?README.md)
- [<EFBFBD>𡁶鍂<EFBFBD><EFBFBD><EFBFBD>(../02-<2D>𡁶鍂<F0A181B6><EFBFBD>撅?README.md)
- [銝𡁜𦛚璅<E79285><EFBFBD>(../03-銝𡁜𦛚璅<E79285>/README.md)
---
**<EFBFBD><EFBFBD><EFBFBD>擧凒<EFBFBD><EFBFBD>** 2025-11-06
**蝏湔擪鈭綽<E988AD>** <20><><EFBFBD>舀沲<E88880><E6B2B2><EFBFBD>
**版本:** v2.0
**<EFBFBD><EFBFBD>𧋦嚗?* v2.0

View File

@@ -1,32 +1,32 @@
# API霈曇恣閫<E681A3><E996AB>
> **版本:** v2.0
> **<EFBFBD><EFBFBD>𧋦嚗?* v2.0
> **<2A><><EFBFBD>擧凒<E693A7><EFBFBD>** 2025-11-06
> **API风格:** RESTful API
> **基础URL** `http://localhost:3001/api/v1`
> **适用范围:** 平台层 + 能力层 + 业务模块层
> **API憌擧聢嚗?* RESTful API
> **<EFBFBD><EFBFBD>URL嚗?* `http://localhost:3001/api/v1`
> **<EFBFBD><EFBFBD><EFBFBD><EFBFBD>凒嚗?* 撟喳蝱撅?+ <20><EFBFBD>撅?+ 銝𡁜𦛚璅<E79285>撅?
---
## <20><> 霈曇恣<E69B87><EFBFBD>
### API First<73><EFBFBD>
- ✅ 先设计API再实现功能
- API是前后端的契约
- API变更需要版本控制
- ✅ 所有API都要有文档
- <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>獢?
### RESTful霈曇恣
- ✅ 使用HTTP动词表示操作GET、POST、PUT、DELETE
- URL表示资源,不表示动作
- ✅ 使用复数名词表示资源集合
- ✅ 嵌套资源不超过2层
- ✅ 使用HTTP状态码表示结果
- <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>
### <20><EFBFBD><EFBFBD><E996AB>
- URL使用小写字母和连字符kebab-case
- ✅ 查询参数使用驼峰命名camelCase
- JSON字段使用驼峰命名camelCase
- <EFBFBD>?URL雿輻鍂撠誩<EFBFBD>摮埈<EFBFBD><EFBFBD><EFBFBD>摮㛖泵嚗ɑebab-case嚗?
- <EFBFBD>?<3F>亥砭<E4BAA5><E7A0AD>㺭雿輻鍂撽澆陸<E6BE86><EFBFBD>嚗ẾamelCase嚗?
- <EFBFBD>?JSON摮埈挾雿輻鍂撽澆陸<EFBFBD><EFBFBD>嚗ẾamelCase嚗?
---
@@ -37,9 +37,9 @@
```
/api/v{version}/{module}/{resource}/{id?}/{action?}
示例:
蝷箔<EFBFBD>嚗?
/api/v1/literature/projects # <20><EFBFBD><E79195><EFBFBD>讃憿寧𤌍<E5AFA7>𡑒”
/api/v1/literature/projects/123 # 获取ID=123的项目
/api/v1/literature/projects/123 # <EFBFBD><EFBFBD>ID=123<EFBFBD><EFBFBD><EFBFBD>?
/api/v1/literature/projects/123/export # 撖澆枂憿寧𤌍嚗<F0A48C8D>𢆡雿頣<E99BBF>
```
@@ -50,19 +50,19 @@
| 霈方<E99C88> | `/auth` | `/api/v1/auth/login` |
| <20><EFBFBD> | `/users` | `/api/v1/users/me` |
| AI<41><EFBFBD> | `/chat` | `/api/v1/chat/conversations` |
| 智能体 | `/agents` | `/api/v1/agents` |
| <EFBFBD><EFBFBD>雿?| `/agents` | `/api/v1/agents` |
| AI<41><49>讃 | `/literature` | `/api/v1/literature/projects` |
| 知识库 | `/knowledge-bases` | `/api/v1/knowledge-bases` |
| <EFBFBD><EFBFBD>摨?| `/knowledge-bases` | `/api/v1/knowledge-bases` |
| <20>唳旿皜<E697BF><E79A9C> | `/data-cleaning` | `/api/v1/data-cleaning/projects` |
| 蝏蠘恣<E8A098><E681A3><EFBFBD> | `/analysis` | `/api/v1/analysis/projects` |
| 蝏蠘恣撌亙<E6928C> | `/tools` | `/api/v1/tools` |
| 蝔蹂辣摰⊥䰻 | `/review` | `/api/v1/review/tasks` |
| LLM蝵穃<E89DB5> | `/llm` | `/api/v1/llm/chat` |
| 管理端 | `/admin` | `/api/v1/admin/users` |
| 蝞∠<EFBFBD>蝡?| `/admin` | `/api/v1/admin/users` |
### 韏<><E99F8F><EFBFBD><EFBFBD>
**✅ 正确示例:**
**<EFBFBD>?甇<>蝷箔<E89DB7>嚗?*
```
GET /api/v1/literature/projects # <20><EFBFBD><E79195>𡑒”
GET /api/v1/literature/projects/:id # <20><EFBFBD>霂行<E99C82>
@@ -72,10 +72,10 @@ DELETE /api/v1/literature/projects/:id # 删除
GET /api/v1/literature/projects/:id/items # <20><EFBFBD>憿寧𤌍銝讠<E98A9D><E8AEA0><EFBFBD>
POST /api/v1/literature/projects/:id/items/import # 撖澆<E69296><E6BE86><EFBFBD>
POST /api/v1/literature/projects/:id/screening/execute # 执行筛选
POST /api/v1/literature/projects/:id/screening/execute # <EFBFBD><EFBFBD>蝑偦<EFBFBD>?
```
**❌ 错误示例:**
**<EFBFBD>?<3F>躰秤蝷箔<E89DB7>嚗?*
```
POST /api/v1/literature/getProjects # 雿輻鍂<E8BCBB><EFBFBD>
POST /api/v1/literature/createProject # 雿輻鍂<E8BCBB><EFBFBD>
@@ -89,13 +89,13 @@ GET /api/v1/literatureProjectList # 驼峰命名
### <20><EFBFBD>雿輻鍂
| 方法 | 用途 | 是否幂等 | 是否安全 |
| <EFBFBD><EFBFBD> | <20><EFBFBD>?| <20>臬炏撟<E7828F><E6929F> | <20>臬炏摰匧<E691B0> |
|------|------|---------|---------|
| **GET** | 获取资源 | ✅ | ✅ |
| **POST** | 创建资源 | ❌ | ❌ |
| **PUT** | 完整更新资源 | ✅ | ❌ |
| **PATCH** | 部分更新资源 | ❌ | ❌ |
| **DELETE** | 删除资源 | ✅ | ❌ |
| **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>?|
### <20><EFBFBD>蝷箔<E89DB7>
@@ -109,7 +109,7 @@ GET /api/v1/literature/projects/123
# <EFBFBD>𥕦<EFBFBD><EFBFBD>
POST /api/v1/literature/projects
Content-Type: application/json
{ "name": "", "description": "..." }
{ "name": "<EFBFBD><EFBFBD>?, "description": "..." }
# <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
PUT /api/v1/literature/projects/123
@@ -119,7 +119,7 @@ Content-Type: application/json
# <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
PATCH /api/v1/literature/projects/123
Content-Type: application/json
{ "name": "" }
{ "name": "<EFBFBD><EFBFBD><EFBFBD>? }
# <EFBFBD>𣳇<EFBFBD><EFBFBD>
DELETE /api/v1/literature/projects/123
@@ -135,15 +135,15 @@ DELETE /api/v1/literature/projects/123
|--------|------|---------|
| **200** | OK | <20>𣂼<EFBFBD>餈𥪜<E9A488><F0A5AA9C>唳旿 |
| **201** | Created | <20>𣂼<EFBFBD><F0A382BC>𥕦遣韏<E981A3><E99F8F> |
| **204** | No Content | 成功但无返回数据(如删除) |
| **204** | No Content | <EFBFBD>𣂼<EFBFBD><EFBFBD><EFBFBD>餈𥪜<EFBFBD><EFBFBD>唳旿嚗<EFBFBD><EFBFBD><EFBFBD>𣳇膄嚗?|
| **400** | Bad Request | 霂瑟<E99C82><E7919F><EFBFBD><EFBFBD>躰秤 |
| **401** | Unauthorized | 未认证(没有Token或Token过期) |
| **403** | Forbidden | 无权限(已认证但权限不足) |
| **404** | Not Found | 资源不存在 |
| **409** | Conflict | 资源冲突(如重复创建) |
| **422** | Unprocessable Entity | 语义错误(如验证失败) |
| **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>憭梯揖嚗?|
| **429** | Too Many Requests | 霂瑟<E99C82><EFBFBD><E9A488>憸𤑳<E686B8><EFBFBD><E59A97><EFBFBD><E7989A> |
| **500** | Internal Server Error | 服务器错误 |
| **500** | Internal Server Error | <EFBFBD>滚𦛚<EFBFBD><EFBFBD>霂?|
### <20><EFBFBD><E59786><EFBFBD>雿輻鍂蝷箔<E89DB7>
@@ -154,7 +154,7 @@ res.status(200).json({ success: true, data: projects });
// 201 Created - <20>𣂼<EFBFBD><F0A382BC>𥕦遣韏<E981A3><E99F8F>
res.status(201).json({ success: true, data: newProject });
// 204 No Content - 成功删除(无内容返回)
// 204 No Content - <EFBFBD>𣂼<EFBFBD><EFBFBD>𣳇膄嚗<EFBFBD><EFBFBD><EFBFBD><EFBFBD>捆餈𥪜<EFBFBD>嚗?
res.status(204).send();
// 400 Bad Request - <20><><EFBFBD>躰秤
@@ -163,22 +163,22 @@ res.status(400).json({
error: { code: 'INVALID_PARAMS', message: '<27><><EFBFBD>躰秤' }
});
// 401 Unauthorized - 未认证
// 401 Unauthorized - <EFBFBD>芾恕霂?
res.status(401).json({
success: false,
error: { code: 'UNAUTHORIZED', message: '霂瑕<E99C82><E79195><EFBFBD>' }
});
// 403 Forbidden - 无权限
// 403 Forbidden - <EFBFBD><EFBFBD><EFBFBD>?
res.status(403).json({
success: false,
error: { code: 'FORBIDDEN', message: '<27><EFBFBD>霈輸䔮' }
});
// 404 Not Found - 资源不存在
// 404 Not Found - <EFBFBD><EFBFBD>銝滚<EFBFBD><EFBFBD>?
res.status(404).json({
success: false,
error: { code: 'NOT_FOUND', message: '资源不存在' }
error: { code: 'NOT_FOUND', message: '<EFBFBD><EFBFBD>銝滚<EFBFBD><EFBFBD>? }
});
// 422 Unprocessable Entity - 撉諹<E69289>憭梯揖
@@ -196,9 +196,9 @@ res.status(422).json({
## <20><> <20><EFBFBD><E6BB9A><EFBFBD><EFBFBD><E996AB>
### 统一响应格式 ⭐ 必须遵守
### 蝏煺<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": "邮箱格式不正确"
"message": "<EFBFBD>桃拳<EFBFBD><EFBFBD>銝齿迤蝖?
},
{
"field": "password",
"message": "密码长度必须大于6位"
"message": "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>6?
}
]
}
@@ -268,7 +268,7 @@ res.status(422).json({
---
## 🔑 认证与授权规范
## <EFBFBD><EFBFBD> 霈方<E99C88>銝擧<E98A9D><E693A7><EFBFBD><EFBFBD><EFBFBD>?
### JWT霈方<E99C88>
@@ -307,12 +307,12 @@ Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
**3. Token餈<6E><E9A488><EFBFBD><E686AD>**
```http
# Token401
# Token<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?01
{
"success": false,
"error": {
"code": "TOKEN_EXPIRED",
"message": "Token"
"message": "Token<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
}
}
@@ -327,23 +327,23 @@ Content-Type: application/json
### <20><><EFBFBD><EFBFBD><EFBFBD>
| 端点类型 | 需要认证 | 角色要求 |
| 蝡舐<EFBFBD>蝐餃<EFBFBD> | <20><><EFBFBD>恕霂?| 閫坿𠧧閬<F0A0A7A7><E996AC> |
|---------|---------|---------|
| 公开端点 | ❌ | 无 |
| 用户端点 | | user |
| 管理端点 | | admin |
| <EFBFBD><EFBFBD>蝡舐<EFBFBD> | <20>?| <20>?|
| <EFBFBD><EFBFBD>蝡舐<EFBFBD> | <EFBFBD>?| user |
| 蝞∠<EFBFBD>蝡舐<EFBFBD> | <EFBFBD>?| admin |
**示例:**
**蝷箔<EFBFBD>嚗?*
```typescript
// 公开端点(无需认证)
// <EFBFBD><EFBFBD>蝡舐<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>霈方<EFBFBD>嚗?
POST /api/v1/auth/login
POST /api/v1/auth/register
// 用户端点需要认证user角色
// <EFBFBD><EFBFBD>蝡舐<EFBFBD><EFBFBD><EFBFBD><EFBFBD>恕霂<EFBFBD><EFBFBD>user閫坿𠧧嚗?
GET /api/v1/literature/projects
POST /api/v1/literature/projects
// 管理端点需要认证admin角色
// 蝞∠<EFBFBD>蝡舐<EFBFBD><EFBFBD><EFBFBD><EFBFBD>恕霂<EFBFBD><EFBFBD>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参数:
- page: 页码默认1
- pageSize: 每页数量默认10最大100
- sortBy: 排序字段默认createdAt
- sortOrder: 排序方向asc/desc默认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嚗?
```
### <20><EFBFBD><E6BB9A><EFBFBD>
@@ -387,16 +387,16 @@ Query参数
## <20><> 蝑偦<E89D91><EFBFBD><E58A90>𦦵揣閫<E68FA3><E996AB>
### 筛选参数
### 蝑偦<EFBFBD><EFBFBD><EFBFBD>?
```
GET /api/v1/literature/projects?status=active&keyword=撉刻捶<E588BB>𤩺𠹭
Query参数:
- status: 状态筛选(active/inactive
- keyword: 关键词搜索(搜索name和description字段)
Query<EFBFBD><EFBFBD>㺭嚗?
- status: <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>active/inactive嚗?
- keyword: <EFBFBD>喲睸霂齿<EFBFBD><EFBFBD><EFBFBD>𦦵揣name<EFBFBD>𩥇escription摮埈挾嚗?
- userId: <20><EFBFBD>ID蝑偦<E89D91><EFBFBD>蝞∠<E89D9E>蝡荔<E89DA1>
- startDate/endDate: 日期范围筛选
- startDate/endDate: <EFBFBD><EFBFBD><EFBFBD><EFBFBD>凒蝑偦<EFBFBD>?
```
### <20>𦦵揣<F0A6A6B5><EFBFBD>
@@ -417,29 +417,29 @@ Query参数
---
## ⚠️ 错误码设计
## <EFBFBD>𩤃<EFBFBD> <20>躰秤<E8BAB0><E7A7A4>挽霈?
### 标准错误码
### <EFBFBD><EFBFBD><EFBFBD><EFBFBD>躰秤<EFBFBD>?
| 错误码 | HTTP状态 | 说明 |
| <EFBFBD>躰秤<EFBFBD>?| HTTP<EFBFBD><EFBFBD>?| 霂湔<E99C82> |
|--------|---------|------|
| `VALIDATION_ERROR` | 422 | <20><>㺭撉諹<E69289>憭梯揖 |
| `UNAUTHORIZED` | 401 | 未认证 |
| `UNAUTHORIZED` | 401 | <EFBFBD>芾恕霂?|
| `TOKEN_EXPIRED` | 401 | Token餈<6E><E9A488> |
| `FORBIDDEN` | 403 | 无权限 |
| `NOT_FOUND` | 404 | 资源不存在 |
| `ALREADY_EXISTS` | 409 | 资源已存在 |
| `FORBIDDEN` | 403 | <EFBFBD><EFBFBD><EFBFBD>?|
| `NOT_FOUND` | 404 | <EFBFBD><EFBFBD>銝滚<EFBFBD><EFBFBD>?|
| `ALREADY_EXISTS` | 409 | <EFBFBD><EFBFBD>撌脣<EFBFBD><EFBFBD>?|
| `QUOTA_EXCEEDED` | 429 | <20><EFBFBD><EFBFBD><E9A09E> |
| `INTERNAL_ERROR` | 500 | 服务器错误 |
| `INTERNAL_ERROR` | 500 | <EFBFBD>滚𦛚<EFBFBD><EFBFBD>霂?|
### 业务错误码
### 銝𡁜𦛚<EFBFBD>躰秤<EFBFBD>?
```typescript
// 模块特定错误码(前缀区分)
ASL_IMPORT_FAILED // AI文献:导入失败
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>躰秤<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>嚗?
ASL_IMPORT_FAILED // AI<EFBFBD><EFBFBD>讃嚗𡁜紡<EFBFBD>亙仃韐?
ASL_SCREENING_IN_PROGRESS // AI<41><49>讃嚗𡁶<E59A97><F0A181B6><EFBFBD>銵䔶葉
PKB_QUOTA_EXCEEDED // <20><EFBFBD>摨橒<E691A8><E6A992><EFBFBD><EFBFBD><E9A09E>
LLM_QUOTA_EXCEEDED // LLM:配额超限
LLM_QUOTA_EXCEEDED // LLM嚗𡁻<EFBFBD>憸肽<EFBFBD><EFBFBD>?
```
---
@@ -452,7 +452,7 @@ LLM_QUOTA_EXCEEDED // LLM配额超限
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>銵冽𦻖<EFBFBD><EFBFBD><EFBFBD>憿餅𣈲<EFBFBD><EFBFBD><EFBFBD>憿蛛<EFBFBD>
- 暺䁅恕pageSize=10
- <20><>憭吠ageSize=100
- 禁止一次性返回全部数据
- <EFBFBD>迫銝<EFBFBD>甈⊥<EFBFBD><EFBFBD><EFBFBD>𧼮<EFBFBD><EFBFBD>冽㺭<EFBFBD>?
```
### 2. 摮埈挾餈<E68CBE>
@@ -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. 蝻枏<E89DBB>蝑𣇉裦
```http
#
# <EFBFBD>?
Cache-Control: public, max-age=300
# ETag
@@ -477,40 +477,40 @@ If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"
---
## ✅ 检查清单
## <EFBFBD>?璉<><E79289><EFBFBD><E4BAA4>?
**霈曇恣<E69B87>蚊PI<50><EFBFBD>憿餅<E686BF><E9A485><EFBFBD>**
- [ ] URL符合RESTful规范(使用名词+复数)
- [ ] 使用正确的HTTP方法GET/POST/PUT/DELETE
- [ ] URL蝚血<EFBFBD>RESTful<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>霂?憭齿㺭嚗?
- [ ] 雿輻鍂甇<EFBFBD><EFBFBD><EFBFBD>TTP<EFBFBD><EFBFBD>嚗𠃑ET/POST/PUT/DELETE嚗?
- [ ] 雿輻鍂甇<E98D82><EFBFBD><EFBC86>TTP<54><EFBFBD><E59786><EFBFBD>
- [ ] 响应格式符合统一规范success + data/error
- [ ] <EFBFBD><EFBFBD><EFBFBD><EFBFBD>蝚血<EFBFBD>蝏煺<EFBFBD><EFBFBD><EFBFBD>嚗ìuccess + data/error嚗?
- [ ] <20><><EFBFBD>恕霂<E68195><E99C82><EFBFBD>亙藁璉<E89781><E79289>仔WT Token
- [ ] 需要权限的接口检查用户角色
- [ ] <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>亙藁璉<EFBFBD><EFBFBD>亦鍂<EFBFBD><EFBFBD><EFBFBD>?
- [ ] <20>𡑒”<F0A19192>亙藁<E4BA99><EFBFBD><E88880><EFBFBD>
- [ ] <20>𡑒”<F0A19192>亙藁<E4BA99><EFBFBD><E88880><EFBFBD>
- [ ] 错误响应包含明确的错误码和错误信息
- [ ] <EFBFBD>躰秤<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>𡒊<EFBFBD><EFBFBD><EFBFBD>霂舐<EFBFBD><EFBFBD><EFBFBD>霂臭縑<EFBFBD>?
- [ ] <20><><EFBFBD>𡅅PI<50><EFBFBD><E8B3A3><EFBFBD>﹝霂湔<E99C82>
---
## <20><> <20><EFBFBD><E8A9A8><EFBFBD>
**总览:**
- [API路由总览](./04-API路由总览.md) ⭐ 查看所有API端点
**<EFBFBD><EFBFBD>嚗?*
- [API頝舐眏<EFBFBD><EFBFBD>](./04-API頝舐眏<EFBFBD><EFBFBD>.md) 潃?<3F><EFBFBD><E4BAA6><EFBFBD><EFBFBD>𡅅PI蝡舐<E89DA1>
**模板:**
**璅⊥踎嚗?*
- [API霈曇恣璅⊥踎](../_templates/API霈曇恣-璅⊥踎.md)
**<EFBFBD><EFBFBD><EFBFBD>𡑒挽霈∴<EFBFBD>**
- [平台基础层](../01-平台基础层/README.md)
- [通用能力层](../02-通用能力层/README.md)
- [撟喳蝱<EFBFBD><EFBFBD><EFBFBD>(../01-撟喳蝱<E596B3><EFBFBD>撅?README.md)
- [<EFBFBD>𡁶鍂<EFBFBD><EFBFBD><EFBFBD>(../02-<2D>𡁶鍂<F0A181B6><EFBFBD>撅?README.md)
- [銝𡁜𦛚璅<E79285><EFBFBD>(../03-銝𡁜𦛚璅<E79285>/README.md)
---
**<EFBFBD><EFBFBD><EFBFBD>擧凒<EFBFBD><EFBFBD>** 2025-11-06
**蝏湔擪鈭綽<E988AD>** <20><><EFBFBD>舀沲<E88880><E6B2B2><EFBFBD>
**版本:** v2.0
**<EFBFBD><EFBFBD>𧋦嚗?* v2.0

View File

@@ -1,7 +1,7 @@
# <20>唳旿摨枏<E691A8><EFBFBD><EFBFBD>
> **目的:** 提供所有Schema和表的快速索引便于查找和理解全局数据架构
> **详细设计:** 请查看各模块的 `01-数据库设计.md`
> **<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`
> **<2A>唳旿摨橒<E691A8>** PostgreSQL 15+
> **<2A><><EFBFBD>擧凒<E693A7><EFBFBD>** 2025-11-06
@@ -9,202 +9,202 @@
## <20><> Schema<6D><EFBFBD>蝑𣇉裦
### Schema隔离原则 ⭐
### Schema<EFBFBD>𠉛氖<EFBFBD><EFBFBD> 潃?
**为什么需要Schema隔离**
1. **模块独立性**每个业务模块有独立的Schema
2. **支持独立部署**:可以单独导出某个模块的数据
3. **权限隔离**可以为不同Schema设置不同权限
4. **避免命名冲突**:不同模块可以有相同的表名
**銝箔<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命名规范:**
**Schema<EFBFBD><EFBFBD><EFBFBD><EFBFBD>嚗?*
```
platform_schema # 平台基础层(全局共享)
platform_schema # 撟喳蝱<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>曹澈嚗?
aia_schema # AI<41><EFBFBD><E7AE84><EFBFBD>
asl_schema # AI<41><EFBFBD><E7AE84><EFBFBD>
pkb_schema # 个人知识库
pkb_schema # 銝芯犖<EFBFBD><EFBFBD>摨?
dc_schema # <20>唳旿皜<E697BF><E79A9C><EFBFBD><EFBFBD>
ssa_schema # <20><EFBFBD>蝏蠘恣<E8A098><E681A3><EFBFBD>
st_schema # 蝏蠘恣<E8A098><E681A3><EFBFBD>撌亙<E6928C>
rvw_schema # 蝔蹂辣摰⊥䰻蝟餌<E89D9F>
admin_schema # 运营管理端(可选,可合并到platform_schema
admin_schema # 餈鞱𨯫蝞∠<EFBFBD>蝡荔<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>撟嗅<EFBFBD>platform_schema嚗?
```
---
## <20><> Schema銝<61><EFBFBD>
| Schema | 说明 | 表数量 | 状态 | 详细设计 |
| Schema | 霂湔<EFBFBD> | 銵冽㺭<E586BD>?| <20><EFBFBD>?| 霂衣<E99C82>霈曇恣 |
|--------|------|--------|------|---------|
| **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个 | ⏳ 规划中 | 待设计 |
| **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>銝?| 敺<>挽霈?|
**总表数:** ~70个(预估)
**<EFBFBD>餉”<EFBFBD><EFBFBD>** ~70銝迎<EFBFBD><EFBFBD>摯嚗?
---
## <20><> platform_schema嚗<61><EFBFBD>啣抅蝖<E68A85><EFBFBD><E69285>
**职责:** 存储全局共享的平台数据,所有业务模块都依赖
**<EFBFBD>諹提嚗?* 摮睃<E691AE><E79D83><EFBFBD><E585B8>曹澈<E69BB9><E6BE88><EFBFBD>唳㺭<E594B3><EFBFBD><E6AEB7><EFBFBD><EFBFBD><EFBFBD><E58A90>⊥芋<E28AA5><EFBFBD>靘肽<E99D98>
**详细设计:** [UAM/01-数据库设计](../01-平台基础层/01-用户与权限中心(UAM)/01-数据库设计.md)
**霂衣<EFBFBD>霈曇恣嚗?* [UAM/01-<EFBFBD>唳旿摨栞挽霈(../01-撟喳蝱<E596B3><EFBFBD>撅?01-<2D><EFBFBD>銝擧<E98A9D><E693A7>𣂷葉敹?UAM)/01-<EFBFBD>唳旿摨栞挽霈?md)
### <20><EFBFBD>銵剁<E98AB5><E58981><EFBFBD>銝擧<E98A9D><E693A7><EFBFBD>
| 表名 | 说明 | 记录数预估 | 详细设计 |
| 銵典<EFBFBD> | 霂湔<E99C82> | 霈啣<E99C88><E595A3><EFBFBD>隡?| 霂衣<E99C82>霈曇恣 |
|------|------|-----------|---------|
| **users** | 用户基础信息 | 10万/年 | [UAM/01-数据库设计](../01-平台基础层/01-用户与权限中心(UAM)/01-数据库设计.md) |
| **users** | <EFBFBD><EFBFBD><EFBFBD><EFBFBD>靽⊥<EFBFBD> | 10銝?撟?| [UAM/01-<EFBFBD>唳旿摨栞挽霈(../01-撟喳蝱<E596B3><EFBFBD>撅?01-<2D><EFBFBD>銝擧<E98A9D><E693A7>𣂷葉敹?UAM)/01-<EFBFBD>唳旿摨栞挽霈?md) |
| **roles** | 閫坿𠧧摰帋<E691B0> | <100 | <20><EFBFBD> |
| **permissions** | <20><><EFBFBD>摰帋<E691B0> | <500 | <20><EFBFBD> |
| **user_roles** | 用户-角色关联 | 10万/年 | 同上 |
| **feature_flags** | Feature Flag配置 ⭐ | <100 | 同上 |
| **user_feature_flags** | 用户-Feature Flag关联 ⭐ | 10万/年 | 同上 |
| **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> |
### LLM相关表
### LLM<EFBFBD><EFBFBD>銵?
| 表名 | 说明 | 记录数预估 | 详细设计 |
| 銵典<EFBFBD> | 霂湔<E99C82> | 霈啣<E99C88><E595A3><EFBFBD>隡?| 霂衣<E99C82>霈曇恣 |
|------|------|-----------|---------|
| **llm_models** | LLM模型配置 | <20 | [LLM网关/01-数据库设计](../02-通用能力层/01-LLM大模型网关/01-数据库设计.md) |
| **llm_usage** | LLM使用记录 ⭐ | 1000万/年 | 同上 |
| **llm_quotas** | LLM配额管理 | 10万/年 | 同上 |
| **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> |
### 监控与日志
### <EFBFBD>烐綉銝擧𠯫敹?
| 表名 | 说明 | 记录数预估 | 详细设计 |
| 銵典<EFBFBD> | 霂湔<E99C82> | 霈啣<E99C88><E595A3><EFBFBD>隡?| 霂衣<E99C82>霈曇恣 |
|------|------|-----------|---------|
| **admin_logs** | 管理员操作日志 | 10万/年 | [监控与日志/01-数据库设计](../01-平台基础层/04-监控与日志/01-数据库设计.md) |
| **error_logs** | 错误日志 | 100万/年 | 同上 |
| **audit_logs** | 审计日志 | 100万/年 | 同上 |
| **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> |
### 蝟餌<E89D9F><E9A48C>滨蔭
| 表名 | 说明 | 记录数预估 | 详细设计 |
| 銵典<EFBFBD> | 霂湔<E99C82> | 霈啣<E99C88><E595A3><EFBFBD>隡?| 霂衣<E99C82>霈曇恣 |
|------|------|-----------|---------|
| **system_configs** | 系统配置 | <100 | [系统配置/01-数据库设计](../01-平台基础层/05-系统配置/01-数据库设计.md) |
| **system_configs** | 蝟餌<EFBFBD><EFBFBD>滨蔭 | <100 | [蝟餌<EFBFBD><EFBFBD>滨蔭/01-<2D>唳旿摨栞挽霈(../01-撟喳蝱<E596B3><EFBFBD>撅?05-蝟餌<E89D9F><E9A48C>滨蔭/01-<2D>唳旿摨栞挽霈?md) |
| **prompt_templates** | Prompt璅⊥踎 | <500 | <20><EFBFBD> |
| **announcements** | 蝟餌<E89D9F><E9A48C><EFBFBD> | <1000 | <20><EFBFBD> |
---
## 🤖 aia_schemaAI智能问答
## <EFBFBD><EFBFBD> aia_schema嚗㇁I<EFBFBD><EFBFBD><EFBFBD><EFBFBD>嚗?
**职责:** 存储AI智能问答相关数据12个智能体、对话历史
**<EFBFBD>諹提嚗?* 摮睃<E691AE>AI<41><EFBFBD><E7AE84><EFBFBD><E6A183><EFBFBD><E8A9A8>唳旿嚗?2銝芣惣<E88AA3><EFBFBD><E8B3AD><EFBFBD>笆霂嘥<E99C82><E598A5><EFBFBD>
**状态:** ✅ 已实现
**详细设计:** [AIA/01-数据库设计](../03-业务模块/AIA-AI智能问答/01-数据库设计.md)(待创建)
**<EFBFBD><EFBFBD><EFBFBD><EFBFBD>** <20>?撌脣<E6928C><E884A3>?
**霂衣<EFBFBD>霈曇恣嚗?* [AIA/01-<EFBFBD>唳旿摨栞挽霈(../03-銝𡁜𦛚璅<E79285>/AIA-AI<41><EFBFBD><E7AE84><EFBFBD>/01-<2D>唳旿摨栞挽霈?md)嚗<><E59A97><EFBFBD>𥕦遣嚗?
### 核心表
### <EFBFBD><EFBFBD>銵?
| 表名 | 说明 | 记录数预估 |
| 銵典<EFBFBD> | 霂湔<E99C82> | 霈啣<E99C88><E595A3><EFBFBD>隡?|
|------|------|-----------|
| **conversations** | 对话会话 | 100万/年 |
| **messages** | 对话消息 | 1000万/年 |
| **agents** | 智能体配置 | <20 |
| **conversation_contexts** | 对话上下文 | 100万/年 |
| **conversations** | 撖寡<EFBFBD>隡朞<EFBFBD> | 100銝?撟?|
| **messages** | 撖寡<EFBFBD><EFBFBD><EFBFBD> | 1000銝?撟?|
| **agents** | <EFBFBD><EFBFBD>雿㯄<EFBFBD>蝵?| <20 |
| **conversation_contexts** | 撖寡<EFBFBD>銝𠹺<EFBFBD><EFBFBD>?| 100銝?撟?|
---
## 📚 pkb_schema(个人知识库)
## <EFBFBD><EFBFBD> pkb_schema<EFBFBD>葵鈭箇䰻霂<EFBFBD><EFBFBD>嚗?
**职责:** 存储个人知识库、文档、RAG问答相关数据
**<EFBFBD>諹提嚗?* 摮睃<E691AE>銝芯犖<E88AAF><EFBFBD>摨瓐<E691A8><E79390><EFBFBD><EFBFBD><E78DA2><EFBFBD>AG<41><EFBFBD><E6A183><EFBFBD><E8A9A8>唳旿
**状态:** ✅ 已实现
**详细设计:** [PKB/01-数据库设计](../03-业务模块/PKB-个人知识库/01-数据库设计.md)(待创建)
**<EFBFBD><EFBFBD><EFBFBD><EFBFBD>** <20>?撌脣<E6928C><E884A3>?
**霂衣<EFBFBD>霈曇恣嚗?* [PKB/01-<EFBFBD>唳旿摨栞挽霈(../03-銝𡁜𦛚璅<E79285>/PKB-銝芯犖<E88AAF><EFBFBD>摨?01-<2D>唳旿摨栞挽霈?md)嚗<><E59A97><EFBFBD>𥕦遣嚗?
### 核心表
### <EFBFBD><EFBFBD>銵?
| 表名 | 说明 | 记录数预估 |
| 銵典<EFBFBD> | 霂湔<E99C82> | 霈啣<E99C88><E595A3><EFBFBD>隡?|
|------|------|-----------|
| **knowledge_bases** | 知识库 | 30万/年 |
| **documents** | 文档 | 300万/年 |
| **document_chunks** | 文档分块(向量化) | 3000万/年 |
| **kb_conversations** | 知识库对话 | 100万/年 |
| **kb_messages** | 知识库对话消息 | 1000万/年 |
| **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銝?撟?|
---
## <20><> rvw_schema嚗<61>阮隞嗅恣<E59785>亦頂蝏<E9A082><E89D8F>
**职责:** 存储稿件审查、评估报告相关数据
**<EFBFBD>諹提嚗?* 摮睃<E691AE>蝔蹂辣摰⊥䰻<E28AA5><E4B0BB><EFBFBD>隡唳𥁒<E594B3>羓㮾<E7BE93>單㺭<E596AE>?
**状态:** ✅ 已实现(独立系统)
**详细设计:** [RVW/01-数据库设计](../03-业务模块/RVW-稿件审查系统/01-数据库设计.md)(待创建)
**<EFBFBD><EFBFBD><EFBFBD><EFBFBD>** <20>?撌脣<E6928C><E884A3><EFBFBD><E5A086><EFBFBD>蝟餌<E89D9F>嚗?
**霂衣<EFBFBD>霈曇恣嚗?* [RVW/01-<EFBFBD>唳旿摨栞挽霈(../03-銝𡁜𦛚璅<E79285>/RVW-蝔蹂辣摰⊥䰻蝟餌<E89D9F>/01-<2D>唳旿摨栞挽霈?md)嚗<><E59A97><EFBFBD>𥕦遣嚗?
### 核心表
### <EFBFBD><EFBFBD>銵?
| 表名 | 说明 | 记录数预估 |
| 銵典<EFBFBD> | 霂湔<E99C82> | 霈啣<E99C88><E595A3><EFBFBD>隡?|
|------|------|-----------|
| **review_tasks** | 审查任务 | 10万/年 |
| **manuscripts** | 稿件信息 | 10万/年 |
| **review_results** | 审查结果 | 10万/年 |
| **methodology_assessments** | 方法学评估 | 10万/年 |
| **guideline_assessments** | 稿约规范性评估 | 10万/年 |
| **review_tasks** | 摰⊥䰻隞餃𦛚 | 10銝?撟?|
| **manuscripts** | 蝔蹂辣靽⊥<EFBFBD> | 10銝?撟?|
| **review_results** | 摰⊥䰻蝏𤘪<EFBFBD> | 10銝?撟?|
| **methodology_assessments** | <EFBFBD><EFBFBD>摮西<EFBFBD>隡?| 10銝?撟?|
| **guideline_assessments** | 蝔輻漲閫<EFBFBD><EFBFBD><EFBFBD><EFBFBD>隡?| 10銝?撟?|
---
## 📖 asl_schemaAI智能文献
## <EFBFBD><EFBFBD> asl_schema嚗㇁I<EFBFBD><EFBFBD><EFBFBD><EFBFBD>讃嚗?
**职责:** 存储文献筛选、提取、分析相关数据
**<EFBFBD>諹提嚗?* 摮睃<E691AE><E79D83><EFBFBD>讃蝑偦<E89D91><EFBFBD><E589B9><EFBFBD><EFBFBD><EFBFBD><E7A194><EFBFBD><EFBFBD>鞟㮾<E99E9F>單㺭<E596AE>?
**状态:** ⏳ 设计中P0优先级
**详细设计:** [ASL/01-数据库设计](../03-业务模块/ASL-AI智能文献/01-数据库设计.md)
**<EFBFBD><EFBFBD><EFBFBD><EFBFBD>** <20>?霈曇恣銝哨<E98A9D>P0隡睃<E99AA1>蝥改<E89DA5>
**霂衣<EFBFBD>霈曇恣嚗?* [ASL/01-<EFBFBD>唳旿摨栞挽霈(../03-銝𡁜𦛚璅<E79285>/ASL-AI<41><EFBFBD><E7AE84><EFBFBD>讃/01-<2D>唳旿摨栞挽霈?md)
### 核心表(预览)
### <EFBFBD><EFBFBD>銵剁<EFBFBD><EFBFBD><EFBFBD>嚗?
| 表名 | 说明 | 记录数预估 |
| 銵典<EFBFBD> | 霂湔<E99C82> | 霈啣<E99C88><E595A3><EFBFBD>隡?|
|------|------|-----------|
| **literature_projects** | 文献项目 | 10万/年 |
| **literature_items** | 文献条目 | 1000万/年 |
| **pico_configs** | PICO纳入排除标准 | 10万/年 |
| **screening_results** | 筛选结果 | 1000万/年 |
| **screening_history** | 筛选历史(可回溯) | 1000万/年 |
| **extraction_tasks** | 提取任务 | 100万/年 |
| **extraction_results** | 提取结果 | 100万/年 |
| **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銝?撟?|
---
## <20>完 dc_schema嚗<61><EFBFBD><EFBFBD>瘣埈㟲<E59F88><E39FB2><EFBFBD>
**职责:** 存储数据清洗任务、ETL配置、NER结果
**<EFBFBD>諹提嚗?* 摮睃<E691AE><E79D83>唳旿皜<E697BF><E79A9C>隞餃𦛚<E9A483><F0A69B9A>TL<54>滨蔭<E6BBA8><E894AD>ER蝏𤘪<E89D8F>
**状态:** ⏳ 规划中P1优先级
**详细设计:** 待设计
**<EFBFBD><EFBFBD><EFBFBD><EFBFBD>** <20>?閫<><E996AB>銝哨<E98A9D>P1隡睃<E99AA1>蝥改<E89DA5>
**霂衣<EFBFBD>霈曇恣嚗?* 敺<>挽霈?
### 核心表(预览)
### <EFBFBD><EFBFBD>銵剁<EFBFBD><EFBFBD><EFBFBD>嚗?
| 表名 | 说明 | 记录数预估 |
| 銵典<EFBFBD> | 霂湔<E99C82> | 霈啣<E99C88><E595A3><EFBFBD>隡?|
|------|------|-----------|
| **cleaning_projects** | 清洗项目 | 10万/年 |
| **data_sources** | 数据源 | 100万/年 |
| **etl_configs** | ETL配置 | 10万/年 |
| **ner_tasks** | NER任务 | 100万/年 |
| **ner_results** | NER结果 | 1000万/年 |
| **cleaning_projects** | <EFBFBD><EFBFBD>憿寧𤌍 | 10銝?撟?|
| **data_sources** | <EFBFBD>唳旿皞?| 100銝?撟?|
| **etl_configs** | ETL<EFBFBD>滨蔭 | 10銝?撟?|
| **ner_tasks** | NER隞餃𦛚 | 100銝?撟?|
| **ner_results** | NER蝏𤘪<EFBFBD> | 1000銝?撟?|
---
## <20><> 頝沒chema靘肽<E99D98><E882BD>喟頂
### 依赖规则 ⭐ 重要
### 靘肽<EFBFBD><EFBFBD><EFBFBD> 潃?<3F><EFBFBD>
**<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>韏吔<EFBFBD>**
```
✅ 业务模块 → platform_schema(允许外键)
✅ 通用能力 → platform_schema(允许外键)
❌ 业务模块之间(禁止直接依赖)
platform_schema → 业务模块(反向依赖)
<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><EFBCB9><EFBFBD>韏吔<E99F8F>
<EFBFBD>?platform_schema <EFBFBD>?銝𡁜𦛚璅<E79285><EFBFBD><E59A97><EFBFBD><EFBFBD>韏吔<E99F8F>
```
### 依赖关系图
### 靘肽<EFBFBD><EFBFBD>喟頂<EFBFBD>?
```
platform_schema.users (1)
(N) 所有业务模块都依赖用户表
<EFBFBD>?(N) <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>⊥芋<EFBFBD><EFBFBD>靘肽<EFBFBD><EFBFBD><EFBFBD>銵?
<20><EFBFBD><E98EBF><EFBFBD> aia_schema.conversations
<20><EFBFBD><E98EBF><EFBFBD> asl_schema.literature_projects
<20><EFBFBD><E98EBF><EFBFBD> pkb_schema.knowledge_bases
@@ -215,67 +215,67 @@ platform_schema.users (1)
platform_schema.llm_usage (<28><EFBFBD>)
- 霈啣<E99C88><E595A3><EFBFBD><EFBFBD>㗇芋<E39787><EFBFBD>LLM靚<4D>
- 通过module字段区分:'AIA', 'ASL', 'PKB'
- <EFBFBD><EFBFBD>module摮埈挾<EFBFBD><EFBFBD>嚗?AIA', 'ASL', 'PKB'蝑?
```
### 憭㚚睸蝷箔<E89DB7>
```sql
-- ✅ 允许业务模块引用platform_schema
-- <EFBFBD>?<3F><>捂嚗帋<E59A97><E5B88B>⊥芋<E28AA5><EFBFBD><E5A092>latform_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)
);
-- ✅ 正确做法:通过user_id关联
-- <EFBFBD>?甇<><EFBFBD>𡁏<EFBFBD>嚗𡁻<E59A97><EFBFBD>user_id<EFBFBD><EFBFBD>
-- <20><EFBFBD><E585B8><EFBFBD><EFBFBD><E686AD>頝冽芋<E586BD><EFBFBD><E5A092><EFBFBD>銝滚銁<E6BB9A>唳旿摨枏<E691A8>
```
---
## 📊 数据量统计(预估)
## <EFBFBD><EFBFBD> <20>唳旿<E594B3><EFBFBD>霈∴<E99C88><EFBFBD>摯嚗?
### <20>农chema蝏蠘恣
| Schema | 表数量 | 年增长记录数 | 存储预估5年 |
| Schema | 銵冽㺭<EFBFBD>?| 撟游<E6929F><E6B8B8>輯扇敶閙㺭 | 摮睃<E691AE><EFBFBD>摯嚗?撟湛<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万/年** | **~500GB5年** |
| 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>** |
### 憭扯”<E689AF>烐綉嚗<E7B689>僑憓鮋鵭>100銝<30><E98A9D>
| 表名 | Schema | 年增长 | 索引策略 |
| 銵典<EFBFBD> | Schema | 撟游<EFBFBD><EFBFBD>?| 蝝<E89D9D>蝑𣇉裦 |
|------|--------|--------|---------|
| llm_usage | platform | 1000万 | 按月分区 |
| messages | aia | 1000万 | 按created_at索引 |
| document_chunks | pkb | 3000万 | 向量索引 |
| literature_items | asl | 1000万 | 按project_id索引 |
| screening_results | asl | 1000万 | 复合索引 |
| llm_usage | platform | 1000銝?| <20><EFBFBD><E39787><EFBFBD> |
| messages | aia | 1000銝?| <20>reated_at<EFBFBD> |
| document_chunks | pkb | 3000銝?| <20><EFBFBD><E89D9D> |
| literature_items | asl | 1000銝?| <20>roject_id<EFBFBD> |
| screening_results | asl | 1000銝?| 憭滚<E686AD><E89D9D> |
---
## 🔍 快速查找指南
## <EFBFBD><EFBFBD> 敹恍<E695B9><E6818D><EFBFBD><EFBFBD><E69AB9>?
### 场景1我要开发某个模块
### <EFBFBD>箸艶1嚗𡁏<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>銝芣芋<EFBFBD>?
1. <20><EFBFBD><E585B6><EFBFBD>銵冽聢銝剜𪄳<E5899C>啣笆摨𠉛<E691A8>Schema
2. <20>孵稬"霂衣<E99C82>霈曇恣"<22>暹𦻖
3. 查看该模块的完整表结构
3. <EFBFBD><EFBFBD>霂交芋<EFBFBD><EFBFBD>摰峕㟲銵函<EFBFBD><EFBFBD>?
### 场景2我要查看某个表的结构
### <EFBFBD>箸艶2嚗𡁏<EFBFBD><EFBFBD><EFBFBD>𧢲<EFBFBD>銝芾”<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
1. <20><>摰朞”撅硺<E69285><E7A1BA>芯葵Schema嚗<61><EFBFBD><EFBFBD><E6A180>賢ế<E8B3A2><EFBFBD>
2. 頧砍<E9A0A7>撖孵<E69296><E79285><E288AA><EFBFBD><EFBFBD><EFBFBD>霈曇恣<E69B87><E681A3>
3. <20>𦦵揣銵典<E98AB5>
@@ -286,53 +286,53 @@ CREATE TABLE ssa_schema.analysis_projects (
3. <20><EFBFBD><E585B8><EFBFBD><EFBFBD><E686AD>頝冽芋<E586BD><EFBFBD><E5A092><EFBFBD>銝滚銁<E6BB9A>唳旿摨枏<E691A8>
### <20>箸艶4嚗𡁏<E59A97><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E69285>唳旿<E594B3><EFBFBD>
1. 阅读本文档快速了解所有Schema
2. 查看[架构设计全景图](../00-系统总体设计/08-架构设计全景图.md)
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)
---
## <20>𩤃<EFBFBD> <20><EFBFBD><E6BBA9><EFBFBD>
### Schema隔离的注意事项
### Schema<EFBFBD>𠉛氖<EFBFBD><EFBFBD><EFBFBD><EFBFBD>憿?
**✅ 正确做法:**
- 业务模块只引用 `platform_schema.users`
- 跨模块数据关联在应用层处理
- 使用 `user_id + 业务ID` 的方式
**<EFBFBD>?甇<><EFBFBD>𡁏<EFBFBD>嚗?*
- 銝𡁜𦛚璅<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?`platform_schema.users`
- 頝冽芋<EFBFBD>埈㺭<EFBFBD><EFBFBD><EFBFBD>𥪜銁摨𠉛鍂撅<EFBFBD><EFBFBD><EFBFBD>?
- 雿輻鍂 `user_id + 銝𡁜𦛚ID` <EFBFBD><EFBFBD>䲮撘?
**❌ 错误做法:**
**<EFBFBD>?<3F>躰秤<E8BAB0>𡁏<EFBFBD>嚗?*
- 銝𡁜𦛚璅<E79285>銋钅𡢿<E99285>湔𦻖憭㚚睸<E39A9A><EFBFBD>
- `platform_schema` 中存储业务数据
- <EFBFBD>?`platform_schema` 銝剖<EFBFBD><EFBFBD><EFBFBD><EFBFBD>⊥㺭<EFBFBD>?
- 銝滚<E98A9D><E79285>雿輻鍂<E8BCBB><EFBFBD><E8A9A8><EFBFBD><EFBFBD><EFBFBD><E3B5AA><EFBFBD>Schema<6D>𠉛氖鈭<E6B096><E988AD><EFBFBD><EFBFBD>𤘪毽瘛<E6AFBD><E7989B>
### <20><EFBFBD>隡睃<E99AA1>撱箄悅
1. **大表必须分页查询**(如 `llm_usage``messages`
2. **热点字段必须加索引**(如 `user_id``created_at`
3. **考虑表分区**(按月/按年,如 `llm_usage`
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`嚗?
4. **摰𡁏<E691B0>敶埝﹝<E59F9D><EFB99D><EFBFBD>唳旿**嚗<><E59A97>1撟游<E6929F><E6B8B8><EFBFBD>𠯫敹梹<E695B9>
---
## <20><> <20><EFBFBD><E8A9A8><EFBFBD>
**规范:**
- [数据库设计规范](./01-数据库设计规范.md) ⭐ 必读
- [数据库架构说明](../00-系统总体设计/03-数据库架构说明.md)
**<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-平台基础层/README.md)
- [通用能力层](../02-通用能力层/README.md)
**<EFBFBD>霈曇恣嚗?*
- [撟喳蝱<EFBFBD><EFBFBD><EFBFBD>(../01-撟喳蝱<E596B3><EFBFBD>撅?README.md)
- [<EFBFBD>𡁶鍂<EFBFBD><EFBFBD><EFBFBD>(../02-<2D>𡁶鍂<F0A181B6><EFBFBD>撅?README.md)
- [銝𡁜𦛚璅<E79285><EFBFBD>(../03-銝𡁜𦛚璅<E79285>/README.md)
**模板:**
- [数据库设计模板](../_templates/数据库设计-模板.md)
**璅⊥踎嚗?*
- [<EFBFBD>唳旿摨栞挽霈⊥芋<EFBFBD>瓢(../_templates/<EFBFBD>唳旿摨栞挽霈?璅⊥踎.md)
---
**<EFBFBD><EFBFBD><EFBFBD>擧凒<EFBFBD><EFBFBD>** 2025-11-06
**蝏湔擪鈭綽<E988AD>** <20><><EFBFBD>舀沲<E88880><E6B2B2><EFBFBD>
**版本:** v1.0
**<EFBFBD><EFBFBD>𧋦嚗?* v1.0

View File

@@ -1,8 +1,8 @@
# API頝舐眏<E88890><EFBFBD>
> **目的:** 提供所有API端点的快速索引便于查找和避免路由冲突
> **详细设计:** 请查看各模块的 `02-API设计.md`
> **基础URL** `http://localhost:3001/api/v1`
> **<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`
> **<2A><><EFBFBD>擧凒<E693A7><EFBFBD>** 2025-11-06
---
@@ -13,9 +13,9 @@
```
/api/v{version}/{module}/{resource}/{id?}/{action?}
示例:
蝷箔<EFBFBD>嚗?
/api/v1/literature/projects # <20><EFBFBD><E79195><EFBFBD>讃憿寧𤌍<E5AFA7>𡑒”
/api/v1/literature/projects/123 # 获取ID=123的项目
/api/v1/literature/projects/123 # <EFBFBD><EFBFBD>ID=123<EFBFBD><EFBFBD><EFBFBD>?
/api/v1/literature/projects/123/export # 撖澆枂憿寧𤌍
```
@@ -23,350 +23,350 @@
| 璅<E79285><EFBFBD><E99A9E> | 頝舐眏<E88890><EFBFBD> | 霂湔<E99C82> |
|---------|---------|------|
| 平台基础层 | `/auth`, `/users`, `/admin` | 认证、用户、管理 |
| 撟喳蝱<EFBFBD><EFBFBD>撅?| `/auth`, `/users`, `/admin` | 霈方<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?|
| LLM蝵穃<E89DB5> | `/llm` | LLM靚<4D>鍂 |
| AIA | `/chat`, `/agents` | AI<41><EFBFBD><E7AE84><EFBFBD> |
| ASL | `/literature` | AI<41><EFBFBD><E7AE84><EFBFBD>讃 |
| PKB | `/knowledge-bases`, `/kb` | 个人知识库 |
| PKB | `/knowledge-bases`, `/kb` | 銝芯犖<EFBFBD><EFBFBD>摨?|
| DC | `/data-cleaning` | <20>唳旿皜<E697BF><E79A9C> |
| SSA | `/analysis` | <20><EFBFBD>蝏蠘恣<E8A098><E681A3><EFBFBD> |
| ST | `/tools` | 蝏蠘恣撌亙<E6928C> |
| RVW | `/review` | 蝔蹂辣摰⊥䰻 |
| ADMIN | `/admin` | 运营管理端 |
| ADMIN | `/admin` | 餈鞱𨯫蝞∠<EFBFBD>蝡?|
---
## 🔐 认证与用户管理(/api/v1/auth, /api/v1/users
## <EFBFBD><EFBFBD> 霈方<E99C88>銝𡒊鍂<F0A1928A>瑞恣<E7919E><E681A3><EFBFBD>/api/v1/auth, /api/v1/users嚗?
**状态:** ✅ 已实现
**详细设计:** [UAM/02-API设计](../01-平台基础层/01-用户与权限中心(UAM)/02-API设计.md)(待创建)
**<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>𥕦遣嚗?
### 霈方<E99C88><E696B9><EFBFBD>
| 蝡舐<E89DA1> | <20><EFBFBD> | 霂湔<E99C82> | 霈方<E99C88> |
|------|------|------|------|
| `/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/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>?|
### <20><EFBFBD>蝞∠<E89D9E>
| 蝡舐<E89DA1> | <20><EFBFBD> | 霂湔<E99C82> | 霈方<E99C88> |
|------|------|------|------|
| `/api/v1/users` | GET | 用户列表(分页) | ADMIN |
| `/api/v1/users/:id` | GET | 用户详情 | ADMIN |
| `/api/v1/users/:id` | PUT | 更新用户 | ADMIN |
| `/api/v1/users/:id` | DELETE | 删除用户 | ADMIN |
| `/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 |
---
## 🤖 LLM大模型网关(/api/v1/llm
## <EFBFBD><EFBFBD> LLM憭扳芋<EFBFBD><EFBFBD><EFBFBD><EFBFBD>/api/v1/llm嚗?
**状态:** ❌ 待实现P0优先级
**详细设计:** [LLM网关/02-API设计](../02-通用能力层/01-LLM大模型网关/02-API设计.md)
**<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)
### LLM靚<4D>
| 蝡舐<E89DA1> | <20><EFBFBD> | 霂湔<E99C82> | 霈方<E99C88> |
|------|------|------|------|
| `/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 | 获取可用模型列表 | |
| `/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>?|
---
## 💬 AI智能问答(/api/v1/chat, /api/v1/agents
## <EFBFBD> AI<EFBFBD><EFBFBD><EFBFBD><EFBFBD>嚗?api/v1/chat, /api/v1/agents嚗?
**状态:** ✅ 已实现
**详细设计:** [AIA/02-API设计](../03-业务模块/AIA-AI智能问答/02-API设计.md)(待创建)
**<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>𥕦遣嚗?
### 撖寡<E69296>蝞∠<E89D9E>
| 蝡舐<E89DA1> | <20><EFBFBD> | 霂湔<E99C82> | 霈方<E99C88> |
|------|------|------|------|
| `/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 | 发送消息 | ✅ |
| `/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>?|
### 智能体管理
### <EFBFBD><EFBFBD>雿梶恣<EFBFBD>?
| 蝡舐<E89DA1> | <20><EFBFBD> | 霂湔<E99C82> | 霈方<E99C88> |
|------|------|------|------|
| `/api/v1/agents` | GET | 智能体列表12个 | |
| `/api/v1/agents/:id` | GET | 智能体详情 | ✅ |
| `/api/v1/agents` | GET | <EFBFBD><EFBFBD>雿枏<EFBFBD>銵剁<EFBFBD>12銝迎<EFBFBD> | <EFBFBD>?|
| `/api/v1/agents/:id` | GET | <EFBFBD><EFBFBD>雿栞祕<EFBFBD>?| <20>?|
---
## 📖 AI智能文献(/api/v1/literature
## <EFBFBD><EFBFBD> AI<EFBFBD><EFBFBD><EFBFBD><EFBFBD>讃嚗?api/v1/literature嚗?
**状态:** ⏳ 设计中P0优先级
**详细设计:** [ASL/02-API设计](../03-业务模块/ASL-AI智能文献/02-API设计.md)
**<EFBFBD><EFBFBD><EFBFBD><EFBFBD>** <20>?霈曇恣銝哨<E98A9D>P0隡睃<E99AA1>蝥改<E89DA5>
**霂衣<EFBFBD>霈曇恣嚗?* [ASL/02-API霈曇恣](../03-銝𡁜𦛚璅<EFBFBD>/ASL-AI<EFBFBD><EFBFBD><EFBFBD><EFBFBD>/02-API霈曇恣.md)
### 憿寧𤌍蝞∠<E89D9E>
| 蝡舐<E89DA1> | <20><EFBFBD> | 霂湔<E99C82> | 霈方<E99C88> |
|------|------|------|------|
| `/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` | 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>?|
### <20><>讃蝑偦<E89D91><EFBFBD><E39A81><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E48185><EFBFBD>嚗争<E59A97>
| 蝡舐<E89DA1> | <20><EFBFBD> | 霂湔<E99C82> | 霈方<E99C88> |
|------|------|------|------|
| `/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 | |
| `/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>?|
### 文献筛选(全文复筛)
### <EFBFBD><EFBFBD>讃蝑偦<EFBFBD><EFBFBD><EFBFBD><EFBFBD>憭滨<EFBFBD>嚗?
| 蝡舐<E89DA1> | <20><EFBFBD> | 霂湔<E99C82> | 霈方<E99C88> |
|------|------|------|------|
| `/api/v1/literature/projects/:id/screening/fulltext` | POST | 执行全文筛选 | ✅ |
| `/api/v1/literature/projects/:id/screening/fulltext/status` | GET | 查询进度 | |
| `/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/knowledge-bases
## <EFBFBD><EFBFBD> 銝芯犖<E88AAF><EFBFBD>摨橒<E691A8>/api/v1/knowledge-bases嚗?
**状态:** ✅ 已实现
**详细设计:** [PKB/02-API设计](../03-业务模块/PKB-个人知识库/02-API设计.md)(待创建)
**<EFBFBD><EFBFBD><EFBFBD><EFBFBD>** <20>?撌脣<E6928C><E884A3>?
**霂衣<EFBFBD>霈曇恣嚗?* [PKB/02-API霈曇恣](../03-銝𡁜𦛚璅<EFBFBD>/PKB-銝芯犖<E88AAF><EFBFBD>摨?02-API霈曇恣.md)<EFBFBD><EFBFBD><EFBFBD>𥕦遣嚗?
### 知识库管理
### <EFBFBD><EFBFBD>摨梶恣<EFBFBD>?
| 蝡舐<E89DA1> | <20><EFBFBD> | 霂湔<E99C82> | 霈方<E99C88> |
|------|------|------|------|
| `/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` | 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>?|
### <20><>﹝蝞∠<E89D9E>
| 蝡舐<E89DA1> | <20><EFBFBD> | 霂湔<E99C82> | 霈方<E99C88> |
|------|------|------|------|
| `/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 | 删除文档 | |
| `/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>?|
### RAG<41><EFBFBD>
| 蝡舐<E89DA1> | <20><EFBFBD> | 霂湔<E99C82> | 霈方<E99C88> |
|------|------|------|------|
| `/api/v1/knowledge-bases/:id/chat` | POST | 知识库问答 | ✅ |
| `/api/v1/knowledge-bases/:id/search` | GET | 语义检索 | ✅ |
| `/api/v1/knowledge-bases/:id/chat` | POST | <EFBFBD><EFBFBD>摨㯄䔮蝑?| <20>?|
| `/api/v1/knowledge-bases/:id/search` | GET | 霂凋<EFBFBD><EFBFBD>蝝?| <20>?|
---
## 🧹 数据清洗整理(/api/v1/data-cleaning
## <EFBFBD><20>唳旿皜<E697BF><E79A9C><EFBFBD><EFBFBD>嚗?api/v1/data-cleaning嚗?
**状态:** ⏳ 规划中P1优先级
**详细设计:** 待设计
**<EFBFBD><EFBFBD><EFBFBD><EFBFBD>** <20>?閫<><E996AB>銝哨<E98A9D>P1隡睃<E99AA1>蝥改<E89DA5>
**霂衣<EFBFBD>霈曇恣嚗?* 敺<>挽霈?
### 皜<><E79A9C>憿寧𤌍
| 蝡舐<E89DA1> | <20><EFBFBD> | 霂湔<E99C82> | 霈方<E99C88> |
|------|------|------|------|
| `/api/v1/data-cleaning/projects` | GET | 清洗项目列表 | |
| `/api/v1/data-cleaning/projects` | POST | 创建清洗项目 | |
| `/api/v1/data-cleaning/projects/:id` | GET | 项目详情 | |
| `/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>?|
### ETL<54>滨蔭
| 蝡舐<E89DA1> | <20><EFBFBD> | 霂湔<E99C82> | 霈方<E99C88> |
|------|------|------|------|
| `/api/v1/data-cleaning/projects/:id/etl` | POST | 配置ETL规则 | |
| `/api/v1/data-cleaning/projects/:id/execute` | POST | 执行清洗任务 | |
| `/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/analysis
## <EFBFBD><EFBFBD> <20><EFBFBD>蝏蠘恣<E8A098><E681A3><EFBFBD>嚗?api/v1/analysis嚗?
**状态:** ⏳ 规划中P2优先级
**详细设计:** 待设计
**<EFBFBD><EFBFBD><EFBFBD><EFBFBD>** <20>?閫<><E996AB>銝哨<E98A9D>P2隡睃<E99AA1>蝥改<E89DA5>
**霂衣<EFBFBD>霈曇恣嚗?* 敺<>挽霈?
### <20><><EFBFBD>憿寧𤌍
| 蝡舐<E89DA1> | <20><EFBFBD> | 霂湔<E99C82> | 霈方<E99C88> |
|------|------|------|------|
| `/api/v1/analysis/projects` | GET | 分析项目列表 | |
| `/api/v1/analysis/projects` | POST | 创建分析项目 | |
| `/api/v1/analysis/projects/:id/execute` | POST | 执行分析 | |
| `/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/tools
## <EFBFBD>圲 蝏蠘恣<E8A098><E681A3><EFBFBD>撌亙<E6928C>嚗?api/v1/tools嚗?
**状态:** ⏳ 规划中P2优先级
**详细设计:** 待设计
**<EFBFBD><EFBFBD><EFBFBD><EFBFBD>** <20>?閫<><E996AB>銝哨<E98A9D>P2隡睃<E99AA1>蝥改<E89DA5>
**霂衣<EFBFBD>霈曇恣嚗?* 敺<>挽霈?
### 撌亙<E6928C><EFBFBD>
| 蝡舐<E89DA1> | <20><EFBFBD> | 霂湔<E99C82> | 霈方<E99C88> |
|------|------|------|------|
| `/api/v1/tools` | GET | 工具列表100+ | ✅ |
| `/api/v1/tools/:id` | GET | 工具详情 | |
| `/api/v1/tools/:id/execute` | POST | 执行工具 | |
| `/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/review
## <EFBFBD><EFBFBD> 蝔蹂辣摰⊥䰻蝟餌<E89D9F>嚗?api/v1/review嚗?
**状态:** ✅ 已实现(独立系统)
**详细设计:** [RVW/02-API设计](../03-业务模块/RVW-稿件审查系统/02-API设计.md)(待创建)
**<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>𥕦遣嚗?
### 摰⊥䰻隞餃𦛚
| 蝡舐<E89DA1> | <20><EFBFBD> | 霂湔<E99C82> | 霈方<E99C88> |
|------|------|------|------|
| `/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 | ✅ |
| `/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/admin
## <EFBFBD><EFBFBD>儭?餈鞱𨯫蝞∠<E89D9E>蝡荔<E89DA1>/api/v1/admin嚗?
**状态:** ⏳ 规划中P1优先级
**详细设计:** [ADMIN/02-API设计](../03-业务模块/ADMIN-运营管理端/02-API设计.md)
**<EFBFBD><EFBFBD><EFBFBD><EFBFBD>** <20>?閫<><E996AB>銝哨<E98A9D>P1隡睃<E99AA1>蝥改<E89DA5>
**霂衣<EFBFBD>霈曇恣嚗?* [ADMIN/02-API霈曇恣](../03-銝𡁜𦛚璅<EFBFBD>/ADMIN-餈鞱𨯫蝞∠<EFBFBD>蝡?02-API霈曇恣.md)
### 用户管理 ⭐
### <EFBFBD><EFBFBD>蝞∠<EFBFBD> 潃?
| 蝡舐<E89DA1> | <20><EFBFBD> | 霂湔<E99C82> | 霈方<E99C88> |
|------|------|------|------|
| `/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 |
| `/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 |
### Feature Flag管理 ⭐
### Feature Flag蝞∠<EFBFBD> 潃?
| 蝡舐<E89DA1> | <20><EFBFBD> | 霂湔<E99C82> | 霈方<E99C88> |
|------|------|------|------|
| `/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 |
| `/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 |
### LLM模型管理 ⭐
### LLM<EFBFBD>蝞∠<EFBFBD> 潃?
| 蝡舐<E89DA1> | <20><EFBFBD> | 霂湔<E99C82> | 霈方<E99C88> |
|------|------|------|------|
| `/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 |
| `/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 |
### Prompt蝞∠<E89D9E>
| 蝡舐<E89DA1> | <20><EFBFBD> | 霂湔<E99C82> | 霈方<E99C88> |
|------|------|------|------|
| `/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/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 |
### <20><EFBFBD><E4BA99>亥砭
| 蝡舐<E89DA1> | <20><EFBFBD> | 霂湔<E99C82> | 霈方<E99C88> |
|------|------|------|------|
| `/api/v1/admin/logs` | GET | 日志列表 | ADMIN |
| `/api/v1/admin/logs/errors` | GET | 错误日志 | ADMIN |
| `/api/v1/admin/logs/operations` | GET | 操作日志 | 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 |
### <20>唳旿<E594B3>亥”
| 蝡舐<E89DA1> | <20><EFBFBD> | 霂湔<E99C82> | 霈方<E99C88> |
|------|------|------|------|
| `/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 |
| `/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 |
---
## <20><> 頝舐眏蝏蠘恣
### 按模块统计
### <EFBFBD>㗇芋<EFBFBD><EFBFBD>霈?
| 模块 | 端点数量 | 状态 |
| <EFBFBD> | 蝡舐<E89DA1><E88890><EFBFBD> | <20><EFBFBD>?|
|------|---------|------|
| 认证与用户 | 10 | ✅ 已实现 |
| LLM网关 | 5 | ❌ 待实现 |
| AI智能问答 | 8 | ✅ 已实现 |
| AI智能文献 | 15 | ⏳ 设计中 |
| 个人知识库 | 10 | ✅ 已实现 |
| 数据清洗 | 5 | ⏳ 规划中 |
| 智能统计分析 | 3 | ⏳ 规划中 |
| 统计工具 | 3 | ⏳ 规划中 |
| 稿件审查 | 5 | ✅ 已实现 |
| 运营管理端 | 20 | ⏳ 规划中 |
| 霈方<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>銝?|
| **<EFBFBD>餉恣** | **~85** | - |
---
## ⚠️ 路由冲突检查
## <EFBFBD>𩤃<EFBFBD> 頝舐眏<E88890><EFBFBD><EFBFBD><E79289>?
### 瞏𨅯銁<F0A885AF><EFBFBD>
**❌ 避免冲突:**
**<EFBFBD>?<3F><EFBFBD><E8B8B9><EFBFBD>嚗?*
```
# 错误:模块名称冲突
# <EFBFBD>躰秤嚗𡁏芋<EFBFBD><EFBFBD>蝘啣<EFBFBD>蝒?
/api/v1/admin/users # 蝞∠<E89D9E>蝡舐<E89DA1><E88890><EFBFBD>蝞∠<E89D9E>
/api/v1/users # 撟喳蝱撅<E89DB1><E69285><EFBFBD><EFBFBD>蝞∠<E89D9E>
# 正确:明确区分
# <EFBFBD>嚗𡁏<EFBFBD>蝖桀躹<EFBFBD>?
/api/v1/auth/profile # 敶枏<E695B6><E69E8F><EFBFBD>靽⊥<E99DBD>
/api/v1/admin/users # 蝞∠<E89D9E>蝡舐鍂<E88890>嵩RUD
```
---
## 🔍 快速查找指南
## <EFBFBD><EFBFBD> 敹恍<E695B9><E6818D><EFBFBD><EFBFBD><E69AB9>?
### <20>箸艶1嚗𡁏䰻<F0A1818F><EFBFBD>銝芣芋<E88AA3><EFBFBD><E39B96><EFBFBD><EFBFBD>𡅅PI
1. 在上面的表格中找到对应模块
1. <EFBFBD><EFBFBD><EFBFBD><EFBFBD>銵冽聢銝剜𪄳<EFBFBD>啣笆摨娍芋<EFBFBD>?
2. <20>孵稬"霂衣<E99C82>霈曇恣"<22>暹𦻖
3. <20><EFBFBD>霂交芋<E4BAA4><EFBFBD>摰峕㟲API<50><49>
### <20>箸艶2嚗朞挽霈⊥鰵API蝡舐<E89DA1>
1. 查看本文档,确保路由不冲突
1. <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>蝖桐<EFBFBD>頝舐眏銝滚<EFBFBD>蝒?
2. <20><><EFBFBD><EFBFBD>API霈曇恣閫<E681A3><E996AB>](./02-API霈曇恣閫<E681A3><E996AB>.md)
3. 雿輻鍂[API霈曇恣璅⊥踎](../_templates/API霈曇恣-璅⊥踎.md)
### <20>箸艶3嚗𡁏䰻<F0A1818F><EFBFBD><EFBFBD>API<50><EFBFBD>
1. <20><><EFBFBD><EFBFBD><EFBFBD><E78DA2>敹恍<E695B9><EFBFBD><EFBFBD><E996AB><EFBFBD>厩垢<E58EA9><EFBFBD>
2. 查看[架构设计全景图](../00-系统总体设计/08-架构设计全景图.md)
2. <EFBFBD><EFBFBD>[<5B><EFBFBD>霈曇恣<E69B87>冽艶<E586BD>霄(../00-蝟餌<E89D9F><E9A48C><EFBFBD>霈曇恣/08-<2D><EFBFBD>霈曇恣<E69B87>冽艶<E586BD>?md)
---
## <20><> <20><EFBFBD><E8A9A8><EFBFBD>
**规范:**
- [API设计规范](./02-API设计规范.md) ⭐ 必读
- [认证与授权规范](./02-API设计规范.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霈曇恣璅⊥踎](../_templates/API霈曇恣-璅⊥踎.md)
**<EFBFBD>唳旿摨橒<EFBFBD>**
@@ -376,7 +376,7 @@
**<EFBFBD><EFBFBD><EFBFBD>擧凒<EFBFBD><EFBFBD>** 2025-11-06
**蝏湔擪鈭綽<E988AD>** <20><><EFBFBD>舀沲<E88880><E6B2B2><EFBFBD>
**版本:** v1.0
**<EFBFBD><EFBFBD>𧋦嚗?* v1.0

View File

@@ -1,9 +1,8 @@
# 浠g爜瑙勮寖
> **版本:** v1.0
> **创建日期:** 2025-10-10
> **适用范围:** 前端React/TypeScript+ 后端Node.js/TypeScript
> **鐗堟湰锛?* v1.0
> **鍒涘缓鏃ユ湡锛?* 2025-10-10
> **閫傜敤鑼冨洿锛?* 鍓嶇<E98D93>锛圧eact/TypeScript锛? 鍚庣<E98D9A>锛圢ode.js/TypeScript锛?
---
## 馃搵 鐩<>
@@ -18,29 +17,26 @@
---
## 🌟 平台能力使用规范2025-11-16 新增)
> **⭐ 重要提示**:平台已提供完整的基础设施服务
> **详细规范**[云原生开发规范](./08-云原生开发规范.md)
## 馃専 骞冲彴鑳藉姏浣跨敤瑙勮寖锛?025-11-16 鏂板<EFBFBD>锛?
> **猸?閲嶈<E996B2>鎻愮ず**锛氬钩鍙板凡鎻愪緵瀹屾暣鐨勫熀纭€璁炬柦鏈嶅姟
> **璇︾粏瑙勮寖**锛歔浜戝師鐢熷紑鍙戣<E98D99>鑼僝(./08-浜戝師鐢熷紑鍙戣<E98D99>鑼?md)
> **璇︾粏鏂囨。**锛歔骞冲彴鍩虹<E98DA9>璁炬柦瑙勫垝](../09-鏋舵瀯瀹炴柦/04-骞冲彴鍩虹<E98DA9>璁炬柦瑙勫垝.md)
### 必须复用的平台服务
### 蹇呴』澶嶇敤鐨勫钩鍙版湇鍔?
**涓氬姟妯″潡锛圓SL/AIA/PKB/DC绛夛級绂佹<E7BB82>閲嶅<E996B2>瀹炵幇浠ヤ笅鍔熻兘锛?*
**业务模块ASL/AIA/PKB/DC等禁止重复实现以下功能**
| 服务 | 导入方式 | 用途 |
| 鏈嶅姟 | 瀵煎叆鏂瑰紡 | 鐢ㄩ€?|
|------|---------|------|
| **瀛樺偍鏈嶅姟** | `import { storage } from '@/common/storage'` | 鏂囦欢涓婁紶涓嬭浇 |
| **日志系统** | `import { logger } from '@/common/logging'` | 标准化日志 |
| **异步任务** | `import { jobQueue } from '@/common/jobs'` | 长时间任务 |
| **缓存服务** | `import { cache } from '@/common/cache'` | 分布式缓存 |
| **数据库** | `import { prisma } from '@/config/database'` | 数据库操作 |
| **鏃ュ織绯荤粺** | `import { logger } from '@/common/logging'` | 鏍囧噯鍖栨棩蹇?|
| **寮傛<EFBFBD>浠诲姟** | `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'
@@ -58,8 +54,7 @@ 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 }
})
@@ -70,8 +65,7 @@ export class LiteratureService {
}
async startScreening(projectId: string, literatureIds: string[]) {
// 5. 使用平台异步任务(长时间任务必须异步)
const job = await jobQueue.push('asl:screening', {
// 5. 浣跨敤骞冲彴寮傛<EFBFBD>浠诲姟锛堥暱鏃堕棿浠诲姟蹇呴』寮傛<EFBFBD>锛? const job = await jobQueue.push('asl:screening', {
projectId,
literatureIds
})
@@ -84,54 +78,44 @@ export class LiteratureService {
---
### ❌ 错误示例:重复实现平台能力
### 鉂?閿欒<E996BF>绀轰緥锛氶噸澶嶅疄鐜板钩鍙拌兘鍔?
```typescript
// ❌ 错误:在业务模块中自己实现存储
// backend/src/modules/asl/storage/LocalStorage.ts ← 不应该存在!
// 鉂?閿欒<E996BF>锛氬湪涓氬姟妯″潡涓<E6BDA1>嚜宸卞疄鐜板瓨鍌?// backend/src/modules/asl/storage/LocalStorage.ts 鈫?涓嶅簲璇ュ瓨鍦<E793A8>
import fs from 'fs'
export class LocalStorage {
async upload(file: Buffer) {
await fs.writeFile('./uploads/file.pdf', file) // ❌ 重复实现
await fs.writeFile('./uploads/file.pdf', file) // 鉂?閲嶅<E996B2>瀹炵幇
return '/uploads/file.pdf'
}
}
// ❌ 错误:在业务模块中自己实现日志
// backend/src/modules/asl/logger/logger.ts ← 不应该存在!
// 鉂?閿欒<E996BF>锛氬湪涓氬姟妯″潡涓<E6BDA1>嚜宸卞疄鐜版棩蹇?// backend/src/modules/asl/logger/logger.ts 鈫?涓嶅簲璇ュ瓨鍦<E793A8>
import winston from 'winston'
export const logger = winston.createLogger({...}) // ❌ 重复实现
export const logger = winston.createLogger({...}) // 鉂?閲嶅<E996B2>瀹炵幇
// ❌ 错误:每次新建数据库连接
// 鉂?閿欒<E996BF>锛氭瘡娆℃柊寤烘暟鎹<E69A9F>簱杩炴帴
import { PrismaClient } from '@prisma/client'
export function getUser() {
const prisma = new PrismaClient() // ❌ 连接泄漏
const prisma = new PrismaClient() // 鉂?杩炴帴娉勬紡
return prisma.user.findMany()
}
```
**涓轰粈涔堥敊璇<E6958A>**
- ❌ 重复代码,难以维护
- ❌ 不同模块实现不一致
- ❌ 无法统一切换环境(本地/云端)
- ❌ 浪费开发时间
- ❌ 云端部署会失败Serverless限制
- 鉂?閲嶅<E996B2>爜锛岄毦浠ョ淮鎶?- 鉂?涓嶅悓妯″潡瀹炵幇涓嶄竴鑷?- 鉂?鏃犳硶缁熶竴鍒囨崲鐜<E5B4B2><E9909C>锛堟湰鍦?浜戠<E6B59C>锛?- 鉂?娴<>垂寮€鍙戞椂闂?- 鉂?浜戠<E6B59C>閮ㄧ讲浼氬け璐ワ紙Serverless闄愬埗锛?
---
### 鏂囦欢涓婁紶瑙勮寖
```typescript
// ✅ 正确:使用存储抽象层
// 鉁?姝g‘锛氫娇鐢ㄥ瓨鍌ㄦ娊璞″眰
const url = await storage.upload('asl/pdf/123.pdf', buffer)
// ❌ 错误:直接操作文件系统
fs.writeFileSync('./uploads/123.pdf', buffer) // Serverless容器重启会丢失
// ❌ 错误:硬编码存储路径
// 鉂?閿欒<E996BF>锛氱洿鎺ユ搷浣滄枃浠剁郴缁?fs.writeFileSync('./uploads/123.pdf', buffer) // Serverless瀹瑰櫒閲嶅惎浼氫涪澶?
// 鉂?閿欒<E996BF>锛氱‖缂栫爜瀛樺偍璺<E5818D>
const filePath = 'D:/uploads/123.pdf' // Windows璺<73>緞锛孡inux鏃犳硶杩愯<E69DA9>
```
@@ -140,7 +124,7 @@ const filePath = 'D:/uploads/123.pdf' // Windows路径Linux无法运行
### 寮傛<E5AFAE>浠诲姟瑙勮寖
```typescript
// ✅ 正确:长时间任务(>10秒必须异步处理
// 鉁?姝g‘锛氶暱鏃堕棿浠诲姟锛?10绉掞級蹇呴』寮傛<E5AFAE>澶勭悊
app.post('/screening/start', async (req, res) => {
const job = await jobQueue.push('asl:screening', data)
res.send({ jobId: job.id }) // 绔嬪嵆杩斿洖锛屼笉绛夊緟瀹屾垚
@@ -152,29 +136,26 @@ 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) // 可能需要10分钟
const results = await processAllLiteratures(data) // <EFBFBD>兘闇€瑕?0鍒嗛挓
res.send({ results }) // Serverless 30绉掕秴鏃讹紒
})
```
---
### 数据库连接规范
### 鏁版嵁搴撹繛鎺ヨ<EFBFBD>鑼?
```typescript
// ✅ 正确:使用全局Prisma实例
// 鉁?姝g‘锛氫娇鐢ㄥ叏灞€Prisma瀹炰緥
import { prisma } from '@/config/database'
export async function getUsers() {
return await prisma.user.findMany()
}
// ❌ 错误:每次新建实例
export async function getUsers() {
const prisma = new PrismaClient() // 连接数耗尽!
return await prisma.user.findMany()
// 鉂?閿欒<E996BF>锛氭瘡娆℃柊寤哄疄渚?export async function getUsers() {
const prisma = new PrismaClient() // 杩炴帴鏁拌€楀敖锛? return await prisma.user.findMany()
}
```
@@ -183,52 +164,44 @@ export async function getUsers() {
### 鏃ュ織瑙勮寖
```typescript
// ✅ 正确:使用平台日志系统
import { logger } from '@/common/logging'
// 鉁?姝g‘锛氫娇鐢ㄥ钩鍙版棩蹇楃郴缁?import { logger } from '@/common/logging'
logger.info('Operation successful', { userId, action: 'upload' })
logger.error('Operation failed', { error: err.message, userId })
// ❌ 错误使用console.log
console.log('Operation successful') // 无法集中收集,难以查询
// ❌ 错误:写本地日志文件
fs.appendFileSync('./app.log', 'Operation successful') // Serverless不支持
```
// 鉂?閿欒<E996BF>锛氫娇鐢╟onsole.log
console.log('Operation successful') // 鏃犳硶闆嗕腑鏀堕泦锛岄毦浠ユ煡璇?
// 鉂?閿欒<E996BF>锛氬啓鏈<E59593>湴鏃ュ織鏂囦欢
fs.appendFileSync('./app.log', 'Operation successful') // Serverless涓嶆敮鎸?```
---
##
###
- ✅ 使用ESLint和Prettier统一代码风格
- ✅ 缩进2个空格
- ✅ 字符串:优先使用单引号 `'`
- ✅ 行尾:不加分号(除非必要)
- ✅ 单行最大长度100字符
- ✅ 使用尾随逗号(对象、数组)
- ?ESLint鍜孭rettier缁熶竴浠g爜椋庢牸
- ??<EFBFBD>?- ?<EFBFBD>?`'`
- ?<EFBFBD>?- ?<EFBFBD>ч100<EFBFBD>
- ?彿<EFBFBD>°
###
- ✅ 一个文件一个组件/类
- ✅ 相关文件放在同一目录
- ✅ 使用barrel exportsindex.ts
- ✅ 测试文件与源文件同目录
- ?<EFBFBD><EFBFBD>??- ?稿<EFBFBD>
- ?barrel exports锛坕ndex.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'
```
### 浠g爜娉ㄩ噴
- ✅ 复杂逻辑必须注释
- ✅ 公共API必须注释
- ✅ 避免无用注释
- ✅ 使用JSDoc格式
- 鉁?澶嶆潅閫昏緫蹇呴』娉ㄩ噴
- 鉁?鍏<>叡API蹇呴』娉ㄩ噴
- 鉁?閬垮厤鏃犵敤娉ㄩ噴
- 鉁?浣跨敤JSDoc鏍煎紡
---
@@ -236,7 +209,7 @@ src/
### 绫诲瀷瀹氫箟
**✅ 推荐:**
**鉁?鎺ㄨ崘锛?*
```typescript
// 浣跨敤interface瀹氫箟瀵硅薄缁撴瀯
interface User {
@@ -255,16 +228,14 @@ enum UserRole {
}
```
**❌ 避免:**
**鉂?閬垮厤锛?*
```typescript
// 涓嶈<E6B693>浣跨敤any
function process(data: any) { //
// ...
function process(data: any) { // 鉂? // ...
}
// 搴旇<E690B4>鏄庣绫诲瀷
function process(data: ProcessData) { //
// ...
function process(data: ProcessData) { // 鉁? // ...
}
```
@@ -303,7 +274,7 @@ import type { Project, ProjectStatus } from './types'
### 缁勪欢瀹氫箟
**✅ 推荐:函数组件 + Hooks**
**鉁?鎺ㄨ崘锛氬嚱鏁扮粍浠?+ Hooks**
```tsx
import { useState } from 'react'
@@ -343,15 +314,14 @@ 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'
@@ -403,8 +373,7 @@ 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'
@@ -420,23 +389,19 @@ 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. 事件处理(useCallback
const handleClick = useCallback(() => {
// 3. 浜嬩欢澶勭悊锛坲seCallback锛? const handleClick = useCallback(() => {
// 澶勭悊閫昏緫
}, [])
// 4. Effects
useEffect(() => {
// 副作用
}, [])
// <EFBFBD>綔鐢? }, [])
// 5. 早期返回Loading/Error
if (!data) return <Loading />
// 5. 鏃╂湡杩斿洖锛圠oading/Error锛? if (!data) return <Loading />
// 6. 娓叉煋
return (
@@ -449,7 +414,7 @@ export function Component({ prop1, prop2 }: ComponentProps) {
### 鏉′欢娓叉煋
**✅ 推荐:**
**鉁?鎺ㄨ崘锛?*
```tsx
// 绠€鍗曟潯浠讹細浣跨敤 &&
{isLoggedIn && <UserMenu />}
@@ -468,14 +433,14 @@ function renderContent() {
return <div>{renderContent()}</div>
```
**❌ 避免:**
**鉂?閬垮厤锛?*
```tsx
// 閬垮厤澶嶆潅鐨勫祵濂椾笁鍏冭繍绠楃<E7BBA0>
{condition1 ? (
condition2 ? <A /> : <B />
) : (
condition3 ? <C /> : <D />
)} // ❌ 难以理解
)} // 鉂?闅句互鐞嗚В
```
---
@@ -487,11 +452,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/ # 鎺у埗鍣<E59F97>紙鍙<E7B499>€夛級
鈹溾攢鈹€ models/ # Prisma妯″瀷
鈹溾攢鈹€ utils/ # 宸ュ叿鍑芥暟
@@ -571,8 +536,7 @@ export async function projectRoutes(server: FastifyInstance) {
}
```
### Service
### Service灞?
```typescript
// services/project.service.ts
import { prisma } from '../lib/prisma'
@@ -580,8 +544,7 @@ import type { CreateProjectDto, UpdateProjectDto } from '../types'
export class ProjectService {
/**
* 获取用户的项目列表
*/
* 鑾峰彇鐢ㄦ埛鐨勯」鐩<EFBFBD>垪琛? */
async getProjects(userId: string, options: PaginationOptions) {
const { page, pageSize } = options
@@ -712,8 +675,7 @@ async function getProject(id: string) {
}
```
### 错误处理中间件
### 閿欒<EFBFBD>澶勭悊涓<EFBFBD>棿浠?
```typescript
// middleware/error-handler.ts
import { FastifyError, FastifyReply, FastifyRequest } from 'fastify'
@@ -727,8 +689,7 @@ export async function errorHandler(
// 璁板綍閿欒<E996BF>
request.log.error(error)
// 自定义错误
if (error instanceof AppError) {
// <EFBFBD>畾涔夐敊璇? if (error instanceof AppError) {
return reply.code(error.statusCode).send({
success: false,
error: {
@@ -783,23 +744,22 @@ export async function errorHandler(
### 鍙橀噺鍛藉悕
```typescript
// ✅ 推荐
// 鉁?鎺ㄨ崘
const userName = 'John' // camelCase
const USER_ROLE = 'admin' // 甯搁噺鐢║PPER_SNAKE_CASE
const isLoading = false // 甯冨皵鍊肩敤is/has/can鍓嶇紑
const hasPermission = true
const canEdit = false
// ❌ 避免
// 鉂?閬垮厤
const user_name = 'John' // 涓嶇敤snake_case
const loading = false // 甯冨皵鍊肩己灏慽s鍓嶇紑
const x = 10 // 无意义的变量名
```
const x = 10 // 鏃犳剰涔夌殑鍙橀噺鍚?```
###
```typescript
// ✅ 推荐
// 鉁?鎺ㄨ崘
function getUser() { } // get: 鑾峰彇鏁版嵁
function fetchProjects() { } // fetch: 寮傛<E5AFAE>鑾峰彇
function createProject() { } // create: 鍒涘缓
@@ -807,24 +767,20 @@ 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 /> // 鍩虹<E98DA9>缁勪欢
<UserProfile /> // 涓氬姟缁勪欢
<ProjectList /> // 鍒楄〃缁勪欢
<CreateProjectModal /> // 寮圭獥缁勪欢
// ❌ 避免
// 鉂?閬垮厤
<button /> // 涓嶇敤灏忓啓
<user_profile /> // 涓嶇敤snake_case
<ListProjects /> // 鍔ㄨ瘝涓嶈<E6B693>鍦ㄥ墠
@@ -838,11 +794,9 @@ function process() { } // 不明确
```typescript
/**
* 创建新项目
* @param userId - 用户ID
* 鍒涘缓鏂伴」鐩? * @param userId - 鐢ㄦ埛ID
* @param data - 椤圭洰鏁版嵁
* @returns 创建的项目对象
* @throws {ValidationError} 当数据验证失败时
* @returns 鍒涘缓鐨勯」鐩<EFBFBD><EFBFBD>璞? * @throws {ValidationError} 褰撴暟鎹<E69A9F>獙璇佸け璐ユ椂
*/
async function createProject(
userId: string,
@@ -855,21 +809,18 @@ async function createProject(
### 浠g爜娉ㄩ噴
```typescript
// ✅ 好的注释:解释为什么
// 使用setTimeout避免阻塞UI渲染
// 鉁?濂界殑娉ㄩ噴锛氳В閲婁负浠€涔?// 浣跨敤setTimeout閬垮厤闃诲<E99783>UI娓叉煋
setTimeout(() => {
processLargeData()
}, 0)
// 等待Dify处理文档最多重试10次
for (let i = 0; i < 10; i++) {
// 绛夊緟Dify澶勭悊鏂囨。锛屾渶澶氶噸璇?0娆?for (let i = 0; i < 10; i++) {
const status = await checkStatus()
if (status === 'completed') break
await sleep(2000)
}
// ❌ 坏的注释:重复代码
// 设置loading为true
// 鉂?鍧忕殑娉ㄩ噴锛氶噸澶嶄唬鐮?// 璁剧疆loading涓簍rue
setLoading(true)
// 璋冪敤API
@@ -894,10 +845,10 @@ await api.getData()
| 绫诲瀷 | 璇存槑 |
|------|------|
| feat | 新功能 |
| feat | 鏂板姛鑳?|
| fix | Bug淇<67><E6B787> |
| docs | 鏂囨。鏇存柊 |
| style | 代码格式(不影响功能) |
| style | 浠g爜鏍煎紡锛堜笉褰卞搷鍔熻兘锛?|
| refactor | 閲嶆瀯 |
| perf | 鎬ц兘浼樺寲 |
| test | 娴嬭瘯鐩稿叧 |
@@ -912,11 +863,8 @@ 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" # ❌ 没有说明是什么bug
git commit -m "完成功能" # ❌ 没有说明是什么功能
```
# 涓嶅ソ鐨勬彁浜?git commit -m "update" # 鉂?澶<>ā绯?git commit -m "fix bug" # 鉂?娌℃湁璇存槑鏄<E6A791>粈涔坆ug
git commit -m "瀹屾垚鍔熻兘" # 鉂?娌℃湁璇存槑鏄<E6A791>粈涔堝姛鑳?```
---
@@ -959,36 +907,30 @@ module.exports = {
---
## 代码Review检查清单
## 浠g爜Review妫€鏌ユ竻鍗?
### 鍔熻兘
- [ ] 鍔熻兘鏄<E58598>惁瀹屾暣瀹炵幇
- [ ]<>惁鏈夐仐婕忕殑杈圭晫鎯呭喌
- [ ] 閿欒<E996BF>澶勭悊鏄<E6828A>惁瀹屽杽
### 浠g爜璐ㄩ噺
- [ ] 代码是否易读易理解
- [ ] 是否有重复代码
- [ ] 函数是否过长(建议<50行
- [ ] 爜鏄<EFBFBD>惁鏄撹<EFBFBD>鏄撶悊瑙?- [ ] 鏄<>惁鏈夐噸澶嶄唬鐮?- [ ] 鍑芥暟鏄<E69A9F>惁杩囬暱锛堝缓璁?50琛岋級
- [ ]<>惁閬靛畧鍛藉悕瑙勮寖
### 鎬ц兘
- [ ]<>惁鏈夋€ц兘闂<E58598><E99782>
- [ ]<>惁鏈変笉蹇呰<E8B987>鐨勯噸娓叉煋
- [ ] 数据库查询是否优化
- [ ] 鏁版嵁搴撴煡璇㈡槸鍚︿紭鍖?
### 瀹夊叏
- [ ]<>惁鏈塖QL娉ㄥ叆椋庨櫓
- [ ]<>惁鏈塜SS椋庨櫓
- [ ] 鏉冮檺楠岃瘉鏄<E79889>惁瀹屽杽
### 娴嬭瘯
- [ ] 是否有单元测试
- [ ] 测试覆盖率是否足够
- [ ] <EFBFBD>惁鏈夊崟鍏冩祴璇?- [ ] 娴嬭瘯瑕嗙洊鐜囨槸鍚﹁冻澶?
---
**文档维护:** 规范更新需同步此文档
**鏂囨。缁存姢锛?* 瑙勮寖鏇存柊闇€鍚屾<E98D9A>姝ゆ枃妗?
**鏈€鍚庢洿鏂帮細** 2025-10-10
**缁存姢鑰咃細** 鎶€鏈<E282AC>礋璐

File diff suppressed because it is too large Load Diff

View File

@@ -1,47 +1,42 @@
# 云原生开发规范
> **文档版本:** V1.1
> **创建日期:** 2025-11-16
# 鈭穃<EFBFBD><EFBFBD><EFBFBD><EFBFBD>𤏸<EFBFBD><EFBFBD>?
> **<2A><><EFBFBD><EFB99D>𧋦嚗?* V1.1
> **<EFBFBD>𥕦遣<EFBFBD><EFBFBD>嚗?* 2025-11-16
> **<2A><><EFBFBD>擧凒<E693A7><EFBFBD>** 2025-12-13 <20><> **Postgres-Only <20><EFBFBD><EFBFBD><E996AB><EFBFBD><EFBFBD>**
> **适用对象:** 所有开发人员
> **强制性:** ✅ 必须遵守
> **<EFBFBD><EFBFBD>鍂撖寡情嚗?* <20><><EFBFBD><EFBFBD><E58CA7>睲犖<E79DB2>?
> **撘箏<EFBFBD><EFBFBD><EFBFBD>** <20>?敹<><EFBFBD><EFBFBD>
> **蝏湔擪<E6B994><E693AA><EFBFBD>** <20><EFBFBD><E59786><EFBFBD>
---
## <20><> <20><>﹝霂湔<E99C82>
本文档定义云原生环境Serverless SAE + RDS + OSS)下的**代码规范**所有业务模块ASL、AIA、PKB等必须遵守。
**阅读时间**10 分钟
**检查频率**:每次代码提交前
<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>
---
## 🌟 核心原则:复用平台能力
> **⭐ 重要提示2025-11-16 更新)**:平台已提供完整的基础设施服务
## <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>滚𦛚
> **霂衣<E99C82><E8A1A3><EFBFBD>﹝**嚗靀撟喳蝱<E596B3><EFBFBD>霈暹鴌閫<E9B48C><E996AB>](../09-<2D><EFBFBD>摰墧鴌/04-撟喳蝱<E596B3><EFBFBD>霈暹鴌閫<E9B48C><E996AB>.md)
### 撟喳蝱撌脫<E6928C>靘𤤿<E99D98><F0A4A4BF>滚𦛚
**銝𡁜𦛚璅<E79285>嚗㇁SL/AIA/PKB/DC蝑㚁<E89D91>摨磰砲憭滨鍂隞乩<E99A9E>撟喳蝱<E596B3><EFBFBD>嚗𣬚<E59A97><E79487>憭滚<E686AD><E6BB9A><EFBFBD>**
| 服务 | 导入方式 | 用途 | 文档 |
| <EFBFBD>滚𦛚 | 撖澆<E69296><E6BE86><EFBFBD> | <20><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调用 | ✅ 平台级 |
### 示例:正确使用平台服务
| **摮睃<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>?撟喳蝱蝥?|
### 蝷箔<E89DB7>嚗𡁏迤蝖桐蝙<E6A190>典像<E585B8><EFBFBD><E594B3>?
```typescript
// ✅ 正确:直接导入平台服务
import { storage } from '@/common/storage'
// <EFBFBD>?甇<>嚗𡁶凒<F0A181B6>亙紡<E4BA99>亙像<E4BA99><EFBFBD><E594B3>?import { storage } from '@/common/storage'
import { logger } from '@/common/logging'
import { jobQueue } from '@/common/jobs'
import { prisma } from '@/config/database'
@@ -55,8 +50,7 @@ export class LiteratureService {
// 2. 雿輻鍂撟喳蝱<E596B3><EFBFBD>蝟餌<E89D9F>
logger.info('PDF uploaded', { projectId, url })
// 3. 使用平台数据库
const literature = await prisma.aslLiterature.create({
// 3. 雿輻鍂撟喳蝱<EFBFBD>唳旿摨? const literature = await prisma.aslLiterature.create({
data: { projectId, pdfUrl: url }
})
@@ -65,36 +59,26 @@ export class LiteratureService {
}
```
### ❌ 错误:重复实现平台能力
### <EFBFBD>?<3F>躰秤嚗𡁻<E59A97>憭滚<E686AD><E6BB9A>啣像<E595A3><EFBFBD><E59597>?
```typescript
// ❌ 错误:在业务模块中自己实现存储
// backend/src/modules/asl/storage/LocalStorage.ts ← 不应该存在!
// <EFBFBD>?<3F>躰秤嚗𡁜銁銝𡁜𦛚璅<E79285>銝剛䌊撌勗<E6928C><E58B97><EFBFBD><E595A3>?// backend/src/modules/asl/storage/LocalStorage.ts <20>?銝滚<E98A9D>霂亙<E99C82><E4BA99><EFBFBD>
export class LocalStorage {
async upload(file: Buffer) {
await fs.writeFile('./uploads/file.pdf', file) // ❌ 重复实现
await fs.writeFile('./uploads/file.pdf', file) // <EFBFBD>?<3F><EFBFBD>摰䂿緵
}
}
// ❌ 错误:在业务模块中自己实现日志
// backend/src/modules/asl/logger/logger.ts ← 不应该存在!
export const logger = winston.createLogger({...}) // ❌ 重复实现
// <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>摰䂿緵
```
**原因**
- ❌ 重复代码,难以维护
- ❌ 不同模块实现不一致
- ❌ 无法统一切换环境(本地/云端)
- ❌ 浪费开发时间
**<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>?
---
## ✅ 推荐做法DO
### 1. 文件存储 ✅
## <EFBFBD>?<3F><EFBFBD><E588BB>𡁏<EFBFBD>嚗㇄O嚗?
### 1. <20><>辣摮睃<E691AE> <20>?
```typescript
// ✅ 正确:使用存储抽象层
// <EFBFBD>?甇<>嚗帋蝙<E5B88B><EFBFBD><E585B8>冽𡂝鞊<E99E8A>
import { storage } from '@/common/storage/StorageFactory'
export async function uploadFile(file: Buffer, filename: string) {
@@ -103,8 +87,7 @@ export async function uploadFile(file: Buffer, filename: string) {
return url
}
// ✅ 正确Excel 直接从内存解析
import * as xlsx from 'xlsx'
// <EFBFBD>?甇<>嚗鍃xcel <20>湔𦻖隞𤾸<E99A9E>摮䁅圾<E48185>?import * as xlsx from 'xlsx'
export async function importExcel(buffer: Buffer) {
const workbook = xlsx.read(buffer, { type: 'buffer' }) // <20><><EFBFBD><EFBFBD><E996AB>
@@ -113,42 +96,35 @@ export async function importExcel(buffer: Buffer) {
}
```
**理由**
- 容器重启不会丢失文件
- 本地开发和生产环境代码一致
- 自动根据环境变量切换存储方式
**<EFBFBD><EFBFBD>眏**嚗?- 摰孵膥<E5ADB5>滚鍳銝滢<E98A9D><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. 数据库连接 ✅
### 2. <EFBFBD>唳旿摨栞<EFBFBD><EFBFBD>?<3F>?
```typescript
// ✅ 正确:使用全局 Prisma Client
// <EFBFBD>?甇<>嚗帋蝙<E5B88B><EFBFBD><EFBFBD> Prisma Client
import { prisma } from '@/config/database'
export async function createProject(data: any) {
return await prisma.aslScreeningProject.create({ data })
}
// ✅ 正确:批量操作使用事务
export async function importLiteratures(literatures: any[]) {
// <EFBFBD>?甇<>嚗𡁏鸌<F0A1818F>𤩺<EFBFBD>雿靝蝙<E99D9D><EFBFBD><E585B6>?export async function importLiteratures(literatures: any[]) {
return await prisma.$transaction(async (tx) => {
return await tx.aslLiterature.createMany({ data: literatures })
})
}
```
**理由**
- 全局实例复用连接
**<EFBFBD><EFBFBD>眏**嚗?- <20><EFBFBD>摰硺<E691B0>憭滨鍂餈墧𦻖
- <20><EFBFBD>餈墧𦻖<E5A2A7><EFBFBD>堒偷
- 事务保证数据一致性
- 鈭见𦛚靽肽<EFBFBD><EFBFBD>唳旿銝<EFBFBD><EFBFBD><EFBFBD>?
---
### 3. 环境变量配置 ✅
### 3. <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>滨蔭 <20>?
```typescript
// ✅ 正确:统一配置管理
// <EFBFBD>?甇<>嚗𡁶<E59A97><EFBFBD><E98A9D>滨蔭蝞∠<E89D9E>
// backend/src/config/env.ts
export const config = {
llm: {
@@ -164,22 +140,19 @@ export const config = {
}
}
// ✅ 正确:使用配置对象
import { config } from '@/config/env'
// <EFBFBD>?甇<>嚗帋蝙<E5B88B><EFBFBD>蝵桀笆鞊?import { config } from '@/config/env'
const apiKey = config.llm.apiKey
```
**理由**
- 配置集中管理
**<EFBFBD><EFBFBD>眏**嚗?- <20>滨蔭<E6BBA8><E894AD>葉蝞∠<E89D9E>
- 蝐餃<E89D90>摰匧<E691B0>
- 靘蹂<E99D98><E8B982><EFBFBD><EFBFBD><EFBFBD>
---
### 4. 长时间任务处理 ✅
### 4. <EFBFBD>踵𧒄<EFBFBD>港遙<EFBFBD><EFBFBD><EFBFBD>?<3F>?
```typescript
// ✅ 正确:异步任务 + 进度轮询
// <EFBFBD>?甇<>嚗𡁜<E59A97>甇乩遙<E4B9A9>?+ 餈𥕦漲頧株砭
export async function startScreening(req, res) {
// 1. <20>𥕦遣隞餃𦛚霈啣<E99C88>
const task = await prisma.aslScreeningTask.create({
@@ -193,9 +166,8 @@ export async function startScreening(req, res) {
// 2. 蝡见朖餈𥪜<E9A488>隞餃𦛚ID
res.send({ success: true, taskId: task.id })
// 3. 后台异步执行(不阻塞请求)
processScreeningAsync(task.id).catch(err => {
console.error('筛选任务失败:', err)
// 3. <EFBFBD>𤾸蝱撘<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>霂瑟<EFBFBD>嚗? processScreeningAsync(task.id).catch(err => {
console.error('蝑偦<E89D91>劐遙<E58A90>仃韐?', err)
})
}
@@ -212,20 +184,16 @@ export async function getTaskProgress(req, res) {
}
```
**理由**
- 避免请求超时SAE默认30秒
**<EFBFBD><EFBFBD>眏**嚗?- <20><EFBFBD>霂瑟<E99C82><EFBFBD>𧒄嚗𠄎AE暺䁅恕30蝘𡜐<E89D98>
- <20><EFBFBD>雿㯄<E99BBF><E3AF84>游末
- <20><EFBFBD><E88880><EFBFBD>隞餃𦛚
**✨ 完整实践参考**
详见 [Postgres-Only异步任务处理指南](../02-通用能力层/Postgres-Only异步任务处理指南.md)基于DC Tool C完整实践
**<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摰峕㟲摰噼殿嚗?
---
### 5. 日志输出 ✅
### 5. <EFBFBD><EFBFBD>颲枏枂 <20>?
```typescript
// ✅ 正确:使用 logger 输出到 stdout
// <EFBFBD>?甇<>嚗帋蝙<E5B88B>?logger 颲枏枂<EFBFBD>?stdout
import pino from 'pino'
const logger = pino({
@@ -241,7 +209,7 @@ export async function uploadFile(req, res) {
// ... 銝𠹺<E98A9D><F0A0B9BA><EFBFBD>
}
// ✅ 正确:结构化日志
// <EFBFBD>?甇<>嚗𡁶<E59A97><F0A181B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
logger.error({
error: err.message,
stack: err.stack,
@@ -249,17 +217,13 @@ logger.error({
}, 'Upload failed')
```
**理由**
- SAE 自动采集 stdout 日志
- 结构化便于查询分析
- 集中查看,不会丢失
**<EFBFBD><EFBFBD>眏**嚗?- SAE <20>芸𢆡<E88AB8><F0A286A1><EFBFBD> stdout <20><EFBFBD>
- 蝏𤘪<EFBFBD><EFBFBD>碶噶鈭擧䰻霂<EFBFBD><EFBFBD>?- <20><><EFBFBD><EFBFBD>嚗䔶<E59A97>隡帋腺憭?
---
### 6. 错误处理 ✅
### 6. <EFBFBD>躰秤憭<EFBFBD><EFBFBD> <20>?
```typescript
// ✅ 正确:统一错误处理
// <EFBFBD>?甇<>嚗𡁶<E59A97><EFBFBD><E98A9D>躰秤憭<E7A7A4><E686AD>
export async function uploadPdf(req, res) {
try {
const file = await req.file()
@@ -282,17 +246,14 @@ export async function uploadPdf(req, res) {
}
```
**理由**
- 用户看到友好错误信息
**<EFBFBD><EFBFBD>眏**嚗?- <20><EFBFBD><E586BD><EFBFBD><E8A781>见末<E8A781>躰秤靽⊥<E99DBD>
- <20><EFBFBD>霈啣<E99C88>霂衣<E99C82><E8A1A3>躰秤
- 不暴露内部实现
- 銝齿𠂔<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
---
### 7. 临时文件处理 ✅
### 7. 銝湔𧒄<EFBFBD><EFBFBD>辣憭<EFBFBD><EFBFBD> <20>?
```typescript
// ✅ 正确:/tmp 目录用完立即删除
// <EFBFBD>?甇<>嚗?tmp <20><EFBFBD><E6A180><EFBFBD>蝡见朖<E8A781>𣳇膄
import fs from 'fs/promises'
import path from 'path'
@@ -300,7 +261,7 @@ export async function extractPdfText(ossKey: string): Promise<string> {
const tmpPath = path.join('/tmp', `${Date.now()}.pdf`)
try {
// 1. OSS 下载到 /tmp
// 1. 隞?OSS 銝贝蝸<EFBFBD>?/tmp
await storage.download(ossKey, tmpPath)
// 2. <20>𣂼<EFBFBD><F0A382BC><EFBFBD>𧋦
@@ -318,51 +279,43 @@ export async function extractPdfText(ossKey: string): Promise<string> {
}
```
**理由**
- /tmp 容量有限512MB
- 容器重启会清空
- 避免磁盘占满
**<EFBFBD><EFBFBD>眏**嚗?- /tmp 摰寥<E691B0><E5AFA5><EFBFBD>嚗?12MB嚗?- 摰孵膥<E5ADB5>滚鍳隡𡁏<E99AA1>蝛?- <20><EFBFBD><EFBFBD><E89DA4><EFBFBD>䭾說
---
## 🏆 Postgres-Only 架构规范2025-12-13 新增)
## <EFBFBD><EFBFBD> Postgres-Only <EFBFBD><EFBFBD><EFBFBD><EFBFBD>嚗?025-12-13 <EFBFBD><EFBFBD>嚗?
### <20><EFBFBD><E8A9A8><EFBFBD>
**Platform-Only 模式**:所有任务管理信息统一存储在 `platform_schema.job.data`,业务表只存储业务信息。
### 任务管理的正确做法
#### ✅ DO: 使用 job.data 存储任务管理信息
**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>瘜?
#### <20>?DO: 雿輻鍂 job.data 摮睃<E691AE>隞餃𦛚蝞∠<E89D9E>靽⊥<E99DBD>
```typescript
// ✅ 正确:任务拆分和断点信息存储在 job.data
// <EFBFBD>?甇<>嚗帋遙<E5B88B><EFBFBD><E28AA5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>靽⊥<E99DBD>摮睃<E691AE><E79D83>?job.data
import { jobQueue } from '@/common/jobs';
import { CheckpointService } from '@/common/jobs/CheckpointService';
// 推送任务时,包含完整信息
await jobQueue.push('asl:screening:batch', {
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>⊥𧒄嚗<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>港縑<EFBFBD>?await jobQueue.push('asl:screening:batch', {
// 銝𡁜𦛚靽⊥<E99DBD>
taskId: 'xxx',
projectId: 'yyy',
literatureIds: [...],
// ✅ 任务拆分信息(存储在 job.data
batchIndex: 3,
// <EFBFBD>?隞餃𦛚<E9A483><F0A69B9A><EFBFBD>靽⊥<E99DBD><EFBFBD><E59A97><EFBFBD>典銁 job.data嚗? batchIndex: 3,
totalBatches: 20,
startIndex: 150,
endIndex: 200,
// ✅ 进度追踪
// <EFBFBD>?餈𥕦漲餈質葵
processedCount: 0,
successCount: 0,
failedCount: 0,
});
// Worker 中使用 CheckpointService
// Worker 銝凋蝙<EFBFBD>?CheckpointService
const checkpointService = new CheckpointService(prisma);
// 保存断点到 job.data
// 靽嘥<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?job.data
await checkpointService.saveCheckpoint(job.id, {
currentBatchIndex: 5,
currentIndex: 250,
@@ -370,52 +323,39 @@ await checkpointService.saveCheckpoint(job.id, {
totalBatches: 20
});
// 加载断点从 job.data
// <EFBFBD>㰘蝸<EFBFBD><EFBFBD>隞?job.data
const checkpoint = await checkpointService.loadCheckpoint(job.id);
if (checkpoint) {
resumeFrom = checkpoint.currentIndex;
}
```
#### DON'T: 在业务表中存储任务管理信息
#### <EFBFBD>?DON'T: <EFBFBD><EFBFBD><EFBFBD>∟”銝剖<EFBFBD><EFBFBD>其遙<EFBFBD>∠恣<EFBFBD><EFBFBD><EFBFBD>?
```typescript
// ❌ 错误:在业务表的 Schema 中添加任务管理字段
model AslScreeningTask {
// <EFBFBD>?<3F>躰秤嚗𡁜銁銝𡁜𦛚銵函<E98AB5> Schema 銝剜溶<E5899C>牐遙<E78990>∠恣<E288A0><E681A3><EFBFBD>畾?model AslScreeningTask {
id String @id
projectId String
// ❌ 不要添加这些字段!
totalBatches Int // ← 应该在 job.data 中
processedBatches Int // ← 应该在 job.data 中
currentIndex Int // ← 应该在 job.data 中
checkpointData Json? // ← 应该在 job.data 中
}
// <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 銝?}
// ❌ 错误:自己实现断点服务
class MyCheckpointService {
// <EFBFBD>?<3F>躰秤嚗朞䌊撌勗<E6928C><E58B97>唳鱏<E594B3><EFBFBD><E5AF9E>?class MyCheckpointService {
async save(taskId: string) {
await prisma.aslScreeningTask.update({
where: { id: taskId },
data: { checkpointData: {...} } // ❌ 不要这样做!
data: { checkpointData: {...} } // <EFBFBD>?銝滩<E98A9D>餈蹱甅<E8B9B1>𡄯<EFBFBD>
});
}
}
```
**銝箔<E98A9D><EFBFBD><E98A8B>撖對<E69296>**
- ❌ 每个模块都要添加相同的字段(代码重复)
- ❌ 违反 DRY 原则
- ❌ 违反 3 层架构原则
- ❌ 维护困难(修改逻辑需要改多处)
- <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>嚗?
### <20><EFBFBD><E7AE84><EFBFBD><EFBFBD>澆ế<E6BE86><EFBFBD><EFBFBD><E996AB>
#### DO: 实现智能双模式处理
#### <EFBFBD>?DO: 摰䂿緵<EFBFBD><EFBFBD><EFBFBD>峕芋撘誩<EFBFBD><EFBFBD>?
```typescript
const QUEUE_THRESHOLD = 50; // 推荐阈值
const QUEUE_THRESHOLD = 50; // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
export async function startTask(items: any[]) {
const useQueue = items.length >= QUEUE_THRESHOLD;
@@ -426,84 +366,68 @@ export async function startTask(items: any[]) {
await jobQueue.push('task:batch', {...});
}
} else {
// 直接模式:小任务(<50条
processDirectly(items); // 快速响应
}
// <EFBFBD>湔𦻖璅<EFBFBD>嚗𡁜<EFBFBD>隞餃𦛚嚗?50<35><EFBFBD>
processDirectly(items); // 敹恍<EFBFBD><EFBFBD>摨? }
}
```
**为什么这样做?**
- ✅ 小任务快速响应(无队列延迟)
- ✅ 大任务高可靠(支持断点续传)
- ✅ 性能与可靠性平衡
#### ❌ DON'T: 所有任务都走队列
**銝箔<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>?
```typescript
// ❌ 错误即使1条记录也使用队列
// <EFBFBD>?<3F>躰秤嚗𡁜朖雿?<3F>∟扇敶蓥<E695B6>雿輻鍂<E8BCBB><EFBFBD>
export async function startTask(items: any[]) {
// <20>㰘捏憭𡁜<E686AD><F0A1819C>唳旿嚗屸<E59A97><E5B1B8><EFBFBD><E588B8><EFBFBD><EFBFBD><EFBFBD>
await jobQueue.push('task:batch', items); // ❌ 小任务会有延迟
}
await jobQueue.push('task:batch', items); // <EFBFBD>?撠譍遙<E8AD8D><EFBFBD><E288A9>匧辣餈?}
```
**銝箔<E98A9D><EFBFBD><E98A8B>撖對<E69296>**
- ❌ 小任务响应慢(队列有轮询间隔)
- ❌ 浪费队列资源
- ❌ 用户体验差
### 阈值推荐值
| 任务类型 | 推荐阈值 | 理由 |
- <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><>眏 |
|---------|---------|------|
| 文献筛选 | 50篇 | 单篇~7秒50篇~5分钟 |
| 数据提取 | 50条 | 单条~5-10秒50条~5分钟 |
| 统计模型 | 30个 | 单个~10秒30个~5分钟 |
| 默认 | 50条 | 通用推荐值 |
| <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>?|
---
## ❌ 禁止做法DON'T
### 1. 本地文件存储 ❌
## <EFBFBD>?蝳<><EFBFBD>𡁏<EFBFBD>嚗㇄ON'T嚗?
### 1. <20>砍𧑐<E7A08D><F0A79190>辣摮睃<E691AE> <20>?
```typescript
// ❌ 禁止:本地文件系统存储
import fs from 'fs'
// <EFBFBD>?蝳<>迫嚗𡁏𧋦<F0A1818F><EFBFBD>隞嗥頂蝏笔<E89D8F><E7AC94>?import fs from 'fs'
export async function uploadFile(req, res) {
const file = await req.file()
const buffer = await file.toBuffer()
// ❌ 错误:容器重启丢失
fs.writeFileSync('./uploads/file.pdf', buffer)
// <EFBFBD>?<3F>躰秤嚗𡁜捆<F0A1819C><EFBFBD><E588B8>臭腺憭? fs.writeFileSync('./uploads/file.pdf', buffer)
res.send({ url: '/uploads/file.pdf' })
}
// ❌ 禁止:依赖本地路径
const uploadDir = '/var/app/uploads'
// <EFBFBD>?蝳<>迫嚗帋<E59A97>韏𡝗𧋦<F0A19D97>啗楝敺?const uploadDir = '/var/app/uploads'
const filePath = path.join(uploadDir, filename)
```
**问题**
- 容器重启或扩容后文件丢失
**<EFBFBD><EFBFBD>**嚗?- 摰孵膥<E5ADB5>滚鍳<E6BB9A>𡝗<EFBFBD>摰孵<E691B0><E5ADB5><EFBFBD>辣銝
- 憭𡁜<E686AD>靘钅𡢿<E99285><EFBFBD><E4ADBE>曹澈<E69BB9><E6BE88>
-<><E89DA4>蝛粹𡢿<E7B2B9><EFBFBD>
**正确做法**:使用 `storage.upload()` 上传到 OSS
**<EFBFBD><EFBFBD>𡁏<EFBFBD>**嚗帋蝙<E5B88B>?`storage.upload()` 銝𠹺<EFBFBD><EFBFBD>?OSS
---
### 2. 内存缓存 ❌
### 2. <EFBFBD><EFBFBD><EFBFBD>蝻枏<EFBFBD> <20>?
```typescript
// ❌ 禁止:内存缓存(多实例不共享)
const cache = new Map<string, any>()
// <EFBFBD>?蝳<>迫嚗𡁜<E59A97>摮条<E691AE>摮矋<E691AE>憭𡁜<E686AD>靘衤<E99D98><E8A1A4>曹澈嚗?const cache = new Map<string, any>()
export async function getProject(id: string) {
// ❌ 错误:扩容后其他实例读不到缓存
if (cache.has(id)) {
// <EFBFBD>?<3F>躰秤嚗𡁏<E59A97>摰孵<E691B0><E5ADB5><EFBFBD>摰硺<E691B0>霂颱<E99C82><E9A2B1><EFBFBD>摮? if (cache.has(id)) {
return cache.get(id)
}
@@ -512,42 +436,32 @@ export async function getProject(id: string) {
return project
}
// ❌ 禁止:全局变量存储状态
let taskStatus = {} // 多实例不同步
// <EFBFBD>?蝳<>迫嚗𡁜<E59A97><EFBFBD><E69285><EFBFBD>摮睃<E691AE><E79D83><EFBFBD>?let taskStatus = {} // 憭𡁜<E686AD>靘衤<E99D98><E8A1A4>峕郊
```
**问题**
- 多实例间数据不同步
- 扩容后缓存失效
- 内存占用不可控
**正确做法**:使用 Redis 或数据库
**<EFBFBD><EFBFBD>**嚗?- 憭𡁜<E686AD>靘钅𡢿<E99285>唳旿銝滚<E98A9D>甇?- <20>拙捆<E68B99>𡒊<EFBFBD>摮睃仃<E79D83>?- <20><><EFBFBD><EFBFBD>删鍂銝滚虾<E6BB9A>?
**甇<><EFBFBD>𡁏<EFBFBD>**嚗帋蝙<E5B88B>?Redis <20>𡝗㺭<F0A19D97><EFBFBD>
---
### 3. 硬编码配置 ❌
### 3. 蝖祉<EFBFBD><EFBFBD><EFBFBD><EFBFBD>蝵?<3F>?
```typescript
// ❌ 禁止:硬编码
// <EFBFBD>?蝳<>迫嚗𡁶蝻𣇉<E89DBB>
const LLM_API_KEY = 'sk-xxx'
const DB_HOST = '192.168.1.100'
const OSS_BUCKET = 'my-bucket'
// ❌ 禁止:写死端口
app.listen(3001)
// <EFBFBD>?蝳<>迫嚗𡁜<E59A97>甇餌垢<E9A48C>?app.listen(3001)
// ❌ 禁止:写死域名
const baseUrl = 'https://api.example.com'
// <EFBFBD>?蝳<>迫嚗𡁜<E59A97>甇餃<E79487><E9A483>?const baseUrl = 'https://api.example.com'
```
**问题**
- 无法切换环境
**<EFBFBD><EFBFBD>**嚗?- <20><EFBFBD><E4ADBE><EFBFBD><EFBFBD><EFBFBD>
- 摰匧<E691B0>憌𡡞埯嚗<E59FAF><E59A97><EFBFBD><EFBFBD><E4BAA4><EFBFBD>
- <20>函蔡<E587BD>圈𠗕
**正确做法**
```typescript
// ✅ 使用环境变量
**<EFBFBD><EFBFBD>𡁏<EFBFBD>**嚗?```typescript
// <20>?雿輻鍂<E8BCBB><EFBFBD><E887AC><EFBFBD>
const apiKey = process.env.LLM_API_KEY
const port = process.env.PORT || 3001
app.listen(port)
@@ -555,124 +469,99 @@ app.listen(port)
---
### 4. 同步长任务 ❌
### 4. <EFBFBD>峕郊<EFBFBD>蹂遙<EFBFBD>?<3F>?
```typescript
// ❌ 禁止:同步处理长任务
// <20>?蝳<>迫嚗𡁜<E59A97>甇亙<E79487><E4BA99><EFBFBD>鵭隞餃𦛚
export async function screenLiteratures(req, res) {
const literatures = await prisma.aslLiterature.findMany({...})
// ❌ 错误100篇可能超过30秒
for (const lit of literatures) {
await llmScreening(lit) // 每篇2-3秒
}
// <EFBFBD>?<3F>躰秤嚗?00蝭<30><EFBFBD><EFBFBD>餈?0蝘? for (const lit of literatures) {
await llmScreening(lit) // 瘥讐<E798A5>2-3蝘? }
res.send({ success: true }) // <20><EFBFBD>撌脩<E6928C><EFBFBD>𧒄
}
// ❌ 禁止:没有超时保护
const result = await axios.get(url) // 可能永久等待
// <EFBFBD>?蝳<>迫嚗𡁏瓷<F0A1818F><EFBFBD><E39591><EFBFBD><E597A1>?const result = await axios.get(url) // <20><EFBFBD>瘞訾<E7989E>蝑匧<E89D91>
```
**问题**
- SAE 请求超时 30 秒
- 前端等待时间过长
**<EFBFBD><EFBFBD>**嚗?- SAE 霂瑟<E99C82><EFBFBD>𧒄 30 蝘?- <20>滨垢蝑匧<E89D91><E58CA7>園𡢿餈<F0A1A2BF>
- <20><EFBFBD><E4ADBE>曄內餈𥕦漲
**正确做法**:异步任务 + 进度轮询(见 DO 第4条
**<EFBFBD><EFBFBD>𡁏<EFBFBD>**嚗𡁜<E59A97>甇乩遙<E4B9A9>?+ 餈𥕦漲頧株砭嚗<E7A0AD><E59A97> DO 蝚?<3F><EFBFBD>
---
### 5. 本地日志文件 ❌
### 5. <EFBFBD>砍𧑐<EFBFBD><EFBFBD><EFBFBD><EFBFBD><20>?
```typescript
// ❌ 禁止:写入本地文件
import fs from 'fs'
// <20>?蝳<>迫嚗𡁜<E59A97><F0A1819C>交𧋦<E4BAA4><EFBFBD>隞?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')
}
// ❌ 禁止:使用 console.log 而不用 logger
console.log('User logged in') // 无结构化,难以查询
```
// <EFBFBD>?蝳<>迫嚗帋蝙<E5B88B>?console.log <EFBFBD><EFBFBD><EFBFBD>?logger
console.log('User logged in') // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>嚗屸𠗕隞交䰻霂?```
**问题**
- 容器重启日志丢失
- 多实例日志分散
- 无法集中分析
**<EFBFBD><EFBFBD>**嚗?- 摰孵膥<E5ADB5>滚鍳<E6BB9A><EFBFBD>
- 憭𡁜<E686AD>靘𧢲𠯫敹堒<E695B9><E5A092>?- <20><EFBFBD><E4ADBE><EFBFBD><EFBFBD><E89189><EFBFBD>
**正确做法**
```typescript
// ✅ 输出到 stdout使用 logger
**<EFBFBD><EFBFBD>𡁏<EFBFBD>**嚗?```typescript
// <20>?颲枏枂<E69E8F>?stdout嚗䔶蝙<E494B6>?logger
logger.info({ userId, action: 'login' }, 'User logged in')
```
---
### 6. 新建数据库连接 ❌
### 6. <EFBFBD>啣遣<EFBFBD>唳旿摨栞<EFBFBD><EFBFBD>?<3F>?
```typescript
// ❌ 禁止:每次请求新建连接
import { PrismaClient } from '@prisma/client'
// <20>?蝳<>迫嚗𡁏<E59A97>甈∟窈瘙<E7AA88>鰵撱箄<E692B1><E7AE84>?import { PrismaClient } from '@prisma/client'
export async function getProjects(req, res) {
// ❌ 错误:每次新建,连接数暴增
const prisma = new PrismaClient()
// <EFBFBD>?<3F>躰秤嚗𡁏<E59A97>甈⊥鰵撱綽<E692B1>餈墧𦻖<E5A2A7>唳𠂔憓? const prisma = new PrismaClient()
const projects = await prisma.aslScreeningProject.findMany()
await prisma.$disconnect()
res.send(projects)
}
// ❌ 禁止:直接使用 pg 或其他驱动
import { Pool } from 'pg'
// <EFBFBD>?蝳<>迫嚗𡁶凒<F0A181B6>乩蝙<E4B9A9>?pg <20><EFBFBD>隞㚚店<E39A9A>?import { Pool } from 'pg'
const pool = new Pool({ connectionString: process.env.DATABASE_URL })
```
**问题**
- 连接数快速耗尽RDS限制 400 连接)
- 性能低下(连接建立耗时)
- 资源浪费
**<EFBFBD><EFBFBD>**嚗?- 餈墧𦻖<E5A2A7>啣翰<E595A3><EFBFBD>堒偷嚗㇌DS<44>𣂼<EFBFBD> 400 餈墧𦻖嚗?- <20><EFBFBD>雿𦒘<E99BBF><EFBFBD><E59A97><EFBFBD>亙遣蝡贝<E89DA1>埈𧒄嚗?- 韏<><E99F8F>瘚芾晶
**正确做法**
```typescript
// ✅ 使用全局 Prisma Client
**<EFBFBD><EFBFBD>𡁏<EFBFBD>**嚗?```typescript
// <20>?雿輻鍂<E8BCBB><EFBFBD> Prisma Client
import { prisma } from '@/config/database'
const projects = await prisma.aslScreeningProject.findMany()
```
---
### 7. 忽略错误 ❌
### 7. 敹賜裦<EFBFBD>躰秤 <20>?
```typescript
// ❌ 禁止:空的 catch
// <20>?蝳<>迫嚗𡁶征<F0A181B6>?catch
try {
await storage.upload(key, buffer)
} catch (error) {
// ❌ 错误被吞掉,无法排查
// <EFBFBD>?<3F>躰秤鋡怠<E98BA1><E680A0><EFBFBD><E39A81><EFBFBD><E4ADBE>埝䰻
}
// ❌ 禁止:不处理 Promise rejection
// <EFBFBD>?蝳<>迫嚗帋<E59A97><EFBFBD><E686AD> Promise rejection
processAsync(taskId) // 瘝⊥<E7989D> .catch()
// ❌ 禁止:返回模糊错误
catch (error) {
// <EFBFBD>?蝳<>迫嚗朞<E59A97><E69C9E>墧芋蝟𢠃<E89D9F>霂?catch (error) {
res.status(500).send({ error: 'Something went wrong' })
// <20><EFBFBD>銝滨䰻<E6BBA8><EFBFBD><EFBFBD><E98A8B><EFBFBD><E988AD><EFBFBD><E68692><EFBFBD><E996AB>
}
```
**问题**
- 错误无法追踪
- 用户体验差
- 排查困难
**<EFBFBD><EFBFBD>**嚗?- <20>躰秤<E8BAB0><EFBFBD>餈質葵
- <20><EFBFBD>雿㯄<E99BBF>撌?- <20>埝䰻<E59F9D>圈𠗕
**正确做法**
```typescript
// ✅ 记录日志 + 友好错误信息
**<EFBFBD><EFBFBD>𡁏<EFBFBD>**嚗?```typescript
// <20>?霈啣<E99C88><E595A3><EFBFBD> + <20>见末<E8A781>躰秤靽⊥<E99DBD>
try {
await storage.upload(key, buffer)
} catch (error) {
@@ -689,57 +578,39 @@ try {
---
## 🔍 代码审查检查清单
在**提交代码前**,请逐项检查:
## <EFBFBD><EFBFBD><><E99A9E>摰⊥䰻璉<E4B0BB><E79289><EFBFBD><E4BAA4>?
<EFBFBD>?*<2A>𣂷漱隞<E6BCB1><E99A9E><EFBFBD>?*嚗諹窈<E8ABB9>鞾★璉<E29885><E79289><EFBFBD>
### <20><>辣摮睃<E691AE>
- [ ] 是否使用 `storage.upload()` 而非 `fs.writeFile()`
- [ ] Excel 是否从内存解析,而非保存到本地?
- [ ] <20>臬炏雿輻鍂 `storage.upload()` <20><EFBFBD> `fs.writeFile()`嚗?- [ ] Excel <20>臬炏隞𤾸<E99A9E>摮䁅圾<E48185><EFBFBD><E7909C><EFBFBD>靽嘥<E99DBD><E598A5>唳𧋦<E594B3><EFBFBD>
- [ ] PDF <20>𣂼<EFBFBD><F0A382BC>擧糓<E693A7><EFBFBD><E8A1A3><EFBFBD><E596B3>支葩<E694AF><EFBFBD>隞塚<E99A9E>
### 数据库
- [ ] 是否使用全局 `prisma` 实例?
- [ ] 是否避免在循环中执行单条查询?(应该批量操作)
- [ ] 批量操作是否使用事务?
### <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>臬炏雿輻鍂鈭见𦛚嚗?
### <20>滨蔭蝞∠<E89D9E>
- [ ] 是否所有配置都从 `process.env` 读取?
- [ ] 是否没有硬编码的 IP、域名、密钥
- [ ] <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>
- [ ] `.env.example` <20>臬炏撌脫凒<E884AB><EFBFBD>
### 长时间任务
- [ ] 超过 10 秒的任务是否改为异步?
- [ ] 是否提供了进度查询接口?
- [ ] 前端是否有轮询或 WebSocket 获取进度?
### <EFBFBD>踵𧒄<EFBFBD>港遙<EFBFBD>?- [ ] 頞<><E9A09E> 10 蝘垍<E89D98>隞餃𦛚<E9A483>臬炏<E887AC>嫣蛹撘<E89BB9>郊嚗?- [ ] <20>臬炏<E887AC>𣂷<EFBFBD><EFBFBD><E988AD>摨行䰻霂𦻖<EFBCB8><F0A6BB96><EFBFBD>
- [ ] <20>滨垢<E6BBA8>臬炏<E887AC>㕑蔭霂<E99C82> WebSocket <20><EFBFBD>餈𥕦漲嚗?
### <20><EFBFBD>
- [ ] 是否使用 `logger` 而非 `console.log`
- [ ] 日志是否结构化JSON格式
- [ ] <20>臬炏雿輻鍂 `logger` <20><EFBFBD> `console.log`嚗?- [ ] <20><EFBFBD><E4BA99>臬炏蝏𤘪<E89D8F><F0A498AA><EFBFBD>JSON<4F><EFBFBD>嚗㚁<E59A97>
- [ ] <20>臬炏霈啣<E99C88><EFBFBD><E988AD><EFBFBD><EFBFBD>雿頣<E99BBF>userId<49><64>ction嚗㚁<E59A97>
### <20>躰秤憭<E7A7A4><E686AD>
- [ ] 所有 async 函数是否有 try-catch
- [ ] 是否记录了详细错误日志?
- [ ] 是否返回了友好的错误信息?
- [ ] <20><><EFBFBD>?async <20>賣㺭<E8B3A3>臬炏<E887AC>?try-catch嚗?- [ ] <20>臬炏霈啣<E99C88><EFBFBD>祕蝏<E7A595><E89D8F>霂舀𠯫敹梹<E695B9>
- [ ] <20>臬炏餈𥪜<E9A488><EFBFBD><E988AD>憟賜<E6869F><E8B39C>躰秤靽⊥<E99DBD>嚗?
### 銝湔𧒄<E6B994><F0A79284>
- [ ] `/tmp` <20><EFBFBD>雿輻鍂<E8BCBB>擧糓<E693A7><EFBFBD><E8A1A3><EFBFBD><E596B3><EFBFBD>
- [ ] 是否在 `finally` 块中清理?
- [ ] 是否避免长期依赖 `/tmp`
- [ ] <20>臬炏<E887AC>?`finally` <20>𦯀葉皜<E89189><E79A9C>嚗?- [ ] <20>臬炏<E887AC><EFBFBD><E8B8B9><EFBFBD>靘肽<E99D98> `/tmp`嚗?
---
## 🎯 快速自检5分钟
**运行以下命令,检查代码中是否有违规**
## <EFBFBD>㴓 敹恍<E695B9>蠘䌊璉<E48C8A>嚗?<3F><><EFBFBD>嚗?
**餈鞱<E9A488>隞乩<E99A9E><E4B9A9>賭誘嚗峕<E59A97><E5B395>乩誨<E4B9A9><E8AAA8><EFBFBD>臬炏<E887AC><EFBFBD>閫?*嚗?
```bash
# 璉<><E79289>交糓<E4BAA4><EFBFBD><E8A18C>砍𧑐<E7A08D><F0A79190>辣摮睃<E691AE>
grep -r "fs.writeFile\|fs.appendFile" backend/src/modules/
# 检查是否有硬编码配置
grep -r "sk-\|http://\|192.168" backend/src/modules/
# <EFBFBD><EFBFBD>交糓<EFBFBD><EFBFBD>蝖祉<EFBFBD><EFBFBD><EFBFBD><EFBFBD>蝵?grep -r "sk-\|http://\|192.168" backend/src/modules/
# 璉<><E79289>交糓<E4BAA4><EFBFBD><E8A18C>啣遣 Prisma 餈墧𦻖
grep -r "new PrismaClient" backend/src/modules/
@@ -748,15 +619,14 @@ grep -r "new PrismaClient" backend/src/modules/
grep -r "console.log" backend/src/modules/
```
**预期结果**:所有检查应该返回 **0 个匹配**
**<EFBFBD><EFBFBD>蝏𤘪<EFBFBD>**嚗𡁏<E59A97><F0A1818F><EFBFBD><E39787><EFBFBD>霂亥<E99C82><E4BAA5>?**0 銝芸龪<E88AB8>?*
---
## 📚 参考文档
- [云原生部署架构指南](../09-架构实施/03-云原生部署架构指南.md) - 包含完整代码示例
## <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>
- [<EFBFBD><EFBFBD>蝡舀芋<EFBFBD><EFBFBD><EFBFBD><EFBFBD>霈曇恣-V2](../00-蝟餌<E89D9F><E9A48C><EFBFBD>霈曇恣/<2F><EFBFBD>蝡舀芋<E88880><EFBFBD><E5A092><EFBFBD>霈曇恣-V2.md) - <20><EFBFBD><E59786>餌熔
- [数据库设计规范](./01-数据库设计规范.md)
- [<EFBFBD>唳旿摨栞挽霈∟<EFBFBD><EFBFBD><EFBFBD>(./01-<2D>唳旿摨栞挽霈∟<E99C88><E2889F>?md)
- [API霈曇恣閫<EFBFBD><EFBFBD>](./02-API霈曇恣閫<E681A3><E996AB>.md)
- [<EFBFBD><EFBFBD><EFBFBD><EFBFBD>](./05-隞<><E99A9E><EFBFBD><E996AB>.md)
- [Git<EFBFBD>𣂷漱閫<EFBFBD><EFBFBD>](./06-Git<69>𣂷漱閫<E6BCB1><E996AB>.md)
@@ -765,14 +635,13 @@ grep -r "console.log" backend/src/modules/
## <20><> <20>湔鰵<E6B994><EFBFBD>
| 日期 | 版本 | 变更内容 | 维护者 |
| <EFBFBD><EFBFBD> | <20><>𧋦 | <20>䀹凒<E480B9><E58792>捆 | 蝏湔擪<E6B994>?|
|------|------|---------|--------|
| 2025-11-16 | V1.0 | 创建文档,定义云原生开发规范 | 架构团队 |
| 2025-11-16 | V1.0 | <EFBFBD>𥕦遣<EFBFBD><EFBFBD>﹝嚗<EFBFBD><EFBFBD>銋劐<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>𤏸<EFBFBD><EFBFBD>?| <20><EFBFBD><E59786><EFBFBD> |
---
**<EFBFBD><EFBFBD>﹝蝏湔擪<EFBFBD><EFBFBD><EFBFBD>** <20><EFBFBD><E59786><EFBFBD>
**<EFBFBD><EFBFBD><EFBFBD>擧凒<EFBFBD><EFBFBD>** 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>?

View File

@@ -1,4 +1,4 @@
# 数据库开发规范
# <EFBFBD>唳旿摨枏<EFBFBD><EFBFBD>𤏸<EFBFBD><EFBFBD>?
> <EFBFBD><EFBFBD>𧋦: v1.0
> <EFBFBD>湔鰵<EFBFBD><EFBFBD>: 2026-01-11
@@ -14,27 +14,27 @@
<EFBFBD>𩤃<EFBFBD><><E69ABA>瘜訫<E7989C>嚗帋遙雿閙㺭<E99699><EFBFBD><E6A180><EFBFBD><E6BBA2><EFBFBD><EFBFBD><EFBFBD><E29786><EFBFBD>隞踝<E99A9E>
```
### 1.2 禁止使用的危险命令
### 1.2 <EFBFBD>迫雿輻鍂<EFBFBD><EFBFBD><EFBFBD>拙𦶢隞?
| <20>賭誘 | <20>梢埯蝑厩漣 | 霂湔<E99C82> |
|------|----------|------|
| `prisma db push --force-reset` | 🔴 **极高** | 会删除所有数据和非Prisma管理的对象 |
| `prisma migrate reset` | 🔴 **极高** | 重置整个数据库 |
| `DROP DATABASE` | 🔴 **极高** | 删除整个数据库 |
| `TRUNCATE TABLE` | 🟠 高 | 清空表数据 |
| `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>?|
### 1.3 推荐的安全命令
### 1.3 <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>典𦶢隞?
| 命令 | 用途 | 安全性 |
| <EFBFBD>賭誘 | <20><EFBFBD>?| 摰匧<E691B0><E58CA7>?|
|------|------|--------|
| `prisma migrate dev` | 开发环境迁移 | ✅ 安全 |
| `prisma migrate deploy` | 生产环境迁移 | ✅ 安全 |
| `prisma db push` (--force-reset) | 同步schema到数据库 | ⚠️ 谨慎使用 |
| `prisma generate` | 生成客户端 | ✅ 安全 |
| `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><EFBFBD>蝡?| <20>?摰匧<E691B0> |
---
## 2. 数据库备份规范
## 2. <EFBFBD>唳旿摨枏<EFBFBD>隞質<EFBFBD><EFBFBD>?
### 2.1 憭<><EFBFBD>賭誘
@@ -51,11 +51,11 @@ docker exec ai-clinical-postgres pg_dump -U postgres -d ai_clinical_research > "
| <20>嗆㦤 | <20>臬炏敹<E7828F>◆ |
|------|----------|
| 执行任何 `prisma migrate` 前 | ✅ 必须 |
| 执行 `prisma db push` 前 | ✅ 必须 |
| 部署到生产环境前 | ✅ 必须 |
| 每日自动备份 | ✅ 推荐 |
| 重大功能发布前 | ✅ 必须 |
| <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>?敹<> |
### 2.3 憭<><EFBFBD><E981A2>辣蝞∠<E89D9E>
@@ -87,7 +87,7 @@ graph TD
### 3.2 <20><EFBFBD>甇仿炊
```bash
# 1. 备份数据库
# 1. <EFBFBD><EFBFBD>唳旿摨?
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. 瘚贝<E7989A>
# 6. 如果失败,恢复备份
# 6. <EFBFBD><EFBFBD>憭梯揖嚗峕<EFBFBD>憭滚<EFBFBD>隞?
cat backup_before_migration.sql | docker exec -i ai-clinical-postgres psql -U postgres -d ai_clinical_research
```
---
## 4. Prisma 与数据库不一致问题
## 4. Prisma 銝擧㺭<EFBFBD><EFBFBD>銝滢<EFBFBD><EFBFBD>湧䔮憸?
### 4.1 Prisma 銝滨恣<E6BBA8><E681A3><EFBFBD>撖寡情
以下数据库对象不在 `schema.prisma` 中定义,需要单独管理:
隞乩<EFBFBD><EFBFBD>唳旿摨枏笆鞊∩<EFBFBD><EFBFBD>?`schema.prisma` 銝剖<EFBFBD>銋㚁<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>祉恣<EFBFBD><EFBFBD><EFBFBD>
| 撖寡情 | 蝐餃<E89D90> | <20><EFBFBD> | <20><EFBFBD><EFBCB7>𡁏𧋦 |
|------|------|------|----------|
| `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` |
| `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` |
### 4.2 恢复非 Prisma 管理的对象
### 4.2 <EFBFBD><EFBFBD><EFBFBD>?Prisma 蝞∠<EFBFBD><EFBFBD><EFBFBD>笆鞊?
```bash
# 如果误删了 pg-boss 相关对象,执行:
# <EFBFBD><EFBFBD>霂臬<EFBFBD>鈭?pg-boss <20><EFBFBD>撖寡情嚗峕<E59A97>銵䕘<E98AB5>
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 检查数据库与 Prisma 一致性
### 4.3 <EFBFBD><EFBFBD>交㺭<EFBFBD><EFBFBD>銝?Prisma <EFBFBD><EFBFBD><EFBFBD>?
```bash
# 查看数据库中的函数
# <EFBFBD><EFBFBD><EFBFBD>唳旿摨㮖葉<EFBFBD><EFBFBD><EFBFBD>?
SELECT routine_name FROM information_schema.routines WHERE routine_schema = 'platform_schema';
# <20><EFBFBD><E4BAA6>唳旿摨㮖葉<E3AE96><E89189>
@@ -140,29 +140,29 @@ SELECT table_name FROM information_schema.tables WHERE table_schema = 'platform_
---
## 5. Schema 架构规范
## 5. 憭?Schema <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
### 5.1 Schema <20><EFBFBD><EFBFBD><E996AB>
| Schema | 用途 | 示例表 |
| Schema | <EFBFBD><EFBFBD>?| 蝷箔<E89DB7>銵?|
|--------|------|--------|
| `platform_schema` | 撟喳蝱<E596B3><EFBFBD>霈暹鴌 | users, tenants, app_cache |
| `admin_schema` | 餈鞱𨯫蝞∠<E89D9E> | admin_operation_logs |
| `aia_schema` | AI<41><EFBFBD><E7AE84><EFBFBD> | conversations, messages |
| `asl_schema` | 文献筛选 | screening_projects, literatures |
| `asl_schema` | <EFBFBD><EFBFBD>讃蝑偦<EFBFBD>?| screening_projects, literatures |
| `dc_schema` | <20>唳旿皜<E697BF><E79A9C> | dc_templates, dc_extraction_tasks |
| `pkb_schema` | 个人知识库 | knowledge_bases, documents |
| `pkb_schema` | 銝芯犖<EFBFBD><EFBFBD>摨?| knowledge_bases, documents |
| `iit_schema` | IIT憿寧𤌍 | projects, audit_logs |
| `rvw_schema` | 霈箸<E99C88><EFBFBD>恣 | review_tasks |
| `capability_schema` | <20>𡁶鍂<F0A181B6><EFBFBD> | prompt_templates |
| `public` | 旧数据/兼容 | users (旧), admin_logs |
| `public` | <EFBFBD>扳㺭<EFBFBD>?<3F>澆捆 | users (<EFBFBD>?, admin_logs |
### 5.2 表命名规范
### 5.2 銵典𦶢<EFBFBD><EFBFBD><EFBFBD>?
```
{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. 外键与数据完整性
## 6. 憭㚚睸銝擧㺭<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
### 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 外键指向检查
### 6.2 憭㚚睸<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
在使用 `prisma db push` 后,检查外键是否正确:
<EFBFBD>其蝙<EFBFBD>?`prisma db push` <EFBFBD>𠬍<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>格糓<EFBFBD>行迤蝖殷<EFBFBD>
```sql
SELECT
@@ -213,7 +213,7 @@ WHERE tc.constraint_type = 'FOREIGN KEY';
```bash
# 1. <20>𨀣迫摨𠉛鍂
# 2. 从备份恢复
# 2. 隞𤾸<EFBFBD>隞賣<EFBFBD>憭?
cat backup_xxx.sql | docker exec -i ai-clinical-postgres psql -U postgres -d ai_clinical_research
# 3. 撉諹<E69289><E8ABB9>唳旿
@@ -222,13 +222,13 @@ npx tsx verify_system.ts
# 4. <20>滚鍳摨𠉛鍂
```
### 7.2 Schema 不一致恢复
### 7.2 Schema 銝滢<EFBFBD><EFBFBD><EFBFBD>憭?
```bash
# 1. 检查差异
# 1. <EFBFBD><EFBFBD>亙榆撘?
npx tsx compare_schema_db.ts
# 2. 恢复缺失的对象
# 2. <EFBFBD><EFBFBD>蝻箏仃<EFBFBD><EFBFBD>笆鞊?
npx prisma db execute --file restore_xxx.sql --schema prisma/schema.prisma
# 3. 撉諹<E69289>
@@ -236,37 +236,37 @@ npx prisma db execute --file restore_xxx.sql --schema prisma/schema.prisma
---
## 8. 开发环境 vs 生产环境
## 8. <EFBFBD><EFBFBD>𤑳㴓憓?vs <20>煺漣<E785BA><EFBFBD>
### 8.1 开发环境
### 8.1 <EFBFBD><EFBFBD>𤑳㴓憓?
- <20>臭誑雿輻鍂 `prisma migrate dev`
- <20>臭誑雿輻鍂 `prisma db push`<EFBFBD><EFBFBD>𠬍<EFBFBD>
- 定期同步生产数据库结构
- 摰𡁏<EFBFBD><EFBFBD>峕郊<EFBFBD>煺漣<EFBFBD>唳旿摨梶<EFBFBD><EFBFBD>?
### 8.2 <20>煺漣<E785BA><EFBFBD>
- **<2A><EFBFBD>**雿輻鍂 `prisma migrate deploy`
- **禁止**使用任何 `--force` `--reset` 参数
- **<EFBFBD>迫**雿輻鍂隞颱<E99A9E> `--force` <EFBFBD>?`--reset` <EFBFBD><EFBFBD>
- <20>䀹凒<E480B9><EFBFBD>憿餅<E686BF><E9A485><EFBFBD><E99C88>
- 必须有最新备份
- <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>隞?
---
## 9. 检查清单
## 9. <EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
### 9.1 数据库变更前检查
### 9.1 <EFBFBD>唳旿摨枏<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
- [ ] 撌脣<E6928C>隞賣㺭<E8B3A3><EFBFBD>
- [ ] 已审查 schema.prisma 变更
- [ ] 已检查是否影响非 Prisma 管理的对象
- [ ] 已准备回滚方案
- [ ] 已在开发环境测试
- [ ] 撌脣恣<EFBFBD>?schema.prisma <EFBFBD>䀹凒
- [ ] 撌脫<EFBFBD><EFBFBD>交糓<EFBFBD>血蔣<EFBFBD><EFBFBD> Prisma 蝞∠<E89D9E><E288A0><EFBFBD>笆鞊?
- [ ] 撌脣<EFBFBD><EFBFBD><EFBFBD>皛𡁏䲮獢?
- [ ] 撌脣銁撘<EFBFBD><EFBFBD>𤑳㴓憓<EFBFBD><EFBFBD>霂?
### 9.2 部署后检查
### 9.2 <EFBFBD>函蔡<EFBFBD><EFBFBD><EFBFBD>?
- [ ] 摨𠉛鍂甇<E98D82><EFBFBD>臬𢆡
- [ ] 数据库连接正常
- [ ] <EFBFBD>唳旿摨栞<EFBFBD><EFBFBD>交迤撣?
- [ ] pg-boss <20><EFBFBD><EFBFBD>虜撌乩<E6928C>
- [ ] <20><EFBFBD><E8A9A8><EFBFBD>瘚贝<E7989A><E8B49D><EFBFBD>
@@ -278,14 +278,14 @@ npx prisma db execute --file restore_xxx.sql --schema prisma/schema.prisma
```
backend/
├── verify_system.ts # 系统完整性验证
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> verify_system.ts # 蝟餌<EFBFBD>摰峕㟲<EFBFBD><EFBFBD>霂?
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> compare_schema_db.ts # Schema銝擧㺭<E693A7><EFBFBD>撖寞<E69296>
├── check_iit_asl_data.ts # 检查模块数据
├── restore_job_common.sql # 恢复 job_common
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> check_iit_asl_data.ts # <EFBFBD><EFBFBD>交芋<EFBFBD>埈㺭<EFBFBD>?
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> restore_job_common.sql # <EFBFBD><EFBFBD> job_common 銵?
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> restore_pgboss_functions.sql # <20><EFBFBD> pg-boss <20>賣㺭
```
### 10.2 快速验证命令
### 10.2 敹恍<EFBFBD><EFBFBD><EFBFBD>𦶢隞?
```bash
# 霈曄蔭<E69B84><EFBFBD><E887AC><EFBFBD>
@@ -294,27 +294,27 @@ $env:DATABASE_URL="postgresql://postgres:postgres123@localhost:5432/ai_clinical_
# 撉諹<E69289>蝟餌<E89D9F>
npx tsx verify_system.ts
# 检查数据
# <EFBFBD><EFBFBD>交㺭<EFBFBD>?
npx tsx check_iit_asl_data.ts
```
---
## 附录:事故案例
## <EFBFBD><EFBFBD><EFBFBD>嚗帋<EFBFBD><EFBFBD><EFBFBD><EFBFBD>靘?
### 案例12026-01-11 数据库重置事故
### <EFBFBD><EFBFBD>1嚗?026-01-11 <EFBFBD>唳旿摨㯄<EFBFBD>蝵桐<EFBFBD><EFBFBD>?
**原因**:使用 `prisma db push --force-reset` 导致非 Prisma 管理的对象丢失
**<EFBFBD><EFBFBD>**嚗帋蝙<E5B88B>?`prisma db push --force-reset` 撖潸稲<EFBFBD>?Prisma 蝞∠<EFBFBD><EFBFBD><EFBFBD>笆鞊∩腺憭?
**影响**
- pg-boss 函数丢失,队列无法注册
- job_common 表丢失
- 用户数据丢失(已通过 seed 恢复)
**敶勗<EFBFBD>**嚗?
- pg-boss <EFBFBD>賣㺭銝仃嚗屸<EFBFBD><EFBFBD><EFBFBD>瘜閙釣<EFBFBD>?
- job_common 銵其腺憭?
- <EFBFBD><EFBFBD><EFBFBD>唳旿銝仃嚗<EFBFBD><EFBFBD><EFBFBD> seed <EFBFBD><EFBFBD>嚗?
**教训**
**<EFBFBD>躰悌**嚗?
1. 瘞貉<E7989E>銝滩<E98A9D>雿輻鍂 `--force-reset`
2. 操作前必须备份
3. 了解 Prisma 的管理边界
2. <EFBFBD><EFBFBD><EFBFBD><EFBFBD>憿餃<EFBFBD>隞?
3. <EFBFBD> Prisma <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
霂西<EFBFBD>嚗䫤docs/08-憿寧𤌍蝞∠<E89D9E>/2026-01-11-<2D>唳旿摨㮖<E691A8><E3AE96><EFBFBD><EFBFBD><EFBFBD>.md`
@@ -323,3 +323,4 @@ npx tsx check_iit_asl_data.ts

View File

@@ -1,29 +1,29 @@
# 璅<E79285>霈方<E99C88><EFBFBD><E996AB>
> 本文档定义了业务模块如何正确使用平台认证能力,确保所有 API 都正确携带和验证用户身份。
> <EFBFBD><EFBFBD><EFBFBD><EFBFBD>銋劐<EFBFBD>銝𡁜𦛚璅<EFBFBD><EFBFBD><EFBFBD><EFBFBD>雿輻鍂撟喳蝱霈方<EFBFBD><EFBFBD><EFBFBD>嚗𣬚靽脲<EFBFBD><EFBFBD>?API <20>賣迤蝖格𡉼撣血<E692A3>撉諹<E69289><E8ABB9><EFBFBD>頨思遢<E6809D>?
## 1. <20><EFBFBD><EFBFBD><E79281>
```
┌─────────────────────────────────────────────────────────────┐
前端
│ ┌─────────────────────────────────────────────────────┐ │
│ │ common/api/axios.ts ← 带认证的 axios 实例 │ │
│ │ framework/auth/api.ts Token 管理 (getAccessToken)│ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
Authorization: Bearer <token>
┌─────────────────────────────────────────────────────────────┐
后端
│ ┌─────────────────────────────────────────────────────┐ │
│ │ common/auth/auth.middleware.ts │ │
│ │ - authenticate: 验证 JWT Token │ │
│ │ - requirePermission: 权限检查 │ │
│ │ - requireRoles: 角色检查 │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
<EFBFBD>𢞖<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><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>?
```
## 2. <20>滨垢閫<E59EA2><E996AB>
@@ -34,12 +34,12 @@
// 撖澆<E69296>撣西恕霂<E68195><E99C82> apiClient
import apiClient from '../../../common/api/axios';
// 使用方式与 axios 完全相同,自动携带 JWT Token
// 雿輻鍂<EFBFBD><EFBFBD>銝?axios 摰<><E691B0><EFBFBD><EFBFBD>嚗諹䌊<E8ABB9>冽𡉼撣?JWT Token
const response = await apiClient.get('/api/v2/xxx');
const response = await apiClient.post('/api/v2/xxx', data);
```
### 2.2 使用原生 fetch需手动添加 Token
### 2.2 雿輻鍂<EFBFBD><EFBFBD> fetch嚗<68><E59A97><EFBFBD>见𢆡瘛餃<E7989B> Token嚗?
```typescript
import { getAccessToken } from '../../../framework/auth/api';
@@ -56,12 +56,12 @@ function getAuthHeaders(): HeadersInit {
return headers;
}
// 所有 fetch 请求使用 getAuthHeaders()
// <EFBFBD><EFBFBD><EFBFBD>?fetch 霂瑟<EFBFBD>雿輻鍂 getAuthHeaders()
const response = await fetch(url, {
headers: getAuthHeaders(),
});
// 文件上传(不设置 Content-Type
// <EFBFBD><EFBFBD>辣銝𠹺<EFBFBD><EFBFBD><EFBFBD>霈曄蔭 Content-Type嚗?
const token = getAccessToken();
const headers: HeadersInit = {};
if (token) {
@@ -76,22 +76,22 @@ const response = await fetch(url, {
## 3. <20>𡒊垢閫<E59EA2><E996AB>
### 3.1 路由添加认证中间件
### 3.1 頝舐眏瘛餃<EFBFBD>霈方<EFBFBD>銝剝𡢿隞?
```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 控制器获取用户 ID
### 3.2 <EFBFBD><EFBFBD><EFBFBD>刻繮<EFBFBD>𣇉鍂<EFBFBD>?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; // <20><EFBFBD>ID
phone: string; // 手机号
phone: string; // <EFBFBD>𧢲㦤<EFBFBD>?
role: string; // 閫坿𠧧
tenantId: string; // 蝘<><E89D98>ID
tenantCode?: string; // 蝘<><E89D98>Code
@@ -126,68 +126,69 @@ interface DecodedToken {
}
```
## 4. 检查清单
## 4. <EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
### 4.1 新模块开发检查清单
### 4.1 <EFBFBD>唳芋<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
- [ ] **<EFBFBD>滨垢 API <20><>辣**
- [ ] 使用 `apiClient` 或添加 `getAuthHeaders()`
- [ ] 文件上传单独处理(不设置 Content-Type
- [ ] 雿輻鍂 `apiClient` <EFBFBD>𡝗溶<EFBFBD>?`getAuthHeaders()`
- [ ] <EFBFBD><EFBFBD>辣銝𠹺<EFBFBD><EFBFBD>閧𡠺憭<EFBFBD><EFBFBD><EFBFBD><EFBFBD>霈曄蔭 Content-Type嚗?
- [ ] 撖澆枂<E6BE86>賣㺭銝滚<E98A9D><E6BB9A><EFBFBD>霂閧鍂 userId <20><>
- [ ] **<EFBFBD>𡒊垢頝舐眏<EFBFBD><EFBFBD>辣**
- [ ] 导入 `authenticate` 中间件
- [ ] 撖澆<EFBFBD> `authenticate` 銝剝𡢿隞?
- [ ] <20><><EFBFBD><EFBFBD><EFBFBD>恕霂<E68195><E99C82>頝舐眏瘛餃<E7989B> `preHandler: [authenticate]`
- [ ] 公开 API(如模板列表)可不添加认证
- [ ] <EFBFBD><EFBFBD> API<EFBFBD><EFBFBD>璅⊥踎<EFBFBD>𡑒”嚗匧虾銝齿溶<EFBFBD>㰘恕霂?
- [ ] **后端控制器文件**
- [ ] **<EFBFBD>𡒊垢<EFBFBD><EFBFBD><EFBFBD><EFBFBD>隞?*
- [ ] 瘛餃<E7989B> `getUserId()`<>𨭌<EFBFBD>賣㺭
- [ ] 移除所有 `MOCK_USER_ID` 或硬编码默认值
- [ ] 蝘駁膄<EFBFBD><EFBFBD><EFBFBD>?`MOCK_USER_ID` <EFBFBD>𣇉蝻𣇉<EFBFBD>暺䁅恕<EFBFBD>?
- [ ] 雿輻鍂 `getUserId(request)` <20><EFBFBD><E79195><EFBFBD> ID
### 4.2 已完成模块状态
### 4.2 撌脣<EFBFBD><EFBFBD>鞉芋<EFBFBD>㛖𠶖<EFBFBD>?
| 模块 | 前端 API | 后端路由 | 后端控制器 | 状态 |
| <EFBFBD> | <20>滨垢 API | <20>𡒊垢頝舐眏 | <20>𡒊垢<F0A1928A><EFBFBD><E689B9>?| <20><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 | |
| 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>?|
## 5. 常见错误和解决方案
## 5. 撣貉<EFBFBD><EFBFBD>躰秤<EFBFBD>諹圾<EFBFBD>單䲮獢?
### 5.1 401 Unauthorized
**原因**: 前端没有携带 JWT Token Token 过期
**<EFBFBD><EFBFBD>**: <EFBFBD>滨垢瘝⊥<EFBFBD><EFBFBD>箏蒂 JWT Token <EFBFBD>?Token <EFBFBD><EFBFBD>
**閫<><E996AB>**:
1. 检查前端 API 是否使用 `apiClient` `getAuthHeaders()`
2. 检查 localStorage 中是否有 `accessToken`
1. <EFBFBD><EFBFBD><EFBFBD>蝡?API <20>臬炏雿輻鍂 `apiClient` <EFBFBD>?`getAuthHeaders()`
2. <EFBFBD><EFBFBD>?localStorage 銝剜糓<EFBFBD><EFBFBD> `accessToken`
3.<><E68692> Token 餈<><E9A488><EFBFBD><E59A97>霂訫<E99C82><E8A8AB><EFBFBD><E594B3>齿鰵<E9BDBF><EFBFBD>
### 5.2 User not authenticated
**原因**: 后端路由没有添加 `authenticate` 中间件
**<EFBFBD><EFBFBD>**: <EFBFBD>𡒊垢頝舐眏瘝⊥<EFBFBD>瘛餃<EFBFBD> `authenticate` 銝剝𡢿隞?
**閫<><E996AB>**: <20>刻楝<E588BB><EFBFBD>銋劐葉瘛餃<E7989B> `preHandler: [authenticate]`
### 5.3 TypeError: Cannot read property 'userId' of undefined
**原因**: 使用了错误的属性名(`request.user.id` 而非 `request.user.userId`
**<EFBFBD><EFBFBD>**: 雿輻鍂鈭<EFBFBD><EFBFBD>霂舐<EFBFBD>撅墧<EFBFBD><EFBFBD>嚗Ǒrequest.user.id` <20><EFBFBD> `request.user.userId`嚗?
**閫<><E996AB>**: 雿輻鍂 `(request as any).user?.userId`
## 6. 参考文件
## 6. <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>隞?
- <20>滨垢 axios 摰硺<E691B0>: `frontend-v2/src/common/api/axios.ts`
- <20>滨垢 Token 蝞∠<E89D9E>: `frontend-v2/src/framework/auth/api.ts`
- 后端认证中间件: `backend/src/common/auth/auth.middleware.ts`
- <20>𡒊垢霈方<E99C88>銝剝𡢿隞? `backend/src/common/auth/auth.middleware.ts`
- <20>𡒊垢 JWT <20>滚𦛚: `backend/src/common/auth/jwt.service.ts`

View File

@@ -1,17 +1,14 @@
# 04-开发规范
> **目标:** 统一团队开发规范,提高代码质量和协作效率
> **适用范围:** 平台层 + 能力层 + 业务模块层
> **强制等级:** ⭐⭐⭐⭐⭐ 必须遵守
# 04-寮€鍙戣<EFBFBD>鑼?
> **鐩<>爣锛?* 缁熶竴鍥㈤槦寮€鍙戣<E98D99>鑼冿紝鎻愰珮浠爜璐ㄩ噺鍜屽崗浣滄晥鐜?
> **閫傜敤鑼冨洿锛?* 骞冲彴灞?+ 鑳藉姏灞?+ 涓氬姟妯″潡灞?
> **寮哄埗绛夌骇锛?* 猸愨瓙猸愨瓙猸?蹇呴』閬靛畧
---
## 馃搵 瑙勮寖鏂囨。鍒楄〃
### 1. 数据库设计规范 ⭐⭐⭐⭐⭐
**文件:** `01-数据库设计规范.md` ⏳ 待创建(从 `01-设计文档/数据库设计文档.md` 提取)
**核心内容:**
### 1. 鏁版嵁搴撹<EFBFBD>璁¤<EFBFBD>鑼?猸愨瓙猸愨瓙猸?**鏂囦欢锛?* `01-鏁版嵁搴撹<E690B4>璁¤<E79281>鑼?md` 鈴?寰呭垱寤猴紙浠?`01-璁捐<E79281>鏂囨。/鏁版嵁搴撹<E690B4>璁℃枃妗?md` 鎻愬彇锛?
**鏍稿績鍐呭<EFBFBD>锛?*
- Schema闅旂<E99785>绛栫暐锛坧latform_schema銆乤sl_schema绛夛級
- 琛ㄥ懡鍚嶈<E98D9A>鑼冿紙灏忓啓+涓嬪垝绾匡級
- 瀛楁<E7809B>鍛藉悕瑙勮寖
@@ -19,55 +16,41 @@
- 澶栭敭绾︽潫瑙勮寖
- 閫氱敤瀛楁<E7809B>锛坈reated_at銆乽pdated_at绛夛級
**快速参考:** [数据库全局视图](./03-数据库全局视图.md) ⭐ 已创建
**<EFBFBD>€熷弬鑰冿細** [鏁版嵁搴撳叏灞€瑙嗗浘](./03-鏁版嵁搴撳叏灞€瑙嗗浘.md) 猸?宸插垱寤?
---
### 2. API设计规范 ⭐⭐⭐⭐⭐
**文件:** `02-API设计规范.md` ⏳ 待创建(从 `01-设计文档/API设计规范.md` 提取)
**核心内容:**
### 2. API璁捐<EFBFBD>瑙勮寖 猸愨瓙猸愨瓙猸?**鏂囦欢锛?* `02-API璁捐<E79281>瑙勮寖.md` 鈴?寰呭垱寤猴紙浠?`01-璁捐<E79281>鏂囨。/API璁捐<E79281>瑙勮寖.md` 鎻愬彇锛?
**鏍稿績鍐呭<EFBFBD>锛?*
- RESTful API璁捐<E79281>鍘熷垯
- URL命名规范(`/api/v1/模块/资源`
- HTTP方法使用规范
- URL鍛藉悕瑙勮寖锛坄/api/v1/妯″潡/璧勬簮`锛?- HTTP鏂规硶浣跨敤瑙勮寖
- 璇锋眰/鍝嶅簲鏍煎紡瑙勮寖
- 错误码设计
- 认证和权限
**快速参考:** [API路由总览](./04-API路由总览.md) ⭐ 已创建
- 閿欒<EFBFBD>鐮佽<EFBFBD>璁?- 璁よ瘉鍜屾潈闄?
**蹇<>€熷弬鑰冿細** [API璺<EFBFBD>敱鎬昏<EFBFBD>](./04-API璺<49>敱鎬昏<E98EAC>.md) 猸?宸插垱寤?
---
### 3. 数据库全局视图 ⭐⭐⭐⭐⭐ ✅ 新增
**文件:** `03-数据库全局视图.md`
### 3. 鏁版嵁搴撳叏灞€瑙嗗浘 猸愨瓙猸愨瓙猸?鉁?鏂板<E98F82>
**鏂囦欢锛?* `03-鏁版嵁搴撳叏灞€瑙嗗浘.md`
**用途:** 提供所有Schema和表的快速索引
**核心内容:**
- Schema划分策略8个Schema
- 所有表的总览和跳转链接
- 跨Schema依赖关系
- 数据量预估
**使用场景:**
**鐢ㄩ€旓細** 鎻愪緵鎵€鏈塖chema鍜岃〃鐨勫揩閫熺储寮?
**鏍稿績鍐呭<E98D90>锛?*
- Schema鍒掑垎绛栫暐锛?涓猄chema锛?- 鎵€鏈夎〃鐨勬€昏<E282AC>鍜岃烦杞<E783A6>摼鎺?- 璺⊿chema渚濊禆鍏崇郴
- 鏁版嵁閲忛<EFBFBD>浼?
**浣跨敤鍦烘櫙锛?*
- 鏌ョ湅鍏ㄥ眬鏁版嵁鏋舵瀯
-<>€熷畾浣嶆煇涓<E78587>〃灞炰簬鍝<E7B0AC>釜Schema
- 了解跨模块数据关系
- 浜嗚В璺ㄦā鍧楁暟鎹<EFBFBD>叧绯?
---
### 4. API路由总览 ⭐⭐⭐⭐⭐ ✅ 新增
**文件:** `04-API路由总览.md`
### 4. API<EFBFBD>敱鎬昏<EFBFBD> 猸愨瓙猸愨瓙猸?鉁?鏂板<E98F82>
**鏂囦欢锛?* `04-API<EFBFBD>敱鎬昏<EFBFBD>.md`
**用途:** 提供所有API端点的快速索引
**核心内容:**
**鐢ㄩ€旓細** 鎻愪緵鎵€鏈堿PI绔<EFBFBD>偣鐨勫揩閫熺储寮?
**鏍稿績鍐呭<E98D90>锛?*
-<>敱鍛藉悕瑙勮寖
- 鎵€鏈夋ā鍧楃殑API绔<49>偣鎬昏<E98EAC>
- 路由冲突检查
- 端点统计(~85个
- <EFBFBD>敱鍐茬獊妫€鏌?- 绔<>偣缁熻<E7BC81>锛垀85涓<35>
**使用场景:**
**浣跨敤鍦烘櫙锛?*
- 鏌ョ湅鍏ㄥ眬API鏋舵瀯
- 閬垮厤璺<E58EA4>敱鍐茬獊
-<>€熸煡鎵炬煇涓<E78587>姛鑳界殑API绔<49>
@@ -75,36 +58,29 @@
---
### 5. 浠g爜瑙勮寖 猸愨瓙猸愨瓙
**文件:** `05-代码规范.md` → 重命名自 `代码规范.md`已存在818行
**鏂囦欢锛?* `05-浠g爜瑙勮寖.md` 鈫?閲嶅懡鍚嶈嚜 `浠g爜瑙勮寖.md`锛堝凡瀛樺湪锛?18琛岋級
**核心内容:**
**鏍稿績鍐呭<EFBFBD>锛?*
- TypeScript缂栫爜瑙勮寖
- React缁勪欢瑙勮寖
- 文件和目录命名
- 代码注释规范
- 鏂囦欢鍜岀洰褰曞懡鍚?- 浠g爜娉ㄩ噴瑙勮寖
- 閿欒<E996BF>澶勭悊瑙勮寖
- 鏃ュ織璁板綍瑙勮寖
**宸叉湁鍐呭<E98D90>锛屽寘鍚<E5AF98>**
- ESLint閰嶇疆
- Prettier閰嶇疆
- 详细的编码规范
- 璇︾粏鐨勭紪鐮佽<EFBFBD>鑼?
---
### 6. Git提交规范 ⭐⭐⭐⭐⭐ ✅ 已完成
**文件:** `06-Git提交规范.md`
### 6. Git鎻愪氦瑙勮寖 猸愨瓙猸愨瓙猸?鉁?宸插畬鎴?**鏂囦欢锛?* `06-Git鎻愪氦瑙勮寖.md`
**核心内容:**
- 远程仓库配置Gitee
- Commit Message格式规范
**鏍稿績鍐呭<EFBFBD>锛?*
- 杩滅▼浠撳簱閰嶇疆锛圙itee锛?- Commit Message鏍煎紡瑙勮寖
- 鍒嗘敮绠$悊绛栫暐
- 中文编码问题解决方案 ⭐ 重要
- Git历史重写与维护
- PR/MR规范和代码审查流程
- 常见问题与最佳实践
**包含实用工具:**
- <EFBFBD>枃缂栫爜闂<EFBFBD><EFBFBD>喅鏂规<EFBFBD> 猸?閲嶈<E996B2>
- Git鍘嗗彶閲嶅啓涓庣淮鎶?- PR/MR瑙勮寖鍜屼唬鐮佸<E990AE>鏌ユ祦绋?- 甯歌<E794AF><EFBFBD><E99782>涓庢渶浣冲疄璺?
**鍖呭惈瀹炵敤宸ュ叿锛?*
- `fix-git-commit-messages.ps1` 鑴氭湰浣跨敤璇存槑
- Git 鍒<>悕閰嶇疆
-<>枃涔辩爜淇<E7889C><E6B787>瀹屾暣娴佺▼
@@ -113,22 +89,19 @@
```
<type>(<scope>): <subject>
feat: 新功能 fix: Bug修复 docs: 文档
feat: 鏂板姛鑳? fix: Bug<EFBFBD><EFBFBD> docs: 鏂囨。
style: 鏍煎紡 refactor: 閲嶆瀯 perf: 浼樺寲
test: 娴嬭瘯 chore: 鏋勫缓 ci: CI/CD
```
---
### 7. 测试规范 ⭐⭐⭐
**文件:** `07-测试规范.md` ⏳ 待创建
**核心内容:**
### 7. 娴嬭瘯瑙勮寖 猸愨瓙猸?**鏂囦欢锛?* `07-娴嬭瘯瑙勮寖.md` 鈴?寰呭垱寤?
**鏍稿績鍐呭<EFBFBD>锛?*
- 鍗曞厓娴嬭瘯瑙勮寖
- 闆嗘垚娴嬭瘯瑙勮寖
- E2E娴嬭瘯瑙勮寖
- 测试覆盖率要求
- 娴嬭瘯瑕嗙洊鐜囪<EFBFBD>姹?
**娴嬭瘯瑕嗙洊鐜囪<E9909C>姹傦細**
- 鏍稿績涓氬姟閫昏緫锛氣墺80%
- 宸ュ叿鍑芥暟锛氣墺90%
@@ -136,83 +109,63 @@ test: 测试 chore: 构建 ci: CI/CD
---
## 🎯 规范优先级
## 馃幆 瑙勮寖浼樺厛绾?
### P0 - 蹇呴』閬靛畧
- ✅ 数据库设计规范
- ✅ API设计规范
- ✅ Git提交规范Commit Message
- 鉁?鏁版嵁搴撹<E690B4>璁¤<E79281>鑼?- 鉁?API璁捐<E79281>瑙勮寖
- 鉁?Git鎻愪氦瑙勮寖锛圕ommit Message锛?
### P1 - 寮虹儓寤鸿<E5AFA4>
- ✅ 代码规范TypeScript/React
- ✅ 错误处理规范
- ✅ 日志记录规范
- 鉁?浠g爜瑙勮寖锛圱ypeScript/React锛?- 鉁?閿欒<E996BF>澶勭悊瑙勮寖
- 鉁?鏃ュ織璁板綍瑙勮寖
### P2 - 寤鸿<E5AFA4>閬靛畧
- ⚪ 测试规范
- ⚪ 文档注释规范
- ⚪ 性能优化规范
- 鈿?娴嬭瘯瑙勮寖
- 鈿?鏂囨。娉ㄩ噴瑙勮寖
- 鈿?鎬ц兘浼樺寲瑙勮寖
---
## 🔍 快速查找
**我要设计数据库表:**`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`
## 馃攳 蹇<>€熸煡鎵?
**鎴戣<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>缂栧啓浠爜锛?* 鈫?`05-浠g爜瑙勮寖.md` 鉁?
**鎴戣<EFBFBD>鎻愪氦浠爜锛?* 鈫?`06-Git鎻愪氦瑙勮寖.md` 鉁?
**鎴戣<EFBFBD>喅涓<EFBFBD>枃涔辩爜锛?* 鈫?`06-Git鎻愪氦瑙勮寖.md` (绗?鑺? 鉁?
**鎴戣<EFBFBD>閰嶇疆杩滅▼浠撳簱锛?* 鈫?`06-Git鎻愪氦瑙勮寖.md` (绗?鑺? 鉁?
**鎴戣<EFBFBD>缂栧啓娴嬭瘯锛?* 鈫?`07-娴嬭瘯瑙勮寖.md`
---
## ⚠️ 违反规范的后果
## 鈿狅笍 杩濆弽瑙勮寖鐨勫悗鏋?
### 鏁版嵁搴撹<E690B4>笉瑙勮寖
- Schema混乱,模块耦合
- ❌ 无法实现模块独立部署
- ❌ 数据迁移困难
- 鉂?Schema娣蜂贡锛屾ā鍧楄€﹀悎
- 鉂?鏃犳硶瀹炵幇妯″潡鐙<E6BDA1>珛閮ㄧ讲
- 鉂?鏁版嵁杩佺Щ鍥伴毦
### API设计不规范
- ❌ 前后端对接困难
- ❌ API文档混乱
- ❌ 版本升级困难
### 代码不规范
- ❌ 代码可读性差
- ❌ 维护成本高
- ❌ Bug率上升
### API璁捐<EFBFBD>涓嶈<EFBFBD>鑼?- 鉂?鍓嶅悗绔<E68297><E7BB94>鎺ュ洶闅?- 鉂?API鏂囨。娣蜂贡
- 鉂?鐗堟湰鍗囩骇鍥伴毦
### 浠爜涓嶈<E6B693>鑼?- 鉂?浠爜鍙<E7889C><E98D99>у
- 鉂?缁存姢鎴愭湰楂?- 鉂?Bug鐜囦笂鍗?
---
## 馃摑 瑙勮寖鏇存柊娴佺▼
1. 提出规范变更需求Issue或PR
2. 团队讨论和评审
3. 更新规范文档
1. 鎻愬嚭瑙勮寖鍙樻洿闇€姹傦紙Issue鎴朠R锛?2. 鍥㈤槦璁ㄨ<E79281>鍜岃瘎瀹?3. 鏇存柊瑙勮寖鏂囨。
4. 閫氱煡鍏ㄥ憳
5. 逐步迁移旧代码
5. 閫愭<EFBFBD>杩佺Щ鏃т唬鐮?
---
## 馃敆 鐩稿叧宸ュ叿
**浠g爜妫€鏌ワ細**
- ESLintJavaScript/TypeScript
- Prettier代码格式化
- StylelintCSS
- ESLint锛圝avaScript/TypeScript锛?- Prettier锛堜唬鐮佹牸寮忓寲锛?- Stylelint锛圕SS锛?
**鎻愪氦妫€鏌ワ細**
- HuskyGit Hooks
- CommitlintCommit Message检查
- Husky锛圙it Hooks锛?- Commitlint锛圕ommit Message妫€鏌ワ級
**鏁版嵁搴擄細**
- PrismaORM + Migration
- pgAdmin数据库管理
- Prisma锛圤RM + Migration锛?- pgAdmin锛堟暟鎹<E69A9F>簱绠悊锛?
---
**鏈€鍚庢洿鏂帮細** 2025-11-06