前回の記事(続きものです):https://qiita.com/arika1125/items/b92746c784a6efc47307
リポジトリ:https://github.com/KanadeYumesaki/dom-enterprise-gateway
1. この記事でやったこと(今日の成果)
P0 の実装は進んでいたものの、バックエンドとフロントエンドを統合して実際に操作できる状態(= PoCとして触れる状態)までは到達していませんでした。
そこで今回は、PoCコスト最小の方針を守りつつ、
- Docker Compose で Backend / Frontend(SSR) / Postgres / Redis / Nginx を一括起動
- OIDC(IdP)なしでも /login → /chat まで到達できる Dev認証(P0.1) を追加
- Settings / Help の Backend API 実装 + Frontend 統合(UIも最低限動く)
- pytest を green に戻す(回帰防止)
- UI/UX 崩れ(パス二重、Cookie未送信、アイコン文字化け等)を修正
までを通しで行いました。
2. 技術スタック(P0)
- Backend: Python 3.12 / FastAPI / LangChain v1 / SQLAlchemy / Alembic(将来) / pytest
- Frontend: Angular 20 / SSR / Zoneless / Signals / Angular Material (MD3)
- Infra: PostgreSQL 15 + pgvector / Redis / Docker Compose / Nginx
3. 全体アーキテクチャ(P0 / P0.1)
ポイントは Nginx を入口に置き、/api だけバックエンドへ流す構成にしたことです。
- フロントを「開発プロキシ」でごまかさず、本番に近いルーティングになります
- CORS 回避にも効きます
4. P0.1:最小コストの “Dev 認証” を追加した理由
P0 の理想は BFF + OIDC(Keycloak等) ですが、PoCの段階でIdPを用意し始めると、
- セットアップの工数
- 環境差分(WSL / Docker / 端末)
- 設定ミスのデバッグ
で時間が溶けがちです。
そこで P0.1 は割り切って、
-
DEV_AUTH_ENABLED=trueのときだけ有効 -
/api/v1/auth/login→/api/v1/auth/callbackで ダミーユーザーの Cookie セッションを発行 - それ以外(DEV無効時)は 501 を返して「本番OIDCは未実装」を明示
という「PoCの入口」を用意しました。
重要:これは“本番用の認証”ではなく、PoCを触れるようにするためのショートカットです。
5. 7.4:user_settings / help を「ちゃんとBackend連携」させた
5.1 Backend(user_settings & help API)
-
GET /api/v1/user/settings/POST /api/v1/user/settingsを実装(部分更新対応) -
GET /api/v1/help/contentを実装(セクション/カテゴリ指定) - テスト追加・修正で回帰しないように
5.2 Frontend(ApiService 統合 + UI側の安定化)
-
apiBaseUrl の二重
/api問題を解消(/api/v1に統一) - Dev認証の Cookie を API 呼び出しに乗せるため
withCredentials: trueを統一 - SSR で落ちないよう
window参照をガード
6. つまずきポイントと解決(実務っぽいトラブルシュート集)
6.1 /api/api/... になって 404 連発
Nginx で /api -> backend にしているのに、フロント側が apiBaseUrl='/api' のままさらに /api を付けてしまい、
- 実リクエストが
/api/api/v1/...
になっていました。
対処:ApiService のパス設計を整理して /api/v1 に一元化。
6.2 Dev認証できたのに API が全部 401(Cookieが送られてない)
Dev認証は Cookie セッションを使います。
Angular の HttpClient はデフォルトだと Cookie を送らないため、
-
/auth/meは curl で通る - でも UI からの API は 401
になりました。
対処:ApiService の全リクエストで withCredentials: true を適用。
6.3 Material アイコンが文字化け(ch や se が見える)
mat-icon がフォントを見つけられず、文字として表示されていました。
対処:index.html と styles.scss に Material Symbols / Roboto を追加。
6.4 relation "t_chat_session" does not exist(テーブル未作成)
Docker Compose で DB を起動しても、マイグレーションを回さないと当然テーブルは増えません。
PoCでは「まず触れる」が重要なので、開発時だけのショートカットを用意しました。
対処:AUTO_CREATE_DB=true のときだけ、起動時に Base.metadata.create_all を実行。
本番では必ず
AUTO_CREATE_DB=falseで Alembic 管理に寄せます。
6.5 ResponseValidationError: updated_at is None
APIレスポンススキーマが updated_at: datetime を必須にしているのに、DB側は NULL があり得て 500。
対処:
- モデルの
updated_atのデフォルト/nullable 方針を見直す - 既存データが null の場合のバックフィル(DEVのみ)
- スキーマ側も「レガシーを許容」する設計に
7. 今日の作業で「人がやったこと」「AIがやったこと」
人がやったこと(現場での手)
- WSL2 上で実行して 実ログ/エラーを回収
- Docker / curl / ブラウザの Network タブで挙動を確認
- 「PoCコスト最小」など、判断軸(スコープ)を決める
AIがやったこと(設計・実装支援)
- 実装方針の整理(P0/P0.1の切り分け)
- Codex に渡すための指示文(原因調査→修正、推測禁止のルール込み)
- エラー原因の仮説立てと、修正パスの提示
- テストが green になるまでの収束(pytest / 型 / SSR / ルーティング)
8. WSL2 での起動・確認(PoC手順)
コマンドは WSL2 (Ubuntu) 内で実行します。
cd ~/work/dom-enterprise-gateway
# 起動
docker compose up --build -d
# 動作確認(例:未ログインなら 401)
curl -i http://localhost/api/v1/auth/me
ブラウザで:
-
http://localhost/login→ ログイン →/chatに遷移 -
/settings/helpも開ける
テスト(WSL):
# Backend
cd ~/work/dom-enterprise-gateway/backend
poetry run pytest
# Frontend(Chrome/Chromium が必要)
cd ~/work/dom-enterprise-gateway/frontend
npm run build
ng test --watch=false
9. 次(P1)にやること
- Dev認証を残したまま、BFF + OIDC に差し替え
- Keycloak の realm/client/role(
admin/user)運用 - Cookieセッションや CSRF 対策など、本番に寄せる
10. まとめ
今日は「実装が進んでいるPoC」を、
- 起動できる
- ログインできる
- チャット画面まで触れる
という “動くPoC” に寄せる作業をやり切りました。
AIソリューションアーキテクト視点だと、実装そのもの以上に
- どういう順番で統合して、どこで詰まり、どう切り分けるか
- どこを PoC で割り切って、どこを P1 で本気にするか
の判断が重要だと改めて実感しました。
次は P1 として、Keycloak を前提に本物の OIDC フローに移行していきます。