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%)
1383 lines
40 KiB
Markdown
1383 lines
40 KiB
Markdown
# **AIclinicalresearch 譚<>剞荳手ァ定牡菴鍋ウサ譴ウ逅<EFBDB3>冠蜻?*
|
||
|
||
> **譁<>。」迚域悽<E59F9F>?* v1.1<EFBFBD>域紛蜷<EFBFBD>rompt邂。逅<EFBFBD>怙豎ゑシ<EFBFBD>
|
||
> **蛻帛サコ譌・譛滂シ?* 2026-01-11
|
||
> **譛蜷取峩譁ー<E8AD81><EFBDB0>** 2026-01-11
|
||
> **菴懆<E68786>シ<EFBFBD>** AI譫カ譫<EFBDB6>ク?
|
||
> **逶ョ逧<EFBDAE>シ?* 邉サ扈滓ァ譴ウ逅<EFBDB3>ス灘燕譚<E78795>剞螳樒鴫迥カ蜀オ<E89C80>御クコ霑占是邂。逅<EFBDA1>ォッ蜥梧惻譫<E683BB>ョ。逅<EFBDA1>ォッ蠑蜿大★蜃<E29885>、<EFBFBD>
|
||
> **蜿俶峩隸エ譏趣シ?* 謨エ蜷亥渚鬥亥サコ隶ョ + Prompt邂。逅<EFBDA1>ウサ扈滄怙豎?
|
||
|
||
---
|
||
|
||
## <20>搭 逶ョ蠖<EFBDAE>
|
||
|
||
1. [蠖灘燕邉サ扈溽憾諤∝<E8ABA4>譫疹(#1-蠖灘燕邉サ扈溽憾諤∝<E8ABA4>譫?
|
||
2. [謨ー謐ョ蠎灘アる擇譴ウ逅<EFBDB3>(#2-謨ー謐ョ蠎灘アる擇譴ウ逅?
|
||
3. [蜷守ォッ譚<EFBDAF>剞螳樒鴫譴ウ逅<EFBDB3>(#3-蜷守ォッ譚<EFBDAF>剞螳樒鴫譴ウ逅<EFBDB3>)
|
||
4. [蜑咲ォッ譚<EFBDAF>剞螳樒鴫譴ウ逅<EFBDB3>(#4-蜑咲ォッ譚<EFBDAF>剞螳樒鴫譴ウ逅<EFBDB3>)
|
||
5. [蟾ョ霍晏<E99C8D>譫疹(#5-蟾ョ霍晏<E99C8D>譫<EFBFBD>)
|
||
6. [譁ーPRD髴豎りァ」隸サ](#6-譁ーprd髴豎りァ」隸?
|
||
7. [譫カ譫<EFBFBD>ョセ隶。蟒コ隶ョ](#7-譫カ譫<EFBDB6>ョセ隶。蟒コ隶ョ)
|
||
8. [螳樊命霍ッ郤ソ蝗セ](#8-螳樊命霍ッ郤ソ蝗?
|
||
9. [<5B><> Prompt邂。逅<EFBDA1>ウサ扈滓紛蜷<E7B49B>(#9-prompt邂。逅<EFBDA1>ウサ扈滓紛蜷<E7B49B>)
|
||
10. [<5B><> 蜿埼ヲ磯㊦郤ウ隸エ譏讃(#10-蜿埼ヲ磯㊦郤ウ隸エ譏<EFBDB4>)
|
||
|
||
---
|
||
|
||
## 1. 蠖灘燕邉サ扈溽憾諤∝<E8ABA4>譫?
|
||
|
||
### 1.1 譬ク蠢<EFBDB8>書邇ー <20>剥
|
||
|
||
**笨?蟾イ譛牙渕遑**<EFBFBD>?
|
||
- 謨ー謐ョ蠎捺怏蝓コ遑逧Фser陦ィ<E999A6><EFBDA8>platform_schema.users` 蜥?`public.users`荳、荳ェ迚域悽<E59F9F>?
|
||
- 譛牙渕譛ャ逧вole蟄玲ョオ<EFBDAE>磯サ倩ョ、蛟シ<E89B9F><EFBDBC>"user"<22>?
|
||
- 蜑咲ォッ譛画揀髯先。<E58588>楔<EFBFBD><E6A594>PermissionContext`<60>会シ御ス?*莉<>ock謨ー謐ョ**
|
||
- 蜷守ォッ**螳悟<E89EB3>豐。譛芽ョ、隸<EFBDA4>/謗域揀邉サ扈<EFBDBB>**
|
||
|
||
**笶?郛コ螟ア蜈ウ髞ョ閭ス蜉<EFBDBD>**<EFBFBD>?
|
||
1. **豐。譛臥匳蠖<E58CB3>/豕ィ蜀窟PI**
|
||
2. **豐。譛雨WT隶、隸∽クュ髣エ莉?*
|
||
3. **豐。譛臥ァ滓姐(Tenant)菴鍋ウサ**
|
||
4. **豐。譛芽ァ定牡譚<E789A1>剞邉サ扈<EFBDBB>(RBAC)**
|
||
5. **豐。譛宇eature Flag謗ァ蛻カ**
|
||
6. **豐。譛牙ョ。隶。譌・蠢礼ウサ扈<EFBDBB>**
|
||
|
||
**<EFBFBD>識 蠖灘燕迥カ諤?*<2A>?
|
||
- 邉サ扈溷、<E6BAB7>コ<EFBFBD>**蜊墓オ玖ッ戊エヲ蜿?*髦カ谿オ
|
||
- 謇譛陰PI驛ス譏ッ**譌<>隶、隸√∵裏驩エ譚<EFBDB4>**迥カ諤?
|
||
- 蜑咲ォッ譚<EFBDAF>剞謗ァ蛻カ譏?*郤ッ螻慕、コ諤?*逧<>ock螳樒鴫
|
||
|
||
---
|
||
|
||
## 2. 謨ー謐ョ蠎灘アる擇譴ウ逅?
|
||
|
||
### 2.1 蠖灘燕User陦ィ扈捺<E68988>?
|
||
|
||
#### **platform_schema.users** 笨?譁ー譫カ譫<EFBDB6>シ<EFBFBD>risma螳壻ケ会シ?
|
||
|
||
```prisma
|
||
model User {
|
||
id String @id @default(uuid())
|
||
email String @unique
|
||
password String
|
||
name String?
|
||
avatarUrl String? @map("avatar_url")
|
||
role String @default("user") // 笞<><E7AC9E><EFBFBD> 邂蜊募ュ礼ャヲ荳イ<E88DB3>御ク榊、溽畑
|
||
status String @default("active")
|
||
kbQuota Int @default(3)
|
||
kbUsed Int @default(0)
|
||
trialEndsAt DateTime? @map("trial_ends_at")
|
||
isTrial Boolean @default(true)
|
||
lastLoginAt DateTime? @map("last_login_at")
|
||
createdAt DateTime @default(now())
|
||
updatedAt DateTime @updatedAt
|
||
|
||
@@schema("platform_schema")
|
||
}
|
||
```
|
||
|
||
#### **public.users** 笶?譌ァ陦ィ<E999A6>亥紙蜿イ驕礼蕗<E7A4BC><E89597>
|
||
|
||
```prisma
|
||
model users {
|
||
id String
|
||
email String @unique
|
||
password String
|
||
name String?
|
||
avatar_url String?
|
||
role String @default("user") // 笞<><E7AC9E><EFBFBD> 蜷梧<E89CB7>キ邂蜊?
|
||
status String @default("active")
|
||
kb_quota Int @default(3)
|
||
kb_used Int @default(0)
|
||
// ... 蜈カ莉門ュ玲ョオ
|
||
|
||
@@schema("public")
|
||
}
|
||
```
|
||
|
||
**笞<><E7AC9E><EFBFBD> 髣ョ鬚假シ?*
|
||
- 荳、荳ェUser陦ィ蟷カ蟄假シ悟多蜷堺ク堺ク閾エ<E996BE><EFBDB4>sers vs User<65>?
|
||
- `role`蟄玲ョオ莉<EFBFBD>クコ蟄礼ャヲ荳イ<EFBFBD>梧裏enum郤ヲ譚<EFBFBD>
|
||
- **豐。譛臥ァ滓姐蜈ウ閨泌ュ玲ョオ<EFBDAE><EFBDB5>enantId<49>?*
|
||
- **豐。譛蛾Κ髣ィ蟄玲ョオ<EFBDAE><EFBDB5>epartment<6E>?*
|
||
- **豐。譛画揀髯宣<E9ABAF>鄂ョ蟄玲ョオ**
|
||
|
||
### 2.2 郛コ螟ア逧<EFBDB1><E980A7>ク蠢<EFBDB8>。ィ
|
||
|
||
譬ケ謐ョPRD髴豎ゑシ碁怙隕∵眠蠅樔サ・荳玖。ィ<EFBFBD>?
|
||
|
||
| 陦ィ蜷<EFBDA8> | Schema菴咲スョ | 逕ィ騾?| 莨伜<E88EA8>郤?|
|
||
|------|-----------|------|--------|
|
||
| **tenants** | platform_schema | 遘滓姐荳サ陦ィ<E999A6>亥現髯「縲∬艮莨√∵悄蛻奇シ<E5A587> | P0 |
|
||
| **tenant_users** | platform_schema | 遘滓姐-逕ィ謌キ蜈ウ閨碑。?| P0 |
|
||
| **departments** | platform_schema | 驛ィ髣ィ/遘大ョ、陦?| P1 |
|
||
| **feature_flags** | platform_schema | Feature Flag驟咲スョ | P0 |
|
||
| **tenant_modules** | platform_schema | 遘滓姐隶「髦<EFBDA2>ィ。蝮鈴<E89DAE>鄂ョ | P0 |
|
||
| **tenant_quotas** | platform_schema | 遘滓姐驟埼「晉ョ。逅<EFBDA1> | P1 |
|
||
| **admin_operation_logs** | admin_schema | 霑占是謫堺ス懈律蠢<E5BE8B> | P1 |
|
||
|
||
**豕ィ諢擾シ?* 蠖灘燕譛我ク荳ェ`AdminLog`陦ィ蝨ィ`public`schema<EFBFBD>御ス<EFBFBD>ク榊ョ梧紛縲?
|
||
|
||
### 2.3 蟾イ譛臥噪螳。隶。譌・蠢?
|
||
|
||
**IIT讓。蝮礼噪螳。隶。譌・蠢?* 笨?<3F>亥庄蜿り<E3828A>シ会シ?
|
||
|
||
```prisma
|
||
model IitAuditLog {
|
||
id String @id @default(uuid())
|
||
projectId String
|
||
userId String
|
||
actionType String
|
||
entityType String
|
||
entityId String
|
||
details Json?
|
||
traceId String
|
||
createdAt DateTime @default(now())
|
||
|
||
@@schema("iit_schema")
|
||
}
|
||
```
|
||
|
||
**蜿ッ螟咲畑諤ァ<E8ABA4><EFBDA7>** 笨?譫カ譫<EFBDB6>ョセ隶。莨倡ァ<EFBDA7>悟庄菴應クコ蜈ィ螻螳。隶。譌・蠢礼噪蜿り<E3828A>?
|
||
|
||
---
|
||
|
||
## 3. 蜷守ォッ譚<EFBDAF>剞螳樒鴫譴ウ逅<EFBDB3>
|
||
|
||
### 3.1 隶、隸∫ウサ扈溽憾諤?笶?**譛ェ螳樒<E89EB3>?*
|
||
|
||
**謳懃エ「扈捺棡<E68DBA>?*
|
||
- 笶?豐。譛画伽蛻ー `/api/auth/login` 謌?`/api/auth/register`
|
||
- 笶?豐。譛雨WT逕滓<E98095>/鬪瑚ッ∝キ・蜈キ
|
||
- 笶?豐。譛芽ョ、隸∽クュ髣エ莉カ<E88E89>亥ヲ?`requireAuth`<EFBFBD>?
|
||
|
||
**蟇ケ豈泌<E8B188>莉夜。ケ逶ョ**<EFBFBD>井サ残odebase_search扈捺棡<EFBFBD>会シ<EFBFBD>
|
||
- ODJ鬘ケ逶ョ譛牙ョ梧紛逧Пassport JWT隶、隸<EFBDA4> 笨?
|
||
- BYSY鬘ケ逶ョ譛雨WT隶、隸∽クュ髣エ莉?笨?
|
||
- **譛ャ鬘ケ逶ョ<E980B6>壼ョ悟<EFBDAE>遨コ逋ス** 笶?
|
||
|
||
### 3.2 謗域揀邉サ扈溽憾諤?笶?**譛ェ螳樒<E89EB3>?*
|
||
|
||
**郛コ螟ア蜀<EFBDB1>ョケ<EFBDAE>?*
|
||
- 笶?豐。譛芽ァ定牡譽譟・荳ュ髣エ莉カ<E88E89>亥ヲ<E4BAA5> `requireRole(['admin'])`<EFBFBD>?
|
||
- 笶?豐。譛画揀髯先丐蟆<E4B890>。ィ<EFBDA1><EFBDA8>OLE_PERMISSIONS<4E>?
|
||
- 笶?豐。譛宇eature Flag譽譟・騾サ霎<EFBDBB>
|
||
|
||
**蠖ア蜩搾シ?*
|
||
- 謇譛陰PI遶ッ轤ケ驛ス譏ッ蜈ャ蠑逧<C280>シ梧裏譚<E8A38F>剞菫晄<E88FAB>?
|
||
- 譌<>豕募玄蛻<E78E84>ョ。逅<EFBDA1>遭蜥梧勸騾夂畑謌?
|
||
- 譌<>豕募ョ樒鴫螟夂ァ滓姐謨ー謐ョ髫皮ヲ?
|
||
|
||
### 3.3 蠖灘燕API扈捺桷
|
||
|
||
**Legacy Routes** (譌<>隶、隸?<3F>?
|
||
|
||
```
|
||
/api/v1/aia/* - AI譎コ閭ス髣ョ遲費シ域裏譚<E8A38F>剞譽譟・<E8AD9F><EFBDA5>
|
||
/api/v1/pkb/* - 荳ェ莠コ遏・隸<EFBDA5>コ難シ域裏譚<E8A38F>剞譽譟・<E8AD9F><EFBDA5>
|
||
/api/v1/rvw/* - 遞ソ莉カ螳。譟・<E8AD9F>域裏譚<E8A38F>剞譽譟・<E8AD9F><EFBDA5>
|
||
```
|
||
|
||
**髣ョ鬚假シ?*
|
||
- 莉サ菴穂ココ驛ス蜿ッ莉・隶ソ髣ョ莉サ菴慕畑謌キ逧<EFBDB7>焚謐?
|
||
- 豐。譛<EFBDA1> `userId` 驩エ譚<EFBDB4>サ霎<EFBDBB>
|
||
- 豐。譛臥ァ滓姐謨ー謐ョ髫皮ヲサ
|
||
|
||
---
|
||
|
||
## 4. 蜑咲ォッ譚<EFBDAF>剞螳樒鴫譴ウ逅<EFBDB3>
|
||
|
||
### 4.1 譚<>剞譯<E5899E>楔蟄伜惠 笨?菴<>サ<EFBFBD>クコMock
|
||
|
||
**譁<>サカ菴咲スョ<EFBDBD>?* `frontend-v2/src/framework/permission/PermissionContext.tsx`
|
||
|
||
**譬ク蠢<EFBDB8>サ」遐<EFBDA3>シ?*
|
||
|
||
```typescript
|
||
// 笞<><E7AC9E><EFBFBD> 遑ャ郛也<E9839B>∽クコ譛鬮俶揀髯撰シ御サ<E5BEA1>セ帛シ蜿第オ玖ッ?
|
||
const MOCK_USER: UserInfo = {
|
||
id: 'test-user-001',
|
||
name: '豬玖ッ慕<EFBDAF>皮ゥカ蜻?,
|
||
email: 'test@example.com',
|
||
version: 'premium', // <20>争 遑ャ郛也<E9839B>?
|
||
avatar: null,
|
||
isTrial: false,
|
||
}
|
||
|
||
// 譚<>剞譽譟・蜃ス謨ー<E8ACA8>亥渕莠散serVersion遲臥コァ<EFBDBA>?
|
||
const checkModulePermission = (requiredVersion?: UserVersion): boolean => {
|
||
if (!user) return false
|
||
if (!requiredVersion) return true
|
||
return checkVersionLevel(user.version, requiredVersion)
|
||
}
|
||
```
|
||
|
||
**UserVersion螳壻ケ会シ?*
|
||
|
||
```typescript
|
||
// framework/permission/types.ts
|
||
export type UserVersion = 'free' | 'basic' | 'professional' | 'premium'
|
||
```
|
||
|
||
### 4.2 譚<>剞譽譟・騾サ霎<EFBDBB> 笨?譫カ譫<EFBDB6>ョ梧紛
|
||
|
||
**讓。蝮玲ウィ蜀梧慮逧<E685AE>揀髯仙」ー譏趣シ?*
|
||
|
||
```typescript
|
||
// 讓。蝮怜ョ壻ケ画磁蜿」
|
||
interface ModuleDefinition {
|
||
id: string
|
||
name: string
|
||
path: string
|
||
requiredVersion?: UserVersion // <20>識 譚<>剞隕∵ア<E288B5>
|
||
// ...
|
||
}
|
||
```
|
||
|
||
**霍ッ逕ア螳亥梱<E4BAA5>?*
|
||
|
||
```typescript
|
||
// RouteGuard.tsx
|
||
if (module.requiredVersion && !checkModulePermission(module.requiredVersion)) {
|
||
return <PermissionDenied />
|
||
}
|
||
```
|
||
|
||
**笨?莨倡せ<E580A1>?*
|
||
- 譚<>剞譯<E5899E>楔隶セ隶。螳悟埋
|
||
- 譏謎コ取黄螻募芦逵溷ョ櫁ョ、隸?
|
||
|
||
**笶?郛コ轤ケ<E8BDA4>?*
|
||
- 逕ィ謌キ菫。諱ッ螳悟<E89EB3>hardcode
|
||
- 豐。譛牙ッケ謗・蜷守ォッAPI
|
||
- 豐。譛臥匳蠖<E58CB3>/逋サ蜃コUI
|
||
|
||
---
|
||
|
||
## 5. 蟾ョ霍晏<E99C8D>譫<EFBFBD>
|
||
|
||
### 5.1 荳傘RD髴豎ら噪蟾ョ霍<EFBDAE>
|
||
|
||
| PRD髴豎?| 蠖灘燕迥カ諤?| 蟾ョ霍<EFBDAE> | 莨伜<E88EA8>郤?|
|
||
|---------|---------|------|--------|
|
||
| **遘滓姐邂。逅<EFBDA1>** | 笶?譌?| 髴螳梧紛螳樒鴫Tenant菴鍋ウサ | P0 |
|
||
| **4遘崎ァ定<EFBDA7>?* (SUPER_ADMIN/HOSPITAL_ADMIN/PHARMA_ADMIN/USER) | 笶?蜿ェ譛臥ョ蜊瓶ole蟄礼ャヲ荳?| 髴RBAC菴鍋ウサ | P0 |
|
||
| **蜩∫煙螳壼宛** (Logo/逋サ蠖暮。? | 笶?譌?| 髴tenant.config JSONB蟄玲ョオ | P0 |
|
||
| **逋サ蠖慕ウサ扈<EFBDBB>** | 笶?譌?| 髴JWT隶、隸∫ウサ扈<EFBDBB> | P0 |
|
||
| **譚<>剞謗ァ蛻カ** | 笨?蜑咲ォッMock / 笶?蜷守ォッ譌?| 髴蜷守ォッ荳ュ髣エ莉?| P0 |
|
||
| **Feature Flag** | 笶?譌?| 髴驟咲スョ陦?譽譟・騾サ霎<EFBDBB> | P0 |
|
||
| **霑占是遶?* (/admin/*) | 笶?譌?| 髴蜈ィ譁ー蠑蜿?| P0 |
|
||
| **譛コ譫<EFBDBA>ォ?* (/org/hospital/*, /org/pharma/*) | 笶?譌?| 髴蜈ィ譁ー蠑蜿?| P1 |
|
||
| **螳。隶。譌・蠢<EFBDA5>** | 笞<><E7AC9E><EFBFBD> 莉<>IT讓。蝮<EFBDA1> | 髴蜈ィ螻螳。隶。邉サ扈<EFBDBB> | P1 |
|
||
|
||
### 5.2 譫カ譫<EFBDB6>アる擇蟾ョ霍<EFBDAE>
|
||
|
||
**蠖灘燕譫カ譫<EFBDB6>シ?* 蜊慕畑謌キ縲∵裏遘滓姐縲∵裏譚<E8A38F>剞
|
||
```
|
||
User (蜊戊。ィ)
|
||
竊?
|
||
Projects/KnowledgeBases/... (逶エ謗・蜈ウ閨<EFBDB3> userId)
|
||
```
|
||
|
||
**逶ョ譬<EFBDAE>楔譫<E6A594>シ?* 螟夂ァ滓姐縲ヽBAC縲∵焚謐ョ髫皮ヲ?
|
||
```
|
||
Tenant (遘滓姐)
|
||
竊?
|
||
Department (驛ィ髣ィ/遘大ョ、)
|
||
竊?
|
||
User (逕ィ謌キ) + Role (隗定牡)
|
||
竊?
|
||
Projects/KnowledgeBases/... (tenant_id + user_id)
|
||
```
|
||
|
||
---
|
||
|
||
## 6. 譁ーPRD髴豎りァ」隸?
|
||
|
||
### 6.1 譬ク蠢<EFBDB8>ァ定牡螳壻ケ会シ域擂閾ェPRD v2.1<EFBFBD>?
|
||
|
||
| 隗定牡Code | 蠖貞ア<E8B29E> | 譚<>剞闌<E5899E>峩 | URL蜑咲シ | 譬ク蠢<EFBDB8>′雍」 |
|
||
|---------|------|---------|---------|---------|
|
||
| **SUPER_ADMIN** | 蟷ウ蜿ー | 蜈ィ螻謨ー謐ョ | /admin | 遘滓姐蠑騾壹∝刀迚碁<E8BF9A>鄂ョ縲 ̄rompt隹<74>シ<EFBFBD> |
|
||
| **HOSPITAL_ADMIN** | 蛹サ髯「遘滓姐 | 譛ャ髯「謨ー謐ョ | /org/hospital | 遘大ョ、邂。逅<EFBDA1><EFBFBD><C280>鬚晏<E9AC9A>驟?|
|
||
| **PHARMA_ADMIN** | 闕ッ莨∫ァ滓姐 | 譛ャ莨<EFBDAC>。ケ逶ョ | /org/pharma | 鬘ケ逶ョ逶第而縲,RO邂。逅<EFBDA1>∝ョ。隶?|
|
||
| **USER** | 莉サ諢冗ァ滓姐 | 荳ェ莠コ/陲ォ謗域揀謨ー謐?| /app | 遘醍<E98198>比ク壼苅謫堺ス<E5A0BA> |
|
||
|
||
### 6.2 遘滓姐邀サ蝙具シ<E585B7>enant Type<70>?
|
||
|
||
```typescript
|
||
enum TenantType {
|
||
HOSPITAL = 'HOSPITAL', // 蛹サ髯「螳「謌キ
|
||
PHARMA = 'PHARMA', // 闕ッ莨∝ョ「謌キ
|
||
JOURNAL = 'JOURNAL', // 譛溷<E8AD9B>螳「謌キ
|
||
}
|
||
```
|
||
|
||
### 6.3 蜩∫煙螳壼宛髴豎?<3F><>
|
||
|
||
**URL遲也払<E4B99F>?*
|
||
```
|
||
騾夂畑逋サ蠖包シ喇ttps://app.yizhengxun.com/auth/login
|
||
荳灘ア樒匳蠖包シ喇ttps://app.yizhengxun.com/t/{tenant_code}/login
|
||
```
|
||
|
||
**遘滓姐驟咲スョ<EFBDBD><EFBDAE>SONB<4E>会シ<E4BC9A>**
|
||
|
||
```json
|
||
{
|
||
"branding": {
|
||
"logoUrl": "https://oss.../jst_logo.png",
|
||
"loginBackgroundUrl": "https://oss.../jst_bldg.jpg",
|
||
"primaryColor": "#0056b3",
|
||
"welcomeTitle": "蛹嶺コャ遘ッ豌エ貎ュ蛹サ髯?AI 荳エ蠎顔ァ醍<EFBDA7>泌ケウ蜿ー",
|
||
"welcomeSubTitle": "譎コ閭ス蛹?ツキ 隗<EFBFBD>激蛹?ツキ 鬮俶譜邇?
|
||
}
|
||
}
|
||
```
|
||
|
||
### 6.4 譎コ閭ス霍ッ逕ア蛻<EFBDB1>書<EFBFBD>育匳蠖募錘霍ウ霓ャ<E99C93>?
|
||
|
||
```typescript
|
||
function getRedirectPath(user, tenant) {
|
||
if (user.role === 'SUPER_ADMIN') return '/admin/dashboard';
|
||
|
||
if (user.role === 'TENANT_ADMIN') {
|
||
if (tenant.type === 'HOSPITAL') return '/org/hospital/dashboard';
|
||
if (tenant.type === 'PHARMA') return '/org/pharma/dashboard';
|
||
}
|
||
|
||
if (tenant.type === 'JOURNAL') return '/app/rvw/dashboard';
|
||
|
||
return '/app/dashboard'; // 鮟倩ョ、<EFBDAE>壽勸騾夂畑謌?
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 7. 譫カ譫<EFBDB6>ョセ隶。蟒コ隶ョ
|
||
|
||
### 7.1 謨ー謐ョ蠎鉄chema隶セ隶。
|
||
|
||
#### **7.1.1 platform_schema<6D>亥ケウ蜿ー譬ク蠢<EFBDB8>。ィ<EFBDA1>?*
|
||
|
||
**A. tenants 陦?* <20><>0<EFBFBD>?
|
||
|
||
```prisma
|
||
model Tenant {
|
||
id String @id @default(uuid())
|
||
name String // 遘滓姐蜷咲ァー<EFBDA7>亥ヲゑシ壼圏莠ャ遘ッ豌エ貎ュ蛹サ髯「<E9ABAF>?
|
||
code String @unique // 遘滓姐莉」遐<EFBDA3>シ亥ヲゑシ嗚st-hospital<61>檎畑莠散RL<52>?
|
||
type TenantType // 遘滓姐邀サ蝙具シ唏OSPITAL/PHARMA/JOURNAL
|
||
status String @default("active") // active/suspended/expired
|
||
|
||
// 蜩∫煙驟咲スョ<EFBDBD><EFBDAE>SONB<4E>?
|
||
config Json @default("{}") // branding驟咲スョ縲∵ィ。蝮苓ョ「髦<EFBDA2>ュ<EFBFBD>
|
||
|
||
// 驟埼「晉ョ。逅<EFBDA1>
|
||
tokenQuota Int? // 諤サToken鬚晏コヲ
|
||
tokenUsed Int @default(0) // 蟾イ菴ソ逕ィToken
|
||
|
||
// 譌カ髣エ謌?
|
||
createdAt DateTime @default(now())
|
||
updatedAt DateTime @updatedAt
|
||
expiresAt DateTime? // 隶「髦<EFBDA2>芦譛滓慮髣エ
|
||
|
||
// 蜈ウ邉サ
|
||
users TenantUser[]
|
||
departments Department[]
|
||
modules TenantModule[]
|
||
|
||
@@index([code])
|
||
@@index([type])
|
||
@@index([status])
|
||
@@map("tenants")
|
||
@@schema("platform_schema")
|
||
}
|
||
|
||
enum TenantType {
|
||
HOSPITAL
|
||
PHARMA
|
||
JOURNAL
|
||
|
||
@@schema("platform_schema")
|
||
}
|
||
```
|
||
|
||
**B. users 陦ィ謇ゥ螻?* <20><>0<EFBFBD>?
|
||
|
||
```prisma
|
||
model User {
|
||
id String @id @default(uuid())
|
||
email String @unique
|
||
password String
|
||
name String?
|
||
avatarUrl String? @map("avatar_url")
|
||
|
||
// <20><> 螟夂ァ滓姐謾ッ謖?
|
||
tenantId String? @map("tenant_id") // 謇螻樒ァ滓姐<E6BB93><E5A790>ULL=蟷ウ蜿ー邂。逅<EFBDA1>遭<EFBFBD><E981AD>
|
||
departmentId String? @map("department_id") // 謇螻樣Κ髣?遘大ョ、
|
||
|
||
// <20><> 隗定牡邉サ扈<EFBDBB>
|
||
role UserRole // SUPER_ADMIN/TENANT_ADMIN/USER
|
||
|
||
// 蜈カ莉門ュ玲ョオ菫晄戟荳榊序...
|
||
status String @default("active")
|
||
kbQuota Int @default(3)
|
||
trialEndsAt DateTime?
|
||
lastLoginAt DateTime?
|
||
createdAt DateTime @default(now())
|
||
updatedAt DateTime @updatedAt
|
||
|
||
// 蜈ウ邉サ
|
||
tenant Tenant? @relation(fields: [tenantId], references: [id])
|
||
department Department? @relation(fields: [departmentId], references: [id])
|
||
|
||
@@index([tenantId])
|
||
@@index([departmentId])
|
||
@@index([role])
|
||
@@map("users")
|
||
@@schema("platform_schema")
|
||
}
|
||
|
||
enum UserRole {
|
||
SUPER_ADMIN // 蟷ウ蜿ー雜<EFBDB0>コァ邂。逅<EFBDA1><E98085>?
|
||
TENANT_ADMIN // 遘滓姐邂。逅<EFBDA1>遭<EFBFBD>亥現髯「/闕ッ莨<EFBDAF>シ?
|
||
USER // 譎ョ騾夂畑謌キ<E8AC8C>亥現逕<E78FBE>/遐皮ゥカ蜻假シ<E58187>
|
||
|
||
@@schema("platform_schema")
|
||
}
|
||
```
|
||
|
||
**C. tenant_members 陦?* <20><>0<EFBFBD>俄恟<E4BF84>?驥<>コウ蜿埼ヲ茨シ壽隼蜷堺クコTenantMember
|
||
|
||
```prisma
|
||
model TenantMember {
|
||
id String @id @default(uuid())
|
||
tenantId String @map("tenant_id")
|
||
userId String @map("user_id")
|
||
role String // 蝨ィ隸・遘滓姐荳ュ逧<EFBDAD>ァ定牡
|
||
joinedAt DateTime @default(now()) @map("joined_at")
|
||
|
||
tenant Tenant @relation(fields: [tenantId], references: [id])
|
||
|
||
@@unique([tenantId, userId])
|
||
@@map("tenant_members") // 隸ュ荵画峩貂<E5B3A9><E8B282>?
|
||
@@schema("platform_schema")
|
||
}
|
||
```
|
||
|
||
**D. departments 陦?* <20><>1<EFBFBD>?
|
||
|
||
```prisma
|
||
model Department {
|
||
id String @id @default(uuid())
|
||
tenantId String @map("tenant_id")
|
||
name String // 遘大ョ、蜷咲ァー<EFBDA7>亥ヲゑシ壼ソ<E5A3BC><EFBDBF>遘托シ?
|
||
parentId String? @map("parent_id") // 荳顔コァ遘大ョ、<EFBDAE>域髪謖∵<E8AC96>大ス「扈捺桷<E68DBA><E6A1B7>
|
||
tokenQuota Int? @map("token_quota") // 遘大ョ、Token鬚晏コヲ
|
||
createdAt DateTime @default(now())
|
||
updatedAt DateTime @updatedAt
|
||
|
||
tenant Tenant @relation(fields: [tenantId], references: [id])
|
||
users User[]
|
||
parent Department? @relation("DepartmentHierarchy", fields: [parentId], references: [id])
|
||
children Department[] @relation("DepartmentHierarchy")
|
||
|
||
@@index([tenantId])
|
||
@@map("departments")
|
||
@@schema("platform_schema")
|
||
}
|
||
```
|
||
|
||
**E. feature_flags 陦?* <20><>0<EFBFBD>?
|
||
|
||
```prisma
|
||
model FeatureFlag {
|
||
id String @id @default(uuid())
|
||
featureKey String @unique @map("feature_key") // 蜉溯<E89C89>譬<EFBFBD>ッ<EFBFBD>シ亥ヲゑシ嗽se_gpt_5<5F>?
|
||
displayName String @map("display_name")
|
||
description String?
|
||
isEnabled Boolean @default(false) @map("is_enabled")
|
||
targetRoles String[] @map("target_roles") // 蜈∬ョク逧<EFBDB8>ァ定牡蛻苓。?
|
||
targetTenants String[] @default([]) @map("target_tenants") // 蜈∬ョク逧<EFBDB8>ァ滓姐ID蛻苓。ィ
|
||
createdAt DateTime @default(now())
|
||
updatedAt DateTime @updatedAt
|
||
|
||
@@map("feature_flags")
|
||
@@schema("platform_schema")
|
||
}
|
||
```
|
||
|
||
**F. tenant_modules 陦?* <20><>0<EFBFBD>?
|
||
|
||
```prisma
|
||
model TenantModule {
|
||
id String @id @default(uuid())
|
||
tenantId String @map("tenant_id")
|
||
moduleCode String @map("module_code") // 讓。蝮嶺サ」遐<EFBDA3>シ<EFBFBD>SL/DC/IIT遲会シ<E4BC9A>
|
||
isEnabled Boolean @default(true) @map("is_enabled")
|
||
expiresAt DateTime? @map("expires_at") // 讓。蝮苓ョ「髦<EFBDA2>芦譛滓慮髣エ
|
||
createdAt DateTime @default(now())
|
||
|
||
tenant Tenant @relation(fields: [tenantId], references: [id])
|
||
|
||
@@unique([tenantId, moduleCode])
|
||
@@map("tenant_modules")
|
||
@@schema("platform_schema")
|
||
}
|
||
```
|
||
|
||
**G. tenant_quota_allocations 陦?* <20><>0<EFBFBD>解氣?驥<>コウ蜿埼ヲ茨シ夂イセ扈<EFBDBE>喧驟埼「晏<EFBDA2>驟<EFBFBD>
|
||
|
||
```prisma
|
||
model TenantQuotaAllocation {
|
||
id Int @id @default(autoincrement())
|
||
tenantId String @map("tenant_id")
|
||
targetType String @map("target_type") // 'DEPARTMENT' | 'USER'
|
||
targetKey String @map("target_key") // DepartmentID 謌?UserID
|
||
limitAmount BigInt @map("limit_amount") // 蛻<><E89BBB>逧Уoken鬚晏コヲ
|
||
usedAmount BigInt @default(0) @map("used_amount") // 蟾イ菴ソ逕?
|
||
createdAt DateTime @default(now())
|
||
updatedAt DateTime @updatedAt
|
||
|
||
@@unique([tenantId, targetType, targetKey])
|
||
@@index([tenantId])
|
||
@@index([targetType, targetKey])
|
||
@@map("tenant_quota_allocations")
|
||
@@schema("platform_schema")
|
||
}
|
||
```
|
||
|
||
**逕ィ騾費シ<E8B2BB>** 蛹サ髯「遶ッ蜿ッ莉・蟆<EFBDA5>サToken鬚晏コヲ蛻<EFBDA6><E89BBB>扈?蠢<><E8A0A2>遘?<3F><>epartment<6E>画<EFBFBD>"蠑<>蛹サ逕?<3F><>ser<65>?
|
||
|
||
#### **7.1.2 admin_schema<6D>郁ソ占是邂。逅<EFBDA1>シ<EFBFBD>**
|
||
|
||
**H. admin_operation_logs 陦?* <20><>1<EFBFBD>俄恟<E4BF84>?驥<>コウ蜿埼ヲ茨シ壼「槫刈module蟄玲ョオ
|
||
|
||
```prisma
|
||
model AdminOperationLog {
|
||
id Int @id @default(autoincrement())
|
||
adminId String @map("admin_id")
|
||
operationType String @map("operation_type") // CREATE_TENANT/UPDATE_FEATURE_FLAG遲?
|
||
targetType String @map("target_type") // tenant/user/config
|
||
targetId String @map("target_id")
|
||
module String? @map("module") // <20><> 謇螻樊ィ。蝮暦シ<E69AA6>IT/ASL/邉サ扈滄<E68988>鄂ョ遲会シ<E4BC9A>
|
||
beforeData Json? @map("before_data")
|
||
afterData Json? @map("after_data")
|
||
ipAddress String? @map("ip_address")
|
||
userAgent String? @map("user_agent")
|
||
createdAt DateTime @default(now())
|
||
|
||
@@index([adminId])
|
||
@@index([operationType])
|
||
@@index([module]) // <20><> 闕ッ莨∫ォッ謖画ィ。蝮玲衍隸「
|
||
@@index([createdAt])
|
||
@@map("admin_operation_logs")
|
||
@@schema("admin_schema")
|
||
}
|
||
```
|
||
|
||
### 7.2 蜷守ォッAPI譫カ譫<EFBDB6>ョセ隶。
|
||
|
||
#### **A. 隶、隸∫ウサ扈<EFBDBB>** <20><>0<EFBFBD>?
|
||
|
||
**霍ッ逕ア<E98095>?* `/api/v1/auth/*`
|
||
|
||
```typescript
|
||
// backend/src/platform/auth/routes.ts
|
||
|
||
POST /api/v1/auth/register // 逕ィ謌キ豕ィ蜀<EFBDA8>
|
||
POST /api/v1/auth/login // 逋サ蠖包シ郁ソ泌屓JWT<57>?
|
||
POST /api/v1/auth/logout // 逋サ蜃コ
|
||
POST /api/v1/auth/refresh // 蛻キ譁ーToken
|
||
GET /api/v1/auth/me // 闔キ蜿門ス灘燕逕ィ謌キ菫。諱ッ
|
||
```
|
||
|
||
**JWT Payload扈捺桷<E68DBA>?*
|
||
|
||
```typescript
|
||
interface JWTPayload {
|
||
userId: string
|
||
email: string
|
||
role: UserRole
|
||
tenantId?: string
|
||
tenantType?: TenantType
|
||
exp: number // 霑<>悄譌カ髣エ
|
||
}
|
||
```
|
||
|
||
#### **B. 隶、隸∽クュ髣エ莉?* <20><>0<EFBFBD>?
|
||
|
||
```typescript
|
||
// backend/src/common/middleware/auth.ts
|
||
|
||
/**
|
||
* JWT隶、隸∽クュ髣エ莉?
|
||
* 鬪瑚ッゝoken蟷カ蟆<EFBDB6>畑謌キ菫。諱ッ謖りスス蛻?req.user
|
||
*/
|
||
export const requireAuth = async (req, res, next) => {
|
||
const token = extractToken(req)
|
||
if (!token) return res.status(401).send({ error: 'Unauthorized' })
|
||
|
||
try {
|
||
const payload = verifyJWT(token)
|
||
req.user = await prisma.user.findUnique({ where: { id: payload.userId } })
|
||
if (!req.user) return res.status(401).send({ error: 'User not found' })
|
||
next()
|
||
} catch (error) {
|
||
return res.status(401).send({ error: 'Invalid token' })
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 隗定牡譚<E789A1>剞荳ュ髣エ莉?
|
||
* 譽譟・逕ィ謌キ譏ッ蜷ヲ蜈キ譛画欠螳夊ァ定<EFBDA7>?
|
||
*/
|
||
export const requireRole = (...allowedRoles: UserRole[]) => {
|
||
return (req, res, next) => {
|
||
if (!req.user) return res.status(401).send({ error: 'Unauthorized' })
|
||
if (!allowedRoles.includes(req.user.role)) {
|
||
return res.status(403).send({ error: 'Forbidden' })
|
||
}
|
||
next()
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 遘滓姐謨ー謐ョ髫皮ヲサ荳ュ髣エ莉?
|
||
* 遑ョ菫晉畑謌キ蜿ェ閭ス隶ソ髣ョ閾ェ蟾ア遘滓姐逧<E5A790>焚謐?
|
||
*/
|
||
export const requireTenantAccess = (req, res, next) => {
|
||
if (!req.user) return res.status(401).send({ error: 'Unauthorized' })
|
||
|
||
// SUPER_ADMIN蜿ッ莉・隶ソ髣ョ謇譛臥ァ滓姐謨ー謐?
|
||
if (req.user.role === 'SUPER_ADMIN') return next()
|
||
|
||
// 蜈カ莉也畑謌キ蜿ェ閭ス隶ソ髣ョ閾ェ蟾ア遘滓姐逧<E5A790>焚謐?
|
||
req.tenantId = req.user.tenantId
|
||
next()
|
||
}
|
||
```
|
||
|
||
#### **C. 霑占是邂。逅<EFBDA1>ォッAPI** <20><>0<EFBFBD>?
|
||
|
||
**霍ッ逕ア<E98095>?* `/api/v1/admin/*`
|
||
|
||
```typescript
|
||
// 遘滓姐邂。逅<EFBDA1>
|
||
POST /api/v1/admin/tenants // 蛻帛サコ遘滓姐
|
||
GET /api/v1/admin/tenants // 遘滓姐蛻苓。ィ
|
||
GET /api/v1/admin/tenants/:id // 遘滓姐隸ヲ諠<EFBDA6>
|
||
PUT /api/v1/admin/tenants/:id // 譖エ譁ー遘滓姐
|
||
DELETE /api/v1/admin/tenants/:id // 蛻<>髯、遘滓姐
|
||
|
||
// Feature Flag邂。逅<EFBDA1>
|
||
GET /api/v1/admin/feature-flags // 闔キ蜿匁園譛宇eature Flag
|
||
PUT /api/v1/admin/feature-flags/:key // 譖エ譁ーFeature Flag
|
||
|
||
// 逕ィ謌キ邂。逅<EFBDA1>
|
||
GET /api/v1/admin/users // 蜈ィ螻逕ィ謌キ蛻苓。ィ
|
||
POST /api/v1/admin/users/:id/assign-tenant // 蛻<><E89BBB>遘滓姐
|
||
```
|
||
|
||
**譚<>剞隕∵アゑシ?* 蜈ィ驛ィ髴隕?`requireRole('SUPER_ADMIN')`
|
||
|
||
#### **D. 譛コ譫<EFBDBA>ョ。逅<EFBDA1>ォッAPI** <20><>1<EFBFBD>?
|
||
|
||
**霍ッ逕ア<E98095>?* `/api/v1/org/*`
|
||
|
||
```typescript
|
||
// 蛹サ髯「邂。逅<EFBDA1>ォ?
|
||
GET /api/v1/org/hospital/departments // 遘大ョ、蛻苓。ィ
|
||
POST /api/v1/org/hospital/departments // 蛻帛サコ遘大ョ、
|
||
GET /api/v1/org/hospital/members // 謌仙遭蛻苓。ィ
|
||
POST /api/v1/org/hospital/members/import // 謇ケ驥丞ッシ蜈・謌仙遭
|
||
|
||
// 闕ッ莨∫ョ。逅<EFBDA1>ォ?
|
||
GET /api/v1/org/pharma/projects // 鬘ケ逶ョ蛻苓。ィ
|
||
GET /api/v1/org/pharma/audit-logs // 螳。隶。譌・蠢<EFBDA5>
|
||
```
|
||
|
||
**譚<>剞隕∵アゑシ?* `requireRole('TENANT_ADMIN')` + `requireTenantAccess`
|
||
|
||
#### **E. 蜈ャ蠑API** <20><>0<EFBFBD>?
|
||
|
||
**霍ッ逕ア<E98095>?* `/api/public/*`
|
||
|
||
```typescript
|
||
// 遘滓姐蜩∫煙驟咲スョ<EFBDBD>域裏髴逋サ蠖包シ?
|
||
GET /api/public/tenant-config?code={code} // 闔キ蜿也ァ滓姐蜩∫煙驟咲スョ
|
||
```
|
||
|
||
### 7.3 蜑咲ォッ譫カ譫<EFBDB6>ョセ隶。
|
||
|
||
#### **A. 隶、隸∵ィ。蝮<EFBDA1>** <20><>0<EFBFBD>?
|
||
|
||
**逶ョ蠖慕サ捺桷<E68DBA>?*
|
||
|
||
```
|
||
frontend-v2/src/modules/auth/
|
||
笏懌楳笏 pages/
|
||
笏? 笏懌楳笏 LoginPage.tsx # 騾夂畑逋サ蠖暮。?
|
||
笏? 笏懌楳笏 TenantLoginPage.tsx # 遘滓姐荳灘ア樒匳蠖暮。オ<EFBDA1>亥勘諤∝刀迚鯉シ<E9AF89>
|
||
笏? 笏披楳笏 RegisterPage.tsx # 豕ィ蜀碁。?
|
||
笏懌楳笏 api/
|
||
笏? 笏披楳笏 authApi.ts # 隶、隸、PI隹<49>畑
|
||
笏懌楳笏 hooks/
|
||
笏? 笏披楳笏 useAuth.ts # 隶、隸?ook
|
||
笏披楳笏 routes.tsx # 隶、隸∬キッ逕ア
|
||
```
|
||
|
||
#### **B. 霑占是邂。逅<EFBDA1>ォッ讓。蝮?* <20><>0<EFBFBD>?
|
||
|
||
**逶ョ蠖慕サ捺桷<E68DBA>?*
|
||
|
||
```
|
||
frontend-v2/src/modules/admin/
|
||
笏懌楳笏 pages/
|
||
笏? 笏懌楳笏 Dashboard.tsx # 霑占是莉ェ陦ィ逶?
|
||
笏? 笏懌楳笏 TenantManagement/ # 遘滓姐邂。逅<EFBDA1>
|
||
笏? 笏? 笏懌楳笏 TenantList.tsx
|
||
笏? 笏? 笏懌楳笏 TenantCreate.tsx
|
||
笏? 笏? 笏懌楳笏 TenantEdit.tsx
|
||
笏? 笏? 笏披楳笏 BrandingConfig.tsx # 蜩∫煙驟咲スョ
|
||
笏? 笏懌楳笏 FeatureFlagManagement.tsx # Feature Flag邂。逅<EFBDA1>
|
||
笏? 笏披楳笏 UserManagement.tsx # 逕ィ謌キ邂。逅<EFBDA1>
|
||
笏懌楳笏 api/
|
||
笏? 笏披楳笏 adminApi.ts
|
||
笏披楳笏 index.tsx # 讓。蝮怜ョ壻ケ<E5A3BB>
|
||
```
|
||
|
||
**讓。蝮玲ウィ蜀鯉シ?*
|
||
|
||
```typescript
|
||
const AdminModule: ModuleDefinition = {
|
||
id: 'admin',
|
||
name: '霑占是邂。逅<EFBDA1>',
|
||
path: '/admin',
|
||
requiredVersion: undefined, // 荳榊渕莠思ersion譽譟?
|
||
requireRole: ['SUPER_ADMIN'], // <20><> 蝓コ莠手ァ定牡譽譟?
|
||
component: lazy(() => import('./layouts/AdminLayout')),
|
||
}
|
||
```
|
||
|
||
#### **C. 譛コ譫<EFBDBA>ョ。逅<EFBDA1>ォッ讓。蝮?* <20><>1<EFBFBD>?
|
||
|
||
**逶ョ蠖慕サ捺桷<E68DBA>?*
|
||
|
||
```
|
||
frontend-v2/src/modules/org/
|
||
笏懌楳笏 hospital/ # 蛹サ髯「邂。逅<EFBDA1>ォ?
|
||
笏? 笏懌楳笏 pages/
|
||
笏? 笏? 笏懌楳笏 Dashboard.tsx
|
||
笏? 笏? 笏懌楳笏 DepartmentManagement.tsx
|
||
笏? 笏? 笏披楳笏 MemberManagement.tsx
|
||
笏? 笏披楳笏 index.tsx
|
||
笏披楳笏 pharma/ # 闕ッ莨∫ョ。逅<EFBDA1>ォ?
|
||
笏懌楳笏 pages/
|
||
笏? 笏懌楳笏 Dashboard.tsx
|
||
笏? 笏懌楳笏 ProjectManagement.tsx
|
||
笏? 笏披楳笏 AuditLogs.tsx
|
||
笏披楳笏 index.tsx
|
||
```
|
||
|
||
---
|
||
|
||
## 8. 螳樊命霍ッ郤ソ蝗?
|
||
|
||
### 8.1 Phase 0<>壼㊥螟<E38AA5>キ・菴懶シ<E687B6>1螟ゥ<E89E9F><EFBDA9>
|
||
|
||
**逶ョ譬<EFBDAE>シ?* 扈滉ク謨ー謐ョ蠎楢。ィ扈捺桷<E68DBA>梧ク<E6A2A7>炊蜴<E7828A>彰驕礼<E9A995>?
|
||
|
||
- [ ] **莉サ蜉。1<EFBDA1>?* 蜀ウ遲紋ソ晉蕗 `platform_schema.users` 霑俶弍 `public.users`
|
||
- 蟒コ隶ョ<E99AB6>壻ソ晉<EFBDBF>?`platform_schema.users`<EFBFBD>域眠譫カ譫<EFBFBD>シ?
|
||
- 霑∫ァサ `public.users` 逧<>紙蜿イ謨ー謐ョ蛻ー `platform_schema.users`
|
||
- 蛻<>髯、 `public.users` 陦?
|
||
|
||
- [ ] **莉サ蜉。2<EFBDA1>?* 蛻帛サコ霑∫ァサ譁<EFBDBB>。」
|
||
- 譴ウ逅<EFBDB3>園譛我ク壼苅讓。蝮怜ッケ User 陦ィ逧<EFBDA8>シ慕畑
|
||
- 蛻カ螳壽焚謐ョ霑∫ァサ閼壽悽
|
||
|
||
### 8.2 Phase 1<>壽焚謐ョ蠎鉄chema隶セ隶。<E99AB6>?螟ゥ<E89E9F><EFBDA9>
|
||
|
||
**P0 譬ク蠢<EFBDB8>。ィ<EFBDA1><EFBDA8>**
|
||
|
||
- [ ] **Day 1荳雁壕<E99B81>?* 隶セ隶。蟷カ蛻帛サ?`tenants` 陦?
|
||
- [ ] **Day 1荳句壕<E58FA5>?* 謇ゥ螻<EFBDA9> `users` 陦ィ<E999A6>亥「槫刈 tenantId, departmentId, role enum<75>?
|
||
- [ ] **Day 2荳雁壕<E99B81>?* 蛻帛サコ `tenant_users`, `feature_flags`, `tenant_modules` 陦?
|
||
- [ ] **Day 2荳句壕<E58FA5>?* 蛻帛サコ Prisma Schema 蟷カ霑占。瑚ソ∫ァ?
|
||
|
||
**莠、莉倡黄<E580A1><E9BB84>**
|
||
- 笨?Prisma Schema螳梧紛螳壻ケ<E5A3BB>
|
||
- 笨?霑∫ァサ閼壽悽霑占。碁夊ソ<E5A48A>
|
||
- 笨?豬玖ッ墓焚謐ョ謠貞<E8ACA0>鬪瑚ッ<E7919A>
|
||
|
||
### 8.3 Phase 2<>壼錘遶ッ隶、隸∫ウサ扈滂シ<E6BB82>3螟ゥ<E89E9F><EFBDA9>
|
||
|
||
- [ ] **Day 1<>?* 螳樒鴫JWT蟾・蜈キ邀?
|
||
- `generateToken()`
|
||
- `verifyToken()`
|
||
- `refreshToken()`
|
||
|
||
- [ ] **Day 2<>?* 螳樒鴫隶、隸、PI
|
||
- POST `/api/v1/auth/register`
|
||
- POST `/api/v1/auth/login`
|
||
- GET `/api/v1/auth/me`
|
||
|
||
- [ ] **Day 3<>?* 螳樒鴫隶、隸∽クュ髣エ莉?
|
||
- `requireAuth`
|
||
- `requireRole`
|
||
- `requireTenantAccess`
|
||
- 蠎皮畑蛻ー邇ー譛鵜egacy API
|
||
|
||
**莠、莉倡黄<E580A1><E9BB84>**
|
||
- 笨?螳梧紛逧<E7B49B>ョ、隸∫ウサ扈?
|
||
- 笨?謇譛陰PI蜉<49>荳願ョ、隸∽ソ晄侃
|
||
- 笨?Postman豬玖ッ暮夊ソ<E5A48A>
|
||
|
||
### 8.4 Phase 3<>壼燕遶ッ隶、隸∝ッケ謗・<E8AC97><EFBDA5>2螟ゥ<E89E9F><EFBDA9>
|
||
|
||
- [ ] **Day 1<>?* 螳樒鴫逋サ蠖暮。オ髱「
|
||
- LoginPage.tsx
|
||
- useAuth Hook
|
||
- Token蟄伜お<E4BC9C><E3818A>ocalStorage<67>?
|
||
|
||
- [ ] **Day 2<>?* 蟇ケ謗・譚<EFBDA5>剞譯<E5899E>楔
|
||
- 譖ソ謐「PermissionContext荳ュ逧<EFBDAD>ock謨ー謐ョ
|
||
- 螳樒鴫莉主錘遶ッ闔キ蜿也畑謌キ菫。諱?
|
||
- 螳樒鴫逋サ蜃コ蜉溯<E89C89>
|
||
|
||
**莠、莉倡黄<E580A1><E9BB84>**
|
||
- 笨?蜿ッ逕ィ逧<EFBDA8>匳蠖?逋サ蜃コ豬∫ィ<E288AB>
|
||
- 笨?蜑咲ォッ譚<EFBDAF>剞謗ァ蛻カ逕滓譜
|
||
|
||
### 8.5 Phase 4<>夊ソ占是邂。逅<EFBDA1>ォッMVP<56>?螟ゥ<E89E9F><EFBDA9>
|
||
|
||
**P0 譬ク蠢<EFBDB8>粥閭ス<E996AD>?*
|
||
|
||
- [ ] **Day 1-2<>?* 遘滓姐邂。逅<EFBDA1>
|
||
- 遘滓姐蛻苓。ィ鬘?
|
||
- 蛻帛サコ遘滓姐陦ィ蜊包シ亥渕譛ャ菫。諱?遘滓姐邀サ蝙具シ?
|
||
- 遘滓姐隸ヲ諠<EFBDA6>。?
|
||
|
||
- [ ] **Day 3<>?* 蜩∫煙驟咲スョ
|
||
- Logo荳贋シ<E8B48B>蛻ーOSS
|
||
- 逋サ蠖暮。オ閭梧勹蝗セ荳贋シ<E8B48B>
|
||
- 驟咲スョ鬚<EFBDAE>ァ<EFBFBD>
|
||
|
||
- [ ] **Day 4<>?* Feature Flag邂。逅<EFBDA1>
|
||
- Feature Flag蛻苓。ィ
|
||
- 蠑蜈ウ蛻<EFBDB3><E89BBB>?
|
||
- 逶ョ譬<EFBDAE>ァ滓姐驟咲スョ
|
||
|
||
- [ ] **Day 5<>?* 髮<><E9ABAE>豬玖ッ<E78E96>
|
||
- 霑占是遶ッ螳梧紛豬∫ィ区オ玖ッ?
|
||
- 譚<>剞謗ァ蛻カ豬玖ッ<E78E96>
|
||
|
||
**莠、莉倡黄<E580A1><E9BB84>**
|
||
- 笨?霑占是邂。逅<EFBDA1>ォッMVP蜿ッ逕ィ
|
||
- 笨?蜿ッ莉・蛻帛サコ遘滓姐
|
||
- 笨?蜿ッ莉・驟咲スョ蜩∫煙
|
||
- 笨?蜿ッ莉・邂。逅<EFBDA1>eature Flag
|
||
|
||
### 8.6 Phase 5<>夂ァ滓姐荳灘ア樒匳蠖包シ<E58C85>2螟ゥ<E89E9F><EFBDA9>
|
||
|
||
- [ ] **Day 1<>?* 螳樒鴫TenantLoginPage
|
||
- 蜉ィ諤∝刈霓ス遘滓姐蜩∫煙驟咲ス?
|
||
- 譖ソ謐「Logo蜥瑚レ譎ッ蝗セ
|
||
- 蜉ィ諤∽クサ鬚倩牡
|
||
|
||
- [ ] **Day 2<>?* 螳樒鴫譎コ閭ス霍ッ逕ア蛻<EFBDB1>書
|
||
- 逋サ蠖募錘譬ケ謐ョrole+tenantType霍ウ霓ャ
|
||
- 豬玖ッ穂ク榊酔隗定牡逧<E789A1>キウ霓ャ騾サ霎<EFBDBB>
|
||
|
||
**莠、莉倡黄<E580A1><E9BB84>**
|
||
- 笨?遘滓姐荳灘ア樒匳蠖暮。オ蜿ッ逕?
|
||
- 笨?URL<52>啻/t/{code}/login` 逕滓譜
|
||
|
||
### 8.7 Phase 6<>壽惻譫<E683BB>ョ。逅<EFBDA1>ォッ<EFBDAB>域潔髴蠑蜿托シ<E68998>
|
||
|
||
**P1 蜉溯<E89C89><E6BAAF>亥錘扈ュ謗呈悄<E59188>会シ?*
|
||
|
||
- [ ] 蛹サ髯「邂。逅<EFBDA1>ォッ<EFBDAB>夂ァ大ョ、邂。逅<EFBDA1>∵<C280>蜻倡ョ。逅<EFBDA1><EFBFBD><C280>鬚晏<E9AC9A>驟?
|
||
- [ ] 闕ッ莨∫ョ。逅<EFBDA1>ォッ<EFBDAB>夐。ケ逶ョ逶第而縲∝ョ。隶。譌・蠢?
|
||
|
||
---
|
||
|
||
## 9. 蜈ウ髞ョ蜀ウ遲也<E981B2>?
|
||
|
||
### 9.1 謚譛ッ蜀ウ遲?
|
||
|
||
| 蜀ウ遲也<E981B2>?| 騾蛾。ケ | 蟒コ隶ョ | 逅<>罰 |
|
||
|--------|------|------|------|
|
||
| **User陦ィ騾画叫** | platform_schema.users vs public.users | 笨?platform_schema.users | 隨ヲ蜷域眠譫カ譫<EFBDB6>シ郡chema髫皮ヲサ貂<EFBDBB>匆 |
|
||
| **JWT蠎馴画叫** | jsonwebtoken vs jose | 笨?jsonwebtoken | 謌千<E8AC8C>遞ウ螳夲シ檎、セ蛹コ豢サ霍?|
|
||
| **蟇<><E89F87>∝刈蟇<E58888>** | bcrypt vs argon2 | 笨?bcrypt | 鬘ケ逶ョ蟾イ譛我セ晁オ厄シ郁ァ!IT讓。蝮暦シ?|
|
||
| **Token蟄伜お** | localStorage vs httpOnly Cookie | 笨?localStorage | 蜑榊錘遶ッ蛻<EFBDAF>ヲサ<EFBDA6>瑚キィ蝓溷暑螂ス |
|
||
| **隗定牡螳壻ケ画婿蠑<E5A9BF>** | 蟄礼ャヲ荳?vs Enum | 笨?Prisma Enum | 邀サ蝙句ョ牙<EFBDAE><E78999>碁∩蜈肴蕎蜀咎漠隸?|
|
||
|
||
### 9.2 荳壼苅蜀ウ遲<EFBDB3>
|
||
|
||
| 蜀ウ遲也<E981B2>?| 騾蛾。ケ | 蟒コ隶ョ | 逅<>罰 |
|
||
|--------|------|------|------|
|
||
| **遘滓姐莉」遐∝髪荳諤?* | 蜈ィ螻蜚ッ荳 vs 邀サ蝙句<E89D99>蜚ッ荳 | 笨?蜈ィ螻蜚ッ荳 | URL `/t/{code}` 髴蜈ィ螻蜚ッ荳 |
|
||
| **驛ィ髣ィ譬大アらコ?* | 蝗コ螳<EFBDBA>2螻?vs 譌<>髯仙アらコァ | 笨?譌<>髯仙アらコァ | 謾ッ謖∝、肴揩扈<E68FA9>サ<EFBFBD>楔譫<E6A594> |
|
||
| **Feature Flag邊貞コヲ** | 遘滓姐郤?vs 逕ィ謌キ郤?| 笨?遘滓姐郤?| 隨ヲ蜷亥膚荳壽ィ。蠑擾シ檎ョ。逅<EFBDA1>ョ蜊?|
|
||
|
||
---
|
||
|
||
## 10. 鬟朱勦荳取倦謌?
|
||
|
||
### 10.1 謚譛ッ鬟朱<E9AC9F>?
|
||
|
||
| 鬟朱勦 | 蠖ア蜩<EFBDB1> | 郛楢ァ」謗ェ譁ス |
|
||
|------|------|---------|
|
||
| **邇ー譛陰PI譌<49>隶、隸?* | 髴隕∝<E99A95>髱「謾ケ騾?| 貂占ソ帛シ丞刈蜈・隶、隸<EFBDA4>シ御シ伜<EFBDBC>菫晄侃謨乗─API |
|
||
| **荳、荳ェUser陦?* | 謨ー謐ョ荳堺ク閾?| 蟆ス蠢ォ扈滉ク<EFBDB8>檎シ門<EFBDBC>霑∫ァサ閼壽<E996BC>?|
|
||
| **遘滓姐謨ー謐ョ髫皮ヲサ** | 蜿ッ閭ス豕<EFBDBD>愆謨ー謐ョ | 荳・譬シ豬玖ッ<E78E96> `requireTenantAccess` 荳ュ髣エ莉?|
|
||
|
||
### 10.2 蠑蜿第倦謌?
|
||
|
||
| 謖第<E8AC96> | 髫セ蠎ヲ | 蠎泌ッケ譁ケ譯<EFBDB9> |
|
||
|------|------|---------|
|
||
| **JWT隶、隸∫ウサ扈<EFBDBB>** | 荳ュ遲<EFBDAD> | 蜿りグDJ/BYSY鬘ケ逶ョ螳樒鴫 |
|
||
| **蜩∫煙蜉ィ諤∝刈霓?* | 荳ュ遲<EFBDAD> | 菴ソ逕ィCSS蜿倬㍼+OSS蝗セ迚ⅡRL |
|
||
| **譎コ閭ス霍ッ逕ア蛻<EFBDB1>書** | 邂蜊?| 蝓コ莠屍ole+tenantType逧<65>f-else |
|
||
|
||
---
|
||
|
||
## 11. 蠑蜿題オ<E9A18C>コ宣怙豎?
|
||
|
||
### 11.1 莠コ蜉幃怙豎?
|
||
|
||
- **蜷守ォッ蠑蜿托シ<E68998>** 1莠?テ<> 10螟ゥ<E89E9F><EFBDA9>hase 0-3<>?
|
||
- **蜑咲ォッ蠑蜿托シ<E68998>** 1莠?テ<> 7螟ゥ<E89E9F><EFBDA9>hase 3-5<>?
|
||
- **豬玖ッ包シ?* 0.5莠?テ<> 3螟ゥ<E89E9F>磯寔謌先オ玖ッ包シ?
|
||
|
||
**諤サ隶。<E99AB6>?* 郤?0莠コ螟ゥ<E89E9F>育コヲ3蜻ィ<E89CBB><EFBDA8>
|
||
|
||
### 11.2 謚譛ッ萓晁オ?
|
||
|
||
**譁ー蠅柤pm蛹<6D>シ<EFBFBD>**
|
||
|
||
```json
|
||
{
|
||
"dependencies": {
|
||
"jsonwebtoken": "^9.0.0",
|
||
"bcryptjs": "^2.4.3"
|
||
},
|
||
"devDependencies": {
|
||
"@types/jsonwebtoken": "^9.0.0",
|
||
"@types/bcryptjs": "^2.4.2"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 12. 諤サ扈<EFBDBB>
|
||
|
||
### 12.1 譬ク蠢<EFBDB8>サ楢ョコ
|
||
|
||
1. **蠖灘燕邉サ扈溷ョ悟<EFBDAE>豐。譛芽ョ、隸<EFBDA4>/謗域揀邉サ扈<EFBDBB>** 笶?
|
||
2. **謨ー謐ョ蠎捺怏荳、荳ェUser陦ィ<E999A6>碁怙扈滉ク** 笞<><E7AC9E><EFBFBD>
|
||
3. **蜑咲ォッ譚<EFBDAF>剞譯<E5899E>楔隶セ隶。螳悟埋<E6829F>御ス<E5BEA1>サ<EFBFBD>クコmock** 笞<><E7AC9E><EFBFBD>
|
||
4. **遘滓姐菴鍋ウサ螳悟<E89EB3>郛コ螟ア<E89E9F>碁怙莉朱峺蠑蜿?* 笶?
|
||
|
||
### 12.2 莨伜<E88EA8>郤ァ蟒コ隶?
|
||
|
||
**P0<50><30>eek 1-2<>会シ<E4BC9A>** 謳ュ蟒コ蝓コ遑譫カ譫<EFBDB6>
|
||
- 謨ー謐ョ蠎鉄chema隶セ隶。 + 霑∫ァサ
|
||
- JWT隶、隸∫ウサ扈<EFBDBB>
|
||
- 隶、隸∽クュ髣エ莉?
|
||
- 逋サ蠖<EFBDBB>/逋サ蜃コ蜉溯<E89C89>
|
||
- 霑占是邂。逅<EFBDA1>ォッMVP<56>育ァ滓姐邂。逅?蜩∫煙驟咲スョ<EFBDBD>?
|
||
|
||
**P1<50><31>eek 3-4<>会シ<E4BC9A>** 螳悟埋譬ク蠢<EFBDB8>粥閭ス
|
||
- Feature Flag邂。逅<EFBDA1>
|
||
- 遘滓姐荳灘ア樒匳蠖暮。?
|
||
- 譛コ譫<EFBDBA>ョ。逅<EFBDA1>ォッ<EFBDAB>亥現髯「迚茨シ<E88CA8>
|
||
|
||
**P2<50><32>eek 5+<2B>会シ<E4BC9A>** 謇ゥ螻募粥閭ス
|
||
- 譛コ譫<EFBDBA>ョ。逅<EFBDA1>ォッ<EFBDAB>郁艮莨∫沿<E288AB><E6B2BF>
|
||
- 鬮倡コァ螳。隶。譌・蠢<EFBDA5>
|
||
- 譚<>剞扈<E5899E>イ貞コヲ謗ァ蛻?
|
||
|
||
### 12.3 荳倶ク豁・陦悟<E999A6>?
|
||
|
||
1. 笨?**Review譛ャ謚・蜻?*<2A>檎。ョ隶、謚譛ッ譁ケ譯?
|
||
2. 笨?**遑ョ螳壼シ蜿第賜譛?*<2A>亥サコ隶?蜻ィ蜀イ蛻コ<E89BBB><EFBDBA>
|
||
3. 笨?**蜷ッ蜉ィPhase 0**<2A>壽焚謐ョ蠎楢。ィ扈滉ク蜥郡chema隶セ隶。
|
||
4. 笨?**蟷カ陦悟星蜉ィ蜑咲ォッ逋サ蠖暮。オ隶セ隶?*<2A><>I隶セ隶。蟶茨シ<E88CA8>
|
||
|
||
---
|
||
|
||
## 9. <20><> Prompt邂。逅<EFBDA1>ウサ扈滓紛蜷<E7B49B>
|
||
|
||
### 9.1 荳コ莉荵<C280>rompt邂。逅<EFBDA1>弍霑占是邂。逅<EFBDA1>ォッ逧<EFBDAF><E980A7>鬲?
|
||
|
||
譬ケ謐ョ縲?2-騾夂畑閭ス蜉帛ア<E5B89B>03-Prompt邂。逅<EFBDA1>ウサ扈滉ク守<EFBDB8>蠎ヲ鬚<EFBDA6>ァ郁ョセ隶。譁ケ譯?md縲具シ<E585B7>**Prompt邂。逅<EFBDA1>ク肴弍蜿ッ騾牙粥閭ス<E996AD>瑚梧弍霑占是邂。逅<EFBDA1>ォッ蟄伜惠逧<E683A0><E980A7>ク蠢<EFBDB8>炊逕ア荵倶ク**縲?
|
||
|
||
#### **荳壼苅逞帷せ<E5B8B7>?*
|
||
|
||
1. **豬玖ッ慕識蠅<E8AD98>裏豕墓ィ。諡溽悄螳樊焚謐ョ**
|
||
- ASL逧<4C>枚迪ョ遲幃蛾怙隕?0遽<30>悄螳槫現蟄ヲ隶コ譁<EFBDBA>ェ瑚ッ∝㊥遑ョ邇<EFBDAE>
|
||
- DC逧<43>焚謐ョ貂<EFBDAE>エ鈴怙隕∫悄螳樒羅蜴<E7BE85>焚謐ョ鬪瑚ッ∵歓蜿匁譜譫?
|
||
- 豬玖ッ慕識蠅<E8AD98>噪蛛<E599AA>焚謐ョ螳悟<E89EB3>譌<EFBFBD>豕墓垓髴イPrompt逧<74>悄螳樣琉鬚?
|
||
|
||
2. **蠖灘燕蠑蜿第オ∫ィ区譜邇<E8AD9C>栫菴?*
|
||
- 豈乗ャ。隹<EFBDA1>紛Prompt髴隕<C280>シ壽隼莉」遐?竊?commit 竊?驛ィ鄂イ 竊?遲牙セ<E78999>AE驥榊星<E6A68A>育コヲ5蛻<35>帖<EFBFBD>?
|
||
- 荳エ蠎贋ク灘ョカ譌<EFBDB6>豕募盾荳手ー<E6898B>ッ包シ井サ紋サャ荳堺シ壼<EFBDBC>莉」遐<EFBDA3>シ?
|
||
- 譌<>豕募ソォ騾溯ソュ莉」<E88E89>御ク螟ゥ蜿ェ閭ス蟆晁ッ募<EFBDAF>谺?
|
||
|
||
3. **逕滉コァ莠区腐鬟朱勦鬮?*
|
||
- 荳譌ヲPrompt蜿醍沿<E9868D>梧園譛臥畑謌キ遶句叉蜿怜スア蜩<EFBDB1>
|
||
- 豐。譛臥<E8AD9B>蠎ヲ譛コ蛻カ<E89BBB>梧裏豕募ー剰激蝗エ鬪瑚ッ<E7919A>
|
||
|
||
#### **隗」蜀ウ譁ケ譯茨シ夂函莠ァ邇ッ蠅<EFBDAF><E8A085>蠎ヲ鬚<EFBDA6>ァ?*
|
||
|
||
隹<EFBFBD>ッ戊<EFBFBD>シ蜷ッDebug讓。蠑丞錘<EFBFBD>瑚<EFBFBD>蜉ィ霍ッ逕ア蛻ーDRAFT迚<EFBFBD>rompt<EFBFBD>碁ェ瑚ッ<EFBFBD>夊ソ<EFBFBD>錘荳髞ョ蜿大ク<EFBFBD>クコACTIVE迚医?
|
||
|
||
### 9.2 Prompt邂。逅<EFBDA1>ウサ扈滓楔譫<E6A594>
|
||
|
||
#### **9.2.1 謨ー謐ョ蠎楢ョセ隶。<E99AB6><EFBDA1>apability_schema<6D>?*
|
||
|
||
```prisma
|
||
// --- Prompt Management System ---
|
||
|
||
model PromptTemplate {
|
||
id Int @id @default(autoincrement())
|
||
code String @unique // 蜚ッ荳譬<C280>ッ<EFBFBD>: 'ASL_SCREENING_TitleAbstract'
|
||
name String // 莠コ邀サ蜿ッ隸サ蜷咲ァー
|
||
module String // 謇螻樊ィ。蝮? ASL, DC, AIA, IIT
|
||
description String?
|
||
variables Json? // 鬚<>悄蜿倬㍼: ["title", "abstract"]
|
||
|
||
versions PromptVersion[]
|
||
|
||
createdAt DateTime @default(now()) @map("created_at")
|
||
updatedAt DateTime @updatedAt @map("updated_at")
|
||
|
||
@@map("prompt_templates")
|
||
@@schema("capability_schema")
|
||
}
|
||
|
||
model PromptVersion {
|
||
id Int @id @default(autoincrement())
|
||
templateId Int @map("template_id")
|
||
version Int // 迚域悽蜿?1, 2, 3...
|
||
content String @db.Text // Prompt蜀<74>ョケ<EFBDAE>域髪謖?andlebars讓。譚ソ<E8AD9A>?
|
||
modelConfig Json? // {"temperature": 0.1, "model": "deepseek-chat"}
|
||
status PromptStatus @default(DRAFT)
|
||
changelog String? // 菫ョ謾ケ隸エ譏<EFBDB4>
|
||
createdBy String? @map("created_by") // <20>剥 螳。隶。<E99AB6>夊ー∽ソョ謾ケ逧?
|
||
|
||
template PromptTemplate @relation(fields: [templateId], references: [id])
|
||
|
||
createdAt DateTime @default(now()) @map("created_at")
|
||
|
||
@@map("prompt_versions")
|
||
@@schema("capability_schema")
|
||
|
||
@@index([templateId, status]) // 鬮倬「第衍隸「莨伜喧
|
||
}
|
||
|
||
enum PromptStatus {
|
||
DRAFT // 闕臥ィソ<EFBDA8>井サ<E4BA95>ebug讓。蠑丞庄隗<E5BA84>シ?
|
||
ACTIVE // 郤ソ荳顔函謨茨シ磯サ倩ョ、<EFBDAE><EFBDA4>
|
||
ARCHIVED // 蠖呈。」
|
||
|
||
@@schema("capability_schema")
|
||
}
|
||
```
|
||
|
||
#### **9.2.2 譁ー蠅櫁ァ定牡荳取揀髯?*
|
||
|
||
| 隗定牡 | 譚<>剞 Code | 隸エ譏<EFBDB4> |
|
||
|------|-----------|------|
|
||
| **SUPER_ADMIN** | prompt:\* | 雜<>コァ邂。逅<EFBDA1>遭諡・譛画園譛画揀髯?|
|
||
| **PROMPT_ENGINEER** <20><> | prompt:view<br>prompt:edit<br>prompt:debug<br>prompt:publish | <20>識 **譬ク蠢<EFBDB8>ァ定牡**<EFBFBD>壻ク謎ク啀rompt蟾・遞句ク域<EFBFBD>荳エ蠎贋ク灘ョカ |
|
||
| HOSPITAL_ADMIN | - | 譛コ譫<EFBDBA>ョ。逅<EFBDA1>遭譌<E981AD>Prompt譚<74>剞 |
|
||
| PHARMA_ADMIN | - | 闕ッ莨∫ョ。逅<EFBDA1>遭譌<E981AD>Prompt譚<74>剞 |
|
||
|
||
**譚<>剞隸ヲ隗」<E99A97>?*
|
||
|
||
- `prompt:view` - 譟・逵輝rompt蛻苓。ィ蜥悟紙蜿イ迚域<E8BF9A>?
|
||
- `prompt:edit` - 蛻帛サコ/菫ョ謾ケDRAFT迚域悽
|
||
- `prompt:debug` - 箝?譬ク蠢<EFBDB8>シ壼シ蜷ッ隹<EFBDAF>ッ墓ィ。蠑?
|
||
- `prompt:publish` - 蜿大クゥRAFT荳コACTIVE
|
||
|
||
#### **9.2.3 譬ク蠢<EFBDB8>橿譛ッ螳樒<E89EB3>?*
|
||
|
||
**A. PromptService<63>亥錘遶ッ<E981B6><EFBDAF>**
|
||
|
||
```typescript
|
||
// backend/src/common/capabilities/prompt/prompt.service.ts
|
||
|
||
export class PromptService {
|
||
private debugUsers = new Set<string>(); // 蜀<>ュ伜ュ伜お隹<E3818A>ッ慕畑謌キ
|
||
private activeCache = new Map<string, string>(); // ACTIVE迚域悽郛灘ュ<E78198>
|
||
|
||
/**
|
||
* 隶セ鄂ョ隹<EFBDAE>ッ墓ィ。蠑<EFBDA1>
|
||
* @requires Permission: prompt:debug
|
||
*/
|
||
async setDebugMode(userId: string, enabled: boolean) {
|
||
if (enabled) {
|
||
this.debugUsers.add(userId);
|
||
} else {
|
||
this.debugUsers.delete(userId);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 闔キ蜿鳳rompt<70>域<EFBFBD>ク蠢<EFBDB8><E8A0A2>蠎ヲ騾サ霎托シ?
|
||
*/
|
||
async get(code: string, variables: any, userId: string): Promise<string> {
|
||
// 1. 譽譟・譏ッ蜷ヲ荳コ隹<EFBDBA>ッ戊?
|
||
if (this.debugUsers.has(userId)) {
|
||
// 莨伜<E88EA8>闔キ蜿縫RAFT迚域悽
|
||
const draft = await this.getDraftVersion(code);
|
||
if (draft) {
|
||
return this.render(draft.content, variables);
|
||
}
|
||
}
|
||
|
||
// 2. 譎ョ騾夂畑謌キ謌匁裏DRAFT譌カ<E8AD8C>瑚執蜿泡CTIVE迚域悽
|
||
let active = this.activeCache.get(code);
|
||
if (!active) {
|
||
const version = await prisma.promptVersion.findFirst({
|
||
where: {
|
||
template: { code },
|
||
status: 'ACTIVE'
|
||
},
|
||
orderBy: { version: 'desc' }
|
||
});
|
||
active = version?.content || this.getFallback(code);
|
||
this.activeCache.set(code, active);
|
||
}
|
||
|
||
return this.render(active, variables);
|
||
}
|
||
|
||
/**
|
||
* Postgres LISTEN/NOTIFY 辜ュ譖エ譁?
|
||
*/
|
||
async initHotReload() {
|
||
const client = await pool.connect();
|
||
await client.query('LISTEN prompt_update');
|
||
|
||
client.on('notification', (msg) => {
|
||
console.log('[PromptService] Received update:', msg.payload);
|
||
this.activeCache.clear(); // 貂<>ゥコ郛灘ュ<E78198>
|
||
});
|
||
}
|
||
}
|
||
```
|
||
|
||
**B. API遶ッ轤ケ隶セ隶。**
|
||
|
||
| 譁ケ豕<EFBDB9> | 霍ッ蠕<EFBDAF> | 譚<>剞 | 謠剰ソー |
|
||
|------|------|------|------|
|
||
| GET | /api/admin/prompts | prompt:view | 闔キ蜿匁園譛臼rompt讓。譚ソ蛻苓。ィ |
|
||
| GET | /api/admin/prompts/:id | prompt:view | 闔キ蜿冶ッヲ諠<EFBDA6>シ亥性蜴<E680A7>彰迚域悽<E59F9F>?|
|
||
| POST | /api/admin/prompts/draft | prompt:edit | 菫晏ュ倩拷遞ソ<E9819E>育函謌先眠迚域悽<E59F9F>茎tatus=DRAFT<46>?|
|
||
| POST | /api/admin/prompts/publish | prompt:publish | 蜿大ク<E5A4A7>沿譛ャ<E8AD9B><EFBDAC>RAFT竊但CTIVE<56>瑚ァヲ蜿鮮OTIFY<46>?|
|
||
| POST | /api/admin/prompts/debug | **prompt:debug** | **蠑蜈ウ隹<EFBDB3>ッ墓ィ。蠑?* |
|
||
|
||
**C. 蜑咲ォッ蜈ィ螻隹<C280>ッ募シ蜈?*
|
||
|
||
```tsx
|
||
// frontend-v2/src/modules/admin/components/PromptDebugSwitch.tsx
|
||
|
||
export const PromptDebugSwitch = () => {
|
||
const { hasPermission } = usePermission();
|
||
const [debugMode, setDebugMode] = useState(false);
|
||
|
||
// <20>白 譚<>剞謗ァ蛻カ<E89BBB>壻サ<E5A3BB>rompt:debug譚<67>剞逕ィ謌キ蜿ッ隗<EFBDAF>
|
||
if (!hasPermission('prompt:debug')) {
|
||
return null;
|
||
}
|
||
|
||
const handleToggle = async (enabled: boolean) => {
|
||
await api.post('/api/admin/prompts/debug', { enabled });
|
||
setDebugMode(enabled);
|
||
};
|
||
|
||
return (
|
||
<>
|
||
<Switch
|
||
checked={debugMode}
|
||
onChange={handleToggle}
|
||
checkedChildren="<22>菅 隹<>ッ墓ィ。蠑<EFBDA1>"
|
||
unCheckedChildren="逕滉コァ讓。蠑<EFBDA1>"
|
||
/>
|
||
{debugMode && (
|
||
<Alert
|
||
type="warning"
|
||
message="笞<><E7AC9E><EFBFBD> 隹<>ッ墓ィ。蠑丞キイ蠑蜷ッ<E89CB7>壽お蠖灘燕豁」蝨ィ菴ソ逕ィ闕臥ィソ迚茨シ<E88CA8>RAFT<46>画署遉コ隸<EFBDBA>"
|
||
banner
|
||
closable={false}
|
||
/>
|
||
)}
|
||
</>
|
||
);
|
||
};
|
||
```
|
||
|
||
### 9.3 豸牙所逧<E68980>園譛我ク壼苅讓。蝮?
|
||
|
||
譬ケ謐ョ譁<EFBFBD>。」隨?闃ゑシ碁怙隕 ̄rompt邂。逅<EFBDA1>噪讓。蝮暦シ<E69AA6>
|
||
|
||
| 讓。蝮<EFBDA1> | 譬ク蠢<EFBDB8>惻譎ッ | Prompt螟肴揩蠎?| 莨伜<E88EA8>郤?|
|
||
|------|---------|-------------|--------|
|
||
| **ASL** | 譬<>「俶遭隕∝<E99A95>遲帙∝<C280>譁<EFBFBD>、咲ュ帙∬ッ∵紺蜷域<E89CB7>?| 箝絶ュ絶ュ絶ュ絶ュ?| P0 |
|
||
| **DC** | Tool B謠仙叙縲ゝool C貂<43>エ励∝<C280>遯∵」豬?| 箝絶ュ絶ュ絶ュ絶ュ?| P0 |
|
||
| **IIT** | 雍ィ謗ァ譽譟・縲∵э蝗セ隸<EFBDBE>悪縲∵衍隸「逕滓<E98095>?| 箝絶ュ絶ュ絶ュ絶ュ?| P1 |
|
||
| **PKB** | RAG髣ョ遲斐∵音螟<E99FB3>炊髦<E7828A>ッサ | 箝絶ュ絶ュ絶ュ<E7B5B6> | P1 |
|
||
| **AIA** | 10+譎コ閭ス菴薙∵э蝗セ隸<EFBDBE><E99AB8>?| 箝絶ュ絶ュ?| P2 |
|
||
| **RVW** | 隗<>激諤ァ譽譟?| 箝絶ュ絶ュ?| P2 |
|
||
|
||
### 9.4 Prompt邂。逅<EFBDA1>シ蜿題ョ。蛻?
|
||
|
||
#### **Phase 0: 蝓コ遑隶セ譁ス<E8AD81>?螟ゥ<E89E9F><EFBDA9>**
|
||
|
||
1. 蛻帛サコ`capability_schema`逧Пrompt逶ク蜈ウ陦?
|
||
2. 豺サ蜉<EFBDBB>`prompt:*`譚<EFBFBD>剞蛻ー`platform_schema.permissions`
|
||
3. 蛻帛サコ`PROMPT_ENGINEER`隗定牡
|
||
4. 螳樒鴫`PromptService`譬ク蠢<EFBFBD>サ霎<EFBFBD>
|
||
|
||
#### **Phase 1: 霑占是遶ッMVP<56>?螟ゥ<E89E9F><EFBDA9>**
|
||
|
||
1. 蜑咲ォッ邂。逅<EFBDA1>阜髱「<E9ABB1>亥<EFBFBD>陦ィ縲∫シ冶セ大勣縲∫沿譛ャ蜴<EFBDAC>彰<EFBFBD><E5BDB0>
|
||
2. 蜈ィ螻隹<C280>ッ募シ蜈ウ扈<EFBDB3>サ?
|
||
3. 闕臥ィソ菫晏ュ<E6998F>/蜿大ク<E5A4A7>粥閭ス
|
||
|
||
#### **Phase 2: 荳壼苅讓。蝮玲磁蜈・<E89C88>磯囂荳壼苅蠑蜿托シ<E68998>**
|
||
|
||
- ASL遲幃画ィ。蝮苓ー<E88B93>畑`promptService.get()`
|
||
- DC謨ー謐ョ貂<EFBDAE>エ玲ィ。蝮苓ー<E88B93>畑`promptService.get()`
|
||
- 蜈カ莉匁ィ。蝮玲潔髴謗・蜈・
|
||
|
||
### 9.5 螳牙<E89EB3>荳朱」取<EFBDA3>?
|
||
|
||
1. **譚<>剞髫皮ヲサ**
|
||
- 荳・譬シ譽譟・`prompt:debug`譚<EFBFBD>剞<EFBFBD>碁亟豁「譎ョ騾夂畑謌キ隸ッ蜈・隹<EFBFBD>ッ墓ィ。蠑?
|
||
- 隹<>ッ墓ィ。蠑冗憾諤∝ュ伜お蝨ィ蜀<EFBDA8>ュ假シ育畑謌キ逋サ蜃コ閾ェ蜉ィ螟ア謨茨シ<E88CA8>
|
||
|
||
2. **螳。隶。譌・蠢<EFBDA5>**
|
||
- `PromptVersion.createdBy`隶ー蠖穂ソョ謾ケ莠?
|
||
- `AdminOperationLog`隶ー蠖募書蟶<EFBFBD>。御クコ
|
||
|
||
3. **蜈懷コ墓惻蛻カ**
|
||
- 莉」遐∽クュ菫晉蕗Hardcoded Prompt菴應クコ邉サ扈溽コァ蜈懷コ?
|
||
- 謨ー謐ョ蠎捺衍隸「螟ア雍・譌カ霑泌屓鮟倩ョ、迚域悽
|
||
|
||
---
|
||
|
||
## 10. <20><> 蜿埼ヲ磯㊦郤ウ隸エ譏<EFBDB4>
|
||
|
||
### 10.1 驥<>コウ逧<EFBDB3><E980A7>髞ョ蟒コ隶?
|
||
|
||
蝓コ莠弱?2-騾夂畑閭ス蜉帛ア<E5B89B>10-譚<>剞菴鍋ウサ譴ウ逅<EFBDB3>渚鬥井ク惹ソョ豁」蟒コ隶?md縲具シ御サ・荳句サコ隶ョ蟾イ謨エ蜷亥芦譛ャ譁<EFBDAC>。」<EFBDA1><EFBDA3>
|
||
|
||
#### 笨?**1. 蠅槫刈TenantQuotaAllocation陦ィ<E999A6><EFBDA8>0<EFBFBD>?*
|
||
|
||
**蜴溷屏<E6BAB7>?* PRD譏守。ョ隕∵アょ現髯「遶ッ謖臥ァ大ョ、/荳ェ莠コ蛻<EFBDBA><E89BBB>驟埼「<E59FBC>
|
||
|
||
**螳樊命<E6A88A>?* 蟾イ蝨ィ7.1.1遶<EFBFBD>闃よ眠蠅杼tenant_quota_allocations`陦?
|
||
|
||
```prisma
|
||
model TenantQuotaAllocation {
|
||
targetType String // 'DEPARTMENT' | 'USER'
|
||
targetKey String // DepartmentID 謌?UserID
|
||
limitAmount BigInt // 蛻<><E89BBB>逧<EFBFBD>「晏コ?
|
||
usedAmount BigInt // 蟾イ菴ソ逕?
|
||
}
|
||
```
|
||
|
||
#### 笨?**2. 陦ィ蜷肴隼荳コTenantMember<65><72>1<EFBFBD>?*
|
||
|
||
**蜴溷屏<E6BAB7>?* "Member"隸ュ荵牙シコ隹<EFBDBA>サ<EFBFBD>サ<EFBFBD><EFBDBB>邉サ<E98289>?User"騾壼クク謖<EFBDB8>匳蠖戊エヲ蜿キ螳樔ス?
|
||
|
||
**螳樊命<E6A88A>?* 蟾イ蟆<EFBDB2>TenantUser`謾ケ荳コ`TenantMember`
|
||
|
||
#### 笨?**3. 螳。隶。譌・蠢怜「槫刈module蟄玲ョオ<EFBDAE><EFBDB5>1<EFBFBD>?*
|
||
|
||
**蜴溷屏<E6BAB7>?* 闕ッ莨∫ォッ髴隕∵衍隸「IIT讓。蝮嶺ク灘ア樊律蠢暦シ<E69AA6>DA 21 CFR Part 11蜷郁ァ<E98381>シ?
|
||
|
||
**螳樊命<E6A88A>?* 蟾イ蝨ィ`AdminOperationLog`陦ィ蠅槫刈`module`蟄玲ョオ蜥檎エ「蠑?
|
||
|
||
#### 笨?**4. Prompt蟾・遞句喧譚<E596A7>剞<EFBFBD><E5899E>0<EFBFBD>?*
|
||
|
||
**蜴溷屏<E6BAB7>?* 霑占是邂。逅<EFBDA1>ォッ譬ク蠢<EFBDB8>粥閭?
|
||
|
||
**螳樊命<E6A88A>?* 蟾イ蝨ィ隨?遶<>螳梧紛隶セ隶。Prompt邂。逅<EFBDA1>ウサ扈<EFBDBB>
|
||
|
||
#### 笨?**5. 雜<>コァ邂。逅<EFBDA1>遭遘榊ュ先焚謐ョ<E8AC90><EFBDAE>0<EFBFBD>?*
|
||
|
||
**蜴溷屏<E6BAB7>?* 蜷ヲ蛻咏ウサ扈滉ク顔コソ蜷取裏豕戊ソ帛<EFBDBF>蜷主<E89CB7>?
|
||
|
||
**螳樊命<E6A88A>?* 蟆<>惠Phase 0螳樒鴫Prisma Seed閼壽悽
|
||
|
||
#### 笨?**6. Phase 0蝗樊サ壽婿譯茨シ<E88CA8>0<EFBFBD>?*
|
||
|
||
**蜴溷屏<E6BAB7>?* 謨ー謐ョ螳牙<E89EB3>蝓コ譛ャ蜴溷<E89CB4>
|
||
|
||
**螳樊命<E6A88A>?* 霑∫ァサ閼壽悽蟆<E682BD><E89F86>驥榊多蜷港public.users`荳コ`public.users_backup`<60>御ソ晉<EFBDBF>?蜻?
|
||
|
||
#### 笨?**7. 遘滓姐驟咲スョAPI郛灘ュ假シ<E58187>1<EFBFBD>?*
|
||
|
||
**蜴溷屏<E6BAB7>?* 豈丈クェ逕ィ謌キ謇灘シ逋サ蠖暮。オ驛ス莨夊ー<E5A48A>畑<EFBFBD>碁ォ伜ケカ蜿台ク矩怙隕∫シ灘ュ?
|
||
|
||
**螳樊命<E6A88A>?* 蟆<>惠螳樊命譌カ豺サ蜉<EFBDBB>`Cache-Control: public, max-age=3600`
|
||
|
||
### 10.2 蜷守サュ謾ケ霑帛サコ隶ョ
|
||
|
||
莉・荳句サコ隶ョ證ゆク榊惠MVP髦カ谿オ螳樊命<EFBFBD>御ス<EFBFBD><EFBFBD>蜈・謚譛ッ蛟コ蜉。貂<EFBFBD>黒<EFBFBD>?
|
||
|
||
#### <20>売 **1. JWT螳牙<E89EB3>諤ァ<E8ABA4><EFBDA7>2<EFBFBD>?*
|
||
|
||
**蟒コ隶ョ<E99AB6>?* 菴ソ逕ィHttpOnly Cookie譖ソ莉」localStorage
|
||
|
||
**逅<>罰<EFBFBD>?* localStorage螳ケ譏灘女XSS謾サ蜃サ
|
||
|
||
**隶。蛻抵シ?* 蝨ィ闕ッ莨∫ォッ荳顔コソ蜑搾シ磯怙譖エ鬮伜ョ牙<EFBDAE>諤ァ<E8ABA4>牙ョ樊命
|
||
|
||
#### <20>売 **2. Prisma Extension螟夂ァ滓姐髫皮ヲサ<EFBDA6><EFBDBB>1<EFBFBD>?*
|
||
|
||
**蟒コ隶ョ<E99AB6>?* 蝨ィORM螻ょシコ蛻カ蜉<EFBDB6>蜈・`tenantId`霑<>サ、
|
||
|
||
**逅<>罰<EFBFBD>?* 髦イ豁「蠑蜿台ココ蜻伜ソ倩ョー蝨ィController螻ょ刈荳ュ髣エ莉?
|
||
|
||
**隶。蛻抵シ?* Phase 2蠑募<E8A091>
|
||
|
||
```typescript
|
||
const prismaExtended = prisma.$extends({
|
||
query: {
|
||
$allModels: {
|
||
async findMany({ args, query }) {
|
||
args.where = { ...args.where, tenantId: currentTenantId };
|
||
return query(args);
|
||
}
|
||
}
|
||
}
|
||
});
|
||
```
|
||
|
||
### 10.3 蜿埼ヲ郁エィ驥剰ッ<E589B0>サキ
|
||
|
||
**諤サ菴楢ッ<E6A5A2>シー<EFBDBC>?* 莨倡ァ 箝絶ュ絶ュ絶ュ絶ュ?
|
||
|
||
- 笨?9譚。蟒コ隶ョ荳ュ<E88DB3>?譚。遶句叉驥<E58F89>コウ<EFBDBA><EFBDB3>2譚。郤ウ蜈・蜷守サュ隶。蛻?
|
||
- 笨?蜿醍鴫莠<E9B4AB><E88EA0>鬚晏<E9AC9A>驟肴ィ。蝙狗噪隶セ隶。郛コ髯キ<E9ABAF><EFBDB7>ritical<61>?
|
||
- 笨?蠑コ隹<EFBDBA>コ<EFBFBD>rompt邂。逅<EFBDA1>噪譬ク蠢<EFBDB8>慍菴?
|
||
- 笨?謠仙<E8ACA0>莠<EFBFBD>ョ樒畑逧<E79591>キ・遞句ョ櫁キオ蟒コ隶ョ<E99AB6>亥屓貊壽婿譯医∫ァ榊ュ先焚謐ョ<E8AC90><EFBDAE>
|
||
|
||
**扈楢ョコ<EFBDAE>?* 譁<>。」雍ィ驥城ォ假シ碁」朱勦蜿ッ謗ァ<E8AC97>?*蜿ッ莉・蠑蟋句シ蜿?*縲?
|
||
|
||
---
|
||
|
||
**謚・蜻雁ョ梧ッ輔ょ㊥螟<E38AA5>・ス蠑蟋句シ蜿台コ<E58FB0>雛<EFBFBD><E99B9B>** <20>噫
|
||
|