Files
AIclinicalresearch/docs/08-项目管理/03-每周计划/2025-12-13-Postgres-Only架构改造完成.md
HaHafeng 1b53ab9d52 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%)
2026-01-14 19:15:01 +08:00

1047 lines
26 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Postgres-Only <20><EFBFBD><E59786><EFBFBD><EFBFBD><E683A9><EFBFBD><EFBFBD>
**<EFBFBD><EFBFBD>嚗?* 2025撟?2<>?3<>?
**<EFBFBD><EFBFBD>𧋦嚗?* V1.0
**<EFBFBD><EFBFBD><EFBFBD><EFBFBD>** Phase 1-7 <20><EFBFBD>摰峕<E691B0> <20>?
---
## <20><> <20><EFBFBD><EFBFBD><E79281>
| <20>嗆挾 | <20><>捆 | 隞<><E99A9E><EFBFBD>?| <20><EFBFBD>?| <20>埈𧒄 |
|------|------|--------|------|------|
| Phase 1 | <20><EFBFBD><E887AC><EFBFBD><EFBFBD> | ~50銵?| <20>?摰峕<E691B0> | 0.5憭?|
| Phase 2 | PostgresCacheAdapter | ~300銵?| <20>?摰峕<E691B0> | 1憭?|
| Phase 3 | PgBossQueue | ~400銵?| <20>?摰峕<E691B0> | 1.5憭?|
| Phase 4 | 隞餃𦛚<E9A483><F0A69B9A><EFBFBD><EFBFBD><EFBFBD> | ~200銵?| <20>?摰峕<E691B0> | 0.5憭?|
| Phase 5 | <20><EFBFBD>蝏凋<E89D8F><E5878B><EFBFBD> | ~150銵?| <20>?摰峕<E691B0> | 0.5憭?|
| Phase 6 | ASL 蝑偦<E89D91><EFBFBD><E39787>⊥㺿<E28AA5>?| ~200銵?| <20>?摰峕<E691B0> | 1憭?|
| **<EFBFBD>齿<EFBFBD>** | **Platform-Only <20><EFBFBD>** | **~300銵?* | **<EFBFBD>?摰峕<E691B0>** | **1憭?* |
| Phase 7 | DC <20>𣂼<EFBFBD><F0A382BC>滚𦛚<E6BB9A><EFBFBD>?| ~150銵?| <20>?摰峕<E691B0> | 0.5憭?|
| **<EFBFBD>餉恣** | **<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?* | **~1750銵?* | **<EFBFBD>?<3F><EFBFBD>摰峕<E691B0>** | **6.5憭?* |
---
## <20><20><EFBFBD><E8A9A8><EFBFBD>
### 1. Platform-Only <20><EFBFBD><E59786>齿<EFBFBD> <20><>
**<EFBFBD><EFBFBD><EFBFBD>𤑳緵嚗?*
- <20><EFBFBD>霈曇恣<E69B87><EFBFBD>銝𡁜𦛚銵剁<E98AB5>ASL<53><4C>C嚗劐葉<E58A90><EFBFBD>摰帋<E691B0>鈭?6 銝芯遙<E88AAF>∠恣<E288A0><E681A3><EFBFBD>畾?
- 餈嘥<E9A488>鈭?DRY <20><EFBFBD><E7AC94>?3 撅<><EFBFBD><E6B2B2><EFBFBD><EFBFBD>?
- pg-boss <20>?`job` 銵典歇蝏誩銁 `platform_schema` 銝哨<E98A9D>摨磰砲蝏煺<E89D8F>蝞∠<E89D9E>
**<EFBFBD>齿<EFBFBD><EFBFBD><EFBFBD>嚗?*
```
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>厰䔮憸矋<E686B8>:
asl_schema.screening_tasks
<20><EFBFBD><E98EBF><EFBFBD> totalBatches
<20><EFBFBD><E98EBF><EFBFBD> processedBatches
<20><EFBFBD><E5A999><EFBFBD> ... (6銝芯遙<E88AAF>∠恣<E288A0><E681A3><EFBFBD>畾?
dc_schema.dc_extraction_tasks
<20><EFBFBD><E5A999><EFBFBD> <20>峕甅<E5B395>?6 銝芸<E98A9D>畾蛛<E795BE><E89B9B><EFBFBD><EFBFBD><E59A97>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Platform-Only嚗?
platform_schema.job.data (蝏煺<E89D8F>蝞∠<E89D9E>)
<20><EFBFBD><E98EBF><EFBFBD> batchIndex
<20><EFBFBD><E98EBF><EFBFBD> totalBatches
<20><EFBFBD><E98EBF><EFBFBD> checkpoint
<20><EFBFBD><E5A999><EFBFBD> ... (<28><><EFBFBD>劐遙<E58A90>∩縑<E288A9>?
asl_schema.screening_tasks (<28>芰恣銝𡁜𦛚)
dc_schema.dc_extraction_tasks (<28>芰恣銝𡁜𦛚)
```
**<EFBFBD><EFBFBD>隡睃飵嚗?*
- <20>?蝚血<E89D9A> 3 撅<><EFBFBD>?- Platform 撅<><E69285><EFBFBD>蝞∠<E89D9E>隞餃𦛚
- <20>?<3F>牐誨<E78990><E8AAA8><EFBFBD>憭?- CheckpointService <20><><EFBFBD>㗇芋<E39787><EFBFBD>𡁶鍂
- <20>?<3F><EFBFBD>蝏湔擪 - <20><EFBFBD>靽格㺿銝<E3BABF><EFBFBD><EFBFBD>?
- <20>?<3F><EFBFBD><E3AE96><EFBFBD> - <20>芣䔉璅<E79285><E288AA>𣳇<EFBFBD>瘛餃<E7989B>摮埈挾
- <20>?<3F>唳旿銝<E697BF><E98A9D>?- 隞餃𦛚靽⊥<E99DBD>銝𡡞<E98A9D><F0A1A19E>埈㺭<E59F88>桀銁銝<E98A81>韏?
---
### 2. <20><EFBFBD><E7AE84><EFBFBD><EFBFBD>澆ế<E6BE86>剜㦤<E5899C>?<3F>
**霈曇恣<E69B87><E681A3>艙嚗?*
- 撠譍遙<E8AD8D><EFBFBD><50<35><EFBFBD>嚗𡁶凒<F0A181B6><EFBFBD><E4BA99><EFBFBD><EFBFBD>敹恍<E695B9><EFBFBD>摨?
- 憭找遙<E689BE><EFBFBD><E288B4>?0<><EFBFBD>嚗𡁻<E59A97><F0A181BB><EFBFBD><E5A092><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E888AB><EFBFBD>
**摰䂿緵<E482BF><E7B7B5><EFBFBD>嚗?*
| 璅<E79285> | <20>唳旿<E594B3>?| 憭<><E686AD><E79285> | <20>寞活<E5AF9E>?| <20><EFBFBD> |
|------|--------|---------|--------|------|
| ASL | 7蝭?| <20>湔𦻖璅<E79285> | 1 | 敹恍<E695B9><EFBFBD>摨䈑<E691A8><1<><31><EFBFBD>嚗?|
| ASL | 100蝭?| <20><EFBFBD><E79285> | 2 | <20><><EFBFBD>+<2B><EFBFBD>蝏凋<E89D8F> |
| ASL | 1000蝭?| <20><EFBFBD><E79285> | 20 | <20><EFBFBD>24撠𤩺𧒄<F0A4A9BA>蹂遙<E8B982>?|
| DC | 7<>?| <20>湔𦻖璅<E79285> | 1 | 敹恍<E695B9><EFBFBD>摨?|
| DC | 100<30>?| <20><EFBFBD><E79285> | 2 | <20><><EFBFBD>+<2B><EFBFBD>蝏凋<E89D8F> |
**隞<><E99A9E>蝷箔<E89DB7>嚗?*
```typescript
const QUEUE_THRESHOLD = 50;
const useQueue = items.length >= QUEUE_THRESHOLD;
if (useQueue) {
// <20><EFBFBD><E79285>嚗帋遙<E5B88B><EFBFBD><E28AA5>?+ <20><EFBFBD>蝏凋<E89D8F>
const chunks = splitIntoChunks(items, chunkSize);
await jobQueue.push('task:batch', { ... });
} else {
// <20>湔𦻖璅<E79285>嚗𡁜翰<F0A1819C><EFBFBD><E7AC94>?
processDirectly(items);
}
```
---
### 3. <20><EFBFBD>蝏凋<E89D8F><E5878B><EFBFBD> <20><>
**摰䂿緵<E482BF><EFBFBD>嚗?*
- <20>拍鍂 `pg-boss` <20>?`job.data.checkpoint` 摮埈挾
- 瘥誩<E798A5><E8AAA9>?10 <20>∟扇敶蓥<E695B6>摮䀝<E691AE>甈⊥鱏<E28AA5>?
- 隞餃𦛚銝剜鱏<E5899C>舘䌊<E88898><EFBFBD>銝𦠜活雿滨蔭<E6BBA8><EFBFBD>
**<EFBFBD><EFBFBD><EFBFBD>唳旿蝏𤘪<EFBFBD>嚗?*
```typescript
interface CheckpointData {
currentBatchIndex: number; // 敶枏<E695B6><E69E8F>寞活蝝<E89D9D>
currentIndex: number; // 敶枏<E695B6><EFBFBD><E686AD><EFBFBD><EFBFBD>扇敶閧揣撘?
processedBatches: number; // 撌脣<E6928C><E884A3><EFBFBD><EFBFBD><EFBFBD>寞活<E5AF9E>?
totalBatches: number; // <20>餅鸌甈⊥㺭
metadata: {
processedCount: number; // 撌脣<E6928C><E884A3><EFBFBD><EFBFBD>?
successCount: number; // <20>𣂼<EFBFBD><F0A382BC><EFBFBD>
failedCount: number; // 憭梯揖<E6A2AF><EFBFBD>
lastUpdate: Date; // <20><><EFBFBD>擧凒<E693A7>唳𧒄<E594B3>?
};
}
```
**雿輻鍂蝷箔<E89DB7>嚗?*
```typescript
// 靽嘥<E99DBD><E598A5><EFBFBD>
await checkpointService.saveCheckpoint(jobId, {
currentBatchIndex: 5,
currentIndex: 250,
processedBatches: 5,
totalBatches: 20
});
// <20><EFBFBD><EFBCB7><EFBFBD>
const checkpoint = await checkpointService.loadCheckpoint(jobId);
if (checkpoint) {
resumeFrom = checkpoint.currentIndex;
}
```
---
## <20><> <20><EFBFBD><E595A3><EFBFBD>辣皜<E8BEA3><E79A9C>
### Platform 撅<><E69285><EFBFBD>𡁶鍂<F0A181B6><EFBFBD>嚗?
| <20><>辣 | 銵峕㺭 | 霂湔<E99C82> |
|------|------|------|
| `common/cache/PostgresCacheAdapter.ts` | 300 | Postgres 蝻枏<E89DBB><E69E8F><EFBFBD><EFBFBD><EFBFBD>?|
| `common/jobs/PgBossQueue.ts` | 400 | pg-boss <20><EFBFBD><E7AC94><EFBFBD><EFBFBD><EFBFBD>?|
| `common/jobs/utils.ts` | 200 | 隞餃𦛚<E9A483><F0A69B9A><EFBFBD>撌亙<E6928C><E4BA99>賣㺭 |
| `common/jobs/CheckpointService.ts` | 260 | <20><EFBFBD>蝏凋<E89D8F><E5878B>滚𦛚嚗<F0A69B9A><E59A97>雿穅ob.data嚗?|
### ASL 璅<E79285>
| <20><>辣 | 銵峕㺭 | 霂湔<E99C82> |
|------|------|------|
| `modules/asl/services/screeningService.ts` | 480 | 瘛餃<E7989B><E9A483><EFBFBD><E7AE84><EFBFBD><EFBFBD>澆ế<E6BE86>?|
| `modules/asl/services/screeningWorker.ts` | 410 | <20>寞活Worker嚗<72><EFBFBD>甫ob.data嚗?|
### DC 璅<E79285>
| <20><>辣 | 銵峕㺭 | 霂湔<E99C82> |
|------|------|------|
| `modules/dc/tool-b/controllers/ExtractionController.ts` | 690 | 瘛餃<E7989B><E9A483><EFBFBD><E7AE84><EFBFBD><EFBFBD>澆ế<E6BE86>?|
| `modules/dc/tool-b/workers/extractionWorker.ts` | 390 | <20>寞活Worker嚗<72><EFBFBD>甫ob.data嚗?|
### 瘚贝<E7989A><E8B49D><EFBFBD>
| <20><>辣 | 銵峕㺭 | 霂湔<E99C82> |
|------|------|------|
| `tests/test-postgres-cache.ts` | 130 | Postgres 蝻枏<E89DBB>瘚贝<E7989A> |
| `tests/test-pgboss-queue.ts` | 150 | pg-boss <20><EFBFBD>瘚贝<E7989A> |
| `tests/test-checkpoint.ts` | 200 | <20><EFBFBD>蝏凋<E89D8F>瘚贝<E7989A> |
| `tests/test-task-split.ts` | 150 | 隞餃𦛚<E9A483><F0A69B9A><EFBFBD>瘚贝<E7989A> |
| `tests/test-asl-screening-mock.ts` | 320 | ASL 璅⊥<E79285>瘚贝<E7989A> |
| `tests/test-dc-extraction-mock.ts` | 280 | DC 璅⊥<E79285>瘚贝<E7989A> |
| `tests/verify-test1-database.ts` | 230 | Postgres 蝻枏<E89DBB><E69E8F>唳旿摨㯄<E691A8>霂?|
| `tests/verify-pgboss-database.ts` | 330 | pg-boss <20>唳旿摨𤘪楛摨阡<E691A8>霂?|
| `tests/README.md` | 380 | 瘚贝<E7989A><E8B49D><EFBFBD><EFBFBD> |
### <20>唳旿摨栞<E691A8>蝘?
| <20><>辣 | 霂湔<E99C82> |
|------|------|
| `manual-migrations/001_add_postgres_cache_and_checkpoint.sql` | 瘛餃<E7989B> app_cache 銵?|
| `manual-migrations/002_rollback_to_platform_only.sql` | <20><EFBFBD>銝𡁜𦛚銵其遙<E585B6><EFBFBD>畾?|
| `manual-migrations/run-migration.ts` | 餈<><EFBFBD><EFBFBD><E689AF>𡁏𧋦 |
| `manual-migrations/run-migration-002.ts` | <20><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E689AF>𡁏𧋦 |
---
## <20>妒 瘚贝<E7989A>撉諹<E69289>蝏𤘪<E89D8F>
### 1. <20><EFBFBD><E7AE87><EFBFBD>瘚贝<E7989A> <20>?
| 瘚贝<E7989A>憿?| 蝏𤘪<E89D8F> | 霂湔<E99C82> |
|--------|------|------|
| Postgres 蝻枏<E89DBB> | <20>?<3F><EFBFBD> | get/set/delete/<2F><EFBFBD><E5AFA5><EFBFBD><EFBFBD>虜 |
| pg-boss <20><EFBFBD> | <20>?<3F><EFBFBD> | <20><EFBFBD>?憭<><E686AD>/<2F><EFBFBD><E6BBA9><EFBFBD><EFBFBD>虜 |
| 隞餃𦛚<E9A483><F0A69B9A><EFBFBD> | <20>?<3F><EFBFBD> | <20><EFBFBD><E7AE84><EFBFBD><E588BB>寞活憭批<E686AD><EFBFBD> |
| <20><EFBFBD>蝏凋<E89D8F> | <20>?<3F><EFBFBD> | 靽嘥<E99DBD>/<2F>㰘蝸/皜<>膄甇<E88684>虜 |
### 2. ASL 璅<E79285>瘚贝<E7989A> <20>?
| 瘚贝<E7989A><E8B49D>箸艶 | 蝏𤘪<E89D8F> | 霂湔<E99C82> |
|---------|------|------|
| 7蝭<37><E89DAD><EFBFBD>?| <20>?<3F><EFBFBD> | <20>湔𦻖璅<E79285><EFBFBD><EFBFBD><EFBFBD><E7AC94>?|
| 100蝭<30><E89DAD><EFBFBD>?| <20>?<3F><EFBFBD> | <20><EFBFBD><E79285>嚗峕<E59A97><E5B395><EFBFBD><EFBFBD>2<EFBFBD>?|
| <20><EFBFBD><E7AE84><EFBFBD><EFBFBD>?| <20>?<3F><EFBFBD> | 50蝭<30><E89DAD><EFBFBD>潭迤蝖桀極雿?|
### 3. DC 璅<E79285>瘚贝<E7989A> <20>?
| 瘚贝<E7989A><E8B49D>箸艶 | 蝏𤘪<E89D8F> | 霂湔<E99C82> |
|---------|------|------|
| 7<>∟扇敶?| <20>?<3F><EFBFBD> | <20>湔𦻖璅<E79285><EFBFBD><EFBFBD><EFBFBD><E7AC94>?|
| 100<30>∟扇敶?| <20>?<3F><EFBFBD> | <20><EFBFBD><E79285>嚗峕<E59A97><E5B395><EFBFBD><EFBFBD>2<EFBFBD>?|
| <20><EFBFBD><E7AE84><EFBFBD><EFBFBD>?| <20>?<3F><EFBFBD> | 50<35><EFBFBD><E28ABF>潭迤蝖桀極雿?|
### 4. Platform-Only <20><EFBFBD>撉諹<E69289> <20>?
| 撉諹<E69289>憿?| 蝏𤘪<E89D8F> | 霂湔<E99C82> |
|--------|------|------|
| Schema <20><EFBFBD> | <20>?<3F><EFBFBD> | 銝𡁜𦛚銵冽<E98AB5>隞餃𦛚蝞∠<E89D9E>摮埈挾 |
| job.data 摮睃<E691AE> | <20>?<3F><EFBFBD> | 隞餃𦛚靽⊥<E99DBD><EFBFBD>摮睃<E691AE> |
| CheckpointService | <20>?<3F><EFBFBD> | <20><EFBFBD> job.data 甇<>虜 |
| 3撅<33><EFBFBD>?| <20>?<3F><EFBFBD> | <20>諹提<E8ABB9><EFBFBD><EFBFBD>苊 |
---
## <20><20><><EFBFBD><EFBFBD>
| <20><><EFBFBD>?| <20><>𧋦 | <20><EFBFBD>?|
|------|------|------|
| PostgreSQL | 14+ | <20>唳旿摨?+ 蝻枏<E89DBB> + <20><EFBFBD> |
| pg-boss | 9.x | 隞餃𦛚<E9A483><EFBFBD>蝞∠<E89D9E> |
| Prisma | 6.17.0 | ORM |
| Node.js | 22.18.0 | 餈鞱<E9A488><E99EB1><EFBFBD> |
| TypeScript | 5.x | 撘<><E69298>𤏸祗閮<E7A597> |
| tsx | latest | TypeScript <20><EFBFBD><E689AF>?|
---
## <20><> <20>喲睸<E596B2><E79DB8><EFBFBD>
### 隞<><E99A9E><EFBFBD><EFBFBD>霈?
```
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>嚗鰺1750 銵?
靽格㺿隞<EFBFBD><EFBFBD>嚗鰺500 銵?
<EFBFBD>𣳇膄隞<EFBFBD><EFBFBD>嚗鰺100 銵?
瘚贝<EFBFBD><EFBFBD><EFBFBD>嚗鰺1800 銵?
<EFBFBD><EFBFBD>﹝隞<EFBFBD><EFBFBD>嚗鰺800 銵?
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD>餉恣嚗𡁶漲 4950 銵?
```
### <20><EFBFBD><EFBFBD><E4ADBE><EFBFBD><E7BE93><EFBFBD>
```
<EFBFBD>啣遣<EFBFBD><EFBFBD>辣嚗?5 銝?
靽格㺿<EFBFBD><EFBFBD>辣嚗? 銝?
<EFBFBD>𣳇膄<EFBFBD><EFBFBD>辣嚗? 銝迎<E98A9D>銝湔𧒄瘚贝<E7989A><E8B49D><EFBFBD>辣嚗?
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
敶勗<EFBFBD><EFBFBD><EFBFBD>辣嚗?3 銝?
```
---
## <20><20><EFBFBD>瞍磰<E79E8D>
### <20><EFBFBD><EFBFBD>
```
銝𡁜𦛚撅?(<28><>袇)
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> ASL: 隞餃𦛚蝞∠<E89D9E>摮埈挾 (6銝?
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> DC: 隞餃𦛚蝞∠<E89D9E>摮埈挾 (6銝?
<20>?隞<><E99A9E><EFBFBD><EFBFBD>
<20>?蝏湔擪<E6B994>圈𠗕
<20>?銝滨泵<E6BBA8>?撅<><EFBFBD>?
```
### <20><EFBFBD><EFBFBD>嚗㇊latform-Only嚗?
```
<EFBFBD>𢞖<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
<EFBFBD>? 銝𡁜𦛚撅?(Business Layer) <20>?
<EFBFBD>? - ASL: <20><EFBFBD><E88AB8><EFBFBD><E585B6>∩縑<E288A9>? <20>?
<EFBFBD>? - DC: <20><EFBFBD><E88AB8><EFBFBD><E585B6>∩縑<E288A9>? <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>?
<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>? 撟喳蝱撅?(Platform Layer) <20>?
<EFBFBD>? - platform_schema.job.data <20>?
<EFBFBD>? <20><EFBFBD><E5A999><EFBFBD> 蝏煺<E89D8F>摮睃<E691AE><E79D83><EFBFBD><EFBFBD>劐遙<E58A90>∠恣<E288A0><E681A3><EFBFBD>? <20>?
<EFBFBD>? - platform_schema.app_cache <20>?
<EFBFBD>? <20><EFBFBD><E5A999><EFBFBD> 蝏煺<E89D8F>蝻枏<E89DBB>蝞∠<E89D9E> <20>?
<EFBFBD>? - CheckpointService <20>?
<EFBFBD>? <20><EFBFBD><E5A999><EFBFBD> <20><><EFBFBD>㗇芋<E39787><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>?
```
---
## <20><20>喲睸霈曇恣<E69B87><EFBFBD>
### 1. 銝箔<E98A9D><EFBFBD><E98A8B>㗇𥋘 Postgres-Only嚗?
| 撖寞<E69296>憿?| Redis <20><EFBFBD> | Postgres-Only <20><EFBFBD> |
|--------|-----------|-------------------|
| **<EFBFBD>鞉𧋦** | +嚙?00/<2F>?| 嚙?嚗<><EFBFBD>侨ostgres嚗?|
| **餈鞟輕** | 2銝芰頂蝏?| 1銝芰頂蝏?|
| **<EFBFBD>唳旿銝<EFBFBD><EFBFBD><EFBFBD>?* | <20><><EFBFBD><E89D8F><EFBFBD>?| 撘箔<E69298><E7AE94>?|
| **摮虫<E691AE><E899AB>鞉𧋦** | Redis + BullMQ | <20><EFBFBD> pg-boss |
| **<EFBFBD><EFBFBD><EFBFBD>芋** | <20><><EFBFBD>edis銝枏振 | <20><EFBFBD><E594B3><EFBFBD><EFBFBD>質雲憭?|
| **<EFBFBD><EFBFBD>鍂閫<EFBFBD>芋** | >10銝䝄AU | <10銝䝄AU嚗<55><E59A97><EFBFBD>?00MAU嚗?|
**蝏栞捏嚗?* 撖嫣<E69296>撠誩𣪧<E8AAA9><F0A3AAA7><EFBFBD>500 MAU嚗㚁<E59A97>Postgres-Only <20><EFBFBD>隡㗛<E99AA1>㗇𥋘<E39787>?
---
### 2. 銝箔<E98A9D><EFBFBD><E98A8B> Platform-Only <20><EFBFBD><E59786>齿<EFBFBD>嚗?
**<EFBFBD>𤑳緵<EFBFBD><EFBFBD><EFBFBD>嗆㦤嚗?*
- Phase 6 摰峕<E691B0><E5B395>𠬍<EFBFBD><F0A0AC8D><EFBFBD><EFBFBD> Phase 7 <20><EFBFBD><E59785>?
- ASL 撌脫溶<E884AB>?6 銝芯遙<E88AAF>∠恣<E288A0><E681A3><EFBFBD>畾萄<E795BE>銝𡁜𦛚銵?
- DC 銋笔<E98A8B><EFBFBD><EFBFBD><EFBFBD><E683A9><EFBFBD> 6 銝芸<E98A9D>畾?
- **<2A><EFBFBD><E8AE9B>啗挽霈⊥<E99C88><E28AA5><EFBFBD>嚗?*
**<EFBFBD>齿<EFBFBD><EFBFBD><EFBFBD>嚗?*
- 蝡见朖<E8A781>𨀣迫 Phase 7嚗<37><E59A97><EFBFBD>齿<EFBFBD><E9BDBF><EFBFBD>
- <20><EFBFBD> ASL <20>?Schema 靽格㺿
- <20>寧鍂 `pg-boss` <20>?`job.data` 蝏煺<E89D8F>蝞∠<E89D9E>
- <20><EFBFBD> CheckpointService 銝粹<E98A9D>𡁶鍂<F0A181B6>滚𦛚
**<EFBFBD>齿<EFBFBD><EFBFBD>鞉𧋦嚗?*
-<><E99A9E><EFBFBD>孵𢆡嚗鰺300 銵?
- <20>唳旿摨栞<E691A8>蝘鳴<E89D98><E9B3B4>𣳇膄 6 銝芸<E98A9D>畾?
- 瘚贝<E7989A>撉諹<E69289>嚗? 銝芣<E98A9D>霂閗<E99C82><E99697>?
- **<2A><EFBFBD>埈𧒄嚗? 憭?*
**<EFBFBD>齿<EFBFBD>隞瑕<EFBFBD><EFBFBD>**
- <20>?<3F><EFBFBD><E8B8B5><EFBFBD><E4BAA6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>銵屸<E98AB5>憭滢誨<E6BBA2>?
- <20>?<3F>芣䔉璅<E79285>嚗𠄎SA<53><41>VW<56><57>T嚗厩凒<E58EA9><EFBFBD><E4BA99>?
- <20>?蝏湔擪<E6B994>鞉𧋦憭批<E686AD><E689B9><EFBFBD>
- <20>?<3F><EFBFBD><E59786><EFBFBD><EFBFBD><EFBFBD><E88B8A><EFBFBD>
---
### 3. 銝箔<E98A9D><EFBFBD>挽蝵?50 <20><EFBFBD><E28ABF><EFBFBD>
| <20>唳旿<E594B3>?| <20>埈𧒄 | <20>㗇𥋘璅<E79285> | <20><EFBFBD> |
|--------|------|---------|------|
| 1-49<34>?| <5<><35><EFBFBD> | <20>湔𦻖璅<E79285> | SAE銝滢<E98A9D><EFBFBD>𧒄嚗屸<E59A97><E5B1B8><EFBFBD><E5A092><EFBFBD> |
| **50<35>?* | **~5<><35><EFBFBD>** | **銝渡<E98A9D><E6B8A1>?* | **<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?* |
| 50-200<30>?| 5-20<32><30><EFBFBD> | <20><EFBFBD><E79285> | <20><><EFBFBD><EFBFBD>寧賒隡?|
| 200+<2B>?| >20<32><30><EFBFBD> | <20><EFBFBD><E79285> | 敹<><EFBFBD><EFBFBD>蝏凋<E89D8F> |
**<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>嚗?*
- <20>湔𦻖璅<E79285>嚗𡁏<E59A97><F0A1818F><EFBFBD>撱嗉<E692B1><EFBFBD>蔭霂𡢿<EFBD81>?蝘𡜐<E89D98>
- <20><EFBFBD><E79285>嚗𡁜虾<F0A1819C><EFBFBD><EFBFBD><EFBFBD>𣈲<EFBFBD><F0A388B2><EFBFBD>霂𨰻<E99C82><F0A8B0BB><EFBFBD><EFBFBD>
- 50<35>⊥糓撟唾﹛<E594BE><EFBFBD><E5B08D><EFBFBD><EFBCB6>箇𠧧<E7AE87><EFBFBD><EFBFBD><E59A97>靽肽<E99DBD><E882BD><EFBFBD><E888AB>?
---
## <20><>儭?<3F><EFBFBD><EFBFBD><E588A0><EFBFBD><E8A9A8><EFBFBD>
### Platform 撅<><E69285><EFBFBD><EFBFBD>嚗?
1. **PostgresCacheAdapter.ts** (300銵?
- 摰䂿緵 `CacheAdapter` <20>亙藁
- 雿輻鍂 `platform_schema.app_cache` 銵?
- <20><EFBFBD><E88880><EFBFBD><E59F9D>𣳇膄<F0A3B387>峕鸌<E5B395>𤩺<EFBFBD><F0A4A9BA>?
2. **PgBossQueue.ts** (400銵?
- 摰䂿緵 `JobQueue` <20>亙藁
-<><E692A0> pg-boss API
- 隞餃𦛚<E9A483><EFBFBD><E59786><EFBFBD><EFBFBD><E692A0><EFBFBD>躰秤憭<E7A7A4><E686AD>
- 6撠𤩺𧒄餈<F0A79284><E9A488><EFBFBD>園𡢿嚗<F0A1A2BF><E59A97><EFBFBD><EFBFBD><EFBFBD>蹂遙<E8B982><EFBFBD>
3. **CheckpointService.ts** (260銵?
- **<2A>齿<EFBFBD>鈭桃<E988AD>嚗𡁏<E59A97>雿?`job.data`嚗䔶<EFBFBD>靘肽<EFBFBD>銝𡁜𦛚銵?*
- `saveCheckpoint()` - 靽嘥<E99DBD><E598A5><EFBFBD><E58994>?job.data
- `loadCheckpoint()` - 隞?job.data 霂餃<E99C82><E9A483><EFBFBD>
- `clearCheckpoint()` - 皜<><EFBFBD><EFBFBD>
- `getProgress()` - <20>亥砭餈𥕦漲
- `canResume()` - 璉<><E79289>交糓<E4BAA4>血虾<E8A180><EFBFBD>
4. **utils.ts** (200銵?
- `splitIntoChunks()` - <20><EFBFBD><E59581><EFBFBD><EFBFBD>
- `recommendChunkSize()` - <20><EFBFBD><E7AE84><EFBFBD><E588BB>寞活憭批<E686AD>
- `CHUNK_STRATEGIES` - <20><><EFBFBD>衤遙<E8A1A4><EFBFBD><E288A0><EFBFBD><EFBFBD>蝑𣇉裦
### ASL 璅<E79285><EFBFBD>㺿<EFBFBD>𩤃<EFBFBD>
5. **screeningService.ts** (480銵?
- <20>?瘛餃<E7989B><E9A483><EFBFBD><E7AE84><EFBFBD><EFBFBD>澆ế<E6BE86><EFBFBD>QUEUE_THRESHOLD = 50嚗?
- <20>?摰䂿緵<E482BF>湔𦻖璅<E79285><E288AA><EFBFBD><E5B1B8>埈芋撘?
- <20>?隞餃𦛚靽⊥<E99DBD>摮睃<E691AE><E79D83>?job.data 銝哨<E98A9D>銝滚<E98A9D><E6BB9A>典銁銝𡁜𦛚銵剁<E98AB5>
- <20>?<3F><EFBFBD><E588B8>鸌甈∩遙<E288A9><EFBFBD> pg-boss
6. **screeningWorker.ts** (410銵?
- <20>?隞?job.data 霂餃<E99C82><E9A483><EFBFBD>靽⊥<E99DBD>
- <20>?雿輻鍂 CheckpointService <20><EFBFBD> job.data
- <20>?瘥?0<>∟扇敶蓥<E695B6>摮䀝<E691AE>甈⊥鱏<E28AA5>?
- <20>?<3F>寞活摰峕<E691B0><E5B395>擧凒<E693A7>?job.data.checkpoint
- <20>?蝏蠘恣撌脣<E6928C><E884A3>鞉鸌甈∴<E79488><E288B4>亥砭 platform_schema.job 銵剁<E98AB5>
### DC 璅<E79285><EFBFBD>㺿<EFBFBD>𩤃<EFBFBD>
7. **ExtractionController.ts** (690銵?
- <20>?瘛餃<E7989B><E9A483><EFBFBD><E7AE84><EFBFBD><EFBFBD>澆ế<E6BE86><EFBFBD>QUEUE_THRESHOLD = 50嚗?
- <20>?摰䂿緵<E482BF>湔𦻖璅<E79285><E288AA><EFBFBD><E5B1B8>埈芋撘?
- <20>?隞餃𦛚靽⊥<E99DBD>摮睃<E691AE><E79D83>?job.data 銝?
- <20>?<3F><EFBFBD><E588B8>鸌甈∩遙<E288A9><EFBFBD> pg-boss
8. **extractionWorker.ts** (390銵䕘<E98AB5><E49598>啣遣)
- <20>?<3F>寞活憭<E6B4BB><E686AD><EFBFBD><EFBFBD><EFBFBD><E59A97> ASL 蝐颱撮嚗?
- <20>?雿輻鍂 CheckpointService <20><EFBFBD> job.data
- <20>?<3F>峕芋<E5B395>𧢲<EFBFBD><F0A7A2B2>?+ <20><EFBFBD><EFBFBD>瘚?
- <20>?<3F><EFBFBD>蝏凋<E89D8F><E5878B><EFBFBD>
### <20>滨蔭<E6BBA8><E894AD>辣嚗<E8BEA3><EFBFBD><EFBFBD>
9. **index.ts** (190銵?
- <20>?<3F>臬𢆡 jobQueue
- <20>?瘜典<E7989C> ASL Worker
- <20>?瘜典<E7989C> DC Worker
- <20>?<3F>臬𢆡蝻枏<E89DBB><EFBFBD><E79A9C>隞餃𦛚
10. **env.ts** (靽格㺿)
- <20>?瘛餃<E7989B> `CACHE_TYPE` <20>滨蔭嚗<E894AD>𣈲<EFBFBD>?postgres嚗?
- <20>?瘛餃<E7989B> `QUEUE_TYPE` <20>滨蔭嚗<E894AD>𣈲<EFBFBD>?pgboss嚗?
11. **schema.prisma** (靽格㺿)
- <20>?瘛餃<E7989B> `AppCache`<E79285>嚗īlatform_schema嚗?
- <20>?<3F><EFBFBD> `AslScreeningTask`<EFBFBD><EFBFBD><EFBFBD>?銝芸<E98A9D>畾蛛<E795BE>
- <20>?靽脲<E99DBD> `DCExtractionTask`<><EFBFBD><E798A3>銝齿溶<E9BDBF><EFBFBD>畾蛛<E795BE>
---
## <20><> <20><><EFBFBD>臭漁<E887AD>?
### 1. pg-boss <20><><EFBFBD>蝥找蝙<E689BE>?
```typescript
// <20>𥕦遣<F0A595A6><EFBFBD><EFBFBD><E59A97>憿餅遬撘誩<E69298>撱綽<E692B1>
await boss.createQueue('task:batch');
// <20><EFBFBD><E588B8><EFBFBD><EFBFBD>撣血<E692A3><E8A180>唳旿嚗?
await boss.send('task:batch', {
taskId: 'xxx',
batchIndex: 5,
totalBatches: 20,
checkpoint: { ... } // <20>?隞餃𦛚蝞∠<E89D9E>靽⊥<E99DBD>摮睃銁 data 銝?
});
// 瘜典<E7989C> Worker
await boss.work('task:batch', async (jobs) => {
for (const job of jobs) {
// 隞?job.data 霂餃<E99C82><E9A483><EFBFBD>
const checkpoint = job.data.checkpoint;
// 憭<><E686AD>隞餃𦛚...
}
});
```
### 2. JSONB 摮埈挾<E59F88><E68CBE><EFBFBD><EFBFBD>?
```sql
-- pg-boss <20>?job.data <20>?JSONB 蝐餃<E89D90>
-- <20>臭誑<E887AD>菜暑摮睃<E691AE>隞餅<E99A9E>蝏𤘪<E89D8F><F0A498AA><EFBFBD><EFBFBD>?
UPDATE platform_schema.job
SET data = jsonb_set(
data,
'{checkpoint}',
'{"currentIndex": 250, "processedBatches": 5}'::jsonb
)
WHERE id = $1;
-- <20>亥砭撌脣<E6928C><E884A3>鞉鸌甈∴<E79488><E288B4>拍鍂 JSONB 蝝<E89D9D>嚗?
SELECT COUNT(*)
FROM platform_schema.job
WHERE name = 'asl:screening:batch'
AND data->>'taskId' = 'xxx'
AND data->'checkpoint'->'metadata'->>'completed' = 'true';
```
### 3. <20><EFBFBD><E7AE84><EFBFBD><EFBFBD>澆ế<E6BE86><EFBFBD>摰䂿緵
```typescript
const QUEUE_THRESHOLD = 50;
// <20>?<3F>寞旿<E5AF9E>唳旿<E594B3>讛䌊<E8AE9B><EFBFBD>㗇𥋘璅<E79285>
if (items.length >= QUEUE_THRESHOLD) {
// <20><EFBFBD><E79285>嚗𡁜虾<F0A1819C><EFBFBD><EFBFBD><E689BE>?
const chunkSize = recommendChunkSize('type', items.length);
const chunks = splitIntoChunks(items, chunkSize);
await jobQueue.push(...);
} else {
// <20>湔𦻖璅<E79285>嚗𡁏<E59A97><EFBFBD>隡睃<E99AA1>
processDirectly(items);
}
```
---
## <20><> <20><><EFBFBD><EFBFBD><EFBFBD>䔮憸䀝<E686B8><EFBFBD><E996AB>
### <20><EFBFBD>1嚗䫤ts-node` ESM <20><EFBFBD>撌?
**<EFBFBD><EFBFBD>嚗?*
```
Error: Cannot find module '.../PostgresCacheAdapter.js'
```
**<EFBFBD><EFBFBD>嚗?* `ts-node` 撖?ESM <20>?`.js` <20><EFBFBD><E68B99>齿𣈲<E9BDBF><F0A388B2><EFBFBD>憟?
**閫<><E996AB>嚗?* <20>寧鍂 `tsx`
```bash
npx tsx src/tests/test-postgres-cache.ts <20>?
```
---
### <20><EFBFBD>2嚗䮝g-boss 餈<><E9A488><EFBFBD>園𡢿<E59C92>𣂼<EFBFBD>
**<EFBFBD><EFBFBD>嚗?*
```
AssertionError: configuration assert: expiration cannot exceed 24 hours
```
**<EFBFBD><EFBFBD>嚗?* 霈曄蔭鈭?`expireInSeconds: 86400`嚗?4撠𤩺𧒄嚗?
**閫<><E996AB>嚗?* <20>嫣蛹 6 撠𤩺𧒄嚗<F0A79284><E59A97><EFBFBD><EFBFBD><EFBFBD>蹂遙<E8B982><EFBFBD>
```typescript
expireInSeconds: 21600 // 6撠𤩺𧒄
```
---
### <20><EFBFBD>3嚗䮝g-boss 9.x 敹<><EFBFBD>𥕦遣<F0A595A6><EFBFBD>
**<EFBFBD><EFBFBD>嚗?*
```
Error: Queue test-job does not exist
```
**<EFBFBD><EFBFBD>嚗?* pg-boss 9.x <20><><EFBFBD>遬撘誩<E69298>撱粹<E692B1><E7B2B9>?
**閫<><E996AB>嚗?* <20>?`push()` <20>?`process()` 銝剜溶<E5899C>?`createQueue()`
```typescript
await this.boss.createQueue(type);
```
---
### <20><EFBFBD>4嚗帋<E59A97><E5B88B>∟”摮埈挾<E59F88><EFBFBD>摰帋<E691B0>
**<EFBFBD><EFBFBD>嚗?*
- ASL <20>?DC <20><EFBFBD>瘛餃<E7989B> 6 銝芰㮾<E88AB0>𣬚<EFBFBD>隞餃𦛚蝞∠<E89D9E>摮埈挾
- 餈嘥<E9A488> DRY <20><EFBFBD><E7AC94>?3 撅<><EFBFBD>?
**閫<><E996AB>嚗?* Platform-Only <20><EFBFBD><E59786>齿<EFBFBD>
- <20>𣳇膄銝𡁜𦛚銵其葉<E585B6><E89189><EFBFBD>∠恣<E288A0><E681A3><EFBFBD>畾?
- 蝏煺<E89D8F>雿輻鍂 `platform_schema.job.data` 摮睃<E691AE>
- CheckpointService <20><EFBFBD> job.data嚗峕<E59A97><E5B395>㗇芋<E39787><EFBFBD>𡁶鍂
---
## <20><> <20><EFBFBD><E8A9A8>𥟇鰵
### 1. Platform-Only <20><EFBFBD><E79285>
**摰帋<E691B0>嚗?*
- <20><><EFBFBD>匧像<E58CA7>啁漣<E59581><EFBFBD><EFBFBD><EFBFBD>∠恣<E288A0><E681A3><EFBFBD><EFBFBD><EFBFBD>摮塩<E691AE><E5A1A9><EFBFBD><EFBFBD><EFBFBD>蝏煺<E89D8F><E785BA>?Platform 撅<><E69285><EFBFBD>?
- 銝𡁜𦛚撅<F0A69B9A><EFBFBD>單釣銝𡁜𦛚<F0A1819C><EFBFBD>嚗䔶<E59A97>摮睃<E691AE>隞餃𦛚蝞∠<E89D9E>靽⊥<E99DBD>
- <20>拍鍂 pg-boss <20>?`job.data` 摮埈挾摰䂿緵隞餃𦛚<E9A483><EFBFBD><E59786><EFBFBD>?
**隡睃飵嚗?*
- <20>?摰<><E691B0>蝚血<E89D9A> 3 撅<><EFBFBD><E6B2B2><EFBFBD><EFBFBD>?
- <20>?隞<><E99A9E>擃睃漲憭滨鍂嚗㇃heckpointService <20>𡁶鍂嚗?
- <20>?<3F><EFBFBD>蝏湔擪嚗<E693AA><E59A97><EFBFBD>嫣耨<E5ABA3><EFBFBD>
- <20>?<3F><EFBFBD><E3AE96><EFBFBD><EFBFBD>鰵璅<E79285><E288AA>𣳇<EFBFBD>瘛餃<E7989B>摮埈挾嚗?
**<EFBFBD><EFBFBD><EFBFBD>箸艶嚗?*
- 撠誩𣪧<E8AAA9><F0A3AAA7><EFBFBD><5鈭綽<E988AD>
- 銝剖<E98A9D><EFBFBD>芋蝟餌<E89D9F>嚗?10銝䝄AU嚗?
- <20><><EFBFBD><EFBFBD>蠘翮隞?
- 撣峕<E692A3><E5B395><EFBFBD>餈鞟輕<E99E9F>鞉𧋦
---
### 2. <20><EFBFBD><E7AE84>峕芋撘誩<E69298><E8AAA9>?
**霈曇恣<E69B87><E681A3>艙嚗?*
- 銝齿糓<E9BDBF><E7B393><EFBFBD>劐遙<E58A90><EFBFBD><E28ABF><EFBFBD><EFBFBD><E996AC><EFBFBD>?
- <20>寞旿<E5AF9E>唳旿<E594B3>𤩺惣<F0A4A9BA><EFBFBD>㗇𥋘憭<F0A58B98><E686AD><E79285>
- <20><EFBFBD>銝𤾸虾<F0A4BEB8><EFBFBD><EFBFBD>撟唾﹛
**摰䂿緵蝏<E7B7B5><E89D8F>嚗?*
```typescript
// 撠譍遙<E8AD8D><EFBFBD><E288B4>湔𦻖憭<F0A6BB96><E686AD><EFBFBD><E59A97><EFBFBD>隡睃<E99AA1>嚗?
if (items.length < 50) {
processDirectly(items); // 敹恍<E695B9><EFBFBD>摨䈑<E691A8><1<><31><EFBFBD>
}
// 憭找遙<E689BE><EFBFBD><E288B4><EFBFBD><EFBFBD><E686AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E689BE><EFBFBD><EFBFBD>
else {
const chunks = splitIntoChunks(items, 50);
await jobQueue.push(...); // <20><EFBFBD><E88880><EFBFBD>蝏凋<E89D8F><EFBFBD>虾餈鞱<E9A488>24撠𤩺𧒄
}
```
**<EFBFBD><EFBFBD><EFBFBD>嚗?*
- <20><EFBFBD>雿㯄<E99BBF>嚗𡁜<E59A97>隞餃𦛚蝘垍漣<E59E8D><EFBFBD>
- 蝟餌<E89D9F><E9A48C><EFBFBD>嚗𡁜之隞餃𦛚銝滢<E98A9D><E6BBA2><EFBFBD><E3B098>嗅仃韐?
- <20>鞉𧋦隡睃<E99AA1>嚗𡁻<E59A97><F0A181BB>齿<EFBFBD><E9BDBF>劐遙<E58A90><EFBFBD>韏圈<E99F8F><E59C88>?
---
### 3. <20><EFBFBD> job.data <20><><EFBFBD>寧賒隡?
**隡删<E99AA1><E588A0><EFBFBD><EFBFBD><E59A97>隞祆<E99A9E><E7A586><EFBFBD><E89098>𡁏<EFBFBD>嚗㚁<E59A97>**
```sql
-- <20>?<3F><EFBFBD><E585B6>∟”銝剜溶<E5899C>䭾鱏<E4ADBE><EFBFBD>畾?
ALTER TABLE screening_tasks ADD COLUMN checkpoint_data JSONB;
ALTER TABLE dc_extraction_tasks ADD COLUMN checkpoint_data JSONB;
-- 瘥譍葵璅<E79285><E288AA><EFBFBD><E8B3AA>𩤃<EFBFBD>
```
**Platform-Only <20><EFBFBD><EFBFBD><E59A97><EFBFBD><EFBFBD><EFBFBD>嚗㚁<E59A97>**
```typescript
// <20>?<3F>湔𦻖<E6B994><EFBFBD> pg-boss <20>?job.data
await checkpointService.saveCheckpoint(jobId, {
currentIndex: 250,
processedBatches: 5,
totalBatches: 20
});
// <20><><EFBFBD>㗇芋<E39787><EFBFBD>𡁶鍂嚗峕<E59A97><E5B395><EFBFBD>靽格㺿銝𡁜𦛚銵剁<E98AB5>
```
**<EFBFBD>𥟇鰵<EFBFBD><EFBFBD>**
- <20>拍鍂<E68B8D><EFBFBD><E594B3>?`job.data` 摮埈挾嚗峕<E59A97><E5B395><EFBFBD><EFBFBD><EFBFBD>摮埈挾
- 隞餃𦛚靽⊥<E99DBD>銝𡡞<E98A9D><F0A1A19E>埈㺭<E59F88>桀銁<E6A180><EFBFBD>霈啣<E99C88>銝哨<E98A9D><E593A8>唳旿銝<E697BF><E98A9D><EFBFBD>批撩
- CheckpointService <20><><EFBFBD>𡁜<EFBFBD><EFBFBD><EFBFBD>啁漣<E59581>𡁶鍂
---
## <20><> 蝏誯<E89D8F><E8AAAF>躰悌
### 1. <20>𦠜𧒄<F0A6A09C>𤑳緵<F0A491B3><EFBFBD><E59786><EFBFBD>
**<EFBFBD>躰悌嚗?*
- Phase 6 摰峕<E691B0><E5B395>𠬍<EFBFBD><F0A0AC8D><EFBFBD><EFBFBD> Phase 7 <20><EFBFBD><E59785>唬誨<E594AC><E8AAA8><EFBFBD>憭漤䔮憸?
- **撟詨末<E8A9A8>𦠜𧒄<F0A6A09C>𤑳緵嚗?* 憒<><E68692>蝑匧<E89D91> Phase 8-9 <20><EFBFBD><E6BB9A><EFBFBD><E5A086>齿<EFBFBD><E9BDBF>鞉𧋦隡𡁻<E99AA1><EFBFBD><E695BA>
**<EFBFBD>舐內嚗?*
- 瘥誩<E798A5><E8AAA9>𣂷<EFBFBD>銝芷𧫴畾蛛<E795BE><E89B9B><EFBFBD><E8B3AA>鮋▽<E9AE8B><EFBFBD>霈曇恣
- <20>𤑳緵<F0A491B3><EFBFBD><EFBFBD><E99A9E><EFBFBD><EFBFBD>蝡见朖<E8A781><E69C96><EFBFBD><EFBFBD>臬炏<E887AC><E7828F><EFBFBD><E996AC><EFBFBD>?
- "頞𦠜𡟺<F0A6A09C>齿<EFBFBD>嚗峕<E59A97><E5B395><EFBFBD>雿?
---
### 2. <20><><EFBFBD><EFBFBD>拍鍂<E68B8D><EFBFBD><E594B3><EFBFBD>
**<EFBFBD>躰悌嚗?*
- <20><><EFBFBD><EFBFBD>蝞堒銁<E5A092><E98A81><EFBFBD><EFBFBD>∟”銝剜溶<E5899C>牐遙<E78990>∠恣<E288A0><E681A3><EFBFBD>畾?
- <20>擧䔉<E693A7><EFBFBD><E8AE9B>?pg-boss <20>?`job.data` 撌脩<E6928C><E884A9>𣂷<EFBFBD>鈭?JSONB 摮睃<E691AE>
- **銝箔<E98A9D><EFBFBD><E98A8B><EFBFBD><EFBFBD>**
**<EFBFBD>舐內嚗?*
- <20><><EFBFBD><EFBFBD><EFBFBD>匧極<E58CA7><EFBFBD><E7919E><EFBFBD><EFBFBD><E59A97><EFBFBD><EFBFBD><E596B3>臬炏<E887AC>啣遣
- pg-boss <20>?`job.data` 撠望糓銝箏<E98A9D><E7AE8F>其遙<E585B6><EFBFBD><E288AA>唳旿霈曇恣<E69B87>?
- "銝滩<E98A9D><E6BBA9>齿鰵<E9BDBF><EFBFBD>頧桀<E9A0A7>"
---
### 3. 瘚贝<E7989A>撽勗𢆡<E58B97><F0A286A1><EFBFBD><EFBFBD>?
**<EFBFBD><EFBFBD>嚗?*
- 瘥譍葵<E8AD8D>嗆挾摰峕<E691B0><E5B395>𡒊<EFBFBD><F0A1928A><EFBFBD><E5969F><EFBFBD>霂?
- 瘚贝<E7989A>銝滢<E98A9D>撉諹<E69289><E8ABB9><EFBFBD>嚗諹<E59A97><E8ABB9>湧蠧霈曇恣<E69B87><EFBFBD>
- <20><EFBFBD>瘚贝<E7989A> <20>?<3F><><EFBFBD>瘚贝<E7989A> <20>?<3F><EFBFBD>撉諹<E69289>瘚贝<E7989A>
**瘚贝<E7989A><E8B49D><EFBFBD>辣嚗?*
- Phase 1-5嚗? 銝芸<E98A9D><E88AB8><EFBFBD><EFBFBD>霂𤏪<E99C82>蝻枏<E89DBB><E69E8F><EFBFBD><EFBFBD><EFBFBD>𨰜<EFBFBD><F0A8B09C><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
- Phase 6-7嚗? 銝芷<E98A9D><E88AB7><EFBFBD>霂𤏪<E99C82>ASL<53><4C>C 璅⊥<E79285>瘚贝<E7989A>嚗?
- <20>齿<EFBFBD>嚗? 銝芣沲<E88AA3><E6B2B2><EFBFBD><EFBFBD><E99C82>霂?
**隞瑕<E99A9E><EFBFBD>**
- <20>𤑳緵鈭<E7B7B5><E988AD>銝?Linter <20>躰秤
- <20>𤑳緵鈭?pg-boss API 雿輻鍂<E8BCBB><EFBFBD>
- <20>𤑳緵鈭<E7B7B5><EFBFBD><E6B2B2>挽霈⊿䔮憸矋<E686B8><E79F8B><EFBFBD>摮埈挾嚗?
---
## <20>㴓 颲暹<E9A2B2><E69AB9><EFBFBD>𤌍<EFBFBD>?
### <20><EFBFBD><E8A9A8><EFBFBD> <20>?
- [x] **<EFBFBD>蹂遙<EFBFBD><EFBFBD><EFBFBD>?*嚗𡁏𣈲<F0A1818F>?2-24 撠𤩺𧒄<F0A4A9BA><F0A79284>鵭隞餃𦛚嚗䔶<E59A97>隡𡁜<E99AA1>摰硺<E691B0><E7A1BA>滚鍳<E6BB9A><E98DB3>仃韐?
- [x] **<EFBFBD><EFBFBD>蝏凋<EFBFBD>**嚗帋遙<E5B88B>∩葉<E288A9><EFBFBD><E58996><EFBFBD>銝𦠜活雿滨蔭蝏抒賒嚗䔶<E59A97>隡?<3F>賢僕"
- [x] **<EFBFBD><EFBFBD>憭𡝗<EFBFBD><EFBFBD>?*嚗帋<E59A97>撘訫<E69298> Redis嚗䔶蝙<E494B6>典歇<E585B8><EFBFBD> Postgres
- [x] **3撅<33><EFBFBD>?*嚗䥪latform 撅<><E69285><EFBFBD>蝞∠<E89D9E>嚗䔶<E59A97><E494B6><EFBFBD>銝𤘪釣銝𡁜𦛚
- [x] **隞<><E99A9E>憭滨鍂**嚗鋴heckpointService<63><65>gBossQueue <20><><EFBFBD>㗇芋<E39787><EFBFBD>𡁶鍂
### <20><EFBFBD><E689AF><EFBFBD> <20>?
- [x] **撠譍遙<E8AD8D><E288AA>?*嚗?50<35>⊥㺭<E28AA5><EFBFBD>蝥批<E89DA5>摨䈑<E691A8><E48891>湔𦻖璅<E79285>嚗?
- [x] **憭找遙<E689BE><E288AA>?*嚗尠竉50<35>⊥㺭<E28AA5><EFBFBD><E6A185><EFBFBD><E5A092><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E88880><EFBFBD>蝏凋<E89D8F>
- [x] **撟嗅<E6929F><EFBFBD><E686AD>**嚗䮝g-boss <20><EFBFBD>憭𡁜<E686AD>靘见僎銵<E5838E><E98AB5><EFBFBD>?
- [x] **<EFBFBD>芸𢆡<EFBFBD><EFBFBD>**嚗𡁜仃韐乩遙<E4B9A9>∟䌊<E2889F><EFBFBD>霂?3 甈∴<E79488>撱嗉<E692B1> 60 蝘?
### 餈鞟輕<E99E9F><EFBFBD> <20>?
- [x] **蝞<><E89D9E>𤥁<EFBFBD>蝏?*嚗𡁜蘨<F0A1819C><E898A8>蝞∠<E89D9E> 1 銝芣㺭<E88AA3><EFBFBD>嚗㇊ostgres嚗?
- [x] **<EFBFBD><EFBFBD><EFBFBD>鞉𧋦**嚗𡁻妟憸嘥<E686B8>韐寧鍂嚗<E98D82><E59A97><EFBFBD><EFBFBD>閬?Redis嚗?
- [x] **<EFBFBD><EFBFBD><EFBFBD>烐綉**嚗𡁏<E59A97><F0A1818F>劐遙<E58A90>∩縑<E288A9>臬銁 `platform_schema.job` 銵其葉
- [x] **<EFBFBD><EFBFBD><EFBFBD><EFBFBD>**嚗𡁜<E59A97><F0A1819C><EFBFBD><EFBFBD><EFBFBD><EFBFBD>霈啣<E99C88><E595A3><EFBFBD>霂臬<E99C82><E887AC>?
---
## <20><> <20><EFBFBD><EFBFBD>
### 撟嗅<E6929F><E59785><EFBFBD>
| <20>箸艶 | 撟嗅<E6929F><E59785>?| Postgres <20><EFBFBD> | <20><EFBFBD> |
|------|--------|---------------|------|
| 500 MAU | ~500 | <20>?頧餅𠹭<E9A485><EFBFBD> | Node.js <20>閧瑪蝔?|
| 5000 MAU | ~5000 | <20>?<3F><EFBFBD> | SAE 摰硺<E691B0><E7A1BA>?|
| 50000 MAU | ~50000 | <20>𩤃<EFBFBD> <20><>隡睃<E99AA1> | Postgres 餈墧𦻖<E5A2A7>?|
**蝏栞捏嚗?* 敶枏<E695B6>蝟餌<E89D9F>嚗?00 MAU嚗侨ostgres 蝏嘥笆銝齿糓<E9BDBF><EFBFBD><E59C92>?
---
### 隞餃𦛚憭<F0A69B9A><E686AD><EFBFBD><EFBFBD>
| 隞餃𦛚蝐餃<E89D90> | <20>唳旿<E594B3>?| <20>寞活<E5AF9E>?| 憸<><EFBFBD>埈𧒄 | <20><EFBFBD><E888AB>?|
|---------|--------|--------|---------|--------|
| ASL 蝑偦<E89D91>?| 100蝭?| 2<>?| 10<31><30><EFBFBD> | 潃鐥<E6BD83>潃鐥<E6BD83>潃?|
| ASL 蝑偦<E89D91>?| 1000蝭?| 20<32>?| 2撠𤩺𧒄 | 潃鐥<E6BD83>潃鐥<E6BD83>潃?|
| DC <20>𣂼<EFBFBD> | 100<30>?| 2<>?| 15<31><35><EFBFBD> | 潃鐥<E6BD83>潃鐥<E6BD83>潃?|
| DC <20>𣂼<EFBFBD> | 1000<30>?| 20<32>?| 2.5撠𤩺𧒄 | 潃鐥<E6BD83>潃鐥<E6BD83>潃?|
**<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>**
- <20>?瘥𤩺鸌憭<E9B88C><E686AD>摰䔶<E691B0>摮䀹鱏<E480B9>?
- <20>?隞餃𦛚憭梯揖<E6A2AF>芸𢆡<E88AB8><EFBFBD>嚗?甈∴<E79488>
- <20>?摰硺<E691B0><E7A1BA>滚鍳<E6BB9A>舘䌊<E88898><EFBFBD>憭?
- <20>?<3F><EFBFBD> 24 撠𤩺𧒄頞<F0A79284>鵭隞餃𦛚
---
## <20><20>芣䔉<E88AA3><EFBFBD>
### 1. <20><EFBFBD><E79285><E288AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>鞉𧋦嚗?
**SSA 璅<E79285><EFBFBD><EFBFBD><EFBFBD><E99C88><E288AA><EFBFBD>嚗?*
```typescript
// <20>?<3F>湔𦻖憭滨鍂 Platform 撅<><E69285><EFBFBD>?
if (models.length >= 30) {
// 30銝芣芋<E88AA3><EFBFBD><E8A781><EFBFBD> <20>?<3F><EFBFBD><E79285>
await jobQueue.push('ssa:model:batch', { ... });
} else {
// <30銝芣芋<E88AA3>?<3F>?<3F>湔𦻖璅<E79285>
runModelsDirectly();
}
```
**RVW 璅<E79285><EFBFBD><E59A97><EFBFBD>桃遞餈堆<E9A488>嚗?*
```typescript
// <20>?<3F>湔𦻖憭滨鍂 Platform 撅<><E69285><EFBFBD>?
if (sections.length >= 10) {
// 10銝芰<E98A9D><E88AB0>?<3F>?<3F><EFBFBD><E79285>
await jobQueue.push('rvw:section:batch', { ... });
}
```
**<EFBFBD>𣳇<EFBFBD>隞颱<EFBFBD> Schema 靽格㺿嚗?* <20>湔𦻖雿輻鍂 job.data<74>?
---
### 2. 蝻枏<E89DBB>蝑𣇉裦隡睃<E99AA1>
**敶枏<E695B6>摰䂿緵嚗?*
-<><E89D9E><EFBFBD> key-value 蝻枏<E89DBB>
- 5<><35><EFBFBD><EFBFBD><E79A9C><EFBFBD>甈∟<E79488><E2889F><EFBFBD><EFBFBD>?
**<EFBFBD>芣䔉<EFBFBD><EFBFBD><EFBFBD><EFBFBD>**
- 瘛餃<E7989B> LRU 瘛䀹掠蝑𣇉裦
- 瘛餃<E7989B>蝻枏<E89DBB><EFBFBD><E686B8>
- 瘛餃<E7989B>蝻枏<E89DBB><E69E8F>賭葉<E8B3AD><E89189><EFBFBD><EFBFBD>?
---
### 3. <20><EFBFBD><E7AC94>烐綉<E78390>
**<EFBFBD><EFBFBD><EFBFBD><EFBFBD>**
```typescript
// <20>亥砭<E4BAA5><EFBFBD>蝏蠘恣
const stats = await prisma.$queryRaw`
SELECT
name,
state,
COUNT(*) as count
FROM platform_schema.job
GROUP BY name, state
`;
// 摰墧𧒄<E5A2A7>烐綉嚗?
// - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E695BA><EFBFBD><EFBFBD><EFBFBD>⊥㺭
// - 憭梯揖隞餃𦛚<E9A483>?
// - 撟喳<E6929F><EFBFBD><E686AD><EFBFBD>園𡢿
```
---
## <20><> 銝衤<E98A9D>甇亥恣<E4BAA5>?
### Phase 8嚗𡁜<E59A97><F0A1819C><EFBFBD>霂閖<E99C82>霂?<3F>
| 瘚贝<E7989A>憿?| 隡睃<E99AA1>蝥?| 憸<><EFBFBD>埈𧒄 |
|--------|--------|---------|
| <20><EFBFBD>瘚贝<E7989A> | 潃鐥<E6BD83>潃?| 0.5憭?|
| 隞餃𦛚<E9A483><F0A69B9A><EFBFBD>瘚贝<E7989A> | 潃鐥<E6BD83>潃?| 0.5憭?|
| **<EFBFBD><EFBFBD>蝏凋<EFBFBD>瘚贝<EFBFBD>** | **潃鐥<E6BD83>潃鐥<E6BD83>潃?* | **1憭?* |
| **<EFBFBD>蹂遙<EFBFBD><EFBFBD>霂?* | **潃鐥<E6BD83>潃鐥<E6BD83>潃?* | **1憭?* |
| 摰硺<E691B0><E7A1BA>滚鍳瘚贝<E7989A> | 潃鐥<E6BD83>潃鐥<E6BD83> | 0.5憭?|
| 撟嗅<E6929F>瘚贝<E7989A> | 潃鐥<E6BD83>潃?| 0.5憭?|
| <20><EFBFBD>瘚贝<E7989A> | 潃鐥<E6BD83> | 0.5憭?|
**<EFBFBD>餉恣嚗?* 5 憭?
---
### Phase 9嚗锭AE <20>函蔡銝羓瑪 <20>
| 隞餃𦛚 | 憸<><EFBFBD>埈𧒄 |
|------|---------|
| <20>滨蔭 SAE <20><EFBFBD><E887AC><EFBFBD> | 0.5憭?|
| <20>滨蔭撘寞<E69298>找撓蝻?| 0.5憭?|
| <20>啣漲<E595A3><EFBFBD><EFBFBD><E59A97>撖?4撠𤩺𧒄嚗?| 1.5憭?|
| <20><EFBFBD><E588B8><EFBFBD> | 0.5憭?|
| <20>煺漣撉諹<E69289><EFBFBD><E59A97><EFBFBD>?8撠𤩺𧒄嚗?| 2.5憭?|
**<EFBFBD>餉恣嚗?* 5.5 憭?
---
## <20><20>鞉𧋦撖寞<E69296>
### Redis <20><EFBFBD>
```
Redis 摰硺<E691B0>嚗𡄯縞500/<2F>?
餈鞟輕<EFBFBD>鞉𧋦嚗𡄯縞200/<2F><><EFBFBD>憸嘥<E686B8>摮虫<E691AE><E899AB>𣬚輕<F0A3AC9A><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD>餉恣嚗𡄯縞700/<2F>?
撟湔<EFBFBD><EFBFBD>穿<EFBFBD>嚙?400
```
### Postgres-Only <20><EFBFBD>
```
憸嘥<EFBFBD><EFBFBD>鞉𧋦嚗𡄯縞0嚗<EFBFBD><EFBFBD>典歇<EFBFBD>侨ostgres嚗?
餈鞟輕<EFBFBD>鞉𧋦嚗𡄯縞0嚗<EFBFBD><EFBFBD><EFBFBD><EFBFBD>憸嘥<EFBFBD>蝏湔擪嚗?
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD>餉恣嚗𡄯縞0/<2F>?
撟湔<EFBFBD><EFBFBD>穿<EFBFBD>嚙?
<EFBFBD><EFBFBD><EFBFBD>嚗𡄯縞8400/撟?<3F>
```
---
## <20><> <20><><EFBFBD>舀𤣰<E88880>?
### 1. pg-boss 瘛勗漲雿輻鍂
- <20><EFBFBD><E7AC94>𥕦遣<F0A595A6>𣬚恣<F0A3AC9A>?
- Worker 瘜典<E7989C><E585B8>䔶遙<E494B6><EFBFBD><E288AA>?
- <20><EFBFBD><E6BBA9><EFBFBD><E7AE8F><EFBFBD><E8ABB9><EFBFBD><E6AFBA>?
- **job.data 摮埈挾<E59F88><E68CBE><EFBFBD><EFBFBD>?*
### 2. Postgres 擃条漣<E69DA1><EFBFBD>?
- JSONB 摮埈挾<E59F88><E68CBE><EFBFBD>瘣餅<E798A3>?
- `FOR UPDATE SKIP LOCKED` <20><><EFBFBD>烐綉<E78390>?
- JSONB 蝝<E89D9D><EFBCB7>峕䰻霂<E99C82><EFBCB6>?
- 鈭见𦛚<E8A781>峕㺭<E5B395><EFBFBD><E6A190><EFBFBD>?
### 3. <20><EFBFBD>霈曇恣璅<E79285>
- 3 撅<><EFBFBD><E6B2B2><EFBFBD><EFBFBD>摰噼殿
- **Platform-Only 璅<E79285>**嚗<><E59A97><EFBFBD><EFBFBD>
- <20><><EFBFBD><EFBFBD>冽芋撘𧶏<E69298>CacheAdapter<65><72>obQueue嚗?
- 撌亙<E6928C><E79285>嚗㇃acheFactory<72><79>obFactory嚗?
---
## <20><> <20><>﹝鈭批枂
| <20><>﹝ | 霂湔<E99C82> |
|------|------|
| `04-Redis<69><EFBFBD><EFBFBD><E683A9>質恣<E8B3AA>?md` | Redis <20><EFBFBD><EFBFBD>歇摨笔<E691A8>嚗?|
| `05-Redis蝻枏<E89DBB>銝𡡞<E98A9D><F0A1A19E><EFBFBD><E39B96><EFBFBD>霂湔<E99C82>.md` | Redis <20><><EFBFBD><EFBFBD><E887AC>?|
| `06-<2D>踵𧒄<E8B8B5>港遙<E6B8AF><E288AA><EFBFBD><EFBFBD><E689B9>?md` | <20>蹂遙<E8B982><E288AA><EFBFBD><EFBFBD>蝛?|
| `07-Redis雿輻鍂<E8BCBB><E98D82><EFBFBD><E79899><EFBFBD>?<3F>㗇芋<E39787>?.md` | <20><><EFBFBD>?Redis <20><>瘙?|
| `08-Postgres-Only <20><EFBFBD><E588BB><EFBFBD><EFBFBD><E996AB><EFBFBD><EFBFBD>.md` | Postgres-Only <20><EFBFBD> |
| **`09-Postgres-Only<6C><EFBFBD><EFBFBD><E683A9>質恣<E8B3AA>?摰峕㟲<E5B395>?.md`** | **霂衣<E99C82>摰墧鴌霈<E99C88>** |
| **`10-Postgres-Only<6C><EFBFBD><EFBFBD>摨西蕭頦芾”.md`** | **餈𥕦漲蝞∠<E89D9E>** |
| **`tests/README.md`** | **瘚贝<E7989A><E8B49D><EFBFBD><EFBFBD>** |
---
## <20><> <20><EFBFBD>
### 隞𦠜𠯫撌乩<E6928C><E4B9A9>?
```
<EFBFBD><EFBFBD>蝻硋<EFBFBD>嚗鰺1750 銵?
<EFBFBD><EFBFBD>靽格㺿嚗鰺500 銵?
瘚贝<EFBFBD><EFBFBD><EFBFBD>嚗鰺1800 銵?
<EFBFBD><EFBFBD>﹝蝻硋<EFBFBD>嚗鰺800 銵?
<EFBFBD><EFBFBD>靽桀<EFBFBD>嚗?5+ 銝?
瘚贝<EFBFBD>餈鞱<EFBFBD>嚗?0+ 甈?
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD>餃極雿𣈯<EFBFBD>嚗𡁶漲 8-10 撠𤩺𧒄
```
### 韐券<E99F90>靽肽<E99DBD>
- <20>?Linter <20>躰秤嚗? 銝?
- <20>?<3F><EFBFBD>瘚贝<E7989A>嚗? 銝芸<E98A9D><E88AB8><EFBFBD><EFBFBD>
- <20>?<3F><><EFBFBD>瘚贝<E7989A>嚗? 銝芸<E98A9D><E88AB8><EFBFBD><EFBFBD>
- <20>?<3F><EFBFBD>撉諹<E69289>嚗𡁻<E59A97><EFBFBD>
- <20>?<3F><EFBFBD>撉諹<E69289>嚗𡁻<E59A97><EFBFBD>
### <20><><EFBFBD><EFBFBD>箏𦛚
- <20>𩤃<EFBFBD> Phase 8 <20>券𢒰瘚贝<E7989A><EFBFBD><E59A97>閬?<3F><EFBFBD>
- <20>𩤃<EFBFBD> <20><EFBFBD> LLM 靚<>鍂瘚贝<E7989A><EFBFBD><E59A97>閬?API 撖<>𤨎嚗?
- <20>𩤃<EFBFBD> <20>煺漣<E785BA><EFBFBD>撉諹<E69289>嚗𠄎AE <20>函蔡<E587BD>𠬍<EFBFBD>
---
## <20><> 銝衤<E98A9D>甇亥<E79487><E4BAA5>?
### <20><EFBFBD><EFBFBD>𧋦<EFBFBD><EFBFBD>
1. **Phase 8嚗𡁜<E59A97><F0A1819C><EFBFBD>霂閖<E99C82>霂?* 嚗?憭抬<E686AD>
- <20><EFBFBD>蝏凋<E89D8F><E5878B><EFBFBD>瘚贝<E7989A>
- 1000蝭<30><E89DAD><EFBFBD><EFBFBD><E6A180><EFBFBD>蝔?
- 摰硺<E691B0><E7A1BA>滚鍳<E6BB9A><EFBFBD>瘚贝<E7989A>
2. **<EFBFBD><EFBFBD><EFBFBD>湔鰵** 嚗?.5憭抬<EFBFBD>
- <20>湔鰵蝟餌<E89D9F><E9A48C><EFBFBD><E59786><EFBFBD>
- <20>湔鰵 ASL 璅<E79285><E288AA><EFBFBD>
- <20>湔鰵 DC 璅<E79285><E288AA><EFBFBD>
### 銝剜<E98A9D><EFBFBD><E59A97><EFBFBD><EFBFBD>
3. **Phase 9嚗锭AE <20>函蔡銝羓瑪** 嚗?.5憭抬<EFBFBD>
- <20>滨蔭<E6BBA8><EFBFBD><E887AC><EFBFBD>
- <20>啣漲<E595A3><EFBFBD>
- <20>煺漣撉諹<E69289>
### <20><EFBFBD><EFBFBD><E59A97>蝏哨<E89D8F>
4. **<EFBFBD>烐綉<EFBFBD><EFBFBD><EFBFBD>?*
- <20>烐綉<E78390><EFBFBD><E7AC94><EFBFBD>
- <20>烐綉蝻枏<E89DBB><E69E8F>賭葉<E8B3AD>?
- <20>寞旿摰鮋<E691B0><E9AE8B><EFBFBD><EFBFBD><EFBFBD><EFBFBD>寞活憭批<E686AD>
---
## <20><> 憿寧𤌍鈭桃<E988AD>
1. **Platform-Only <20><EFBFBD><E59786>𥟇鰵** <20><>
- 擐硋<E69390><E7A18B><EFBFBD> job.data <20><><EFBFBD>∠恣<E288A0><E681A3>芋撘?
- <20><>迤摰䂿緵鈭<E7B7B5><EFBFBD><EFBFBD>蝏煺<E89D8F>蝞∠<E89D9E>
- <20><EFBFBD>銝箸<E98A9D>雿喳<E99BBF>頝菜<E9A09D>靘?
2. **<EFBFBD><EFBFBD><EFBFBD>峕芋撘誩<EFBFBD><EFBFBD>?* <20>
- <20>寞旿<E5AF9E>唳旿<E594B3>讛䌊<E8AE9B><EFBFBD>㗇𥋘璅<E79285>
- <20><EFBFBD>銝𤾸虾<F0A4BEB8><EFBFBD><EFBFBD>摰𣬚<E691B0>撟唾﹛
- <20><EFBFBD>雿㯄<E99BBF>隡睃<E99AA1>
3. **<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>** <20>
- 銝滚<E98A9D><E6BB9A>仿<EFBFBD>憭𣇉<E686AD>隞?
- <20>拍鍂 Postgres 摰䂿緵 Redis 蝥批<E89DA5><E689B9><EFBFBD><EFBFBD><EFBFBD>?
- <20><><EFBFBD>撠誩𣪧<E8AAA9>笔翰<E7AC94>蠘翮隞?
---
## <20><> <20>𠉛頂銝𤾸<E98A9D>擐?
**憿寧𤌍韐蠘提鈭綽<E988AD>** <20><EFBFBD>
**撘<><E69298>穃𪂹<E7A983><F0AA82B9><EFBFBD>** 2025撟?2<>?<3F>?- 2025撟?2<>?3<>?
**敶枏<E695B6><E69E8F><EFBFBD><E59786><EFBFBD>** Phase 1-7 摰峕<E691B0>嚗釶hase 8-9 敺<><E695BA>銵?
---
**<EFBFBD><EFBFBD><EFBFBD><EFBFBD>𧋦嚗?* V1.0
**<EFBFBD><EFBFBD><EFBFBD>擧凒<EFBFBD><EFBFBD>** 2025撟?2<>?3<>?
**銝𧢲活<F0A7A2B2>湔鰵嚗?* Phase 8 摰峕<E691B0><E5B395>?