i_like_banana

キャリアビジョン


非同期ドリブンで壊さず速くする。設計書とAI基盤で同期コストを最小化し、チームの開発速度を引き上げる。

## そう思う理由 - 設計書やPRなど、書いたもので合意を取り、同期コストを最小化して開発を回すのが自分の型。 - 既存システムの改修・安定運用が得意。AI活用では、エージェントの出力を検証する中で生成物の品質を見極められるようになった。 - この「非同期で回す力」と「AIの品質管理力」を組み合わせて、会議を増やさず開発速度と品質を同時に上げたい。 ## 具体的にやりたいこと - チーム全体の生産性を底上げする仕組みを作る。 - 自身の実績として、AIレビューツールの設定チューニングで重大誤検知を1/3に低減、AI回答精度を2.5%→80%超に改善しサポート工数を月41時間削減した経験がある。 - 一度仕込めば人を介さず全体に効く仕組みを、設計・実装・QAの各工程に展開したい。 ## 働きたいチーム - 設計書・PRベースの非同期レビューで意思決定が進む文化があるチーム - 上記のような非同期のリーダーシップに理解のあるチーム - AI活用に本気で投資しつつ、品質とセキュリティを妥協しないチーム - 同期ミーティングは方向確認に絞り、作業時間を最大化できる開発体制 ## 今後のキャリア目標 2年以内に、開発チームのデプロイ頻度を2倍にしながら、本番障害ゼロを維持する。指標はデプロイ頻度・リードタイム・障害件数で測る。

プロジェクト経験

2026年/3ヶ月以内

プロダクトAI活用プロジェクト

## 概要 以下2つのアプローチによるfreeeサインチームの業務効率化 - エンジニア向けClaude Code 並列起動開発プロセスの導入 - セールス職向けプロダクト仕様調査工数の削減 ## 目的 - エンジニアPR数増加 - セールス商談数捻出のための調査工数削減 ## やったこと - git worktree + git worktree runnerをベース技術とし、並列起動開発の環境構築スクリプトとworktree環境の構築スクリプトを作成。手順書をつくって展開し、ワークショップをエンジニア向けに開催。 - Devinを利用し、プロダクトリポジトリを読み込ませ、ソースコードベースで技術質問に回答できるように設定。その後、技術以外の質問に回答できるよう、プロダクト連携仕様やプランごとに使える機能の一覧をプロダクトリポジトリにインプット。 ## 成果 - チーム全体PR数を1か月あたり25%増加 - セールスの調査工数を1か月あたり41時間削減 ## 工夫 - もともとDocker前提の構築手順であったが、遅いので、Docker非依存の構築手順をつくり、さらにworktreeセットアップ手順を別に作った。結果、worktreeをセットアップしてからClaude Codeを起動させるまでの時間を3分 => 1秒以下にした。 - Devinへの非技術インプットが読める最大行数が5000件以下であることが判明した。かつ、Devinに検索キーワードを与えないとインプットを読んでくれなかった。そこで、もともと1ファイル3万件程度のインプットだったものを14ファイルに分割し、それぞれのファイルにDevinが検索しやすいようにキーワードを追加した。結果、14ファイルすべて単純なプロンプトで読み取れるようになり、回答精度が2.5% => 81%に増加。 ## 自身の生産性について - もともと3並列だったものを5並列にし、1か月50PR => 1か月100PRまで増加

2026年/3ヶ月以内

アプリケーションで利用するマルウェアスキャンのセキュリティ強化対応

## プロジェクト名 アプリケーションで利用するマルウェアスキャンのセキュリティ強化対応 ### 役割・主業務 <!-- 例)〜という課題があったため、〜を担当し、〜を行った。 --> アプリケーション既存のマルウェアスキャンは、s3アップロード後のイベント駆動で動作していたため、検体ファイルがs3にアップロードされてしまう。加えて、s3アップロードをイベントとしたlambdaで起動しているため、s3ファイルアップロード以外が起点となるアプリケーション操作までカバーしきれていない。 よって、ファイルアップロードが起点となるすべてのアプリケーション操作を、アップロード前のos一時領域に格納されたタイミングで検知し、パーミッションレベルでアプリケーションから隔離するcloudoneを導入。ファイルアップロード起点処理の全てに新しい検体検出ロジックを差し込むことで、ファイルアップロード前に安全にマルウェアを除去できるようにした。 ### 成果 <!-- 任意。定量的な数字があると良い。 例)〜を行った結果、MAUが〜%改善した。 --> SREと協業し、検出ロジックの適用箇所を調査。12箇所あった旧ロジックに新ロジックをラップする形でPR数を5に抑え、かつ、本番障害ゼロを達成。 また、cloudoneはローカル開発環境を用意してないため、ローカル開発用にclaude codeでエミュレートツールを作成。開発のリードタイムを抑えた。 ならびに、旧検出ロジックを削除するため、プロダクトのリポジトリとインフラリポジトリを並行調査して作成したインフラ構成図とterraform改修作業計画をSREにレビューしてもらい、アプリケーション層とインフラ層それぞれでインシデントゼロで旧ロジック削除を達成。

2025年/3ヶ月以内

Amazon EKS Cluster の バージョンアップデート

## 概要 Amazon EKS Cluster の バージョンアップデート業務。 自身の担当アプリケーションが動作するEKS Cluster のEOLに対応するため、バージョンアップデート業務を担当。 ## 目指す利益 - サービス無停止による運用損失コストゼロ - インシデントによるサービス損失コストゼロ ## 解決したい顧客課題 サービスを無停止でアップデートを完遂させ、運用品質を維持しつづける。 ### システムの具体的な内容: freeeではプロダクトの単位で、EKS Cluster を導入してクラスタ単位の運営をしています。アップデートの宣言ファイルは Terraform、k8sクラスタ構成管理はhelmfileで実施されています。クラスタデリバリーはArgo CDで実現します。運用監視ツールはDatadogです。 アップデートはローリングアップデートではなくブルーグリーンデプロイで実施します。そのため、システム停止を伴わずに実現できます。具体的な実現方式は以下の4手順により実施します。 1. 新クラスタ準備 - クラスタ構成のみ作り、node や pod は起動させない状態 2. 旧クラスタのweight切り替え - 旧クラスタのautoHeal を off にしてworkerとcronを停止、新クラスタのnodeとpodを起動させる 3. トラフィック切り替え - 段階的に新クラスタへのトラフィックを増やして切り替え完了 4. 旧クラスタの廃棄 アップデート時のトラフィック切り替えには [tentez](https://github.com/FeLvi-zzz/tentez) を使い、段階的なトラフィック切り替えを実現することで動的なサーバリソース割り当てを安全に実施できるように工夫されています。 以上の手順を、integration, staging, productionの3環境に対して実施します。 ## 担当 手順準備、スケジューリング、作業実施(ArgoCD操作、k8s cli操作、yamlファイル作成)、関係者調整まで一貫して担当。 ## 出した成果 - スケジューリング遅延、システムダウン、インシデント、すべてゼロで作業を完遂。 ## 成果に繋がった工夫 ### 1. コミュニケーションサポート 手順はSRE部隊が用意したものがあったが、自プロダクト用に最適化されていなかったので問い合わせを重ねつつ懸念点を払拭。 検証環境にて手順をすべて事前検証し、必要な作業時間を予測されるエラーログの情報をすべて手順書にフィードバックして、当日の作業トラブルをゼロにした。 ### 2. 安全安心なスケジューリング アプリケーションチーム、QAチーム、SREと連携し、インシデントの要因をすべて事前に潰した。アプリケーションリリースのタイミングと作業をずらしつつ、システムが高負荷な時間帯と、バッチジョブの高頻度な時間を調査してバッティングしないようにし、かつ、EOLの1か月前以内に収まるようスケジューリング。 ### 3. 切り替えのためのリソース設計 切り替えにおいては、新旧の2クラスタが並行稼働するため、リソースが溢れないように設計しました。Aurora Postgresql のmax_connectionとRedisのコネクション数が現稼働数の2倍を許容できるかを調査し、かつ、クラスタのjobワーカーが2重起動しないように作業実施しました(手動で片側のワーカーを止めるか、2重起動しても問題ないようにアプリケーションのジョブを改修するかで迷いましたが、工数をみて前者の作業を取りました) 以上です。

2025年/半年以内

freee サイン「新リース会計基準対応」機能の新規開発

## プロジェクトの概要 ■ 概要 freeeサイン「新リース会計基準対応」機能の新規開発。契約書からリース該当性をAIで自動判定し、必要情報を自動抽出する機能。 参考) https://www.freee.co.jp/sign/new-lease-accounting/ ■ 背景 2024年から新リース会計基準が適用され、企業は保有する全契約書についてリース該当性の判定が必要になった。手作業での判定・情報抽出は工数が膨大で、経理担当者の負担軽減が求められていた。 ■ 技術スタック Ruby on Rails 7.2 / React + TypeScript / standard-ui(freee内製デザインシステム)/ LLM + AI-OCR / PostgreSQL ■ チーム構成 8名(Design 1名、PdM 1名、Eng 4名、QA 2名) ■ 担当 開発エンジニアとして実装全般を担当。Eng 4名中、フルスタック担当として、フロントエンド・バックエンド両方の設計・実装をリードした。 ■ 実績 4ヶ月で213件のPRをマージ。 ## 目指す利益 - 新リース会計基準対応市場でのシェア獲得 - freee固定資産とのクロスセルによる収益拡大 - Standard/Advance/Enterpriseプランの価値向上 ## 解決したい顧客課題 1. 初年度の判定作業が膨大 - 新規適用時、過去の全契約書についてリース該当性を確認する必要がある - 経理担当者の工数が膨大になる 2. 判定の複雑さ - 新リース会計基準の3要件(資産特定・経済的利益・使用支配権)の判定には専門知識が必要 3. 抽出作業の非効率 - 長文契約書から契約期間・リース料等の必須項目を手作業で抽出 - 入力ミスのリスクが高い 4. 監査対応の負担 - 判定根拠の記録・保存が煩雑 - 監査時の証跡提出に工数がかかる ## 出した成果 ### プロジェクト成果 1. **スケジュール2ヶ月前倒しでリリース達成** - 当初見積もり:12月末リリース → 実績:10月末にコア機能実装完了 - 見積もり根拠:過去の同規模機能開発(契約台帳機能)の実績工数から算出 - 前倒しできた要因:Claude Code活用による実装工数削減(詳細は後述) 2. **レビュー改善要望の8割を取り込み** - 前倒しで確保した2ヶ月を、ユーザー体験の改善に投資 - 操作の連続性、エラー体験、認知負荷、操作効率の4観点で40件近くの改善を実施 3. **品質確保** - QA期間中に24件のバグ修正PRを迅速にマージ - リリース後1ヶ月時点で重大バグ(業務停止・データ損失)0件 - 軽微な表示崩れ等は3件報告、即日対応 ### 生産性の変化 Claude Code導入後PR数5.2倍増加 ## 成果に繋がった工夫 ### 1. standard-ui(freee内製デザインシステム)の導入 #### 1.1 課題 - freee Signでは新UIライブラリ(standard-ui)の導入事例がほぼなかった - 既存のサンプルコードが少なく、開発効率が上がらない状態だった - Eng 4名のうち、サインへのstandard-ui導入経験者は0名だった #### 1.2 対応 自分がstandard-uiの技術検証と設計を先行して行い、チームに展開する方針を取ることにした。 ##### 1.2.1 アーキテクチャ設計 hooks/pages/templates層の責務分離パターンを設計した。standard-uiの制約上、コンポーネントにビジネスロジックを持たせると再利用性が下がると判断したため、以下の分離を行った: - hooks層:API通信のみ - pages層:ビジネスロジック・状態管理 - templates層:UI表示のみ ##### 1.2.2 チームへの展開 - 設計パターンをドキュメント化(CLAUDE.md含む1,443行)し、他メンバー3名にレクチャーを実施 - PRレビューで一貫性を担保 - 結果として、他メンバーからの「設計どうすればいい?」という質問が3週目以降ほぼゼロに ##### 1.2.3 開発元との連携 ライブラリの制約による不具合を3件発見し、開発元チームに報告・改善提案を行った。うち2件はプロジェクト期間中にライブラリに反映された。 #### 1.3 結果 - UI/画面関連で39件のPRをマージ(チーム全体の約7割) - 他メンバー3名もstandard-uiで実装できる状態になった ### 2. Claude Codeを活用した開発効率化 #### 2.1 課題 - 新UIライブラリの既存サンプルが少なく、手動でのコーディングでは開発速度が上がらない - 当初の見積もりでは12月末リリース予定だったが、スコープ追加の可能性があった - 開発とレビューを両立させる必要があった #### 2.2 対応 ##### 2.2.1 CLAUDE.mdによるコード生成精度の向上 グローバルCLAUDE.md(全プロジェクト共通)とプロジェクト固有のCLAUDE.mdを整備し、Claude Codeの出力品質を最適化した。 **グローバルCLAUDE.mdの設計方針**: - 過度なエンジニアリングの禁止:要求されていない機能追加やリファクタリングを抑制 - 簡潔な応答:冗長表現を排除し、実行と結果報告を優先 - コメント記載原則:「What」ではなく「Why/Why Not」を書かせる - ハードコーディング禁止:特定のテスト入力に依存しない汎用的な実装を指示 **プロジェクト固有のCLAUDE.mdの設計方針**: - hooks/pages/templates層の責務と分離理由を明記 - アンチパターンと、なぜそれが問題なのかを記載 - 実装例(Good/Bad)を具体的に提示 設計書もマークダウン化し、Claude Codeが仕様を理解した上でコード生成できるようにした。 **コード生成の実測値**: - 生成コードのうち、修正なしでマージできた割合:約30% - 軽微な修正(変数名、型定義等)でマージできた割合:約40% - 大幅な修正が必要だった割合:約30% - 「7割のコード自動生成」とは、上記の「修正なし」+「軽微な修正」の合計 ##### 2.2.2 並列処理によるプロンプト応答の高速化 CLAUDE.mdに並列化の指示を明記し、Claude Codeの処理を最適化した。 ``` # CLAUDE.mdに記載した並列化ルール - 独立したタスクは必ず並列実行せよ - 並列化可能: 複数ファイルの読み込み、複数の検索、複数のAgent起動 - 依存関係のあるタスク(読む→分析→修正)は順次実行せよ ``` また、モデルの使い分けを指示し、コスト削減と高速化を両立した: - haiku(軽量):簡単な作業、定型作業、タスク分解 - sonnet(標準):一般的な実装 - opus(高性能):複雑な実装、重要な意思決定、設計判断 Exploreサブエージェントを活用し、コードベース探索時のコンテキスト消費を抑制した。 ##### 2.2.3 git worktreeによる3並列開発 git worktreeを利用してClaude Codeを3並列で動かす環境を構築した。 - worktree A:機能実装 - worktree B:バグ修正 - worktree C:レビュー対応 1つのタスクがClaude Codeの応答待ちの間に、別のworktreeで作業を進められるようになった。 ##### 2.2.4 Claude Skillsによるコードレビュー自動化 Claude Skillsを利用して、PRのコードレビューを自動化した。 - 差分を読み込ませてレビューコメントを生成 - 定型的な指摘(命名規則、型定義、コメント記載原則など)はClaude Codeに任せ、自分はロジックの妥当性に集中 #### 2.3 結果 - Claude Codeによる7割のコード自動生成を実現(修正なし30% + 軽微修正40%) - 当初見積もり4ヶ月 → 実績2ヶ月でコア機能実装完了 - 余った2ヶ月でレビュー改善要望の8割を取り込むことができた - 個人の生産性が3.8倍、レビュー含めた総合的な貢献が2.6倍に向上 #### 2.4 Claude Code活用の再現性 本プロジェクトで得た知見は、以下の条件で他プロジェクトにも適用可能と考える: - **適用しやすい条件**:定型的なCRUD実装、既存パターンの踏襲、テストコード生成 - **適用しにくい条件**:複雑なビジネスロジック、セキュリティクリティカルな実装、既存コードの大規模リファクタリング - **環境非依存の知見**:CLAUDE.mdによるルール明文化、並列化の考え方、人間とAIの役割分担 ### 3. ユーザー体験の改善 #### 3.1 課題 リースチェック機能は経理担当者が数百件の契約書を判定する業務フロー。1件あたりの操作ストレスが積み重なると、全体の業務効率に大きく影響する。 #### 3.2 対応 ##### 3.2.1 操作の連続性を確保(フロー改善) 経理担当者が「判定 → 次の契約書 → 判定 → ...」を繰り返す業務フローを想定し、操作の中断を最小化した。 | 改善内容 | ユーザーのストレス | |---------|------------------| | 「続けて入力」機能の実装 | 1件判定するたびに一覧に戻る手間を削減 | | レコード間移動時のフォーム値保持 | 入力途中で移動しても値がリセットされない | | 文書保管完了後のリンク表示 | 次のアクションへの導線を明確化 | | ページング時にテーブル部分のみ更新 | 画面全体のちらつきを防止 | ##### 3.2.2 エラー体験の改善 エラーが発生したとき、ユーザーが「何が問題で、何をすればいいか」を即座に理解できるようにした。 | 改善内容 | ユーザーのストレス | |---------|------------------| | エラーメッセージの日本語化・統一 | 英語や技術用語による混乱を防止 | | エラー時にユーザーアクションを追加 | 「どうすればいいか」を明示 | | バリデーションメッセージの改善 | 入力ミスの原因を具体的に表示 | | 403エラーメッセージの統一 | 権限エラー時の対応方法を明確化 | ##### 3.2.3 認知負荷の軽減 初めて使うユーザーでも迷わないよう、情報設計を改善した。 | 改善内容 | ユーザーのストレス | |---------|------------------| | 空状態UIの追加 | 0件時に「何をすべきか」を明示 | | ヘルプページへのリンク追加 | 不明点をすぐに解決できる導線 | | アイコンと説明文の追加 | 機能の目的を視覚的に伝達 | | 見出し文言・構造の修正 | 画面の階層構造を明確化 | | 不要な必須ラベルの削除 | 視覚的ノイズを削減 | ##### 3.2.4 操作効率の改善 繰り返し操作のストレスを削減した。 | 改善内容 | ユーザーのストレス | |---------|------------------| | 一括操作UIの実装 | 1件ずつ操作する手間を削減 | | チェックボックス→トグルボタンへ変更 | 操作の意図をより直感的に | | ダブルサブミット対策 | 誤操作による重複処理を防止 | | 一括操作の確認ダイアログUI改善 | 操作内容の確認を明確化 | #### 3.3 結果 - レビュー改善要望の8割を取り込み - QA期間中に発見されたUX課題を24件迅速に修正 - リリース後1ヶ月時点で重大なUXバグ0件 **効果測定の課題**: 本プロジェクトでは定量的なUX指標(タスク完了率、エラー率等)の計測基盤がなく、定性的な評価にとどまった。今後の課題として、UX改善の効果を定量的に測定できる仕組みの導入を検討している。 ### 得られた知見 #### Claude Code活用のポイント 1. **CLAUDE.mdの階層設計** - グローバル(全プロジェクト共通):過度なエンジニアリング禁止、コメント原則など汎用ルール - プロジェクト固有:アーキテクチャ、責務分離パターンなど文脈依存ルール - 「何を」だけでなく「なぜ」を書くと精度が上がる 2. **並列化による効率化** - CLAUDE.mdに並列化ルールを明記し、独立タスクは並列実行させる - モデル使い分け(haiku/sonnet/opus)でコスト削減と高速化を両立 - git worktreeで3並列開発環境を構築し、応答待ち時間を有効活用 3. **レビュー自動化** - Claude Skillsで定型的な指摘を自動化し、人間は本質的なレビューに集中 - 結果としてレビュー数2.1倍、品質も維持 4. **AIツール活用の限界認識** - 生成コードの30%は大幅修正が必要 → 過信せず検証が必須 - 複雑なビジネスロジックは人間が設計し、AIは実装を補助する役割分担が有効 #### 新技術導入のポイント - 1人が先行して検証・設計し、チームに展開する方式が有効 - 開発元との連携は早めに行うと、プロジェクト期間中に改善が入る #### ユーザー体験改善のポイント 1. **業務フロー全体を想定する** - 1件の操作だけでなく、数百件を繰り返す業務フローを想定 - 1件あたり数秒のストレスでも、積み重なると大きな負担になる 2. **エラー体験は「次のアクション」まで設計する** - 「何が問題か」だけでなく「どうすればいいか」を伝える - 技術用語を排除し、ユーザーの言葉で説明する 3. **開発効率化で生まれた余裕をUX改善に投資する** - Claude Code活用で2ヶ月前倒し → その時間をレビュー改善要望の取り込みに使用 - 技術的な効率化は、最終的にユーザー価値に還元すべき ## リリース後の取り組み - CSVエクスポート機能の追加開発(外部固定資産システム連携用) - ユーザーフィードバックに基づくUI改善 - パフォーマンス最適化 ## 今後の展開 - 契約内容変更時の再判定機能 - 網羅性チェック機能(取引タグとの紐づけ) ## キャリアビジョンに対するふりかえり 本プロジェクトで、Claude Code活用による開発効率化と、ユーザー体験改善を両立できた。技術的な効率化で生まれた余裕を、ユーザー価値に還元するサイクルを回せることが自分の強みだと認識した。 ### 具体的にやりたいことのアップデート - ユーザーの業務フロー全体を俯瞰し、ストレスポイントを特定 - 技術的な実現可能性を踏まえた優先順位付け - 開発効率化とUX改善の両輪を回すチームづくり ### 今後の課題 - UX改善の効果を定量的に測定する仕組みの導入 - AI活用のベストプラクティスをチーム・組織に展開する仕組みづくり

2024年/半年以内

freee人事労務 雇用契約 | 文書の一括作成・送信機能を開発

## 概要 freee人事労務に、雇用契約の人的ミスを改善する目的で雇用契約周りの業務を効率化するサービスを以前に開発しました([詳細](https://www.freee.co.jp/employment-contract/))。 サービス開発後、ユーザーテストを重ねるなかで、雇用契約の文書手続きを一括で行いたい要望を多く頂きました。プロダクトマネージャと協議を重ね、文書を一括で作成・送信する機能を開発しました。 ## 目指す利益 年間繰り返し利益(ARR)の2000万円向上。 ## 担当 要件定義から設計、開発、品質保証(QA)、セキュリティテスト、リリースまで一貫してプロジェクトに関与しました。 特に、QAとセキュリティテストのコミュニケーションをリードし、仕様の認識齟齬をゼロに抑え、スケジュールを前倒ししてリリースすることができました。 ## 解決したい顧客課題 人材会社のユーザーさんを例に説明します。 ある人材会社では1回の雇用契約更新で、派遣社員300人が対象にされます。これまでの機能は社員1人を選択して文書の作成と送信を行うUXであり、1通の文書の送信が実施されるまでに5分程度の時間が掛かります。更新期間1ヶ月以内に担当者1人でこの業務を行うには、他の業務の中断を余儀なくされます。 そこで、更新期間1か月の間に300人分の文書を担当者1人で送信可能にし、他の業務に支障をきたさない状態にすることが理想となります。 ## 出した成果 - リリース期間を2か月前倒しできた - 上記の理想状態を達成した([詳細記事](https://www.freee.co.jp/cases/kanemotogumi/)) ※人材会社ではないが、同様に業務効率を改善した例として掲載 ## 成果に繋がった工夫 ### 現実的な期間でリリースを可能にする設計をした 一括処理をするさい、リッチな設計にするにはPub/Subが必要となります。しかし機能リリースを入社シーズンに合わせたかったので、処理は非同期にするもののイベント駆動のUXはやめました。その代わり、社内でUX検証をしてユーザーが気づきやすいUIを実装してカバーしました。 また、一括処理の外部サービスへのリクエストは、外部サービスの過負荷を避ける方式にしました。外部サービスは社内プロダクトですが、負荷検証環境がないのでリクエストが並列で実施された時にどれだけ高負荷になるか見立てができません。加えて、大量の文書が一回で処理しきれず、ジョブのタイムアウトに抵触する可能性がありました。そこで、一回の処理の上限を100文書にしてタイムアウト制限をクリアし、かつ、リクエストを直列にして外部サービスの過負荷を避けるようにしました。一括処理の完了時間が並列処理と比べて延びてしまうデメリットについては、処理中に別の処理を実施できるようにしてユーザーのフラストレーションを減らす工夫をしました。 ### つくる機能とつくらない機能の優先順位を設定 当初は、3つのサブ機能が対象となっていました。このうち2つが一括処理に必要な根幹機能であり、残りの1つは一括処理のヒューマンエラーを防ぐための機能となります。 ヒューマンエラーを防ぐ機能はUXの設計にかかる時間が予測しづらかったので、まずは根幹機能のみ作成しました。その後、社内のメンバーに機能を試用してもらう会を開催し、課題を洗い出しました。その結果、「ユーザーは一括で作成したい訳ではなく、文書をミスなく確実に送信できることを確認したい」という知見を得ました。 言い換えると、ヒューマンエラーを防ぐ機能のニーズは曖昧だということがわかったのです。ヒューマンエラーを防ぐ機能を用意することよりも、そもそもヒューマンエラーが起こりえないUXにすることのほうが求められていると感じました。 結果、ヒューマンエラー防止機能はリリースから除外し、リリース後に文書送信のエラー率の分析とユーザーテストを実施してからUX設計することに決定しました。 ### 仕様の認識齟齬をゼロに抑える QA(品質テスト)とセキュリティテストは外部のチームの方に実施いただいてました。通常、外部とのやり取りはテキストコミュニケーションがメインであるため、5~10%程度の認識齟齬が発生しますが、それらの齟齬を対面コミュニケーションを増やすことでゼロにできました。 QAについては、設計文書を厚めに記載し、さらに日次でミーティングを開催しました。その結果、テキストコミュニケーションでは見落としがちな微妙なニュアンスの言語化コストを削減できました。さらに、言語化しきれない相手のニーズをこちらが再言語化し、テスト実施に必要な準備のオンボーディングをご提案しました。リリース後のふりかえりでは「コミュニケーションがしやすく、前回のリリースと比較してとても仕事がしやすかった」とフィードバックを頂きました。 セキュリティテストについては、開発完了一か月前からこちらの進捗を相手に細かく伝え、スケジュールの認識合わせを重ねました。さらに、テスト内容についてガイドラインを貰い、診断対象の処理やAPIの数、定義してあるコードの場所、UIでどこをクリックしたときに実施されるのかを詳細に文書化してテスト実施者の頭の手間を削減しました。加えて、機能のチュートリアル動画を撮り、対面でオンボーディングミーティングを実施し、テストがスムーズに進むようサポートしました。担当の方からは「とてもテストがスムーズに実行できる。3日くらい前倒しできそう」とフィードバックを頂きました。 テスト中はトラブルがありましたが、関係者を集めて当日中に問題解決できたのでリリース遅延はしませんでした。 ## リリース後にやったこと ### つくらないと決めた機能のニーズ調査 Datadogで単一処理のAPIの実施回数を見て、一括処理に必要か検討しました。大まかには一括処理での必要性は見えるものの、実際のユーザーアクションから分析したほうが効果的だと分かりましたので、Webアナリティクス用のイベントロガーを実装して現在データが溜まるのを待っています。 ### 設計文書作成のプロセス改善 設計文書を作成する工程に思ったより時間を使いましたのでふりかえりをしました。時間を使った理由は、設計文書がQAなどチーム外の方に向けた情報とチーム内に向けた情報が一緒くたに記載されていたことが原因だと分かりました。そこで、チーム外向けの文書とチーム内向けの文書を分けることにしました。次の開発では設計文書の作成時間を半分にできました。 ### セキュリティテスト環境の改善 テスト中のトラブルについてSREの方と一緒にふりかえりをしました。結果として、テスト環境は開発者が他の意図で使うことを想定した仕組みを流用していたために起きたと判明しました。テスト用の専用環境を作ることが根本解決につながると分かり、今後テストの頻度も多くなることが分かったため、現在はSREの方にテスト用の永続環境を用意いただきました。改善できた工数は、テストのトラブル解消に使った4hとテスト環境の準備に使った16hを合計して20hです。

2023年/1年以内

freeeサインの認証システムをfreeeのマイクロサービスに移行し、アカウントIDとセッションを統合する

## 概要 [freee](https://www.freee.co.jp/)のビジョンである[統合型経営プラットフォーム](https://corp.freee.co.jp/vision/)を実現するために、freee共通の認証システムを[freeeサイン](https://www.freee.co.jp/sign/)に導入してユーザー体験を向上させる ## 顧客規模 freeeの有料課金ユーザー[約46万事業所](https://corp.freee.co.jp/service/) ## 担当 マネージャー1、PdM1、エンジニア4のスクラム開発体制において、エンジニアとして参加。 ※ スクラムマスターは特定の人間に割り当てず、エンジニア全員が分担してやっている スクラムは1週間スプリント。イメージ図は[こちら](https://speakerdeck.com/yasuakiomokawa/huroxiao-lu-falsexiang-shang-karashi-merukai-fa-sheng-chan-xing-falsegao-mefang-mohuwakuwoyan-ete-how-to-go-on-high-peformance-with-mob-work?slide=7) ## 解決したい課題 ### プロダクトとして解決したい課題 #### 1. freeeユーザーの体験が悪いので改善したい ##### 1.1. freeeプロダクトのあるべき姿 freeeのサービスはアカウントを共通管理しており、1つのアカウントでログインすると他のプロダクトに追加認証なしで遷移できるようになっています。たとえば、従業員がマイナンバー登録を行いたいときは[freee人事労務](https://accounts.secure.freee.co.jp/login/hr)にログインして従業員情報ページから[freeeマイナンバー管理](https://accounts.secure.freee.co.jp/login/mynumber)のリンクをクリックして登録を行うように実装されていますが、このとき従業員はfreeeマイナンバー管理に追加でログインする必要はありません。理由として、freee人事労務とfreeeマイナンバー管理のアカウントは、[freeeプロダクト共通のアカウント管理基盤](https://accounts.secure.freee.co.jp)で管理されており、アカウントのIDとセッションがプロダクトで共通のものになっているためです。 ##### 1.2. あるべき姿に対して、現状のfreeeサインはどうなっているか 一方、freeeサイン(以下:サイン)は、freeeのアカウント管理基盤を利用しておらず、freeeサイン内部の認証システムを利用しています(実装は[devise](https://github.com/heartcombo/devise)を使っています)。サインを利用するにはfreeeアカウントのログインに加え、サインのログイン画面にも遷移してログインしなければなりません。この体験がユーザー離脱の可能性を高め、クロスセルの機会も損ねています。数字の面でも、サインはfreeeの他のプロダクトと比べると年次成長率が期待通りになっていません。[ファクトブック](https://corp.freee.co.jp/ir/05_factbook_jp.pdf)にはプロダクト単位のYoYは公開されていませんが、freee全体のYoYの成長率を考慮すると、サインのアカウントを共通基盤に統合することでプロダクトの成長とユーザー体験の向上が期待できます。 ###### (補足)プロダクトの現状が生まれた経緯 経緯として、freeeサインはもともと別の会社が作ったNINJA SIGNというサービスをfreeeがM&Aしたもので、NINJA SIGNからfreeeサインにサービス名を変更したタイミングではfreeeのOpenId Connectを使ってアカウント情報を連携をしていました。当時はアカウントを統合しようとしても開発規模の試算すら難しい状況でしたので、連携という形を選択しました。 ここからは想像ですが、M&Aから2年以上が経過し、freeeの中で統合体験を顧客に提供することが経営ビジョンとして明確になり、サインのIDセッション統合を現実的に進めることが経営価値として認識されるようになったのではないかと思います。 #### 2. freeeの他のプロダクトとシームレスな連携ができないので改善したい ##### 2.1. サインの現在のプロダクト連携機能の概要 サインは現在、freee会計とfreee人事労務と連携する機能があります。これらはサインの[Web API](https://ninja-sign.com/v1/docs)を会計と人事労務が実行することで実現しています。また、サインのサブスクリプション管理システムはfreeeのマイクロサービスに連携しており、これはfreeeのアカウント管理基盤サーバを[RP](https://www.ogis-ri.co.jp/otc/hiroba/technical/openid-connect/chap3.html)としてサインがOpenId Connectで実現しています。 ##### 2.2. 上記の状況によって起きている問題点 ###### 2.2.1. アカウント情報を連携する手間が発生している 連携プロダクトは、サインのWeb APIを実行してサインのアカウント情報を取得し、連携プロダクトのアカウントと紐づけて情報を管理しています。このため、連携プロダクトは、自プロダクトのアカウント情報とサインのアカウント情報を定期的に同期しなければならないので手間です。アカウントを統合することで、プロダクト連携の手間を削減します。 ###### 2.2.2. サブスクリプションデータを非効率な方法で連携している freeeのサブスクリプション管理システムは[zuora](https://www.zuora.com/jp/)をラッパーしており、zuoraの内部処理はある程度のベストエフォートを許容することで高パフォーマンスを実現しています。内部処理が失敗した場合、5-10分くらい置いてから再びアクセスすると処理が成功していることが多いです。この仕様により、サインは1分程度の間隔でfreeeのサブスクリプションシステムに通信をして情報を同期しています。しかし、この処理はあまり効率的ではありません。freeeのシステムにpub/subを実装すればより効率的です。 一方で、freeeのシステムは他の全プロダクトから使われるシステムであり、サインの都合だけで機能追加してもコストメリットが判断できません。サインの出す利益率がfreeeの全プロダクトのなかで最上位でないため、優先的にやるべきか判断しにくいのが理由です。 以上の問題を、サインがfreeeのアカウント基盤を導入してサブスクリプションデータを基盤から参照することで解決します。 ### プロダクトとして解決したい課題をふまえ、今回のプロジェクトで解決したい課題 #### サインの現時点の利益率に比べると、かなり規模の大きい開発が予想されるため、実施に踏み切れない 上記1と2の課題を解決するためにIDセッション統合を進めたいのですが、サインの利益率はfreee全体で最上位でない一方、IDセッション統合は誰も見通しの見えないくらいに大規模な開発が想像されており、誰がどのように舵を切って進めればよいか明確ではありません。 freee内部でも、他プロダクトのIDセッションを統合するという開発は前例がないので、どう進めていいのか具体的な案が出ない状況です。 そこで、IDセッション統合を実装するために、技術的な範囲でどれくらいの工数がかかるのかを見積もるのが今回のプロジェクトの目的となります。 ## 取り組み ### 見積もる方式を決定する サインのIDセッション統合を最初に検討したとき、我々のチームのマネージャーがfreeeのCTOに試算で9か月と説明しました。案は以下の3パターンを出しました。 1. freeeの共通基盤を取り入れたプロダクトをゼロから作り、現在のサインと並行稼働する時期を設けて9か月かけて移行を完了する 2. 現在のサインにfreeeの共通基盤を導入し、現在のユーザーを9か月かけて導入した基盤に移行する 3. freeeの共通基盤を取り入れたプロダクトをゼロから作り、離脱率の低い優良ユーザーを9か月かけて移行させる。それ以外のユーザーは現在のサインを引き続き使ってもらうが、2年程度の猶予期間を設けたのち、現在のサインをサービス終了とする CTOからは、「パターンをいくつ出しても、9か月の内訳(具体的な開発テーマとそれぞれの見積もり工数)がハッキリしないことには実施判断が難しい」と言われました。とはいえ、上記3パターンすべてを見積もるにはチームリソースが足りず、サインの全エンジニアのリソースを割けるほどのコストメリットが当時の段階で見極められなかったのでチームで担当するしかありませんでした。 我々のチームはfreeeの共通基盤について知識がなかったので、1の案は現実的でありません。2と3は見積りという意味ではやることが同じだと判断したので、作業範囲の絞れている2の「現在のサインにfreeeの共通基盤を導入し、現在のユーザーを導入した基盤に移行する」方式を見積ることに決定しました。 ### 開発テーマを洗い出すため、freeeの共通基盤を学習する 我々のチームにはfreeeの認証基盤の知識がありませんでしたので、マネージャーにお願いしてfreeeの他プロダクトのエンジニアにレクチャーしてもらうようにしました。 そこでわかったことは以下の通りです。 1. 課金単位の概念が、サインは「チーム」という単語を使い、freeeは「事業所」という単語を使っている 2. サインはユーザーとチームが1:1関係だが、freeeはユーザーと事業所が1:n関係である 3. freeeは、ユーザーと事業所を紐づけるMembershipというモデルを定義しており、このモデルに各プロダクトごとのRoleというモデルを紐づけることで、「プロダクト単位のユーザーと事業所との紐付け」を管理している 4. サインの現在のOIDC連携は、freeeの会計Roleを使っている。統合にあたっては、サイン用のRole、つまり「サインRole」を定義してやる必要がある 以上4点を判断材料にした結果、ユーザー/事業所/Membershipという3つのモデルを、サインのデータベース上で一対一に紐づけた状態をIDセッション統合におけるゴールとして定めました。 ### 学習した結果をもとに、開発テーマを導出する 定めたゴールから逆算し、テーマを導出しました。 1. サインは会計Roleとして連携しているため、アカウント連携についてfreee共通基盤との不整合が既に発生している。これを解消する設計を行う 2. freeeの認証基盤を構成するgemがサインに導入できるかを調査し、導入設計を行う 3. freeeの共通基盤は、事業所という概念がある前提で認証を構成する。サインのチームという概念とfreeeの事業所という概念を不整合なく読み替えるため、サインのデータベースにfreeeのデータをどのタイミングでどのように紐づけるかの設計を行う 4. freeeの認証基盤を構成する要素としてredisを使っている箇所があり、サインのredisとコンフリクトさせないための設計を行う さらに、上記4テーマを実現するうえで必要となる以下の4テーマを定義しました。 1. freeeはユーザーと事業所が1:n関係であるため、サインのチームもユーザーとの1:n関係に対応させる設計を行う 2. サインはOEM機能を提供しており、各サービスプロバイダの識別にサブドメインを使っている。しかしfreeeの共通基盤を使うには、サインのドメインを「freee.co.jp」にしないと共通基盤のCookieが参照できない(現在のドメインはninja-sign.comなのでドメイン移行も必要だが、作業の不確実性がそこまで高くないので今回の見積もりからは外しました)。よって、サブドメイン以外によるOEM提供のための設計を行う 3. freeeの認証基盤を使うため、サインが使っているdeviseによる認証をすべてdevise以外で出来るように変更する。具体的には、deviseが実現しているパスワード変更やユーザーアンロックなどの機能を、フルスクラッチで作成して最後にfreeeの認証基盤でセッション管理するよう置き換えるための設計を行う 4. サインには受領者ユーザーという概念がある。このユーザーは、サインにアカウントを持たなくても、文書を受領したり契約にサインを行うことができるように導入した概念である。データ的には、チームに所属しないアカウントとして定義されている。このアカウントは現在、サインのUserモデルにフラグを追加することで定義しており、データ移行の際に障害となる。具体的には、文書とチームの所属関係を定義するデータモデルが、チームに所属するサインのアカウントと受領者ユーザーアカウントを混同して扱っているのが理由である。このため、受領者ユーザーという概念を別のモデルに分離するための設計を行う 以上、メイン4テーマ + 付随テーマ4の合計8テーマについて見積もりを行うことに決定しました。テーマの決定にあたっては、チームのマネージャー、サインのPdM、エンジニア同士でミーティングを行い決定しました。 ### 考慮しなくていいこと(やらないこと)を決める PdMと話し合い、以下のことを決めました。 #### OEMとして提供しているプロダクトにサインアップしているアカウントは移行しない アカウントの扱いは考慮しないといけないが、統合の対象ではないと判断しました。OEMはfreee連携機能を提供していないからです。 #### SAML連携をしているアカウントは移行しない サインはプロダクト連携の方法としてSAMLを提供していますが、SAML認証を使っているアカウントはOEMの文脈に似ているため、IDセッション統合の対象外としました。統合を終えた後に扱いを判断します。 ### メインテーマ4つについて設計書(DesignDocs)を書く サインに以前導入した[DesignDoc](https://note.com/omokawa_yasuaki/n/nd07e43c3e24f)のテンプレートに沿って、上記のテーマについてDesignDocを書いてゆきました。開発テーマの導出の時点でタスクが具体的になっていた付随テーマ4つについては書きませんでした。 メインテーマを再掲します。 > 1. サインは会計Roleとして連携しているため、アカウント連携についてfreee共通基盤との不整合が既に発生している。これを解消する設計を行う > 2. freeeの認証基盤を構成するgemがサインに導入できるかを調査し、導入設計を行う > 3. freeeの共通基盤は、事業所という概念がある前提で認証を構成する。サインのチームという概念とfreeeの事業所という概念を不整合なく読み替えるため、サインのデータベースにfreeeのデータをどのタイミングでどのように紐づけるかの設計を行う > 4. freeeの認証基盤を構成する要素としてredisを使っている箇所があり、サインのredisとコンフリクトさせないための設計を行う 以下、1のテーマから順に説明します #### 1. サインは会計Roleとして連携しているため、アカウント連携についてfreee共通基盤との不整合が既に発生していることの解消 データ不整合が発生するタイミングは以下の2つです。 1. freeeアカウント連携時にサインのチームが連携しているfreeeの事業所に所属しているかチェックしていないために起こるパターン 2. freeeで事業所とユーザーの所属情報が変更されるとサインで変更を追えないために起こるパターン(freeeの他のプロダクトは共通のアカウントであるため、変更を追う仕組みを実装していない) サインのデータベースを調査した結果、不整合のパターンは現在3パターン存在しました。 1. チームと連携した事業所に所属していないfreeeユーザーでサインに連携しているパターン 2. freeeで事業所への招待が取り消されたfreeeユーザーでサインに連携しているパターン 3. freeeで事業所自体を削除したfreeeユーザーでサインに連携しているパターン 上記パターンを解消するためのユーザー操作フローを作成しました。フローを作成する経緯としては、freeeの規約ならびにサービス運用の倫理的な観点として「ユーザーの同意を得る必要があるため」です。そのため、ユーザーのサインインを契機として、移行の操作をユーザー自身で行なってもらうような導線を設計しました。 #### 2. freeeの認証基盤を構成するgemがサインに導入できるかを技術調査する まず、freeeのgemが存在するGitHubリポジトリの参照権限がサインのエンジニアになかったので、マネージャー経由で権限を付与いただくようお願いしました。その上で、gemのReadMeを参照して導入を試みましたがうまくいきませんでした。 ##### 2.1. freeeのリポジトリで公開しているgemをサインのリポジトリに導入することをfreeeは意図していなかったため、gemを適切にインストールする方法が確立されていなかった freeeの方に、GitHub Packagesで公開いただきそちらをサインにインストールしました。 ##### 2.2. サインのテストが落ちる freeeのgemを使ってgRPCの設定をしたところエラーが発生しました。調査したところ、利用を試みているactioncableがredis-rb v5のpub/subを設定する際に、freeeのgemの内部でRedisのソースコードを拡張して使用している箇所のSubscribedClientを参照してしまってエラーとなっていました。freeeのエンジニアの方に調査いただいた結果、Redisのソースコードをfreeeのgemに導入するさい、モジュール名を`Redis`のまま導入してしまったのが原因と判明しました。モジュール名を置換いただいてエラーが解決しました。 ##### 2.3. サインに導入しているgemをダウングレードしないとfreeeのgemがインストールできない freeeのgemが[faraday](https://github.com/lostisland/faraday)に依存しており、サインもfaradayを使っているので問題なくインストールできると思われましたが失敗しました。freeeのgemはfaradayのv1に依存していますが、サインのはv2に依存しているため、サインのfaradayをダウングレードしないとfreeeのgemがインストールできないことが分かりました。 しかしfreeeのfaraday v1は、freeeの課金システムのクライアントプログラムが依存しているため簡単にアップグレードができないとのことです。対応策としては、freeeの認証gemから課金情報の取得箇所への依存を外してOpenAPI経由で課金情報を取得するような構成にすることを検討いただくことにしました。 なお、どうしてもサインのfaradayのダウングレードが避けられない場合に備え、ダウングレードしたときの動作確認のタスクも工数見積もりしました。 #### 3. サインのチームという概念とfreeeの事業所という概念を不整合なく読み替えるため、サインのデータベースにfreeeのデータをどのタイミングでどのように紐づけるか設計する ##### 3.1. データのあるべき姿を決める 読み替えるデータは、ユーザーデータと事業所データの2つですので、以下の方針で読み替えることにしました。 1. ユーザーについては、freeeの認証gemからfreeeユーザーのデータを一意に特定できるidが取得できるので、サインのデータベースに存在するユーザーのidと紐づける中間テーブルを作成する 2. 事業所は、freeeの認証gemからユーザーの所属事業所をプロダクト単位で一意に特定できるidが取得できるので、サインのデータベースに存在するチームのidと事業所のidを紐づける中間テーブルを作成する ##### 3.2. データの生成順序のパターンを決定します 以下の3パターンに決定しました。 1. freeeの他のプロダクトを使っているがサインを使ってないfreeeユーザーがサインにアカウント登録するケース 2. サインにアカウントが存在するユーザーがfreeeアカウントと連携するケース 3. データを紐づけるタイミングはユーザー操作を起点とします(サービスの規約に対応するため)。ただ、サインの既存機能でfreeeアカウント連携(OIDC連携)をしているサインのユーザーは規約に同意したものと判断できるので、backfillで対応します ##### 3.3. データモデル作成 ER図を作成し、メンバー間で共有しました。 ##### 3.4. データクラス設計 調査したところ、サインの既存機能であるfreee連携機能のモデルクラスのデータ生成タイミングと同様のタイミングで中間テーブルデータを作成することで対応できそうでしたので、既存のモデルクラスを改修することで対応します。具体的には、モデルクラスに`after_save` フックを適用して新規データを生成します。 ##### 3.5. タスクを洗い出す 以下の12タスクを洗い出し、見積もりました。 1. ユーザーを特定する中間テーブルの作成 2. 事業所を特定する中間テーブルの作成 3. モデルクラスの作成(ユーザー用) 4. モデルクラスの作成(事業所用) 5. 既にfreee連携を実施しているユーザーのデータを使って中間テーブルのデータをbackfillする 6. 中間テーブルが存在したら既存のfreee連携データを削除できないようにする。既存データは過去に実装した課金基盤統合で課金情報の取得に使っているため、完全に移行しきる前にこのデータを削除するとシステム障害となる 7. freeeの共通アカウント管理画面から、サインのアカウント登録機能を追加する 8. 今回新しく作成した中間テーブルからデータを取得し、テーブルがなければ既存の連携データからチームを取得するような事業所取得クラスを作る 9. 8と同じ要領でユーザーデータを取得するクラスを作る 10. 既存のfreee連携データを使ってチームとユーザーを取得する箇所をサインのソースコードから洗い出す 11. 既存のfreee連携データを使ってチームとユーザーを取得する箇所を、新しく作成した取得クラスへ置き換える 12. サインロールをfreeeアカウント管理に追加するよう依頼する #### 4. freeeの認証基盤を構成する要素としてredisを使っている箇所があり、サインのredisとコンフリクトさせないようにする 調査した結果、freeeの認証基盤は内部的に旧認証と新認証をそれぞれ使っていることがわかりました。当時は新認証の移行段階であり、旧/新の認証の設定が必要で、旧認証のほうがredisを認証基盤の内部で混在して使用していました。そのため設定が必要でした。 しかし、現在はすべて内部的に新認証を使って設定するようになっています。新認証はredisをラップする構成を取り、新認証を使うのであればredisの設定を完全に新認証の内部に隠蔽できるようになりました。よって、旧認証の設定であるredisの設定は不要ということが判明しました。 ### 設計したテーマを見積もる 主にメインテーマ4つを調査し、設計書を書き、タスクに分解して見積もりをした結果、タスクのストーリーポイントは合計で502ポイントとなりました。我々のチームのベロシティは1週間スプリントでだいたい18ポイントなので、27週間(6ヶ月)かかる見積もりを出しました。見積もりを出す期限が決まっていたせいか、見積もりの精度は35-40%程度です。あと100ポイントくらいは増える可能性はありますが、IDセッション統合を前に進めるための材料としては適切とCTOに判断されました。 ※ 付随テーマ4つに関しては見積もりまで完了できませんでしたが、メインテーマ4つでIDセッション統合の全体工数の6割以上を占めるということをCTOと認識合わせしていました。そのため、付随テーマの見積もりが完了しきらなくてもどう進めるかの検討は出来そうだと判断されたようです。 ## 出した成果 - IDセッション統合の技術的な課題とやること、現実的な期間の見通しが出たことで、次に何を決定しなければならないか明確になりました。 - IDセッション統合を現実的に進めるために関係各所が議論するための判断材料を提供できました。 やることのメリット/デメリットを検討し、現実的にエンジニアのリソースをどれだけ確保していつまでに統合しきるのかについて、工数見積もり後の1ヶ月以内に経営陣に決定させるよう後押しできました。 ## 成果につながった工夫 スプリントレトロスペクティブを繰り返してみて、我々のチームにはいくつかの工夫のパターンが見られました。 ※ 我々はレトロの手法に[KPT](https://shiftasia.com/ja/column/kpt%E3%81%A8%E3%81%AF/)を採用していますので、以下、KPTの用語が登場します。 おおきく3つに分けると、`モチベーションの維持`、`ちょくちょくふりかえる`、`ゴールをきちんと定めてから行動する`です。これらの工夫を行なった結果、メインテーマ4つを1ヶ月で設計して工数見積もりまで完了させることができました。 以下、それぞれの工夫を解説します。 ### モチベーションの維持 プロジェクトの前半において、メインテーマは4つに絞ってそれぞれチームメンバーをアサインしたものの、各自で調査をするときに小さなゴールを設定しきれず、なかなか進捗が出ませんでした。 普段の開発では、タスクを設定するときに準備条件と完了条件を定めるようチームでルール化しています。こうすることでアサインしたメンバーのモチベーションを高め、進捗のスピードを上げやすくすることが狙いです。しかし今回のテーマは不確実が大きすぎて準備条件も完了条件も定めることができず、メンバーもフラストレーションを感じ進捗も思うように出ませんでした。 プロジェクト開始当初のKPTのProblemを抜粋すると、以下の記述があります。 ``` 暗中模索みを覚えていて水中を突き進む感じがあるのでしばらくは産みの苦しみ ``` 当時着手していたタスクと見ると、スプリントプランニングで21ポイントがついていました。通常の開発であれば5ポイント以上のタスクは分割することをガイドラインとして定めてましたが、今回は分割できるほどタスクについての知識が無かったので、調査をしつつ課題が出たらそれをタスクにしていく方式で調査を進めました。 とはいうものの、何もアウトプットや課題が可視化できずに敗北感を味わうような日もありました。そこで、デイリースクラムやslackで積極的に自分たちの達成できたちょっとしたgoodをアウトプットするようにしました。たとえば、アウトプットを意識するようになった当時のKPTには以下のgoodが出ました。 ``` freeeの認証ライブラリ使って色々やってるんだよ的な機能の解説で少し安心というか脱・暗中模索感が10%ぐらいあった ``` このgoodは、freeeの認証gemを動かしてアカウントデータを取得できたときの喜びが表出されています。このように、ほんのちょっとしたことでも「自分達は進捗しているんだという意識づけ」に繋げることができました。加えて、KPTのときにはメンバーの日常生活で良かったこともgoodとして出すようにしました。具体的には以下のような感じです。 ``` 誕生日プレゼントもらいました。ありがとうございます! ``` 今まで我々のチームが取り組んだプロジェクトの中で最も不確実性が高いものだったので、細かい達成感を得られる機会を意図的に設けてモチベーションが維持されるようにしました。 ### ちょくちょくふりかえる レトロのProblemで以下の意見が出ました。 ``` そもそもゴールは本当に明確になっているのか?という疑問はある。どれだけタスクをこなしても向かっている先が違っていると困る ``` チームでも「たしかにそうだよね」という話になりました。不確実性の高いプロジェクトでしたので、1つ調査が進むと1つ不明確な点が出てくる、みたいな気が滅入る状態を私も含めみんな経験していたようです。 そこで、もともと1週間だったスプリントを3日にしました。レトロの頻度がこれまでの2倍になった計算です。デイリースクラムで毎日課題や状況の共有はしていましたが、「じゃあ次どうする?」といったネクストアクションに結びつけるための深いふりかえりができない状態だったことや、1つ調査が進むと1つ不明確な点が出てきて変化が激しかったので1週間スプリントは遅すぎると思ったのが理由です。 3日にした効果として、主に技術調査の進捗が大きくスピードアップしました。たとえばfreeeのgemをインストールするときにRedisのエラーが起きたとき、デイリースクラムでは解決策が見出せず、担当したエンジニアも「とりあえず一人でなんとか頑張る」状態でした。しかし3日スプリントにしてKPTでふりかえりをしたとき、「freeeのエンジニアの人に皆んなで聞いてみようか」という意見をチームから出すことができました。その結果、3日悩んだエラーの原因が30分のミーティングで判明し、1日後に解消いただきました。 その後のレトロで「もう少し早くfreeeの方に聞けたらよかった一方、組織が違うと気軽に聞きづらいのでみんなで聞けてよかった」という意見が出ました。もともとfreeeサインは別の会社が作ったプロダクトである関係で、我々のチームはfreeeサイン株式会社の所属で、相談した方はfreee株式会社の所属なのです。そのせいもあって、会社間で変に遠慮が発生することがありました。しかし実際に話を聞いてみたらfreeeのエンジニアの方は気さくで親切でフットワークも軽く、今後も積極的にコミュニケーションを取っていこうと思えた体験でした。 ### ゴールをきちんと定めてから行動する メイン4テーマの調査をするうち、優先度が頻繁に変わりました。たとえば、データ不整合と読み替えのテーマに関しては、データ不整合のパターンが明確になってデータの紐付けパターンが明確になった時点で読み替えの必要が薄れたため、テーマの優先度を下げたり、逆に後になって「パターンは明確になったけど、そのパターンのデータは実際にどう作るの?」という疑問が出たときは優先度を上げて対応したりといったことが起こりました。 我々のチームはアプリケーション基盤を扱うため、顧客や事業部、他のチームのエンジニアからの問い合わせが常に発生しています。今回のプロジェクトにかけられた実際のリソースは70%くらいで、残りはそれらの問い合わせ対応やfreeeの基盤を導入した開発環境を整備するためのリファクタリングに費やしていました。 そのため、スプリントゴールを重要視して「いま何をゴールとすべきか」の共通認識をとるようにしました。結果として、チームがバラバラにならず、メインテーマに集中できました。 ## 全体を通しての所感 今回のプロジェクトでは、技術調査以外はすべてモブワークを推進し、設計書を書くときも含めてすべてエンジニア4人で行いました。そのせいか、情報共有のスピードやふりかえり後のネクストアクションの決定のしやすさは以前に担当した他のプロジェクトと比較して早く進められたと認識しています。モブワークに関しては、以前実施したときに、メリットも大きいですが[デメリットも同じくらい大きい](https://note.com/omokawa_yasuaki/n/n46d4227e9ee5#c02e6309-2b79-4952-875b-1799e5deb8ca)と感じましたので使い所が難しいですが、今回のように不確実性が高く状況が頻繁に変化する状況においてはメリットが大きい方法だと再認識できました。 私は、[アジャイルの12の原則](https://agilemanifesto.org/iso/ja/principles.html)のなかで以下の原則を最も大事にしています。 ``` アジャイル・プロセスは持続可能な開発を促進します。 一定のペースを継続的に維持できるようにしなければなりません。 ``` 今回のプロジェクトはチームにとってかなり大きな負担をかけたので、持続可能という観点ではチームに私が貢献できるところはまだまだあると思いました。じっさい、見積もりが終わってチームに「このペースでどれくらい仕事できますか?」と訊いたところ、1ヶ月が限界だと言われました。当時のKPTで出たProblemを抜粋します↓ ``` - ここ最近疲れた。ちょっとこれで継続は合理的でない=ベストじゃない感があるので今後はこのあたりを調整してベストを尽くすようにしたい - 今回に限らず、突発&締め切りがすでに決まった状態で降ってくるものがあると辛い ``` 個人的にもかなりメンタルに負荷をかけてしまったプロジェクトでしたので、今後は持続的な価値提供ができるチーム体制の構築を個人課題としていきたいと思います。加えて、チームの扱うテーマが広くなったせいで差し込みタスクや並行テーマが多い点も、安定したチームパフォーマンスの実現には好ましくないので改善を検討しています。 以上です。 最後まで読んでいただきありがとうございました。

2021年/2年以内

クラウド電子契約サービスfreeeサインのオンライン決済機能開発

## 概要 会社のビジョンにマッチするターゲット顧客として、個人事業主向けのサービスプランを用意し、オンデマンドで利用できるようにする ## 顧客規模 既存サービスに存在する潜在顧客30万人 ## 担当 8人チームの中でバックエンドをメインで担当。 バックエンドとフロントエンドの割合は8:2程度。 ## 課題 ### 1. 個人事業主へアプローチするプラットフォームがない - freeeサイン(以下:自サービス)は法人向けであり、個人事業主向けのプランがない。 - ミッション実現のためスモールビジネス市場を開拓したかったが、実現するためのプラットフォームがなかった ### 2. 必要な作業を自動化できていない - サブスクリプションサービスであるものの、Stripe Billingなどのサブスクリプション決済サービスを導入しておらず、請求情報は手計算していた。 - 個人事業主にはオンデマンドでサービスを提供しないと機会損失になる。請求を手計算するとコストメリットもスケールメリットも得られない ### 3. 既存サービスの顧客に、シームレスにサービスを提供できない - 自サービスはfreee会計(以下:外部サービス)との連携を強化して、外部サービスが持つ顧客に価値提供をする狙いがあった。 - しかし外部サービスとの連携機能がないため、価値提供ができない状態だった ## 取り組み ### 1. 「個人事業主へアプローチするプラットフォームがない」への対応 #### 外部サービスの課金単位と自サービスの課金単位をマッピング - 自動課金したときの連携情報を一意で把握できるようにした。 - サブスクリプション管理サービスであるzuoraを導入し、請求業務などを自動化できるようになった。 ### 2. 「必要な作業を自動化できていない」への対応 #### 自動課金機能の実装 - 課金情報を自サービスと連携してDBに保持 - 具体的には、Web APIを外部サービスに実装して自サービスから呼び出し、呼び出した結果を判定して自サービスのプラン情報データベースを更新して連携。 #### 実装した効果 - 手計算の業務時間である月30時間のコストをゼロ時間にした - 営業コストは月30万減少 - マーケティング効率は150%向上した ### 3. 「既存サービスの顧客に、シームレスにサービスを提供できない」への対応 #### 外部サービスアカウントを使ったシングルサインオンの実装 - 外部サービスのアカウントを使ってシングルサインオンを実現 - 外部サービスの持つ情報をスムーズに自サービスへ取り込みやすくした ## 工夫した点 #### 1. 外部サービスアカウントを使ったシングルサインオンの実装での工夫 ##### 1.1 セキュリティ対策 - OAuth2認証でシングルサインオンを実装しようとしたが、[セキュリティリスク](https://tech-lab.sios.jp/archives/13002)の問題からOpenID Connectで実装することにした ##### 1.2 工数削減 - 既存システムには[Doorkeeper](https://github.com/doorkeeper-gem/doorkeeper)を用いたOAuth2プロバイダがあったので、[OpenID Connect拡張](https://github.com/doorkeeper-gem/doorkeeper-openid_connect)を使って実装工数を50%程度削減しつつ実装できた ##### 1.3 ライブラリを使って実装の正しさを確認 - シングルサインオンのクライアントにはOpenID Connect拡張で推奨されている[omniauth_openid_connect gem](https://github.com/omniauth/omniauth_openid_connect)を使用 - 実装内容の正しさを素早く確認できた。たとえば、OpenID Connect拡張を使って実現した認可URL生成が[RFC](https://tools.ietf.org/html/rfc6749#section-3.3)と異なっていることを低コストで発見できた ##### 1.4 使用する技術について効率的な学習を実施 - OpenID Connectの実装を理解するため、omniauth_openid_connect gemを読んで得た知見を[登壇](https://speakerdeck.com/yasuakiomokawa/how-to-implements-csrf-detection-on-web-api)してアウトプット - 実装でつまずきそうな箇所を知ることができたので2週間程度は実装工数を前倒しできた - 登壇後は[感想ブログ](https://note.com/omokawa_yasuaki/n/ncdc97b3e4baa)を書いてふりかえりをした #### 2. 自動課金機能の実装での工夫 ##### 2.1 同期処理のエラー対策(冪等性確保対策) Zuoraは課金情報を登録するときにタイムアウトが発生しやすい。課金に失敗したときに同期用のWeb APIコールを実施したら同期エラーとなる。そのため、エラーにならないよういくつか案を検討した 1. (不採用)Webhookをzuoraを中継するシステムに導入する 1.1. zuoraとの連携が難しい 2. (不採用)自サービスのトップページに遷移したら同期処理を走らせるよう実装し、ユーザにはシステムメッセージでトップページに遷移してもらうよう促す 2.1. あまりにもユーザビリティを損ねる 3. (採用)画面遷移が実施されるたびに同期処理ジョブをSidekiqのlow-priorityキューに格納して同期処理を行う 3.1. toC向け以外の機能にも処理負荷が掛かるデメリットを受け入れた上で、リアルタイム同期に近い状態を作り出せるメリットを採択 #### 3. スケジュールを守るための工夫 - 進捗の遅れを挽回するためにモブワークを導入し、リードタイムを185%向上させた - 詳しい内容は[こちら](https://speakerdeck.com/yasuakiomokawa/huroxiao-lu-falsexiang-shang-karashi-merukai-fa-sheng-chan-xing-falsegao-mefang-mohuwakuwoyan-ete-how-to-go-on-high-peformance-with-mob-work)を参照

プロジェクトカテゴリ
担当工程
経験した職種・役割
あなたが実際に使っていた技術
このプロジェクト詳細は公開されていません

プロジェクトカテゴリ
担当工程
経験した職種・役割
あなたが実際に使っていた技術
このプロジェクト詳細は公開されていません

マネージメント能力

B2B SaaSプロダクトにおける技術的意思決定とデリバリーを一貫してマネジメントした。具体的には、認証基盤統合・セキュリティ基盤刷新・AI活用による業務効率化の3領域で、課題特定から設計ドキュメント執筆、アーキテクチャ設計、実装、段階的リリースまでをオーナーとして推進した。関係者との方向合わせは初期に集中させ、以降は設計ドキュメントを起点とした非同期コミュニケーションで並行して複数施策を進めた。
各施策を「設計が明文化され、リスクが特定され、段階的にリリースできる状態」にする責務があった。認証基盤統合では、旧ドメイン/新ドメインの二重構成・OIDC・複数事業所という固有の複雑性を整理し、送信者・受領者8パターンの画面遷移を設計してチケット起票・見積もりまで完了させ、チームが迷いなく実装に着手できる状態を作ること。セキュリティ基盤刷新では、全17箇所のファイルアップロード経路に統一的なエラーハンドリングを導入し、ユーザーに適切なフィードバックが返る状態にすること。AI活用では、セールスがプロダクト仕様を自力で調査でき、問い合わせ工数が削減された状態にすること。いずれも「自分がいなくても回る状態」を作ることがゴールだった。
### 基本方針:初期同期→設計ドキュメント駆動→非同期フィードバック 私のマネジメントスタイルは「最初に関係者と方向を合わせて人となりを把握し、あとは設計ドキュメントを叩き台に非同期で進める」というものだ。ミーティングを増やすのではなく、ドキュメントの質を上げることで同期の回数を最小化し、かつその人に刺さるコミュニケーションをとることで仕事の質を最大化する。この方針には理由がある。同期コミュニケーションは方向合わせには有効だが、詳細の詰めには非効率で、参加者の時間を拘束し、集中を削ぐ。設計ドキュメントであれば、相手が都合の良いタイミングでレビューでき、フィードバックも文脈付きで残る。結果として判断のトレーサビリティが上がり、後から参加するメンバーのキャッチアップコストも下がる。 この方針を3つの施策で実践した。 --- ### 施策1:認証基盤統合 — 複雑性の言語化と設計リード **課題の構造** freee共通ログインへの移行にあたり、自社プロダクトには旧ドメイン/新ドメインの二重構成、OIDC認証、複数事業所対応という固有の複雑性があった。これらが組み合わさることで、ユーザーの画面遷移パターンが爆発的に増え、「何をどの順番で作ればよいか」がチーム内で共有されていなかった。 **アプローチ** まずTechLeadの技術方針を起点に、自分でDesign Doc(DD)を2本執筆した。1本目はmembership同期の技術仕様、2本目はUXジャーニーとして送信者・受領者それぞれの画面遷移を網羅した。ここで意識したのは「抽象的な方針を具体的なパターンに落とし込む」ことだ。 具体的には、送信者・受領者の8パターンのBefore/After画面遷移図をFigJamで作成した。この遷移図があることで、TechLead・PdL・QAとの体験整理が効率的に進んだ。全員が同じ図を見ながら「このパターンはどうなる?」と議論できるため、認識のズレが早期に解消された。 体験整理の結果をもとにJiraチケットを起票し、見積もりをリードした。チケットは実装単位で分割し、依存関係を明示した。これにより、自分以外のメンバーも「次に何をやるべきか」が明確になった。 **障害と工夫** 最初のDD執筆時、自分の設計意図を十分に共有できず、TechLeadから「なぜその方式を選んだのか」という指摘を受けた。設計の結論だけを書いて、トレードオフの比較や却下した選択肢の理由を省略していたためだ。この反省から、DDに「検討した代替案と却下理由」のセクションを追加し、意思決定の背景を明文化するようにした。結果として非同期レビューの質が上がり、同期ミーティングは方向合わせの1回で済むようになった。 --- ### 施策2:セキュリティ基盤刷新(マルウェアスキャン)— 計画から実装・リリースまで一貫リード **課題の構造** freee共通のマルウェアスキャン基盤が導入されることになり、アプリケーション側のエラーハンドリングを全面的に対応する必要があった。プロダクトにはファイルアップロード経路が17箇所あり、それぞれ異なる実装パターンで作られていた。さらにSREチームとの連携が必要で、アプリチーム単独では完結しない施策だった。 **アプローチ** まずSREとのsyncミーティングを自分から設定し、基盤側の仕様と制約を把握した。この初期同期で「アプリ側が何をすべきか」の輪郭を掴んだ後は、設計ドキュメントを書いて非同期でレビューを得る形に切り替えた。 全17箇所のアップロード経路を調査し、「アップロード前にバリデーターで検出するパターン」と「StorageObject経由で検出するパターン」の2つに分類した。この分類により、最小限のコード変更で全経路をカバーするアーキテクチャを設計できた。闇雲に17箇所を個別対応するのではなく、パターンを抽象化して統一的に処理する方針だ。 実装はPRを細かく分割し、Flipper(フィーチャーフラグ)制御で段階的にリリースした。全PRでテストとQA確認を実施し、問題があれば即座にフラグをOFFにできる体制を整えた。 **障害と工夫** 実装中に想定外の問題が発覚した。Unixのfile descriptor(FD)の特性により、マルウェアとして検出・削除されたファイルでも、FDが開いたままであればS3へのアップロードが成功してしまうという問題だ。これはマルウェアスキャンの意味を根本から無効化するリスクだった。 この問題は事前の設計段階では想定できなかった。しかし、PRを細かく分割して早期に動作確認するサイクルを回していたからこそ、リリース前に発見できた。発見後は、アップロード前にファイルの存在を再検証する事前検知ロジックを自分で設計・実装して解決した。 リリース完了後は、旧スキャン基盤(ClamAV Lambda)の削除計画も作成し、SREのレビューを取得した。「作って終わり」ではなく、旧基盤の廃止まで見据えてオーナーシップを持った。 --- ### 施策3:AI活用によるセールス工数削減 — 課題特定から方針転換まで **課題の構造** PdM(プロダクトマネージャー)へのヒアリングで、セールスからのプロダクト仕様問い合わせが多く、PdMの時間を圧迫していることを特定した。社内にはAIチャットボット(Devin)が導入されていたが、プロダクト仕様への回答精度が低く、活用されていなかった。 **アプローチ** まずQAチームにDevinが何を苦手としているかヒアリングし、課題特定資料を作成した。この資料をもとにPdM・QAと作戦会議を実施し、改善方針を決めた。 当初はClaude Code(自分が普段使っている開発ツール)のskill機能で解決を試みた。しかし、実際のユーザーであるセールスにとってはDevinの方が使いやすいことがわかり、方針を転換した。「自分が得意なツールで解く」のではなく「ユーザーが使いやすいツールを改善する」という判断だ。 Devinの既存回答を調査したところ、プロダクト仕様に関するヘルプページの情報量が不足していることが根本原因だった。さらに、Devinには一度に読み込める行数に制限があることも判明した。そこで、ヘルプページの拡充に加え、ファイル分割と検索キーワードの拡充を行い、ヘルプページ参照率を82%まで改善した。 改善後はセールスチームに自ら展開して利用を促進し、定着を図った。 **障害と工夫** 最大の障害は方針転換の判断だった。Claude Codeのskill開発にすでに時間を投下していたが、しかし「誰のための改善か」に立ち返り、セールスが日常的に使えるDevinの改善に舵を切った。この判断ができたのは、早い段階でPdM・QA・セールスにヒアリングし、ユーザーの実態を把握していたからだ。 --- ### 横断的に見た自分のマネジメントスタイル 3つの施策に共通するのは以下のパターンだ。 1. **初期同期で方向を合わせる**: TechLead、SRE、PdM等のステークホルダーと最初に認識を揃える 2. **設計ドキュメントで具体化する**: 抽象的な方針を、パターン分類・遷移図・アーキテクチャ図に落とし込む 3. **非同期フィードバックで磨く**: ドキュメントをレビューに出し、相手のペースでFBをもらう 4. **段階的にリリースする**: PRを分割し、フィーチャーフラグ等で安全にデリバリーする 5. **後始末まで含めてオーナーシップを持つ**: 旧基盤の削除計画、ユーザーへの展開まで自分でやる このスタイルの利点は、自分が複数施策を並行して進められることだ。同期ミーティングを最小化し、設計ドキュメントを起点に非同期で回すことで、今期は認証基盤・セキュリティ・AI活用の3領域を同時にリードできた。 一方で課題もある。設計の意図を十分に言語化しないと、非同期レビューで「なぜその判断をしたのか」が伝わらず、結果として同期の追加ミーティングが必要になる。この反省から、設計ドキュメントには必ず「検討した代替案と却下理由」を含めるようにした。ドキュメントの質を上げることが、非同期コミュニケーションの質を上げ、最終的にデリバリー速度を上げる。

アピール項目


アウトプット

GitHub アカウント
あり
Qiita アカウント
あり
Zenn アカウント
あり
Speaker Deck アカウント
あり
SlideShare アカウント
未入力です
特にアピールしたいアウトプット
あり

今後、身につけなければいけないと思っている技術は何ですか?

AIとインフラ

あなたが一番パフォーマンスを出せるのはどんな環境ですか?

- 構造がしっかりしていて、目的がはっきりしている仕事をコツコツ粘り強くやれる環境 - 静かなところ - パーソナルスペースのあるところ - カオスじゃないところ

生成AIの活用状況

日常的な情報収集・業務活用
ChatGPTやGeminiなどのチャットツールを、情報収集、ドキュメント作成、翻訳に日常的に活用
業務でコード補完系の生成AIを活用
GitHub Copilot等のコーディング支援ツール
業務でコード生成、コーディングエージェント系の生成AIを利用
コードレビュー、テストコード生成、デバッグに生成AIを活用
サービス・プロダクトへの応用
既存のサービスやプロダクトに生成AI(API利用など)を組み込み、LangChainやLlamaIndexなどのフレームワークを使った開発経験

キャラクター

直近で一番やりたいこと
技術を極めたい
好きなスタイル
好きな規模
水とプログラミングどっちが大事?
自信を持って人より秀でていると言える点
学習能力 / 問題解決力 / 責任感
スキルのタイプ
得意なフェーズ
会社を選ぶ一番の基準
風通しの良さや意思決定ライン
やりたくない分野
金融 / 広告 / ゲーム / アダルト / 仮想通貨
その他の特徴
使用言語にはこだわらない / 勉強会でLTをよくする / 起業/創業期のベンチャーにいた / 多職種のバックグラウンドがある / OSSのコミッターである / stackoverflowで回答した
その他のやりたいこと・やりたくないこと

カオスな仕事はきらい。

やりたい事

手を動かして設計してコードを書きたい
絶対やりたくない
あまりやりたくない
別に普通
やりたい
絶対やりたい
価値あるプロダクトを作り成長させたい
絶対やりたくない
あまりやりたくない
別に普通
やりたい
絶対やりたい
学び続けて技術力でプロダクトに貢献したい
絶対やりたくない
あまりやりたくない
別に普通
やりたい
絶対やりたい
意義があることや社会に貢献できる仕事がしたい
絶対やりたくない
あまりやりたくない
別に普通
やりたい
絶対やりたい
人や計画の調整・マネジメントをしたい
絶対やりたくない
あまりやりたくない
別に普通
やりたい
絶対やりたい
レガシーなシステムの保守・運用・改善をしたい
絶対やりたくない
あまりやりたくない
別に普通
やりたい
絶対やりたい
企画や仕様を考えるところから関わりたい
絶対やりたくない
あまりやりたくない
別に普通
やりたい
絶対やりたい
業務効率を改善して一緒に働く人のためになりたい
絶対やりたくない
あまりやりたくない
別に普通
やりたい
絶対やりたい
全社横断的な共通基盤作りや強化をしたい
絶対やりたくない
あまりやりたくない
別に普通
やりたい
絶対やりたい
組織や文化を作る・成長させる仕事をしたい
絶対やりたくない
あまりやりたくない
別に普通
やりたい
絶対やりたい

基本プロフィール

年齢
今年で40代前半
好きなテキストエディタ
Visual Studio Code
希望勤務地
東京都 / 京都府 / 福岡県 / リモート勤務
家庭の事情や体調など、都合に合わせてリモート出来れば問題ない
希望年収
未入力
ご意見箱

要望、不具合報告、使いづらい点や感想など、お気軽にお寄せください。
いただいたご意見は、今後のサービス向上に活用させていただきます。

なお、このフォームは受付専用のため、返信を行っておりません。
返信を希望する場合はお問い合わせよりご連絡ください。

  • {{error}}
転職ドラフトを友人や同僚に薦める可能性はどのくらいありますか?