i_like_banana

3年後の目標や野望


プロダクトのビジネス価値を最大化する

## そう思う理由 私はこれまでの経験から、スケジュールどおりに機能をリリースすることが重要だと理解しています。しかし、自分が設計した機能をユーザーに十分に活用されていない経験をしたため、「これではいけない」と感じました。 ## 具体的にやりたいこと - アジャイル/スクラム を用いたソフトウェア開発で、スプリントレビューを積極的に活用する - プロダクトのアクセスログ、アプリケーションログ、アナリティクスログを組み合わせてユーザーの行動データを把握する - ユーザーの状況を鬼の如く徹底的に言語化する

年収評価シート

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)を参照

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

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

マネージメント能力

アピール項目


アウトプット

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

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

- OSSを解読してコミットできる程度のソフトウェア設計技術 - 認証/認可の技術 - カウンセリング技術 - モダンフロントエンド(特にテスト)

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

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

キャラクター

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

仕事仲間の幸せに繋がらないことをやりたくない。

やりたい事

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

基本プロフィール

年齢
今年で30代後半
好きな Text Editor
Visual Studio Code
希望勤務地
東京都 / 京都府 / 福岡県 / リモート勤務
家庭の事情や体調など、都合に合わせてリモート出来れば問題ない
希望年収
1000万円
転職ドラフトに参加して
企業から指名を受け取ろう!
会員登録をして転職ドラフトに参加すると、参加企業から年収付きの指名を受け取ることができるようになります。
会員登録する
ご意見箱

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

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

  • {{error}}
SIGN UPSIGN IN


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