Files
AIclinicalresearch/docs/00-系统总体设计/06-模块独立部署与单机版方案.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

41 KiB
Raw Blame History

<EFBFBD><EFBFBD><EFBFBD><EFBFBD>函蔡銝𤾸<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>

*<EFBFBD><EFBFBD><EFBFBD><EFBFBD>𧋦嚗? v1.0
*<EFBFBD>𥕦遣<EFBFBD><EFBFBD>嚗? 2025-11-06
<EFBFBD><EFBFBD><EFBFBD>擧凒<EFBFBD><EFBFBD> 2025-11-06
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><EFBFBD>霈曇恣
雿𡏭<EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>舀沲<E88880><E6B2B2><EFBFBD>


<EFBFBD><EFBFBD> <20><EFBFBD><E8A9A8><EFBFBD>

  1. *<EFBFBD><EFBFBD>摰䂿緵瘥譍葵璅<EFBFBD><EFBFBD><EFBFBD><EFBFBD>函蔡嚗?

    • <EFBFBD>靘肽<EFBFBD>撟喳蝱撅<EFBFBD><EFBFBD><EFBFBD>𡁶鍂<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>嚗?
    • <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>鈭批<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
    • <EFBFBD><EFBFBD>摰䂿緵<EFBFBD>砍𧑐<EFBFBD><EFBFBD>蝵莎<EFBFBD>
  2. *<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>嚗?

    • <EFBFBD><EFBFBD><EFBFBD>拍鍂Electron獢<EFBFBD>沲嚗?
    • <EFBFBD><EFBFBD>憭滨鍂<EFBFBD><EFBFBD><EFBFBD><EFBFBD>嚗?
    • <EFBFBD><EFBFBD><EFBFBD><EFBFBD>霈曇恣嚗?

<EFBFBD>㴓 Part 1嚗𡁏芋<F0A1818F>㛖𡠺蝡钅<E89DA1>蝵脫䲮獢?

<EFBFBD><EFBFBD><EFBFBD><EFBFBD>艙嚗𡁶𡠺蝡钅<EFBFBD>蝵?<3F>?摰<><E691B0>摮斤<E691AE>

*<EFBFBD>喲睸瘣𧼮<EFBFBD>嚗?

<EFBFBD><EFBFBD><EFBFBD>函蔡<EFBFBD><EFBFBD><EFBFBD><EFBFBD>鉄銋㚁<EFBFBD>
<0A>?<3F>臭誑<E887AD>閧𡠺<E996A7><EFBFBD>
<0A>?<3F>臭誑<E887AD>閧𡠺餈鞱<E9A488>
<0A>?<3F>臭誑<E887AD>閧𡠺<E996A7><F0A1A0BA><EFBFBD>?
<0A>?<3F>臭誑<E887AD>閧𡠺<E996A7><F0A1A0BA>漣

雿<><E99BBF><EFBFBD><EFBFBD>
<0A>?摰<><E691B0>銝滢<E98A9D>韏硋<E99F8F>隞碶誨<E7A2B6>?
<0A>?摰<><E691B0>銝滚<E98A9D>鈭怠抅蝖<E68A85>霈暹鴌

*蝐餅<EFBFBD>嚗?

撠勗<EFBFBD><EFBFBD>銝芰𡠺蝡讠<EFBFBD><EFBFBD>𧢲㦤App嚗?
- 摰<><E691B0>韏𡝗<E99F8F>雿𦦵頂蝏<E9A082><E89D8F>Android/iOS嚗?
- 摰<><E691B0>韏𣇉頂蝏鬹PI嚗<49><E59A97><EFBFBD>誩仍<E8AAA9><E4BB8D><EFBFBD>雿滨<E99BBF>嚗?
- 雿<><E99BBF><EFBFBD>臭誑<E887AD><EFBFBD>銝贝蝸<E8B49D><E89DB8><EFBFBD><EFBFBD><E98B86><EFBFBD><EFBFBD>銵䎚<E98AB5><E48E9A>桊頧?

璅<E79285><E288AA><EFBFBD><E7A589>函蔡銋<E894A1>糓銝<E7B393><E98A9D><EFBFBD>
- 摰<><E691B0>韏硋像<E7A18B><EFBFBD><EFBFBD><EFBFBD>瑁恕霂<E68195><E99C82><EFBFBD><EFBFBD><EFBFBD><EFBFBD>嚗?
- 摰<><E691B0>韏㚚<E99F8F>𡁶鍂<F0A181B6><EFBFBD><EFBFBD><E69285>LLM蝵穃<E89DB5><E7A983><EFBFBD><EFBFBD><EFBFBD><E78DA2><EFBFBD><EFBFBD><EFBFBD>嚗?
- 雿<><E99BBF><EFBFBD>臭誑<E887AD><EFBFBD><E7A589><EFBFBD><E69E8F><EFBFBD><EFBFBD>蝵脯<E89DB5><E884AF><EFBFBD><EFBFBD>?

<EFBFBD>𣑐 <20><EFBFBD><EFBFBD>嚗𡁜<E59A97><F0A1819C><EFBFBD><E6B994><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E588BB><EFBFBD><E585B6><EFBFBD>鈭批<E988AD>嚗?

<EFBFBD><EFBFBD><EFBFBD>箸艶

  • <EFBFBD>?璅<E79285>雿靝蛹<E99D9D><EFBFBD>鈭批<E988AD><E689B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>恣蝔輻頂蝏<E9A082><E89D8F>
  • <EFBFBD>?摰<E691B0><EFBFBD><E996AC><EFBFBD><E691B0><EFBFBD>砍𧑐<E7A08D><EFBFBD>蝵?
  • <EFBFBD>?銝滢<E98A9D>韏硋<E99F8F>隞𡝗芋<F0A19D97><EFBFBD>撟喳蝱

<EFBFBD><EFBFBD><EFBFBD>肽楝

*<EFBFBD><EFBFBD>韏𣇉<EFBFBD>撟喳蝱撅<EFBFBD><EFBFBD><EFBFBD>𡁶鍂<EFBFBD><EFBFBD><EFBFBD><EFBFBD>韏瑟<EFBFBD><EFBFBD>?

摰∠阮蝟餌<EFBFBD><EFBFBD><EFBFBD>鈭批<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<0A>𢞖<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>?
<0A>?   RVW摰∠阮蝟餌<E89D9F><E9A48C><EFBFBD>鈭批<E988AD>                    <20>?
<0A>?                                         <20>?
<0A>? <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>?<3F>?
<0A>? <20>? 銝𡁜𦛚璅<E79285>撅?                         <20>?<3F>?
<0A>? <20>? RVW嚗<57>阮隞嗅恣<E59785><EFBFBD>                     <20>?<3F>?
<0A>? <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>?<3F>?
<0A>?                                         <20>?
<0A>? <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>?<3F>?
<0A>? <20>? <20>𡁶鍂<F0A181B6><EFBFBD><EFBFBD><E69285><EFBFBD><E695B9><EFBFBD><EFBFBD>嚗?             <20>?<3F>?
<0A>? <20>? - LLM蝵穃<E89DB5>                          <20>?<3F>?
<0A>? <20>? - <20><>﹝憭<EFB99D><E686AD>撘閙<E69298>                      <20>?<3F>?
<0A>? <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>?<3F>?
<0A>?                                         <20>?
<0A>? <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>?<3F>?
<0A>? <20>? 撟喳蝱<E596B3><EFBFBD><EFBFBD><E69285><EFBFBD><E695B9><EFBFBD><EFBFBD>嚗?             <20>?<3F>?
<0A>? <20>? - <20><EFBFBD>霈方<E99C88><EFBFBD><E59A97><EFBFBD>𣇉<EFBFBD>嚗?               <20>?<3F>?
<0A>? <20>? - 摮睃<E691AE><E79D83>滚𦛚                          <20>?<3F>?
<0A>? <20>? - <20>烐綉<E78390><EFBFBD>                          <20>?<3F>?
<0A>? <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>?<3F>?
<0A>?                                         <20>?
<0A>? <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>?<3F>?
<0A>? <20>? <20><EFBFBD><E7A589>唳旿摨?                         <20>?<3F>?
<0A>? <20>? PostgreSQL嚗㇄ocker嚗?               <20>?<3F>?
<0A>? <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>?<3F>?
<0A><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>?

Step 1: 隞<><E99A9E><EFBFBD><E89D8F>嚗㇈onorepo嚗?

AIclinicalresearch/
  <20><EFBFBD><E98EBF><EFBFBD> packages/                    # Monorepo<70><6F><EFBFBD>?
  <20>?  <20>?
  <20>?  <20><EFBFBD><E98EBF><EFBFBD> platform-core/           # 撟喳蝱<E596B3><EFBFBD><EFBFBD>虾憭滨鍂嚗?
  <20>?  <20>?  <20><EFBFBD><E98EBF><EFBFBD> auth/                # <20><EFBFBD>霈方<E99C88>
  <20>?  <20>?  <20><EFBFBD><E98EBF><EFBFBD> storage/             # 摮睃<E691AE><E79D83>滚𦛚
  <20>?  <20>?  <20><EFBFBD><E98EBF><EFBFBD> monitoring/          # <20>烐綉<E78390><EFBFBD>
  <20>?  <20>?  <20><EFBFBD><E5A999><EFBFBD> index.ts
  <20>?  <20>?
  <20>?  <20><EFBFBD><E98EBF><EFBFBD> capabilities-core/       # <20>𡁶鍂<F0A181B6><EFBFBD><E8B3A2><EFBFBD><EFBFBD>虾憭滨鍂嚗?
  <20>?  <20>?  <20><EFBFBD><E98EBF><EFBFBD> llm-gateway/         # LLM蝵穃<E89DB5>
  <20>?  <20>?  <20><EFBFBD><E98EBF><EFBFBD> document-processor/  # <20><>﹝憭<EFB99D><E686AD>
  <20>?  <20>?  <20><EFBFBD><E98EBF><EFBFBD> rag-engine/          # RAG撘閙<E69298>
  <20>?  <20>?  <20><EFBFBD><E5A999><EFBFBD> index.ts
  <20>?  <20>?
  <20>?  <20><EFBFBD><E98EBF><EFBFBD> module-aia/              # AI<41><EFBFBD><E79285>
  <20>?  <20>?  <20><EFBFBD><E98EBF><EFBFBD> backend/
  <20>?  <20>?  <20><EFBFBD><E98EBF><EFBFBD> frontend/
  <20>?  <20>?  <20><EFBFBD><E5A999><EFBFBD> package.json
  <20>?  <20>?
  <20>?  <20><EFBFBD><E98EBF><EFBFBD> module-asl/              # AI<41><49>讃璅<E79285>
  <20>?  <20>?  <20><EFBFBD><E98EBF><EFBFBD> backend/
  <20>?  <20>?  <20><EFBFBD><E98EBF><EFBFBD> frontend/
  <20>?  <20>?  <20><EFBFBD><E5A999><EFBFBD> package.json
  <20>?  <20>?
  <20>?  <20><EFBFBD><E98EBF><EFBFBD> module-review/           # 摰∠阮蝟餌<E89D9F><E79285>
  <20>?  <20>?  <20><EFBFBD><E98EBF><EFBFBD> backend/
  <20>?  <20>?  <20><EFBFBD><E98EBF><EFBFBD> frontend/
  <20>?  <20>?  <20><EFBFBD><E5A999><EFBFBD> package.json
  <20>?  <20>?
  <20>?  <20><EFBFBD><E5A999><EFBFBD> ...
  <20>?
  <20><EFBFBD><E98EBF><EFBFBD> products/                    # <20><EFBFBD>鈭批<E988AD><E689B9><EFBFBD>
  <20>?  <20>?
  <20>?  <20><EFBFBD><E98EBF><EFBFBD> review-system/           # 摰∠阮蝟餌<E89D9F><E9A48C><EFBFBD>鈭批<E988AD> 潃?
  <20>?  <20>?  <20><EFBFBD><E98EBF><EFBFBD> docker-compose.yml
  <20>?  <20>?  <20><EFBFBD><E98EBF><EFBFBD> deploy.sh
  <20>?  <20>?  <20><EFBFBD><E98EBF><EFBFBD> README.md
  <20>?  <20>?  <20><EFBFBD><E5A999><EFBFBD> package.json         # 靘肽<E99D98><E882BD>喟頂
  <20>?  <20>?
  <20>?  <20><EFBFBD><E98EBF><EFBFBD> literature-system/       # AI<41><49><EFBFBD><EFBFBD>鈭批<E988AD> 潃?
  <20>?  <20>?  <20><EFBFBD><E5A999><EFBFBD> ...
  <20>?  <20>?
  <20>?  <20><EFBFBD><E5A999><EFBFBD> full-platform/           # 摰峕㟲撟喳蝱
  <20>?      <20><EFBFBD><E5A999><EFBFBD> ...
  <20>?
  <20><EFBFBD><E5A999><EFBFBD> ...

Step 2: 靘肽<E99D98>蝞∠<E89D9E>嚗īackage.json嚗?

摰∠阮蝟餌<EFBFBD><EFBFBD><EFBFBD>鈭批<EFBFBD><EFBFBD><EFBFBD><EFBFBD>韏吔<EFBFBD>

// products/review-system/package.json
{
  "name": "@yizhengxun/review-system",
  "version": "1.0.0",
  "private": true,
  "dependencies": {
    // 撟喳蝱<E596B3><EFBFBD><EFBFBD><E59A97><EFBFBD><EFBFBD>嚗?
    "@yizhengxun/platform-core": "workspace:*",
    
    // <20>𡁶鍂<F0A181B6><EFBFBD><EFBFBD><E59A97><EFBFBD><EFBFBD>嚗?
    "@yizhengxun/capabilities-core": "workspace:*",
    
    // 銝𡁜𦛚璅<E79285>
    "@yizhengxun/module-review": "workspace:*"
  },
  "scripts": {
    "build": "node build.js",
    "deploy": "sh deploy.sh"
  }
}

撟喳蝱<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>㗇𥋘<EFBFBD>批紡<EFBFBD><EFBFBD>

// packages/platform-core/index.ts

// 摰峕㟲撖澆枂嚗<E69E82>鍂鈭𤾸<E988AD><F0A4BEB8>游像<E6B8B8><EFBFBD>
export * from './auth';
export * from './storage';
export * from './monitoring';
export * from './notification';

// 蝎曄<E89D8E>撖澆枂嚗<E69E82>鍂鈭𡒊𡠺蝡衤漣<E8A1A4><E6BCA3><EFBFBD>
export { 
  // <20>芸紡<E88AB8><EFBFBD><E7AE8F><EFBFBD><EFBFBD><EFBFBD>恕霂<E68195><E99C82><EFBFBD>?
  authMiddleware, 
  jwtService 
} from './auth';

export { 
  // <20>芸紡<E88AB8><EFBFBD><E7AE8F><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E585B8>?
  uploadFile, 
  downloadFile 
} from './storage';

export { 
  // <20>芸紡<E88AB8><EFBFBD><E7AE8F><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E689B9>?
  logError, 
  logAudit 
} from './monitoring';

Step 3: <20><EFBFBD><E69E8F>𡁏𧋦

*摰∠阮蝟餌<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>嚗?

// products/review-system/build.js

const { build } = require('esbuild');
const { dependencies } = require('./package.json');

async function buildReviewSystem() {
  console.log('<27><>遣摰∠阮蝟餌<E89D9F><E9A48C><EFBFBD>鈭批<E988AD>...');
  
  // 1. <20><><EFBFBD>𡒊垢
  await build({
    entryPoints: ['../../packages/module-review/backend/src/index.ts'],
    bundle: true,
    platform: 'node',
    target: 'node18',
    outfile: 'dist/backend/index.js',
    external: ['pg', 'fastify', 'prisma'],  // 銝齿<E98A9D><E9BDBF><EFBFBD><EFBFBD>鈭𥕦之摨?
    
    // <20>芸𢆡<E88AB8><F0A286A1>鉄靘肽<E99D98>
    plugins: [
      // <20>芸𢆡閫<F0A286A1><E996AB>workspace靘肽<E99D98>
      resolveWorkspaceDependencies()
    ]
  });
  
  // 2. <20><><EFBFBD>滨垢
  await build({
    entryPoints: ['../../packages/module-review/frontend/src/main.tsx'],
    bundle: true,
    platform: 'browser',
    outfile: 'dist/frontend/index.js',
    loader: { '.tsx': 'tsx' }
  });
  
  // 3. 憭滚<E686AD><EFBFBD><E695B9><EFBFBD><EFBFBD>  copyFiles([
    'docker-compose.yml',
    'README.md',
    'deploy.sh'
  ]);
  
  console.log('<27><>遣摰峕<EFBFBD>?);
}

buildReviewSystem();

Step 4: Docker<65>函蔡<E587BD>滨蔭

*摰∠阮蝟餌<EFBFBD><EFBFBD><EFBFBD><EFBFBD>函蔡嚗?

# products/review-system/docker-compose.yml

version: '3.8'

services:
  # PostgreSQL<51>唳旿摨橒<E691A8><E6A992><EFBFBD>嚗?
  postgres:
    image: postgres:15-alpine
    container_name: review-system-postgres
    environment:
      POSTGRES_DB: review_system
      POSTGRES_USER: review
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    networks:
      - review-network

  # <20>𡒊垢<F0A1928A>滚𦛚嚗<F0A69B9A><E59A97><EFBFBD>怠像<E680A0><EFBFBD><E595A3><EFBFBD>𡁶鍂<F0A181B6><EFBFBD><EFBFBD><E69285>
  backend:
    build:
      context: ./dist/backend
    container_name: review-system-backend
    environment:
      DATABASE_URL: postgresql://review:${DB_PASSWORD}@postgres:5432/review_system
      LLM_API_KEY: ${LLM_API_KEY}
    depends_on:
      - postgres
    networks:
      - review-network

  # <20>滨垢<E6BBA8>滚𦛚
  frontend:
    build:
      context: ./dist/frontend
    container_name: review-system-frontend
    ports:
      - "80:80"
    depends_on:
      - backend
    networks:
      - review-network

volumes:
  postgres_data:

networks:
  review-network:
    driver: bridge

Step 5: 銝<><E98A9D><EFBFBD>蝵脰<E89DB5><E884B0>?

#!/bin/bash
# products/review-system/deploy.sh

echo "======================================"
echo "  摰∠阮蝟餌<E89D9F><E9A48C><EFBFBD><E7A589>函蔡<E587BD>𡁏𧋦"
echo "======================================"

# 1. 璉<><E79289>主ocker
if ! command -v docker &> /dev/null; then
    echo "<22>躰秤嚗𡁏𧊋摰㕑<E691B0>Docker"
    exit 1
fi

# 2. 霈曄蔭<E69B84><EFBFBD><E887AC><EFBFBD>
read -p "霂瑁<E99C82><E79181>交㺭<E4BAA4><EFBFBD><EFBFBD><E69296>: " DB_PASSWORD
read -p "霂瑁<E99C82><E79181>他LM API撖<49>𤨎: " LLM_API_KEY

export DB_PASSWORD
export LLM_API_KEY

# 3. <20>臬𢆡<E887AC>滚𦛚
docker-compose up -d

# 4. 蝑匧<E89D91><E58CA7>滚𦛚<E6BB9A>臬𢆡
echo "蝑匧<E89D91><E58CA7>滚𦛚<E6BB9A>臬𢆡..."
sleep 10

# 5. <20><EFBFBD><E598A5>𡝗㺭<F0A19D97><EFBFBD>
docker exec review-system-backend npx prisma migrate deploy

# 6. <20>𥕦遣暺䁅恕蝞∠<E89D9E><E288A0>?
docker exec review-system-backend node scripts/create-admin.js

echo "======================================"
echo "  <20>函蔡摰峕<E691B0>嚗?
echo "  霈輸䔮<E8BCB8><EFBFBD>嚗冴ttp://localhost"
echo "  蝞∠<E89D9E><E288A0>䁅揭<E48185><EFBFBD>admin@review.com"
echo "<><E69296>嚗惨dmin123嚗<33><EFBFBD>𦠜𧒄靽格㺿嚗?
echo "======================================"

<EFBFBD>喲睸<EFBFBD><EFBFBD><EFBFBD><EFBFBD>

1. 撟喳蝱撅<E89DB1><E69285>蝎曄<E89D8E><E69B84><EFBFBD><E5B1B8><EFBFBD>

摰峕㟲撟喳蝱<EFBFBD><EFBFBD><EFBFBD>瑁恕霂<EFBFBD><EFBFBD>憭齿<EFBFBD>嚗㚁<EFBFBD>

// 摰峕㟲撟喳蝱
- 憭𡁶<EFBFBD><EFBFBD>瑟𣈲<EFBFBD>?
- RBAC<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
- SSO<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
- 蝚砌<EFBFBD><EFBFBD>寧蒈敶𤏪<EFBFBD>敺桐縑<EFBFBD><EFBFBD><EFBFBD>銝𡁜凝靽∠<EFBFBD>?
- 憭齿<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>

*摰∠阮蝟餌<EFBFBD><EFBFBD><EFBFBD><EFBFBD>瑁恕霂<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>嚗?

// 摰∠阮蝟餌<E89D9F><E9A48C><EFBFBD>鈭批<E988AD>
- <EFBFBD><EFBFBD>𣇉<EFBFBD><EFBFBD><EFBFBD>霈方<EFBFBD><EFBFBD><EFBFBD>?<EFBFBD><EFBFBD>?
- <EFBFBD><EFBFBD><EFBFBD>閫坿𠧧嚗<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>颲㻫<EFBFBD><EFBFBD>恣蝔蹂犖嚗?
- <EFBFBD><EFBFBD>JWT<EFBFBD><EFBFBD>oken霈方<EFBFBD>
- <EFBFBD>SO<EFBFBD><EFBFBD><EFBFBD>憭𡁶<EFBFBD><EFBFBD>?

*摰䂿緵<EFBFBD><EFBFBD>嚗?

// packages/platform-core/auth/simple-auth.ts
// 銝箇𡠺蝡衤漣<E8A1A4><E6BCA3><EFBFBD>靘𤤿<E99D98><F0A4A4BF>𣇉<EFBFBD>霈方<E99C88>

export class SimpleAuthService {
  // <20><EFBFBD><E88AAF>蹱瓲敹<E793B2><E695B9><EFBFBD>?
  async login(email: string, password: string) { }
  async register(email: string, password: string) { }
  async verifyToken(token: string) { }
  async logout(userId: string) { }
  
  // 蝘駁膄憭齿<E686AD><E9BDBF><EFBFBD>
  // <20>?async loginWithWeChat()
  // <20>?async setupSSO()
  // <20>?async multiTenantCheck()
}

2. <20>𡁶鍂<F0A181B6><EFBFBD><EFBFBD><E69285>蝎曄<E89D8E><E69B84><EFBFBD><E5B1B8><EFBFBD>

*摰峕㟲撟喳蝱<EFBFBD><EFBFBD>LM蝵穃<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>嚗?

// 摰峕㟲撟喳蝱
- <EFBFBD><EFBFBD>10+蝘齿芋<EFBFBD>?
- Feature Flag<EFBFBD><EFBFBD>
- <EFBFBD><EFBFBD>蝞∠<EFBFBD>
- <EFBFBD>鞉𧋦<EFBFBD><EFBFBD><EFBFBD>
- A/B瘚贝<EFBFBD>

*摰∠阮蝟餌<EFBFBD><EFBFBD><EFBFBD>LM蝵穃<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>嚗?

// 摰∠阮蝟餌<E89D9F><E9A48C><EFBFBD>鈭批<E988AD>
- <EFBFBD>芣𣈲<EFBFBD>?-2蝘齿芋<EFBFBD><EFBFBD>DeepSeek + Claude嚗?
- <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
- <EFBFBD>eature Flag
- <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?

*摰䂿緵<EFBFBD><EFBFBD>嚗?

// packages/capabilities-core/llm-gateway/simple-llm.ts

export class SimpleLLMGateway {
  // <20><EFBFBD><E88AAF>蹱瓲敹<E793B2><E695B9><EFBFBD>?
  async chat(params: ChatParams) { }
  async checkQuota(userId: string) { }
  
  // 蝘駁膄憭齿<E686AD><E9BDBF><EFBFBD>
  // <20>?async getCostStats()
  // <20>?async selectModelByVersion()
  // <20>?async runABTest()
}

3. <20>唳旿摨梶<E691A8><E6A2B6>𠉛氖

*摰峕㟲撟喳蝱<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>嚗?

-- 撟喳蝱撅<E89DB1>chema
platform_schema.users
platform_schema.tenants
platform_schema.feature_flags
-- ...

-- <20><><EFBFBD>㗇芋<E39787>𣶷chema
aia_schema.*
asl_schema.*
review_schema.*
-- ...

*摰∠阮蝟餌<EFBFBD><EFBFBD><EFBFBD>鈭批<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>嚗?

-- <20><EFBFBD><E88AB8><EFBFBD><E680A0><EFBFBD><EFBFBD><EFBFBD>CREATE DATABASE review_system;

-- 蝞<><E89D9E>𣇉<EFBFBD><F0A38789><EFBFBD>銵?
CREATE TABLE users (
  id UUID PRIMARY KEY,
  email VARCHAR(255) UNIQUE NOT NULL,
  password VARCHAR(255) NOT NULL,
  role VARCHAR(50) NOT NULL,  -- admin/editor/reviewer
  created_at TIMESTAMP DEFAULT NOW()
);

-- 摰∠阮蝟餌<E89D9F><E9A48C><EFBFBD><EFBFBD><EFBFBD>∟”
CREATE TABLE review_tasks (...);
CREATE TABLE review_journals (...);
CREATE TABLE review_reviewers (...);
-- ...

<EFBFBD><EFBFBD>鈭批<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?

隡睃飵 霂湔<EFBFBD>
*<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>? <EFBFBD>臭誑<EFBFBD>閧𡠺摰帋遠<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
<EFBFBD><EFBFBD><EFBFBD>函蔡 <EFBFBD><EFBFBD>臭誑<EFBFBD>砍𧑐<EFBFBD><EFBFBD>蝵莎<EFBFBD><EFBFBD>唳旿摰<EFBFBD><EFBFBD><EFBFBD>𠉛氖
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> 銝滚蔣<EFBFBD><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>鈭䕘<E988AD><E49598>曹澈<E69BB9>滚𦛚嚗<F0A69B9A><EFBFBD>鞟鍂鈭𤾸像<F0A4BEB8><EFBFBD><E79285>嚗?

<EFBFBD><EFBFBD><EFBFBD>箸艶

  • <EFBFBD>?<3F><EFBFBD><E691B0>韐凋僭憭帋葵璅<E79285>
  • <EFBFBD>?鈭𤑳垢SaaS<61>函蔡
  • <EFBFBD>?璅<E79285>銋钅𡢿<E99285><F0A1A2BF><EFBFBD><E996AC>鈭怎鍂<E6808E><EFBFBD><E79195>唳旿

<EFBFBD><EFBFBD><EFBFBD>肽楝

*撟喳蝱撅<EFBFBD><EFBFBD><EFBFBD>𡁶鍂<EFBFBD><EFBFBD><EFBFBD><EFBFBD>銝箏<EFBFBD>鈭急<EFBFBD><EFBFBD>?

摰峕㟲撟喳蝱<EFBFBD><EFBFBD><EFBFBD><EFBFBD>滚𦛚<EFBFBD><EFBFBD><EFBFBD>嚗?

<0A>𢞖<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><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
<0A>?                   API蝵穃<E89DB5>嚗𠃋ong/Traefik嚗?               <20>?
<0A>?             頝舐眏嚗?aia/* /asl/* /review/*               <20>?
<0A><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><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
         <20>?             <20>?             <20>?
         <20>?             <20>?             <20>?
<0A>𢞖<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>?<3F>𢞖<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>?<3F>𢞖<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>?
<0A>?AIA璅<E79285><E288AA>滚𦛚  <20>?<3F>?ASL璅<E79285><E288AA>滚𦛚  <20>?<3F>?RVW璅<E79285><E288AA>滚𦛚  <20>?
<0A>?(<28><EFBFBD><E7A589>函蔡)   <20>?<3F>?(<28><EFBFBD><E7A589>函蔡)   <20>?<3F>?(<28><EFBFBD><E7A589>函蔡)   <20>?
<0A><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>?<3F><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>?<3F><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>?
         <20>?             <20>?             <20>?
         <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><E6B0AF><EFBFBD><EFBFBD><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>𢞖<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>?
         <20>?   <20>曹澈<E69BB9>滚𦛚嚗<F0A69B9A><EFBFBD><EFBFBD>嚗?       <20>?
         <20>? - <20><EFBFBD>霈方<E99C88><E696B9>滚𦛚              <20>?
         <20>? - 摮睃<E691AE><E79D83>滚𦛚                 <20>?
         <20>? - <20>烐綉<E78390>滚𦛚                 <20>?
         <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>?
                      <20>?
         <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>?
         <20>? <20>曹澈<E69BB9>滚𦛚嚗<F0A69B9A><E59A97>𡁶鍂<F0A181B6><EFBFBD><EFBFBD><E69285>      <20>?
         <20>? - LLM蝵穃<E89DB5><E7A983>滚𦛚              <20>?
         <20>? - <20><>﹝憭<EFB99D><E686AD><EFBFBD>滚𦛚              <20>?
         <20>? - RAG撘閙<E69298><E99699>滚𦛚              <20>?
         <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>?
                      <20>?
         <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>?
         <20>?   <20>曹澈<E69BB9>唳旿摨?              <20>?
         <20>? - PostgreSQL (憭锭chema)   <20>?
         <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>?

Step 1: <20>滚𦛚<E6BB9A><F0A69B9A><EFBFBD>

*撟喳蝱<EFBFBD><EFBFBD><EFBFBD>滚𦛚嚗<EFBFBD>𡠺蝡钅<EFBFBD>蝵莎<EFBFBD>嚗?

# services/platform/docker-compose.yml

services:
  # <20><EFBFBD>霈方<E99C88><E696B9>滚𦛚
  auth-service:
    image: yizhengxun/auth-service:latest
    ports:
      - "3001:3000"
    environment:
      DATABASE_URL: ${DATABASE_URL}
      JWT_SECRET: ${JWT_SECRET}

  # 摮睃<E691AE><E79D83>滚𦛚
  storage-service:
    image: yizhengxun/storage-service:latest
    ports:
      - "3002:3000"
    environment:
      OSS_ENDPOINT: ${OSS_ENDPOINT}

  # <20>烐綉<E78390>滚𦛚
  monitoring-service:
    image: yizhengxun/monitoring-service:latest
    ports:
      - "3003:3000"

*<EFBFBD>𡁶鍂<EFBFBD><EFBFBD><EFBFBD>滚𦛚嚗<EFBFBD>𡠺蝡钅<EFBFBD>蝵莎<EFBFBD>嚗?

# services/capabilities/docker-compose.yml

services:
  # LLM蝵穃<E89DB5><E7A983>滚𦛚
  llm-gateway:
    image: yizhengxun/llm-gateway:latest
    ports:
      - "3010:3000"
    environment:
      DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY}
      QWEN_API_KEY: ${QWEN_API_KEY}

  # <20><>﹝憭<EFB99D><E686AD><EFBFBD>滚𦛚
  document-processor:
    image: yizhengxun/document-processor:latest
    ports:
      - "3011:3000"

  # RAG撘閙<E69298><E99699>滚𦛚
  rag-engine:
    image: yizhengxun/rag-engine:latest
    ports:
      - "3012:3000"

*銝𡁜𦛚璅<EFBFBD><EFBFBD>滚𦛚嚗<EFBFBD>𡠺蝡钅<EFBFBD>蝵莎<EFBFBD>嚗?

# services/modules/review-system/docker-compose.yml

services:
  review-system:
    image: yizhengxun/review-system:latest
    ports:
      - "4001:3000"
    environment:
      # 靘肽<E99D98><E882BD>曹澈<E69BB9>滚𦛚
      AUTH_SERVICE_URL: http://auth-service:3000
      STORAGE_SERVICE_URL: http://storage-service:3000
      LLM_GATEWAY_URL: http://llm-gateway:3000
      DOCUMENT_PROCESSOR_URL: http://document-processor:3000
      
      # <20>芸楛<E88AB8><E6A59B><EFBFBD><EFBFBD>Schema
      DATABASE_URL: postgresql://user:pass@postgres:5432/platform?schema=review_schema

Step 2: API蝵穃<E89DB5><E7A983>滨蔭

*Kong API蝵穃<E89DB5><E7A983>滨蔭嚗?

# api-gateway/kong.yml

_format_version: "3.0"

services:
  # <20><EFBFBD>霈方<E99C88><E696B9>滚𦛚
  - name: auth-service
    url: http://auth-service:3000
    routes:
      - name: auth-routes
        paths:
          - /api/auth

  # 摰∠阮蝟餌<E89D9F><E79285>
  - name: review-system
    url: http://review-system:3000
    routes:
      - name: review-routes
        paths:
          - /api/review
    plugins:
      - name: jwt
        config:
          secret_is_base64: false
          key_claim_name: kid

  # AI<41><49>讃璅<E79285>
  - name: literature-system
    url: http://literature-system:3000
    routes:
      - name: literature-routes
        paths:
          - /api/literature
    plugins:
      - name: jwt

Step 3: <20>滚𦛚<E6BB9A><EFBFBD>帋縑

*銝𡁜𦛚璅<EFBFBD><EFBFBD><EFBFBD>曹澈<EFBFBD>滚𦛚嚗?

// packages/module-review/backend/src/services/review.service.ts

import { AuthClient } from '@yizhengxun/platform-core/clients';
import { LLMClient } from '@yizhengxun/capabilities-core/clients';

export class ReviewService {
  private authClient: AuthClient;
  private llmClient: LLMClient;
  
  constructor() {
    // 餈墧𦻖<E5A2A7><EFBFBD>鈭急<E988AD><E680A5>?
    this.authClient = new AuthClient({
      baseURL: process.env.AUTH_SERVICE_URL
    });
    
    this.llmClient = new LLMClient({
      baseURL: process.env.LLM_GATEWAY_URL
    });
  }
  
  async createReviewTask(userId: string, file: File) {
    // 1. 撉諹<E69289><E8ABB9><EFBFBD><EFBFBD><E59A97><EFBFBD><EFBFBD>鈭怨恕霂<E68195><E99C82><EFBFBD><EFBFBD>
    const user = await this.authClient.verifyUser(userId);
    
    // 2. 銝𠹺<E98A9D><F0A0B9BA><EFBFBD>辣嚗<E8BEA3><E59A97><EFBFBD><EFBFBD>鈭怠<E988AD><E680A0><EFBFBD><E586BD><EFBFBD>
    const fileUrl = await this.storageClient.upload(file);
    
    // 3. AI<41><49><EFBFBD><EFBFBD><E59A97><EFBFBD><EFBFBD>鈭俠LM蝵穃<E89DB5>嚗?
    const analysis = await this.llmClient.chat({
      messages: [{ role: 'user', content: `<60><><EFBFBD>餈嗵<E9A488>蝔蹂辣: ${fileUrl}` }]
    });
    
    // 4. 靽嘥<E99DBD><E598A5>啗䌊撌梁<E6928C><E6A281>唳旿摨?
    const task = await prisma.reviewTask.create({
      data: {
        userId,
        fileUrl,
        analysis: analysis.content
      }
    });
    
    return task;
  }
}

<EFBFBD><EFBFBD><EFBFBD><EFBFBD>函蔡<EFBFBD><EFBFBD>郊撉?

*1. <20>函蔡<E587BD>曹澈<E69BB9>滚𦛚嚗<F0A69B9A><E59A97>甈⊥<E79488><EFBFBD>嚗?

# <20>函蔡撟喳蝱<E596B3><EFBFBD><E7AE87>滚𦛚
cd services/platform
docker-compose up -d

# <20>函蔡<E587BD>𡁶鍂<F0A181B6><EFBFBD><E8B3A2>滚𦛚
cd services/capabilities
docker-compose up -d

# <20>函蔡API蝵穃<E89DB5>
cd services/api-gateway
docker-compose up -d

2. <20>函蔡銝𡁜𦛚璅<E79285><EFBFBD><E59A97><EFBFBD><EFBFBD>嚗㚁<E59A97>

# <20><EFBFBD>蝵脣恣蝔輻頂蝏<E9A082><EFBFBD>?
cd services/modules/review-system
docker-compose up -d

# 摰<E691B0>A韐凋僭鈭<E583AD>恣蝔輻頂蝏<E9A082><E89D8F><EFBFBD><EFBFBD><E88AB7>函蔡餈嗘<E9A488>銝芣芋<E88AA3>?
# <20><EFBFBD><E79285>銝漤<E98A9D><EFBFBD><E996AC>蝵?

3. <20>啣恥<E595A3>瑁揚銋啣<E98A8B>隞𡝗芋<F0A19D97><EFBFBD>

# 摰<E691B0>B韐凋僭鈭<E583AD>I<EFBFBD><49>讃璅<E79285><EFBFBD><E59A97><EFBFBD>函蔡餈嗘葵璅<E79285>
cd services/modules/literature-system
docker-compose up -d

# <20>曹澈<E69BB9>滚𦛚撌脩<E6928C><E884A9>函蔡嚗䔶<E59A97><E494B6><EFBFBD><EFBFBD><E996AC>憭漤<E686AD>蝵?
# <20><EFBFBD>憓𧼮<E68693><F0A7BCAE><EFBFBD>銝𡁜𦛚璅<E79285>

<EFBFBD>棅儭?Part 2嚗鍃lectron<6F>閙㦤<E99699><E3A6A4>䲮獢?

銝箔<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>嚗?

<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>

  1. **<2A>唳旿<E594B3><EFBFBD>**嚗𡁜龫<F0A1819C>煺葵鈭箸㺭<E7AEB8><EFBFBD><E6A190><EFBFBD>隡牐<E99AA1>蝡?
  2. 蝳餌瑪雿輻鍂嚗𡁏<EFBFBD><EFBFBD><EFBFBD>蝵𤑳<EFBFBD>餈墧𦻖
  3. **靘踵𡉼<E8B8B5>?*嚗𡁜虾隞亙銁隞颱<E99A9E><E9A2B1><EFBFBD>銝𠰴<E98A9D><EFBFBD><EFBFBD>?
  4. **<2A><EFBFBD>餈鞱<E9A488>**嚗帋<E59A97>靘肽<E99D98>憭㚚<E686AD><E39A9A>滚𦛚<E6BB9A>?

*<EFBFBD><EFBFBD><EFBFBD><EFBFBD>嚗?

  • 銝芯犖<EFBFBD><EFBFBD>
  • <EFBFBD>唳旿<EFBFBD>𤩺<EFBFBD><EFBFBD><EFBFBD><EFBFBD>蝛嗉<EFBFBD>?
  • <EFBFBD><EFBFBD>蝏𦦵㴓憓<EFBFBD><EFBFBD><EFBFBD>箸艶

Electron<EFBFBD><EFBFBD>銝𡒊緵<EFBFBD>劐誨<EFBFBD><EFBFBD><EFBFBD>撖孵<EFBFBD><EFBFBD>喟頂

<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>蝡舐<EFBFBD>嚗?

<EFBFBD>𢞖<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
<0A>?           瘚讛<E7989A><E8AE9B>?(Chrome)               <20>?
<0A>? <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>? <20>?
<0A>? <20>?  <20>滨垢 (React + Vite)              <20>? <20>?
<0A>? <20>?  http://localhost:5173            <20>? <20>?
<0A>? <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>? <20>?
<0A><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>?
              <20>?HTTP霂瑟<E99C82>
<0A>𢞖<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>?
<0A>?    <20>𡒊垢 (Node.js + Fastify)            <20>?
<0A>?    http://localhost:3001               <20>?
<0A>? <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>? <20>?
<0A>? <20>? API頝舐眏<E88890><E79C8F><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E9A489><EFBFBD>risma ORM     <20>? <20>?
<0A>? <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>? <20>?
<0A><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>?
              <20>?
<0A>𢞖<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>?
<0A>? PostgreSQL (Docker)                    <20>?
<0A>? localhost:5432                         <20>?
<0A><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>?

Electron<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>嚗?

<EFBFBD>𢞖<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
<0A>?                 Electron 摨𠉛鍂                              <20>?
<0A>?                                                            <20>?
<0A>? <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>?
<0A>? <20>?           皜脫<E79A9C>餈𤤿<E9A488> (Chromium)                        <20>? <20>?
<0A>? <20>? <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>? <20>? <20>?
<0A>? <20>? <20>?  <20>滨垢 (React)  潃?憭滨鍂<E6BBA8><EFBFBD><EFBFBD><E99A9E>                 <20>? <20>? <20>?
<0A>? <20>? <20>?  file://app/index.html                       <20>? <20>? <20>?
<0A>? <20>? <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>? <20>? <20>?
<0A>? <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>?
<0A>?                     <20>?IPC<50>帋縑                            <20>?
<0A>? <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>?
<0A>? <20>?           銝餉<E98A9D>蝔?(Node.js)                          <20>? <20>?
<0A>? <20>? <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>? <20>? <20>?
<0A>? <20>? <20>? API<50><EFBFBD><E9A489><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 潃?憭滨鍂<E6BBA8><EFBFBD><EFBFBD><E99A9E>              <20>? <20>? <20>?
<0A>? <20>? <20>? Prisma ORM<52><4D>𧋦<EFBFBD><EFBFBD>隞嗥頂蝏?                     <20>? <20>? <20>?
<0A>? <20>? <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>? <20>? <20>?
<0A>? <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>?
<0A>?                     <20>?                                    <20>?
<0A>? <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>?
<0A>? <20>?    SQLite (撋<><E6928B>撘𤩺㺭<F0A4A9BA><EFBFBD>)                            <20>? <20>?
<0A>? <20>?    ~/Documents/YizhengxunData/app.db               <20>? <20>?
<0A>? <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>?
<0A>?                                                            <20>?
<0A>? <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>?
<0A>? <20>?    摮鞱<E691AE>蝔?(Python/R)                                <20>? <20>?
<0A>? <20>?    <20><><EFBFBD>𣂼<EFBFBD><F0A382BC><EFBFBD><EFBFBD><EFBFBD><E6A180>?                               <20>? <20>?
<0A>? <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>?
<0A><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><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?

<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>舀䲮獢?

1. <20>滨垢隞<E59EA2><E99A9E>憭滨鍂嚗?0%+ 憭滨鍂嚗?

*<EFBFBD><EFBFBD><EFBFBD>滨垢隞<EFBFBD><EFBFBD>嚗Áeb<EFBFBD><EFBFBD><EFBFBD>嚗?

// frontend/src/api/client.ts
const API_BASE_URL = 'http://localhost:3001';

export const apiClient = {
  async get(url: string) {
    return fetch(`${API_BASE_URL}${url}`);
  },
  async post(url: string, data: any) {
    return fetch(`${API_BASE_URL}${url}`, {
      method: 'POST',
      body: JSON.stringify(data)
    });
  }
};

Electron<EFBFBD><EFBFBD><EFBFBD>蝡荔<EFBFBD>靽格㺿API靚<EFBFBD><EFBFBD><EFBFBD>嚗㚁<EFBFBD>

// electron-frontend/src/api/client.ts

// 雿輻鍂Electron<6F><6E>PC<50>帋縑嚗諹<E59A97><EFBFBD><E494B6>浹TTP
const { ipcRenderer } = window.require('electron');

export const apiClient = {
  async get(url: string) {
    // <20><EFBFBD>IPC<50><EFBFBD><E785BE><EFBFBD>銝餉<E98A9D>蝔?
    return ipcRenderer.invoke('api-request', {
      method: 'GET',
      url
    });
  },
  async post(url: string, data: any) {
    return ipcRenderer.invoke('api-request', {
      method: 'POST',
      url,
      data
    });
  }
};

*React蝏<EFBFBD>辣摰<EFBFBD><EFBFBD>銝漤<EFBFBD><EFBFBD>㺿嚗?

// 銝𡁜𦛚蝏<F0A69B9A>辣摰<E8BEA3><E691B0>銝滚<E98A9D> <20>?
function UserList() {
  const [users, setUsers] = useState([]);
  
  useEffect(() => {
    // API靚<49><EFBFBD><EFBFBD>銝滚<E98A9D><EFBFBD><E59A97><EFBFBD><EFBFBD><EFBFBD><E588B8><EFBFBD>
    apiClient.get('/api/users').then(setUsers);
  }, []);
  
  return <div>{/* ... */}</div>;
}

*憭滨鍂<EFBFBD><EFBFBD><EFBFBD>90%+ <20>?

  • <EFBFBD>?<3F><><EFBFBD>兴eact蝏<74>
  • <EFBFBD>?<3F><><EFBFBD>务I摨橒<E691A8>Ant Design嚗?
  • <EFBFBD>?<3F><><EFBFBD>厩𠶖<E58EA9><F0A0B696><EFBFBD><E681A3><EFBFBD>Zustand嚗?
  • <EFBFBD>?<3F><><EFBFBD>㕑楝<E39591><EFBFBD>React Router嚗?
  • <EFBFBD>𩤃<EFBFBD> <20><EFBFBD>靽格㺿API靚<49>鍂撅<E98D82><E69285>1銝芣<E98A9D>隞塚<E99A9E>

2. <20>𡒊垢隞<E59EA2><E99A9E>憭滨鍂嚗?0%+ 憭滨鍂嚗?

*<EFBFBD><EFBFBD><EFBFBD>𡒊垢隞<EFBFBD><EFBFBD>嚗Áeb<EFBFBD><EFBFBD><EFBFBD>嚗?

// backend/src/routes/users.ts
import { FastifyInstance } from 'fastify';

export async function userRoutes(fastify: FastifyInstance) {
  // GET /api/users
  fastify.get('/api/users', async (request, reply) => {
    const users = await prisma.user.findMany();
    return users;
  });
  
  // POST /api/users
  fastify.post('/api/users', async (request, reply) => {
    const user = await prisma.user.create({
      data: request.body
    });
    return user;
  });
}

*Electron<EFBFBD><EFBFBD><EFBFBD>蝡荔<EFBFBD>銝餉<EFBFBD>蝔页<EFBFBD>嚗?

// electron-backend/src/ipc-handlers.ts
import { ipcMain } from 'electron';
import { prisma } from './prisma-client';

// 憭滨鍂銝𡁜𦛚<F0A1819C><EFBFBD> 潃?
import { UserService } from '../../../backend/src/services/user.service';

export function setupIpcHandlers() {
  const userService = new UserService(prisma);
  
  // 撠<>TTP頝舐眏頧祆揢銝截PC Handler
  ipcMain.handle('api-request', async (event, { method, url, data }) => {
    // 頝舐眏<E88890><E79C8F><EFBFBD><EFBFBD><E59A97><EFBFBD>𣇉<EFBFBD><F0A38789><EFBFBD>astify嚗?
    if (url === '/api/users' && method === 'GET') {
      return userService.findAll();
    }
    
    if (url === '/api/users' && method === 'POST') {
      return userService.create(data);
    }
    
    // ... <20><EFBFBD>頝舐眏
  });
}

*<EFBFBD><EFBFBD>銝𡁜𦛚<EFBFBD><EFBFBD><EFBFBD><EFBFBD>憭滨鍂嚗?

// backend/src/services/user.service.ts
// 餈嗘葵<E59798><E891B5><EFBFBD>汾eb<65><62><EFBFBD>Electron<6F><6E><EFBFBD><EFBFBD><EFBFBD>鈭?<3F>?

export class UserService {
  constructor(private prisma: PrismaClient) {}
  
  async findAll() {
    return this.prisma.user.findMany();
  }
  
  async create(data: CreateUserDto) {
    // 銝𡁜𦛚<F0A1819C><EFBFBD>
    const hashedPassword = await bcrypt.hash(data.password, 10);
    return this.prisma.user.create({
      data: {
        ...data,
        password: hashedPassword
      }
    });
  }
}

*憭滨鍂<EFBFBD><EFBFBD><EFBFBD>80%+ <20>?

  • <EFBFBD>?<3F><><EFBFBD>农ervice撅<65><E69285>銝𡁜𦛚<F0A1819C><EFBFBD>嚗?
  • <EFBFBD>?<3F><><EFBFBD>侨risma Model<65>峕䰻霂?
  • <EFBFBD>?<3F><><EFBFBD>匧極<E58CA7>瑕遆<E79195>?
  • <EFBFBD>𩤃<EFBFBD> <20><><EFBFBD><E996AC><EFBFBD><EFBFBD>嚗䥅TTP頝舐眏 <20>?IPC Handler
  • <EFBFBD>𩤃<EFBFBD> <20><><EFBFBD>𤜯<EFBFBD><EFBFBD>PostgreSQL <20>?SQLite

3. <20>唳旿摨㯄<E691A8><E3AF84><EFBFBD>嚗㇊ostgreSQL <20>?SQLite嚗?

*Prisma Schema靽格㺿嚗<E3BABF><E59A97>撠𤩺㺿<F0A4A9BA><EFBFBD>嚗?

// electron-backend/prisma/schema.prisma

datasource db {
  // Web<65><62><EFBFBD>PostgreSQL
  // provider = "postgresql"
  // url      = env("DATABASE_URL")
  
  // Electron<6F><6E><EFBFBD>SQLite 潃?
  provider = "sqlite"
  url      = "file:./app.db"
}

// Model摰帋<E691B0><EFBFBD><E691B0>銝滚<E98A9D> <20>?
model User {
  id        String   @id @default(uuid())
  email     String   @unique
  password  String
  name      String?
  
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
  
  @@map("users")
}

*瘜冽<EFBFBD>鈭钅★嚗?

// SQLite銝齿𣈲<E9BDBF><F0A388B2><EFBFBD>鈭𢏺ostgreSQL<51><EFBFBD>?

// <20>?PostgreSQL<51><EFBFBD>嚗玺QLite銝齿𣈲<E9BDBF><F0A388B2><EFBFBD>
- JSON<EFBFBD>㛖掩<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>TEXT摮睃<EFBFBD>?
- 憭齿<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?
- <EFBFBD>𣂷<EFBFBD><EFBFBD>𡁜<EFBFBD><EFBFBD>賣㺭

// <20>?閫<><E996AB><EFBFBD><EFBFBD>嚗?
// 1. <20>汽EXT摮睃<E691AE>JSON嚗<4E><E59A97><EFBFBD><EFBFBD><E585B8><EFBFBD>嚗?
model Config {
  id    String @id
  data  String  // JSON.stringify(data)
}

// 2. 蝞<><E89D9E>𡝗䰻霂<E99C82><EFBD87><EFBFBD>憭齿<E686AD>SQL嚗?
// 3. <20><EFBFBD><E585B8><EFBFBD>摰䂿緵<E482BF>𣂷<EFBFBD><F0A382B7><EFBFBD>

摰峕㟲憿寧𤌍蝏𤘪<EFBFBD>

AIclinicalresearch/
  <20><EFBFBD><E98EBF><EFBFBD> packages/                    # <20>曹澈隞<E6BE88><E99A9E>嚗㇈onorepo嚗?
  <20>?  <20><EFBFBD><E98EBF><EFBFBD> frontend-core/           # <20>滨垢<E6BBA8><EFBFBD>嚗Áeb + Electron憭滨鍂嚗?
  <20>?  <20><EFBFBD><E98EBF><EFBFBD> backend-core/            # <20>𡒊垢<F0A1928A><EFBFBD>嚗Áeb + Electron憭滨鍂嚗?
  <20>?  <20><EFBFBD><E5A999><EFBFBD> shared-types/            # <20>曹澈蝐餃<E89D90>摰帋<E691B0>
  <20>?
  <20><EFBFBD><E98EBF><EFBFBD> apps/
  <20>?  <20><EFBFBD><E98EBF><EFBFBD> web/                     # Web<65><62><EFBFBD>敶枏<E695B6>嚗?
  <20>?  <20>?  <20><EFBFBD><E98EBF><EFBFBD> frontend/
  <20>?  <20>?  <20><EFBFBD><E5A999><EFBFBD> backend/
  <20>?  <20>?
  <20>?  <20><EFBFBD><E5A999><EFBFBD> electron/                # Electron<6F>?潃?
  <20>?      <20><EFBFBD><E98EBF><EFBFBD> main/                # 銝餉<E98A9D>蝔页<E89D94>Node.js<6A>𡒊垢嚗?
  <20>?      <20>?  <20><EFBFBD><E98EBF><EFBFBD> src/
  <20>?      <20>?  <20>?  <20><EFBFBD><E98EBF><EFBFBD> main.ts      # Electron<6F>亙藁
  <20>?      <20>?  <20>?  <20><EFBFBD><E98EBF><EFBFBD> ipc-handlers.ts  # IPC憭<43><E686AD><EFBFBD>?
  <20>?      <20>?  <20>?  <20><EFBFBD><E98EBF><EFBFBD> services/    # 憭滨鍂backend-core
  <20>?      <20>?  <20>?  <20><EFBFBD><E5A999><EFBFBD> prisma/
  <20>?      <20>?  <20>?      <20><EFBFBD><E5A999><EFBFBD> schema.prisma  # SQLite<74><65>𧋦
  <20>?      <20>?  <20><EFBFBD><E5A999><EFBFBD> package.json
  <20>?      <20>?
  <20>?      <20><EFBFBD><E98EBF><EFBFBD> renderer/            # 皜脫<E79A9C>餈𤤿<E9A488>嚗㇌eact<63>滨垢嚗?
  <20>?      <20>?  <20><EFBFBD><E98EBF><EFBFBD> src/
  <20>?      <20>?  <20>?  <20><EFBFBD><E98EBF><EFBFBD> main.tsx
  <20>?      <20>?  <20>?  <20><EFBFBD><E98EBF><EFBFBD> api/         # IPC摰<E691B0>蝡?
  <20>?      <20>?  <20>?  <20><EFBFBD><E98EBF><EFBFBD> pages/       # 憭滨鍂frontend-core
  <20>?      <20>?  <20>?  <20><EFBFBD><E5A999><EFBFBD> components/  # 憭滨鍂frontend-core
  <20>?      <20>?  <20><EFBFBD><E5A999><EFBFBD> package.json
  <20>?      <20>?
  <20>?      <20><EFBFBD><E98EBF><EFBFBD> resources/           # <20><EFBFBD><EFBFBD><E99F8F>
  <20>?      <20>?  <20><EFBFBD><E98EBF><EFBFBD> python/          # Python餈鞱<E9A488><E99EB1>?
  <20>?      <20>?  <20><EFBFBD><E98EBF><EFBFBD> r/               # R餈鞱<E9A488><E99EB1><EFBFBD><EFBFBD><E68692><EFBFBD><E996AC>
  <20>?      <20>?  <20><EFBFBD><E5A999><EFBFBD> assets/
  <20>?      <20>?
  <20>?      <20><EFBFBD><E5A999><EFBFBD> electron-builder.yml # <20><EFBFBD><E69E8F>滨蔭
  <20>?
  <20><EFBFBD><E5A999><EFBFBD> ...

<EFBFBD>喲睸摰䂿緵蝏<EFBFBD><EFBFBD>

1. Electron銝餉<E98A9D>蝔页<E89D94>main.ts嚗?

// apps/electron/main/src/main.ts

import { app, BrowserWindow, ipcMain } from 'electron';
import path from 'path';
import { setupIpcHandlers } from './ipc-handlers';
import { initDatabase } from './database';
import { startPythonService } from './python-service';

let mainWindow: BrowserWindow | null = null;

async function createWindow() {
  // 1. <20>𥕦遣瘚讛<E7989A><E8AE9B><EFBFBD><E587BD>?
  mainWindow = new BrowserWindow({
    width: 1200,
    height: 800,
    webPreferences: {
      nodeIntegration: false,
      contextIsolation: true,
      preload: path.join(__dirname, 'preload.js')  // 摰匧<E691B0><E58CA7><EFBFBD>PC獢交𦻖
    }
  });
  
  // 2. <20>㰘蝸<E3B098>滨垢嚗<E59EA2><E59A97>鈭抒㴓憓<E3B493><E68693>
  if (app.isPackaged) {
    mainWindow.loadFile(path.join(__dirname, '../renderer/index.html'));
  } else {
    // 撘<><E69298>𤑳㴓憓<E3B493><E68693>餈墧𦻖<E5A2A7>訓ite撘<65><E69298><EFBFBD><E78390>    mainWindow.loadURL('http://localhost:5173');
  }
  
  // 3. <20><EFBFBD><E598A5>𡝗㺭<F0A19D97><EFBFBD>
  await initDatabase();
  
  // 4. <20>臬𢆡Python<6F><6E>﹝憭<EFB99D><E686AD><EFBFBD>滚𦛚
  await startPythonService();
  
  // 5. 霈曄蔭IPC憭<43><E686AD><EFBFBD>?
  setupIpcHandlers();
}

// Electron<6F>笔𦶢<E7AC94><EFBFBD>
app.whenReady().then(createWindow);

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

app.on('activate', () => {
  if (BrowserWindow.getAllWindows().length === 0) {
    createWindow();
  }
});

2. IPC憭<43><E686AD><EFBFBD><EFBFBD>ipc-handlers.ts嚗?

// apps/electron/main/src/ipc-handlers.ts

import { ipcMain } from 'electron';
import { prisma } from './prisma-client';

// 憭滨鍂銝𡁜𦛚<F0A1819C><EFBFBD> 潃?
import { UserService } from '@yizhengxun/backend-core/services';
import { ProjectService } from '@yizhengxun/backend-core/services';
import { ConversationService } from '@yizhengxun/backend-core/services';

export function setupIpcHandlers() {
  // <20><EFBFBD><E598A5>𡝗<EFBFBD><F0A19D97>?
  const userService = new UserService(prisma);
  const projectService = new ProjectService(prisma);
  const conversationService = new ConversationService(prisma);
  
  // <20><EFBFBD><E586BD><EFBFBD>API
  ipcMain.handle('api:users:list', async () => {
    return userService.findAll();
  });
  
  ipcMain.handle('api:users:create', async (event, data) => {
    return userService.create(data);
  });
  
  // 憿寧𤌍<E5AFA7><EFBFBD>API
  ipcMain.handle('api:projects:list', async (event, userId) => {
    return projectService.findByUser(userId);
  });
  
  ipcMain.handle('api:projects:create', async (event, data) => {
    return projectService.create(data);
  });
  
  // 撖寡<E69296><E5AFA1><EFBFBD>API
  ipcMain.handle('api:conversations:create', async (event, data) => {
    return conversationService.create(data);
  });
  
  ipcMain.handle('api:conversations:chat', async (event, data) => {
    // 靚<>鍂LLM嚗<4D>𧋦<EFBFBD><EFBFBD>鈭𤑳垢API嚗?
    return conversationService.chat(data);
  });
  
  // <20><><EFBFBD><EFBFBD>
  ipcMain.handle('api:files:upload', async (event, file) => {
    // 靽嘥<E99DBD><E598A5>唳𧋦<E594B3><EFBFBD>隞嗥頂蝏?
    const filePath = await saveFile(file);
    return { url: filePath };
  });
}

3. <20>滨垢IPC摰<E691B0>蝡荔<E89DA1>api-client.ts嚗?

// apps/electron/renderer/src/api/client.ts

const { ipcRenderer } = window.require('electron');

export const apiClient = {
  // <20><EFBFBD>API
  users: {
    async list() {
      return ipcRenderer.invoke('api:users:list');
    },
    async create(data: any) {
      return ipcRenderer.invoke('api:users:create', data);
    }
  },
  
  // 憿寧𤌍API
  projects: {
    async list(userId: string) {
      return ipcRenderer.invoke('api:projects:list', userId);
    },
    async create(data: any) {
      return ipcRenderer.invoke('api:projects:create', data);
    }
  },
  
  // 撖寡<E69296>API
  conversations: {
    async create(data: any) {
      return ipcRenderer.invoke('api:conversations:create', data);
    },
    async chat(data: any) {
      return ipcRenderer.invoke('api:conversations:chat', data);
    }
  },
  
  // <20><>辣銝𠹺<E98A9D>
  files: {
    async upload(file: File) {
      // 撠<>ile頧祆揢銝慷uffer
      const buffer = await file.arrayBuffer();
      return ipcRenderer.invoke('api:files:upload', {
        name: file.name,
        data: Buffer.from(buffer)
      });
    }
  }
};

4. Python摮鞱<E691AE>蝔讠恣<E8AEA0>?

// apps/electron/main/src/python-service.ts

import { spawn, ChildProcess } from 'child_process';
import path from 'path';
import { app } from 'electron';

let pythonProcess: ChildProcess | null = null;

export async function startPythonService(): Promise<void> {
  return new Promise((resolve, reject) => {
    // Python餈鞱<E9A488><E99EB1>嗉楝敺<E6A59D><E695BA><EFBFBD><EFBFBD><E69E8F><EFBFBD><E59785><EFBFBD>
    const pythonPath = app.isPackaged
      ? path.join(process.resourcesPath, 'python', 'python.exe')
      : 'python';  // 撘<><E69298>𤑳㴓憓<E3B493><EFBFBD>函頂蝏𡼏ython
    
    // Python<6F>𡁏𧋦頝臬<E9A09D>
    const scriptPath = app.isPackaged
      ? path.join(process.resourcesPath, 'python', 'extraction_service', 'main.py')
      : path.join(__dirname, '../../../../extraction_service/main.py');
    
    // <20>臬𢆡Python餈𤤿<E9A488>
    pythonProcess = spawn(pythonPath, [
      '-m', 'uvicorn',
      'main:app',
      '--host', '127.0.0.1',
      '--port', '8000'
    ], {
      cwd: path.dirname(scriptPath),
      stdio: 'pipe'
    });
    
    // <20>穃𨯬颲枏枂
    pythonProcess.stdout?.on('data', (data) => {
      console.log(`Python: ${data}`);
      if (data.toString().includes('Application startup complete')) {
        resolve();
      }
    });
    
    pythonProcess.stderr?.on('data', (data) => {
      console.error(`Python Error: ${data}`);
    });
    
    pythonProcess.on('error', reject);
  });
}

export function stopPythonService(): void {
  if (pythonProcess) {
    pythonProcess.kill();
    pythonProcess = null;
  }
}

// 摨𠉛鍂<F0A0899B><E98D82><EFBFBD>箸𧒄<E7AEB8>喲𡡒Python<6F>滚𦛚
app.on('will-quit', stopPythonService);

5. <20><EFBFBD><E69E8F>滨蔭嚗Ềlectron-builder.yml嚗?

# apps/electron/electron-builder.yml

appId: com.yizhengxun.aiclinical
productName: 憯寡<EFBFBD>敺服I蝘𤑳<EFBFBD><EFBFBD><EFBFBD>

# <20><EFBFBD><E69E8F><EFBFBD>
directories:
  output: dist
  buildResources: resources

# Windows<77>滨蔭
win:
  target:
    - nsis
    - portable
  icon: resources/icon.ico

# NSIS摰㕑<E691B0>蝔见<E89D94><E8A781>滨蔭
nsis:
  oneClick: false
  allowToChangeInstallationDirectory: true
  createDesktopShortcut: always
  createStartMenuShortcut: true

# Mac<61>滨蔭
mac:
  target:
    - dmg
    - zip
  icon: resources/icon.icns
  category: public.app-category.productivity

# <20><EFBFBD><E69E8F><EFBFBD><EFBFBD><E98984><EFBFBD>隞?
files:
  - "main/**/*"
  - "renderer/**/*"
  - "!**/*.ts"
  - "!**/*.map"

# 憸嘥<E686B8><EFBFBD><E99F8F>嚗㇊ython餈鞱<E9A488><E99EB1><EFBFBD>嚗?
extraResources:
  - from: resources/python
    to: python
  - from: ../../../../extraction_service
    to: python/extraction_service

# <20><EFBFBD><E69E8F>𤾸之撠?
asar: true
asarUnpack:
  - "**/*.node"
  - "resources/**/*"

<EFBFBD>閙㦤<EFBFBD><EFBFBD><EFBFBD><EFBFBD>喲睸<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?

<EFBFBD><EFBFBD>1嚗𡁏<EFBFBD><EFBFBD><EFBFBD><EFBFBD>蝘荔<EFBFBD>500MB+嚗?

*<EFBFBD><EFBFBD><EFBFBD><EFBFBD>捆嚗?

摰㕑<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
- Electron獢<6E>沲嚗鰺100MB
- Node.js餈鞱<E9A488><E99EB1><EFBFBD><E5A19A><EFBFBD><EFBFBD>汞lectron銝?
- <20>滨垢隞<E59EA2><E99A9E><EFBFBD><E59A97>霂穃<E99C82>嚗㚁<E59A97>~10MB
- <20>𡒊垢隞<E59EA2><E99A9E><EFBFBD><E59A97>霂穃<E99C82>嚗㚁<E59A97>~5MB
- SQLite<74>唳旿摨橒<E691A8>~5MB嚗<42>征摨橒<E691A8>
- Python餈鞱<E9A488><E99EB1><EFBFBD>~150MB
- Python靘肽<E99D98>嚗鰺100MB
- R餈鞱<E9A488><E99EB1><EFBFBD><E5A19A><EFBFBD><EFBFBD>嚗鰺200MB
- R靘肽<E99D98><EFBFBD><EFBFBD><EFBFBD>嚗鰺100MB

<0A>餉恣嚗?00-700MB

*隡睃<EFBFBD><EFBFBD><EFBFBD>嚗?

  1. <EFBFBD>?雿輻鍂ASAR<41>讠憬嚗𠄌lectron暺䁅恕嚗?
  2. <EFBFBD>?銝滚<E98A9D><E6BB9A>俘餈鞱<E9A488><E99EB1><EFBFBD><EFBFBD><E99A9E>蝡舐<E89DA1><E88890><EFBFBD><EFBFBD><E996AC>
  3. <EFBFBD>?Python靘肽<E99D98>蝎曄<E89D8E><EFBFBD><EFBFBD><E898A8>鉄敹<E98984><E695B9><EFBFBD><EFBFBD><EFBFBD>嚗?
  4. <EFBFBD>?憓鮋<E68693><E9AE8B>湔鰵嚗<E9B0B5>蘨銝贝蝸<E8B49D><EFBFBD><E79D83><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>

<EFBFBD><EFBFBD>2嚗朞楊撟喳蝱<EFBFBD>澆捆<EFBFBD>?

<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>

  • Windows x64
  • Windows ARM64嚗𠄎urface蝑㕑挽憭<E68CBD><E686AD>
  • macOS x64
  • macOS ARM64嚗㇁pple Silicon嚗?
  • Linux x64

瘚贝<EFBFBD>撌乩<EFBFBD><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嚗朞䌊<EFBFBD>冽凒<EFBFBD>?

*electron-updater<65>滨蔭嚗?

// apps/electron/main/src/updater.ts

import { autoUpdater } from 'electron-updater';
import { dialog } from 'electron';

export function setupAutoUpdater() {
  // <20>滨蔭<E6BBA8>湔鰵<E6B994>滚𦛚<E6BB9A>?
  autoUpdater.setFeedURL({
    provider: 'generic',
    url: 'https://releases.yizhengxun.com'
  });
  
  // 璉<><E79289>交凒<E4BAA4>?
  autoUpdater.checkForUpdatesAndNotify();
  
  // <20>𤑳緵<F0A491B3><EFBFBD><E59581>?
  autoUpdater.on('update-available', () => {
    dialog.showMessageBox({
      type: 'info',
      title: '<27>𤑳緵<F0A491B3><EFBFBD><E59581>?,
      message: '<EFBFBD>瘚见<EFBFBD><EFBFBD><EFBFBD><EFBFBD>穿<EFBFBD><EFBFBD>臬炏蝡见朖銝贝蝸嚗?,
      buttons: ['<27>?, '<EFBFBD>?]
    }).then((result) => {
      if (result.response === 0) {
        autoUpdater.downloadUpdate();
      }
    });
  });
  
  // 銝贝蝸摰峕<E691B0>
  autoUpdater.on('update-downloaded', () => {
    dialog.showMessageBox({
      type: 'info',
      title: '<27>湔鰵撌脣停蝏?,
      message: '<EFBFBD><EFBFBD><EFBFBD>砍歇銝贝蝸嚗峕糓<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>',
      buttons: ['蝡见朖摰㕑<EFBFBD>', '蝔滚<EFBFBD>']
    }).then((result) => {
      if (result.response === 0) {
        autoUpdater.quitAndInstall();
      }
    });
  });
}

<EFBFBD><EFBFBD> <20><EFBFBD>撖寞<E69296>

銝厩<EFBFBD><EFBFBD>函蔡<EFBFBD><EFBFBD>撖寞<EFBFBD>

蝏游漲 鈭𤑳垢SaaS <EFBFBD><EFBFBD>鈭批<EFBFBD><EFBFBD>? Electron<EFBFBD>閙㦤<EFBFBD>?
<EFBFBD>函蔡<EFBFBD><EFBFBD> 鈭𤑳垢<EFBFBD>滚𦛚<EFBFBD>? Docker摰孵膥 <EFBFBD>砍𧑐摰㕑<EFBFBD>
<EFBFBD>唳旿摮睃<EFBFBD> 鈭𤑳垢PostgreSQL <EFBFBD>砍𧑐PostgreSQL <EFBFBD>砍𧑐SQLite
*蝵𤑳<EFBFBD><EFBFBD><EFBFBD>瘙? <EFBFBD><EFBFBD>𠉛<EFBFBD> <EFBFBD>舐氖蝥選<EFBFBD>LLM<EFBFBD><EFBFBD>嚗? <EFBFBD><EFBFBD>蝳餌瑪
<EFBFBD>湔鰵<EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD>交凒<EFBFBD>? Docker<EFBFBD>𨅯<EFBFBD><EFBFBD>湔鰵 摨𠉛鍂<EFBFBD><EFBFBD><EFBFBD>?
摰㕑<EFBFBD><EFBFBD>曉漲 <EFBFBD>𣳇<EFBFBD>摰㕑<EFBFBD> Docker<EFBFBD>函蔡 <EFBFBD><EFBFBD><EFBFBD>鋆?
<EFBFBD><EFBFBD>憭滨鍂 100% 80%嚗<>移蝞<E7A7BB><E89D9E><EFBFBD><EFBFBD> 90%
<EFBFBD><EFBFBD>鍂摰<EFBFBD> 銝芯犖<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD>駁堺<EFBFBD><EFBFBD><EFBFBD><EFBFBD> 銝芯犖<EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD>? <EFBFBD>甈⊥<EFBFBD>兵icense <EFBFBD>甈⊥<EFBFBD>扯揚銋?
蝏湔擪<EFBFBD>鞉𧋦 雿? 銝? 擃?

<EFBFBD><20><><EFBFBD>遣霈?

<EFBFBD><EFBFBD>𧫴畾萄<EFBFBD><EFBFBD>?

<EFBFBD>嗆挾銝<EFBFBD><EFBFBD><EFBFBD><EFBFBD>?6銝芣<E98A9D>嚗㚁<E59A97>

  • <EFBFBD>?銝𤘪釣鈭𤑳垢SaaS<61>?
  • <EFBFBD>?摰<><E691B0>7銝芯<E98A9D><E88AAF>⊥芋<E28AA5>?
  • <EFBFBD>?撱箇<E692B1>Monorepo<70><EFBFBD><EFBFBD><EFBFBD>芣䔉<E88AA3>枏抅蝖<E68A85>嚗?

<EFBFBD>嗆挾鈭䕘<EFBFBD>6-12銝芣<E98A9D>嚗㚁<E59A97>

  • <EFBFBD>?撘<><E69298>𤑳𡠺蝡衤漣<E8A1A4><E6BCA3><EFBFBD><EFBFBD>恣蝔輻頂蝏麄<E89D8F><E9BA84>I<EFBFBD><49>讃嚗?
  • <EFBFBD>?<3F><EFBFBD>Docker<65>砍𧑐<E7A08D><EFBFBD>蝵?
  • <EFBFBD>?撉諹<E69289><E8ABB9><EFBFBD><EFBFBD><E79285>

<EFBFBD>嗆挾銝㚁<EFBFBD>12-18銝芣<E98A9D>嚗㚁<E59A97>

  • <EFBFBD>?撘<><E69298>䫿lectron<6F>閙㦤<E99699><E3A6A4><EFBFBD><EFBFBD><E68692><EFBFBD><EFBFBD><EFBFBD><E79899>
  • <EFBFBD>?<3F><EFBFBD><EFBFBD><E691B0>蝳餌瑪雿輻鍂
  • <EFBFBD>?<3F><EFBFBD>銝芯犖<E88AAF><EFBFBD><EFBFBD>

<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>亙𪑛銝芣䲮獢<EFBFBD><EFBFBD>

  1. <EFBFBD><EFBFBD><EFBFBD><EFBFBD>函蔡<EFBFBD><EFBFBD>祕蝏<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
  2. Electron<EFBFBD>閙㦤<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>𤏸恣<EFBFBD>𡜐<EFBFBD>
  3. Monorepo<EFBFBD><EFBFBD><EFBFBD><EFBFBD>挽霈∴<EFBFBD>