技術的負債を草の根活動で改善していった話
こんにちは、大平(@yohira_dev)です。 2018年10月から3年間、業務委託としてグロービスの決済プラットフォームの改善に着手してきました。 本記事では2018年~2021年末までの「グロービスの決済システムがどう変化してきたか」「発生する技術的負債をどう改善してきたか」を赤裸々に解説していきたいと思います。
プロダクトの位置づけ
グロービスは主に、"社会人に必要なビジネススキルを動画で学べるサービス"「GLOBIS 学び放題」とその海外版である「GLOBIS Unlimited」を展開しています。
この二つのサービスの共通決済基盤を、近年のビジネス状況の変化に追従できる速度をキープしながら安定して運用することがグロービスの決済チームのミッションです。
ジョイン当初の状況
さて、当初の決済基盤は大体こんな感じでした。
チームはプロダクトオーナー+フロントエンドエンジニア一人+バックエンドエンジニア+私。わくわくしてきましたね。
2018年10月~12月(2018年度3Q)
ジョイン。とりあえず不具合修正のチケットを捌きながら、gemライブラリのアップデートなど草の根活動をやっていくことにしました。 社内で利用する管理画面がjQuery 1.1、かつnpm管理されていない(assets/にどこから拾ってきたのかもわからないjQueryライブラリの実体ファイルが置いてあるだけ)状態だったのでnpmとwebpack, typescriptを導入しました。新規でフロントを書く場合はこの構成を利用するようにしました。 これで一部ではありますが、管理されたライブラリ群でTypeScriptの型の恩恵を受けられ、近代的な構文でフロントエンドが書けるようになりました。 社内ドキュメントツールはQiita::Teamを利用していましたが、機能や設計の意図などが抜け落ちている状態だったので実際に動かしたり、コードを読みながら重要な仕様や挙動をドキュメント化していきました。
オフショアに外注したコードらしく、品質が悪かったため、どこかを直すとどこかが壊れる状態でした。社内の基幹システム(外注管理)とも連携しており、改修に時間がかかる状況でした。
またCIは回っているもののCircleCIの設定ファイルを確認すると、modelとserviceの一部分しかテストが実行されない設定になっていました。この時期はローカルでmasterの全テストを実行すると失敗しました。
ロクに価値ある機能がリリースできず「オレ、契約終了になるのでは?」とビクビクしながら仕事をしている時期でした。
2019年1月~3月(2018年度4Q)
サービスのうち、一般ユーザーが触る部分はSPAになっていたので、チーム内のフロントエンドエンジニアとペアプロを実施しました。
この頃はReact hooksがまだなく、react-redux, HOCなどを駆使してSPAを構築する時代でした。
また思想がエンジニア個々人によってかなりばらつきがあったので、ページをまたぐと全く違うReactの世界が広がっている、という状況でした。楽しいですね。
React(redux) + TypeScriptの最新の書き方をキャッチアップしつつ、とりあえずチーム全員がSPAでもフロントを触れるような仕組みになってきたところにフロントエンドエンジニアが退職。
人数が少なく既存のコードベースの理解にもかなり時間が掛かる状況だったので、やむなくスプリントを1week →2week単位に変更しました。
期を同じくしてfigmaで現状から画面を作ってくれていたデザイナーが別プロダクトへ異動。デザイナー不在に。「フルスタックで何でもやっていくしかない」と腹を括りました。 さらに、この時期から
などの要望から、決済基盤をGMOからStripeに移行するプロジェクトが開始され、運用しているチームからの不具合対応をこなしながら新機能開発を行う日々が始まりました。
2019年3月~6月(2019年度1Q)
新卒エンジニアが3人入社し、フロントエンドエンジニアをチーム外から週2日くらいのコミットでお願いしてもらうもその人が退職するなど、チーム編成もかなりダイナミックに動いていて正直不安定な時期だったと思います。
また、dependabotの導入により、ライブラリのアップデートを自動化しました。「rubocopの警告部分を直したPRを出す」「null制約が必要なはずなのについていないものにnull制約をつけるmigrationを書いていく」という作業をスプリント外の作業として地道に行うようにしました。千里の道も一歩から。
2019年7月~9月(2019年度2Q)
CI上のRSpecが全てのファイルに対して実行されるようになり、テストの失敗、リグレッションの発生を早期に検知できる仕組みが最低限整いました。
決済周りの実装で金額周りの不整合が起こると致命的なので、チームメンバー全員で集まって大画面にコードを映しながらレビューをする「モブレビュー」という仕組みを導入。
短期的な実装速度はやや落ちますし、思考に対する負荷は高いですが、設計から実装までの一貫したノウハウをチームメンバー内で共通化するという意味でかなり成果があったと思っています。
Model、Serviceあたりも地道にテストを増量しました。ただ、Factoryの定義がいい加減だったので全員で直す(修正する)こともありました。
2019年10月~12月(2019年度3Q)
「うちら受託開発じゃなくて自社プロダクトやってるんだから、目の前の案件を捌くだけで精一杯じゃダメだよね」ということで、中期ロードマップを決める動きや、各チームのスクラムをまとめる「Scrum at Scale」のような動きが出てきた時期です。
rubocopの警告を5件まで減らしました。
アーキテクチャ設計周りについての知見をチームで深めるために「マイクロサービス勉強会」「PofEAA勉強会」などを立ち上げました。
2020年1月~3月(2019年度4Q)
この時期は、粛々と決済プラットフォーム移行を進めました。テーブル定義にNOT NULLを入れる草の根活動も実を結んできました。
また、RubyのEOLが迫ってきていたので2.4 → 2.5 系にアップデートしました。このころ、新卒エンジニアがチームへジョインしました。
iOSアプリ「GLOBIS 学び放題App」が、Appleの課金レギュレーションに違反していたため運営側からアプリのアップデートを止められることもありました。
2020年4月~6月(2020年度1Q)
コロナショック。それまではチームメンバーも週3回くらい出社していたのですが、全員リモートを余儀なくされます。
前もって「設計ノウハウのドキュメント化」「モブレビューによるチーム内での知識共有」「属人性の排除」をやってきたため、想定より業務効率への影響は少なかったといえます。
ドキュメント管理ツールはQiita::TeamからNotionへ移行。
この時期からQAチームが立ち上がり、新機能リリースのときはテストに入ってくれる流れが確立しました。
サービス自体も「巣ごもり需要」で家でビジネス動画を見る人が増え、ユーザー数が伸びた時期でもあります。
リモート環境下で決済プラットフォームの切り替えを決行し、本番環境へのリリースも問題なく終了し、同じチームで動いていた新卒エンジニアが社内MVPを獲得しました。
2020年7月~12月(2020年度2Q・3Q)
アップデートの止まったiOSアプリを救うべく、In App Purchaseの実装に取り組みました。これまで積み上げてきたチーム開発のノウハウを活かし、iOSアプリチームと混成チームを組んでやりきりました。
この頃にはWeb決済の品質は大分安定してきていて、不具合問い合わせもかなり抑制されてきたように感じます。
2021年1月~3月(2020年度4Q)
EOL直前でなんとかRubyの2.5 から2.6へのアップデートを間に合わせました。
2021年3月~6月(2021年度1Q)
ビジネスを英語で、動画で学べる「GLOBIS Unlimited」をリリース。
なんとか決済基盤を共通化することができ、課金周りの開発工数削減・運用の安定化を実現しました。
2021年7月~9月(2021年度2Q)
サービスの新規ユーザ獲得施策として「キャンペーン機能」をリリース。
この頃からついに、masterマージ即リリースの仕組みが回るようになりました。
2021年10月~12月(2021年度3Q いまここ)
GLOBIS Unlimitedでの海外ユーザーの獲得を加速させるべく、ドル決済機能を決済プラットフォームに組み込みました。
チームとしてはペアプロ・モブプロを積極的に活用し始めていて、これによって属人的な知識をチームの集合知に変換していっています。
課題は解決したのか?
最初に上げた課題はいまこんな状況です。
まだまだ、やりきれていない部分も多いですが、だいぶいい感じになってきたのではないかと思っています。
グロービスでは一緒に働くエンジニアを募集しています。
記事を読んで頂きありがとうございました。 グロービスでは一緒に働く仲間を募集しています。 決済まわりは求められる品質もシビアなのでしんどいことも多いですが、その分需要も多く面白い領域の仕事です。 カジュアル面談も積極的に行っておりますので、少しでも教育×ITに興味があれば是非お話をさせてください。