我が家は共働きで、財布はそれぞれで管理しつつ生活費は収入に応じて大まかに按分するという運用をしています。
支出した生活費はすべて一元的に記録し、按分割合を掛けて月末に清算することで、個人支出の自由度と公平性を両立して、その気になれば後から調査・支出分析も可能というGoodな仕組みになっています。
割り勘の記録については、様々なサービスがありますが、Splitwiseを採用しています。
明細ひとつひとつに傾斜割合をつけることができるので、今回の要件にはぴったりです。
ただ、「自動で50:50以外の傾斜割合を設定する」という機能はSplitwise Pro(月700円/人)が必要。夫婦二人で月1400円は決して安くない出費です、しかも利用目的が傾斜を自動設定するだけ。
現行ソリューション
SplitwiseにはAPIアクセスは無料でついてくるというクソデカメリットがあります。というか、これがSplitwise採用最大の理由です。
そこで、最低限動作する形で自宅グループの最新レコードを取得し、すべての明細に負担割合を設定しなおすLambda関数を作成することで、Proプランなしに家庭内の按分割合を自動で設定することができています。
1日で作ったので、とりあえず家庭内利用に問題ないレベルだけで実装されており、2時間ごとにGetExpensesで返ってくる直近20件の明細のみを対象に動作し、結果は自分のSlackワークスペースにログが残るという単純なシステムです。コアロジック(金額計算)以外のテストコードはありません。
2時間以内に20件以上の家庭出費が発生することは考えづらく、インプットデータはSplitwiseのアプリ内でバリデーションされるという前提に立っているので、はっきり言って雑な実装ですが1年以上うまく動作していました。
レガシーコード改善
非常にいい感じに働いていてくれたのですが、ある日「グループIDを指定して取得しているのにグループIDがNullのデータが混入する」というSplitwise側で謎のエラーが発生した結果、この関数も処理中にコケてしまいました。更に悪いことに、発覚が1週間以上遅れたため20件以上のレコードが積み上がり、過去分の再実行に一苦労しました。
ちょうどt-wadaさんの実録レガシーコード改善を読んで意識が高まっていたので、まごうことなきレガシーコードであるこの関数をTDDで改善していきます
- TDDによるモダナイズを体験する
- openapi-typescriptを利用してタイプセーフなコードを書く
- エラー時にSlack経由で自分にメンションを飛ばし、検知を早める
もともとSwaggerのAPI定義は公開されていたのですが、当時はTSの型定義にうまく変換できずにいたために、any
でお茶を濁していたのですが、そうも言っていられないので今回はキッチリやることが目標です。
序であり結:型を追加する
まずテストを増やしたいところですが、TypeScriptの恩恵で対処できる部分を先に潰しておきます。
結論から言うとこれだけでやりたいことがほぼ終わってしまいました…テストは異常系を追加してログの出力確認をしたのみです
使ったものはOpenAPI-typescript
OpenAPIの定義ファイルからd.tsファイルを生成してくれるので、typesディレクトリに突っ込んでターンエンド。
こんな感じでAPIのパスごとに型がついているので、呼び出してanyを全部潰していきます。
エラーが無くなるまで書き直して、イケてない関数名などを直して終了。