# PJ概要
OCIをインフラとした、マルチテナント・マルチサービスの高可用要件 業務向けSaaSのマルチチーム開発PJ
# 業務内容
初期はメインアプリケーションの機能開発。中期はマルチテナント接続制御の独自実装。この時期のPJのマルチサービス・マルチチーム要件化を受けて、PJ向けSSO(シングルサインオン)サービス用アプリケーションの設計・実装を担当。また、追加されたチームがマルチテナントDBに対して、1対1のアプリインスタンスの作成を主張したため、チーム間での設計齟齬を避ける目的で前述の接続制御コードのライブラリ化を提案。新規チームの信任を受けて作成。同時にOCIインフラ上でのマルチサービス連携の基礎設計とデプロイを担当。後期〜現在、正式にアプリチームと独立してインフラチームに所属し、OCIインフラ, SSOサービス, アプリコアライブラリ(同等機能のRust言語版ライブラリとして、Github上にanimagram.jp/state-engineを趣味の範囲で作成中)の設計実装管理を担当中。
年月 主な業務
2025年4月 研修(WSL・Git・Docker・PHP・Laravel環境構築)
2025年5月 統計機能開発
2025年6月 会計機能開発
2025年7月 会計機能開発(継続)
2025年8月 動的マルチテナントDB接続制御機能開発
2025年9月 PJシステム設計修正・OCIインフラ設計
2025年10月 OCIインフラ作成(一部リプレイス業務)・SSOアプリケーション設計及び実装
2025年11月 アプリコア向けPHPライブラリ(composer package)開発
2025年12月 PHPライブラリ
2026年1月 OCIインフラ更新・PHPライブラリ更新・SSOサービス・管理業務
# 解決済み課題1 マルチテナントDBへの動的接続制御の追加
2025年8月着手・達成
## 課題内容
1年以上の既往開発によってソースコードが膨大なLaravelアプリケーションへのマルチテナントDBへの接続制御機能追加
## 解決
アプリケーションの起動後の適切な作動順(認証ミドルウェアの直前)に、ユーザーから受け取る識別子から所属テナント識別子を割り出し、リクエストスコープコンテクストに入力するミドルウェアを作成。さらに、モデルファイル(データベーステーブル由来のオブジェクト定義ファイル)のうち、テナント識別子を利用して接続を決める必要があるモデルにのみ接続組み立てメソッドを動作させた。これにより、既存のDB呼び出し部に一切変更を加えず、ユーザー・テーブルごとに適切な接続を使用できる機能を実現した。
## 備考
Laravel Tenancyという既存の同要件向けライブラリがあるが、リファクタリング回避とテナント固有接続先以外に柔軟に接続先を選択できるため、独自実装とした。判断時は、事前にプロジェクトリーダーに相談を行っている。
# 解決済み課題2 要件変更に対応したOCIインフラの全面リプレイス
2025年9月着手・同10月達成
## 課題内容
PJの要件変更により、マルチテナントDB・マルチサービス連携が要求されるOCIインフラ環境の再設計とリプレイス作業
## 解決
PJチーム内で既にOKE・MySQL HeatWave(いずれもOCIのマネージドサービス)が技術選定されていたため、これらを組み合わせ、ワンマン管理に耐えられるようにterraformにて設計・既存アプリとDBデータを維持してインフラをリプレイスした。terraform applyによる、0からのOKE作成が、24時間を徹してもデバッグ不可であったため、断念してwebコンソール上でクイック作成したのちterraform importする方針に転換。課題を完了した。
## 備考
24時間連続でインフラに向けた作業をした点は、集中力の低下による事故を起こしかねない点で、反省している。また、プロセスが死ぬ(OCIによって失敗した作成物がまるごと自動消去される状況)では、ログの取り出しが非常に困難であり、ログのとれないデバッグ作業は非効率な手段であることを学んだ。
# 解決済み課題3 マルチチーム間でのサービス設計の統一
## 課題内容
PJ要件が、SSOを介したマルチサービスへ変更され、PJ外で開発を進めていた既存アプリのチームが、PJ内の1つのチームとして位置づけられた。このチームへ、発足時からのPJチームから前提共有が不十分だったため、マルチテナントDB要件を新チームが未想定だったことが発覚(発見・報告は私)、情報共有不足による不信感やオンプレ経験チームであったこともあり、1テナントに1アプリケーションプロセスを充てる方針を主張、チーム間で異なるインフラを要求していた。
## 解決
既に開発していたマルチテナントDB接続の動的制御を含むコード群を、composer packageとして切り出し、マルチテナント環境を未想定だったチームに導入提案。承認を受けてライブラリを開発。
## 備考
スケーリング不可欠な高可用サービスであり、コストやアプリ要件から、K8sの設計意図を汲んだ、1ネームスペース1サービス、1アプリケーションが全てのテナントを処理可能、という設計が最も合理的であると判断した。
## その他 技術的判断例
2025年10月 着手・完了
SSO(Single Sign-on)の設計にあたり、同ルートドメインを持つ複数サービスへ、最もセキュアで確実なトークンの受け渡し方として、httponly cookieを選択。SSOアプリケーションは、SSOのフロントにアクセスし、JWTステートレストークンの発行を受ける。ブラウザクライアントはcookieにJWTトークンを保持した状態で、SSOアプリによって各アプリの特定エンドポイントにリダイレクト。リダイレクト先のクライアントアプリはSSOと共有している公開鍵によってJWTをencodeする、という設計を行い、実装・デプロイまでを1ヶ月で行った。