新規CRM/SaaSプロダクト開発
2023年8月創業のベンチャー企業にて、CRM/SaaSプロダクトの開発をPL/PGとして担当。 Nest.jsプロジェクトのクリーンアーキテクチャ/DDD構成への改修と、テスト並列化・クエリ最適化・DB設定チューニング・アラート整備による速度改善を主導。 機能面では、全文検索(OpenSearch)導入、CSVインポート、SMS多要素認証、カレンダー/メール外部連携、多言語対応、非同期バルク処理基盤など幅広く設計・実装。 設計から本番運用(ECS)まで一貫して携わっている。
主な実績
- Nest.jsプロジェクトをクリーンアーキテクチャ/DDD構成へ改修し、テスト並列化・クエリ最適化で速度改善
- OpenSearchによる全文検索・あいまい検索・重複検出を設計導入し、多言語の文字正規化まで対応
- SQSベースの非同期バルクワーカー基盤を設計し、排他ロック・部分失敗集計・進捗再開を実装
- k6+Datadog APMの負荷テスト基盤を構築し、DB設定・コネクションプールの最適化を実施
- Gmail/Outlook連携・SMS多要素認証・CSVインポート・多言語対応など主要機能を実装
設計と判断
◆ 長時間キューワーカーの排他制御を「取得時ロック」だけに頼らず、リース延命・所有権再確認・リトライ枯渇時の能動解放まで含むライフサイクル全体として設計した
状況
非同期バルク処理基盤で、ワーカーの処理時間がロックやメッセージ可視性の想定窓を超えるケースがあり、stale-lock奪取・二重処理・詰まりが競合する状況だった。
判断
ロックheartbeatに加えメッセージvisibilityも延長し、処理側でも所有権を再確認、リトライ枯渇時は配信回数を見てロックを能動解放する設計を採った。
理由
取得時点の排他だけでは「リトライ待機中の保持」と「stale-lock奪取復旧」が競合し、どちらか一方の対策では二重実行かデッドロックのいずれかが残るため。
◆ 一括処理全体を単一トランザクションで包む案を退け、部分失敗はスキップ+件数集計で扱い、走査はoffsetではなくkeysetで行う設計を選んだ
状況
数万件規模のバルク処理で、途中失敗時の扱いと、更新しながらのページング走査の整合性が問題になった。
判断
全件失敗にせずスキップ+件数返却で集計する粒度を定め、走査は不変キーによるkeyset/searchAfterに統一。全件選択はincludedIdsと検索条件+excludedIdsの二系統で受ける設計にした。
理由
単一トランザクションは内側の非トランザクショナル副作用(検索インデックス等)と不整合を起こし、offset走査は更新中のデータで取りこぼし・重複が発生するため。
◆ 全文検索の重複判定でAIを本番の判定器に据える案を退け、開発用ラベラーに限定。本番は相対スコア指標とminimum_should_matchの調整で制御した
状況
OpenSearchによる重複レコード検出で、判定精度の要求と誤検出/見逃しのトレードオフをどう制御するかが課題だった。
判断
AIは閾値調整のための正解ラベル作成にのみ使い、本番判定は検索スコアの絶対値ではなく1位2位のギャップ等の相対指標と、minimum_should_matchのチューニングで行った。
理由
AI判定を本番経路に入れるとレイテンシ・コスト・再現性の問題が生じる一方、相対指標ベースならデータ分布の変化に頑健で、挙動が説明可能なため。
