アーキテクチャ図
レイヤ構成・コンポーネント分割・デプロイ構成を示します。
1. レイヤ構成(論理アーキテクチャ)
flowchart TB
subgraph P["プレゼンテーション層(ブラウザ SPA)"]
A1["app.js(画面制御・状態管理・WSクライアント)"]
A2["markdown.js(Markdown→HTML 変換)"]
A3["style.css / index.html"]
end
subgraph E["エッジ層(ASGIミドルウェア)"]
M1["PrivateNetworkGuard
(プライベートNW限定)"]
M2["TLS 終端(自己署名証明書)"]
end
subgraph C["アプリケーション層(FastAPI ルーター)"]
R1["auth / users"]
R2["servers / invites"]
R3["messages / dms"]
R4["files / render"]
R5["ws(WebSocket・既読)"]
end
subgraph S["ドメイン・サービス層"]
SV1["services.py
(権限判定・整形・通知対象解決)"]
SV2["security.py
(ハッシュ・トークン)"]
SV3["ws_manager.py
(ConnectionManager)"]
end
subgraph D["データアクセス層"]
O1["models.py(ORMエンティティ)"]
O2["database.py(Session/Engine)"]
end
subgraph I["インフラ層"]
DB[("SQLite")]
FS[("ローカルファイル
uploads")]
PU["PlantUML jar + JRE"]
end
P --> E --> C --> S --> D --> I
R4 --> PU
flowchart TB
subgraph P["Presentation layer (browser SPA)"]
A1["app.js (UI control, state, WS client)"]
A2["markdown.js (Markdown to HTML)"]
A3["style.css / index.html"]
end
subgraph E["Edge layer (ASGI middleware)"]
M1["PrivateNetworkGuard
(private network only)"]
M2["TLS termination (self-signed cert)"]
end
subgraph C["Application layer (FastAPI routers)"]
R1["auth / users"]
R2["servers / invites"]
R3["messages / dms"]
R4["files / render"]
R5["ws (WebSocket, read state)"]
end
subgraph S["Domain / service layer"]
SV1["services.py
(authorization, serialization, targets)"]
SV2["security.py
(hashing, tokens)"]
SV3["ws_manager.py
(ConnectionManager)"]
end
subgraph D["Data access layer"]
O1["models.py (ORM entities)"]
O2["database.py (Session/Engine)"]
end
subgraph I["Infrastructure layer"]
DB[("SQLite")]
FS[("Local files
uploads")]
PU["PlantUML jar + JRE"]
end
P --> E --> C --> S --> D --> I
R4 --> PU
図2. 論理レイヤ構成。上位層は下位層にのみ依存する一方向の依存関係。
2. コンポーネント構成(バックエンド)
flowchart LR main["main.py
(アプリ起動・ルーター登録)"] subgraph routers["routers/"] auth["auth.py"] users["users.py"] servers["servers.py"] invites["invites.py"] messages["messages.py"] dms["dms.py"] files["files.py"] render["render.py"] ws["ws.py"] end deps["deps.py
get_current_user"] services["services.py"] security["security.py"] wsm["ws_manager.py
manager"] models["models.py"] database["database.py"] config["config.py / settings"] guard["network_guard.py"] tls["tls.py"] main --> routers main --> guard main --> tls main --> config routers --> deps routers --> services routers --> models messages --> wsm dms --> wsm ws --> wsm auth --> security deps --> security services --> models models --> database database --> config
flowchart LR main["main.py
(startup, router registration)"] subgraph routers["routers/"] auth["auth.py"] users["users.py"] servers["servers.py"] invites["invites.py"] messages["messages.py"] dms["dms.py"] files["files.py"] render["render.py"] ws["ws.py"] end deps["deps.py
get_current_user"] services["services.py"] security["security.py"] wsm["ws_manager.py
manager"] models["models.py"] database["database.py"] config["config.py / settings"] guard["network_guard.py"] tls["tls.py"] main --> routers main --> guard main --> tls main --> config routers --> deps routers --> services routers --> models messages --> wsm dms --> wsm ws --> wsm auth --> security deps --> security services --> models models --> database database --> config
図3. バックエンドのモジュール依存関係。リアルタイム配信が必要なルーターのみ ws_manager に依存する。
3. デプロイ構成
flowchart TB
subgraph host["社内サーバーホスト(オンプレミス / Windows)"]
subgraph proc["uvicorn プロセス"]
app["backend.main:app(FastAPI)"]
end
subgraph rt["同梱ランタイム"]
jre["runtime/jdk-17 JRE"]
jar["plantuml/plantuml-*.jar"]
end
subgraph data["data/"]
sqlite[("localchat.db")]
uploads[("uploads/")]
end
certs["certs/server.crt + server.key
(自己署名・自動生成)"]
frontend["frontend/(静的配信)"]
end
pc1["社員PC(ブラウザ)"]
pc2["社員PC(ブラウザ)"]
pc1 -- "HTTPS/WSS
社内LAN" --> app
pc2 -- "HTTPS/WSS
社内LAN" --> app
app --> sqlite
app --> uploads
app --> certs
app --> frontend
app --> jre
jre --> jar
flowchart TB
subgraph host["On-prem server host (Windows)"]
subgraph proc["uvicorn process"]
app["backend.main:app (FastAPI)"]
end
subgraph rt["Bundled runtime"]
jre["runtime/jdk-17 JRE"]
jar["plantuml/plantuml-*.jar"]
end
subgraph data["data/"]
sqlite[("localchat.db")]
uploads[("uploads/")]
end
certs["certs/server.crt + server.key
(self-signed, auto-generated)"]
frontend["frontend/ (static hosting)"]
end
pc1["Employee PC (browser)"]
pc2["Employee PC (browser)"]
pc1 -- "HTTPS/WSS
LAN" --> app
pc2 -- "HTTPS/WSS
LAN" --> app
app --> sqlite
app --> uploads
app --> certs
app --> frontend
app --> jre
jre --> jar
図4. デプロイ構成。単一ホスト上で uvicorn が全機能を提供する。DB・ファイル・証明書・ランタイムをすべてローカルに保持する。
4. 主な設計方針
| 方針 | 内容 |
|---|---|
| 完全オフライン | 外部CDN・クラウド・SaaSに一切接続しない。依存ライブラリ・ランタイム・図表エンジンをすべて同梱。 |
| 閉域網限定 | <code>PrivateNetworkGuard</code> によりプライベートIP以外からのHTTP/WebSocketを拒否(多層防御)。 |
| 外部依存の最小化 | パスワードハッシュ・トークン署名を標準ライブラリのみで実装(bcrypt/jose不使用)。 |
| 単一プロセス | メッセージブローカーを使わず、プロセス内 <code>ConnectionManager</code> でWS接続を管理。 |
| 段階的フォールバック | PlantUML未導入時はソース表示にフォールバックし、機能停止させない。 |