2013年に入社して以降、10年間一貫してfreee会計というSaaSサービスの開発に携わってきました。
また、2016年からはfreee会計開発チームのマネージャ、2018年からは会計、人事労務、モバイル、QA、CRE等プロダクト開発組織の開発本部長として開発組織や採用課題にも対処してきました。
マネジメントポジションになっても、コードはこれまでずっと書いてきていたのでそこは安心してください。
主な役割と成果
# Webの開発エンジニア(フロント/サーバ/インフラ)
サーバサイドはRuby on Rails(と一部Golang)、フロントエンドはJavaScript->TypeScript + React、インフラはEC2->EKSという構成で開発していました。
規模としては、https://speakerdeck.com/waka/da-kinapurodakutofalseyu-tefang?slide=9 が参考になりますが、コード規模はサーバ/フロント共にこのスライドの1.4倍程度になっています
## 会計機能周りの機能開発(主だったもの)
### 会計データを結果整合で集計する
利用事業所が増えたことで、会計データを集計して表示する機能が軒並みパフォーマンスが大きく劣化。
(BS, PLといったレポーティング系の機能)
そのため、元になる入出金データの作成/更新/削除時にあらかじめ中間集計データを作るように変更。
この際、入出金データのトランザクションが長くなったため、ロックエラーが頻発するように。
欲しかったのは、事業所単位で直列に処理しつつ、分散させる仕組み。
そこで、EventStreamベースのアーキテクチャに変更して、集計処理をトランザクションから別プロセスに分割するようにした。
EventStreamにはAWSのKinesisを採用。当時はマネージドのKafkaがまだ無かったこと、SQSのFIFOキューは書き込み数の制限を超えてしまうため不採用とした。
ざっくりした流れとしては、変更ログ -> fluentdのoutでKinesisに流す -> コンシューマで集計処理、という感じにしました。
### Ruby版Kinesisクライアントライブラリ
Kinesisのクライアントライブラリ(Kinesis Client Library = KCL)は公式から提供されているものがJavaベースのものしかなく、コンシューマをSpringベースで作りました。
WebアプリケーションはRailsベースで作っているので、同じリソースを複数言語で処理しないといけないことに不満があり、公式のspecificationを満たすRuby実装を作ってみました。
https://github.com/waka/kcl-rb
詰まったときや再起動した際の復旧のため、チェックポイントの管理にDynamoDBを使っています。
その後、コンシューマからRailsのAPIを叩くような形にしたため、kcl-rbを使うことはなかったのですが、
社内の共通基盤としてPubSubを作ることになり、上記リポジトリをfolkしたものを使っています。
### 会計データ登録の自動化
リリース当初、クラウド会計であること以上の機能的な売りが欲しくて開発した機能です。
自動で経理というオンラインバンクの明細データと連携してルール+推測ロジックで会計データを自動生成する機能
銀行口座の明細の文言に対して、ルールベースのフィルタをかけて、マッチしたものを登録した内容で会計データを作るようなもの
前方一致、中間一致、後方一致等のマッチングケースが書けます
ルールのパターンが将来複数になっていくことを考慮してストラテジーパターンで作りました
工夫したポイントとしては、明細データが数億件溜まっていってもインデックスを使い切れるように設計した点
### 各種インポート機能及び基盤開発
初期の頃に他社サービスから移行する仕組みがなかったため、提案して開発しました。
他社会計ソフトからのCSVインポート。データ量や行単位のチェック項目が多くバッチ処理にて実装
他社のソフトが出してくるCSVがCSVの仕様を満たしていないものが多く、腐敗防止層を作って本当にCSVに変換するのが大変でした
数千行以上のCSVを1トランザクションでActiveRecord化するとエラー時にメモリを使い切ってしまうリスクがあるので、1行ずつコミットしてトランザクションを小さくしつつ、エラー内容をユーザーがわかるような仕組みにしました
### 権限管理の導入及び基盤開発
ABACな権限管理の仕組みを導入。後続のサービスでも使えるようにgemとして切り出せる形で実装
デフォルトの権限セット+ユーザーが自由に権限を設定できるようなカスタム権限という感じです。
その後、利用プランによっても権限を変えたいケースが出てきたため、ABACな権限管理フィルタも実装しました。
### 申請ワークフロー機能開発
Googleフォームのような自由に入力パーツを組み合わせ可能なフォームに申請プロセスをくっつけられるものを作りました。
自由なフォームを実現するために非定型なスキーマをMySQL上に作って開発。
入力フォームごとのテーブルを作って、表示時に結合するような作りにしました。
申請プロセスは会計領域以外(例えば人事労務での労務申請等)にも使うユースケースがありそうだったので、Golang + gRPCベースのマイクロサービスとして切り出す作業も合わせてやりました
### Rails, Rubyアップデート
Rails5, Ruby2.7まではほぼ自分がバージョンアップをしていました。
ほとんど自社のコード起因の問題でしたが、パフォーマンス劣化が起きた点については、Railsのissueに報告等するようにしています
### 数えきれない不具合対応
ジョジョではありませんが、たくさんやりました。
普通のエラーからイレギュラーなデータ修正や、パフォーマンス改善(主にクエリ)など運用系の課題は得意です(得意になりました)
# モバイルアプリの開発エンジニア(iOS/Android)
## iOSアプリの立ち上げ
会社の忘年会にて社長からモバイルアプリを作りたいと言われ、1ヶ月でストア申請まで完了
当時モバイルアプリ経験者がいなかったため、一から技術選定+機能開発+リリースまで
外で登壇して採用プレゼンスを上げたいという狙いもあり、当時はまだ少なかったリアクティブな構成で作りました
## Androidアプリの立ち上げ
iOSと同じく一から技術選定+機能開発+リリース
構成もiOSと合わせてリアクティブなレイヤードアーキテクチャを採用
# プロダクトチーム及び開発全体のマネージャ
2016年に会社に初めてマネジメントロールが出来たタイミングから8年間従事していました。
まだ売上が厳しかった時代から上場、上場後のグロースフェーズまで一通り経験しています。
開発面では、取り組んでいたことの一部は発表資料に記載している「大きなプロダクトの育て方」スライドに詳しく書いてあります。
スタートアップ時代からパブリックカンパニーになっていく中で、品質面でのマインドセットやサービス品質をユーザーさんから求められる水準まで、サービスの成長を止めずに改善できるかに頭を使っていたことが多かったと思います。
大きなトピックとしては、会計という割とクリティカルなサービスで決算データの集計に結果整合性なアーキテクチャ(裏側はAWS Kinesis)を採用したというものがあります。マルチテナント且つ複数ユーザーで同時編集されることが増え、ロックエラーが頻発していたことに対する対策としてやったのですが、結果クリティカルな不具合を出すこともなく、その後のユーザー増にも耐えていってくれている感じでよかったです。
組織面では、役割上採用面の貢献を求められることが多く、これまで1000回以上面接を行い、100人以上の中途エンジニアのオファーから受諾獲得までやってきました。
その他、組織が大きくなるなかでエンジニアの成長/評価軸の目線を揃えていきたくなったので、https://jobs.freee.co.jp/engineers/ のページに載っている「freeeの開発文化」というのを中途のエンジニアたちにヒアリングもしながら社内/社外公開しました。マネージャがフィードバックする際のポイントに使われているので、意外と根付いてくれてよかったです。