プロジェクト · 2019 · リード

Elevatus:AI 搭載マルチテナント採用 SaaS

Elevatus のロードマップ実行とマイクロサービスへの移行をリード--中東の企業と政府向けクラウド採用プラットフォームで、Keycloak・Camunda・DDD を本格運用した記録。

Client-server architecture diagram showing request-response flow, hero image for architecture topic posts.

Elevatus は本物だ。今日 elevatus.jobs で動いている。中東の政府が公務員採用ラウンドに使っている。1000人規模の HR オペレーションを持つ企業も使っている。どちらも—異なるテナント、まったく異なるコンプライアンスの包絡線—が同じコアプラットフォームで動いている。

2018年から2020年にかけて Talentera(現 Elevatus)のロードマップチームでテクニカルチームリーダー兼 IC アーキテクトを担当した。私が構築したもの、リードしたもの、間違いを犯した場所—それがこのケーススタディが扱うことだ。

出発点:AOL/Navi サーバー上の TCL/TK

いや、タイポじゃない。

参加した時点では、コードベースの一部は AOL/Navi ウェブサーバー上の Tcl/Tk で動いていた—製品がエンタープライズ SLA を扱うことを期待されている一方でサポート切れを迎えつつあるスタックだ。PHP 7 モノリス、成長する Vue.js フロントエンド、一貫したサービス間コントラクトのない初期 Java 8 サービスも抱えていた。

マイグレーションはグリーンフィールドじゃなかった。そんなことはない。月曜朝のダウンタイムを許容できない政府省庁というライブテナントを抱えながら、デカップリングされるよう設計されたことのないシステムを同時にデカップリングしている。アプローチはストラングラーフィグだった:新機能は初日から境界付きコンテキストのマイクロサービスとして実装された;レガシーサーフェスは段階的に置き換えられた。ルーティングレイヤー(Nginx、後に API ゲートウェイ)がカットをクライアントに見えないようにした。

強制機能としてのドメイン駆動設計

DDD はプロダクトチームとサービス境界を交渉するために使った言語だった。アカデミックな演習じゃなく—エンジニアが「その機能は候補ドメインに属する、採用担当者ドメインに入れると2年かけてほどくことになる」と言えるメカニズムだった。マルチプロダクト、マルチスクワッドの環境では、その語彙はアーキテクチャ図よりも価値がある。

生まれた境界付きコンテキスト—候補、応募、ワークフロー、アイデンティティ、アナリティクス—はチームの所有権にクリーンにマッピングされた。政府クライアントがカスタム採用ステージを要求したとき、ワークフローチームは候補やアナリティクスに触れずにそれを所有した。それが求めている成果だ:変更の分離。

Camunda BPMN:グローバルではなくテナントごとのワークフロー

これはその時期に最も満足している決断だ。

採用ワークフローは本当に変動する。政府省庁の公務員採用フローには14ステージ、3つの承認委員会、法律で義務付けられた待機期間があるかもしれない。スタートアップのフローは5ステージで一週間で終わるかもしれない。どちらもハードコードできない。どちらか一方に使えないほど複雑にしない設定 UI は構築できない。

できることは、両方を BPMN プロセス定義としてモデル化し、テナントごとに保存し、共有の Camunda エンジン上で実行することだ。新しいエンタープライズクライアント向けのワークフローバリアントの追加はスプリントじゃなく BPMN ファイルのデプロイになった。その文がセールスチームが大規模な政府クライアントにプラットフォームが調達要件を処理するのに十分柔軟だと約束したとき、多くの重みを担う。

Camunda の決断は監査可能性もタダで提供した。政府クライアントは、彼らの開発者がより要求が高いわけではなく法務チームがそうだから、エンタープライズクライアントが気にしない方法で監査可能性を気にする。すべてのワークフロー遷移が Camunda イベントだ。監査証跡はクエリで、フォレンジクス演習じゃない。

Keycloak とフェデレーテッドアイデンティティの問題

マルチテナンシーはユーザーが複数のテナントコンテキストに存在した瞬間に複雑になる。

MENA 採用市場では、候補者は広く応募する。優秀なエンジニアは三つの採用ラウンドに同時にアクティブかもしれない—テック企業で一つ、政府省庁で一つ、地域銀行で一つ—全部同じプラットフォームで。同じメールアドレス。同じ人間。三つの完全に別個のテナントコンテキスト、三つの完全に別個の応募状態、そして三つのテナントのいずれも候補者が他にも応募していることを知れないという明示的な要件。

答えはテナントごとのレルムとクロスレルムトークン交換を使った Keycloak だった。候補者のコアプロファイルは共有アイデンティティスペースに住んでいた。応募データはテナントレルムに住んでいた。認証はテナントスコープだった—あるテナントのセッションから別のテナントに誤って資格情報を持ち込めなかった。Keycloak のレルムフェデレーションは、2年目にエッジケースが現れるときにセキュリティインシデントを生む種類の作業であるアイデンティティフェデレーションをゼロから構築せずにこれを扱いやすくした。

2018年の「AI 搭載」、正直に

Elevatus のピッチには AI 搭載採用が含まれていた。それは本当だった。また、聞こえるよりも少し複雑でもあった。

GPT-3 は存在しなかった。持っていたのは ML 駆動の CV パースとスコアリング、重み付き基準での候補者ランキング、初期のビデオ面接分析だった。CV パースが本番でうまく機能した部分だった—アラビア語、英語、フランス語、ヒンディー語の非構造化履歴書からの構造化抽出、ランキングモデルが採用基準に対してスコアリングできる候補者プロファイルに正規化した。

テナントごとのモデルパーソナライゼーションがアーキテクチャ上面白い部分だった。政府省庁の採用担当者の決断(資格確認と規制コンプライアンスが支配する)は、テック企業の決断(ポートフォリオと実証されたスキルが支配する)で訓練されたものとは意味のある形で違うランキングモデルを形作った。それは正しい結果だ—でも、グローバルモデル一つを動かせばない保存と配信の問題でもある。ML インフラへのマルチテナンシー適用はそれ自体の制約のレイヤーだ。

ビデオ面接分析は動いた。振り返ると、2018年に持っていたよりもはるかに厳格なバイアスと公平性のツールが必要なシステムでもあった。政府クライアントは「このモデルは人口統計グループをまたいで候補者を公平に扱うか」への明示的な答えを要求した—哲学的に先進的だからではなく、多様性義務が契約上の問いにしたからだ。「モデルがそう言ったから」は大臣のオフィスが受け入れる答えじゃない。これを早く学んだ。この分野はその後追いついてきた。

モバイルレイヤー:やり直したいこと

Ionic が先で、Flutter が後。どちらもウェブ体験のモバイルへの適応であり、それが見えていた。

モバイルでの候補者エクスペリエンス—応募する、ステータスを追跡する、電話でビデオ面接をする—は、デスクトップでの採用担当者エクスペリエンスとは異なる UX 制約を持っている:数百人の候補者をレビューし、一括決断し、採用ラウンドを運営する。モバイルをポートとして構築した。モバイルファーストで設計されたプロダクトほど良くなることはなかった。

今日これをやるなら、候補者 UX と採用担当者 UX は両方のコンシューマーを念頭に置いて設計された API レイヤーをバックエンドで共有する別々のプロダクトだろう。これはみんなが一度、困難な方法で学ぶ API ファーストのレッスンだ。私はもう学んだ。

私が所有したもの

  • 複数スクワッドをまたいだロードマップ実行とスプリント計画
  • DDD ファシリテーションと境界付きコンテキスト境界の決断
  • Camunda BPMN インテグレーションアーキテクチャとテナントごとのワークフローモデル
  • Keycloak レルムフェデレーション設計
  • マイクロサービスマイグレーション順序(ストラングラーフィグ実行)
  • クロスサービスコミュニケーション向けの RabbitMQ イベントトポロジー
  • スクワッドをまたいだ Jenkins パイプライン標準化

政府が実際に使っている。その文は調達プロセス、セキュリティレビュー、カスタマイゼーション交渉、そして「実際に使う」が必要とするインテグレーション作業を経た後では違って響く。フレンドリーな初期採用者を持つ MVP じゃない。ダウンタイムを許容できない機関のクリティカルプロセスを動かしている本番ソフトウェアだ。

それが作ったものだ。