🙆

法改正をマイクロサービスで立ち向かう(前編)

2021/12/15に公開
1

はじめに

ボリュームが多くなってしまったので前編・後編の2部構成になります。
Engineers Advent Calendarなのでエンジニア向けの記事になります。
ドメイン駆動開発やマイクロサービスといった用語が出てきますが、詳しく知らなくても雰囲気で読める様にしたハズ。 [1]
前編はテクニカルな話は扱いません。

背景とか

LITALICOは障害福祉領域において複数の事業を展開していますが、コア事業として以下の2つがあります。

  • 児童福祉法に基づく障害児支援事業
  • 障害者総合支援法に基づく就労支援事業

領域は違うものの、その支援内容については各種法令に沿って行われるものとなっています。
今自身が携わっているプロダクトでは前者の障害児支援事業に携わっている事業所さま [2] 向けの運営支援システムとなります。

運営支援システムはその支援内容にあわせて機能提供を行っており、 給付費の請求業務も含まれます。

給付費請求については馴染みがない人が多いと思いますので軽く補足します。
一番身近な医療をベースで説明すると、お医者さんに掛かった際の医療費は原則3割自己負担分として支払っていらっしゃると思います。
その際に受け取られる診療明細書に点数が書いてあると思いますが、その点数はお医者さんが勝手に決めたものではなく診療報酬制度というもので決めれたものになります。
また、3割支払いされた残りの費用を請求するレセプト業務がそれにあたります。

障害者福祉領域では自己負担が1割だったりしますが、医療と同じように支援内容に応じて点数が 障害福祉サービス等に係る報酬 として定められています。
この定められた点数のことを報酬単位と呼びます。

今回記事として取り上げるのは、この 障害福祉サービス等に係る報酬 が3年に1度大きな改定が行われるのですが、ちょうど今年が法改正のタイミングにあたります。
システム対応するにあたり、どうやって立ち向かっていって乗り越えたかについてお話したいと思います。
「複雑なルールが絡み合ったシステムの関心事(今回は法改正というテーマ)をどう紐解いて実現していったか」という一つの事例としてお伝えできれば幸いです。

法改正への対応の難しさ

まず法律改正に伴いどう変更があるかのキャッチアップが大変ですw
今回の法改正の資料としては. こちら にまとめられていますが、資料の多くまた記載されている内容もドメイン知識がないと一筋縄ではいかなかったりします。
また、現時点では情報が集約されておりQ&Aも整備されて掲載されていますが、法律施行前までは五月雨に情報がアップされて随時変更も加えられていく流れとなっています。
開発をする上で如何に精度高く情報をキャッチアップして、素早く且つ正確にシステムへ反映していくことが重要になります。
扱っている業務としては日々の運営や月一回の請求業務があり、法改正は期日通り施行され待ってはくれません。
法改正の対応プロジェクトとしてはシステム停止を最低限にし、エンドがずらせない形となります。

次に報酬制度自体が複雑で難解という点です。
一つ一つの支援内容に対して様々な条件の組み合わせによって報酬単位が定まるようになっています。加算だけでなく減算や割合に応じた加算もあったりします。
この報酬単位の組み合わせを表したものを報酬算定構造と呼びますが、組み合わせの数が膨大です。
この組み合わせの複雑さもあって請求業務周りの単体テストで4,000オーバーのケースほど必要になっています。
また、組み合わせがある算定要件(パラメータ)が法改正によって増減します。システム改修時に報酬算定構造を誤って設計(確定情報ではないキャッチアップした情報で設計を行うので厳密には予想に近いですが :sweat_smile: )を行うと大変なことになります。 [3]

次に、法改正がされても旧制度の対応は維持しつづけないという点が難しいです。
過去行った支援に対しての給付費の請求で誤りがあった場合に、過去時点での報酬制度に応じた請求をやり直す必要がある為です。
これは報酬算定構造のロジックの肥大に直結します。元々扱うドメインが複雑でテストケースも膨大なのに、更に複雑さが増すというのはかなり辛いです。
旧制度のビジネスルールにを壊すことなく新制度に対応することが求められます。
開発期間が非常に限定され、短期間となるのは上述の通りですが、新制度だけでも検証するのに手一杯なのですが、どこまで旧制度の検証を行えるかが課題となります。

課題まとめ

法改正の対応の難しさをまとめると以下の課題になります。

  1. 期間内で必ず対応を完了することが求められる
    情報が出てこないと開発がスタートできず、かといって情報が全て出揃ってからシステム全体の設計〜実装を行っていたら間に合わない。
  2. 既存の膨大なロジック及びテストケースに条件分岐が発生し、データの互換性を保つことが難しい
    法改正では報酬単位の見直しだけでなく、報酬算定構造に影響がある変更。。軽微なもの、廃止されるもの、新規追加されるものと多岐にわたります。
    単純に既存ロジックに対して条件分岐を追加してしまうとコードの可読性低下やテストコードのメンテナンスの難易度が上昇します。
    またロジックに追従してデータの拡張も必要です。
  3. デグレを発生させてはいけない、また品質担保する為のコストを少なくしたい
    組織内にはQAチームが存在していますが、法改正ではレセプト業務以外も改修範囲が広く、短期間で全てのケースを確認することはできません。
    人で全てカバーするのは難しいので品質を確保する為の仕組みが必要です・

これらの課題を解決していく必要があります。

課題解決に向けてのアプローチ

運営支援システムはマイクロサービスとして構築しています。
サービス立ち上げ当初から業務単位にサービスを切り出し、開発を行ってきました。
特にレセプト業務はコアドメインという位置づけで慎重に分析・設計し、境界づけて実装を行ってきました。

上記でまとめた課題に対してどうマイクロサービスとして立ち向かっていったかを一言でいうと

同一の関心事を時系列で分断させ別の関心事として扱う

になります。

具体的にはレセプト業務ドメインを扱うAPIを旧制度と新制度でそれぞれ別APIとして実装しました。
旧制度と新制度の切り替えは支援を提供した月によって判断可能です。提供月によってまったく異なるビジネスルールを適用するというイメージです。
元の関心事は同じですが、時間が違ったら関心事は別で扱っても良いのでは?という判断でドメイン分割を行いました。
ドメイン分割を行うことで上述した課題のうち、2つが解消できました。

  • ドメイン自体のコードベースが別になることで条件分岐がなくなりシンプルになる
    データも独立して存在するので、既存のデータの拡張を考えなくて済みます。
  • 旧制度のドメイン・ビジネスルールには手をいれないので、完全に仕様を保ったまま動かし続けることができる
    なにも変わらないという安心感は何事にも代えがたいですw
    リグレッションテストが最低限で済みます。

逆にドメイン分割することによるデメリットがないか?という所は気になると思います。
おそらく以下の2点が気になるかと思います。

  1. 2重メンテナンスになって辛くならない?
    バグ修正や機能追加とかで改修コストが倍になったりしないか?
  2. インフラやデプロイコストが2倍にならない?

1に関してはまったく問題になっていません。逆に拡張しやすくメンテナンスも楽だとさえ感じています。
それぞれ大丈夫だと考えている理由として以下になります。

  1. 十分に責務が絞られて限定的になっているので改修対象とならないことが多い
  2. インフラ・デプロイコスト < 品質担保に関わるコスト となる

1つ目は理由というよりは前提に近いですが、責務が明確になっており、そうそうロジックに手を入れなくてもよい状態にするということです。
うまく関心事が閉じ込めが出来ているので可能になっている。。綺麗に分割することができる!です。
法改正に関わらない改修は、バグやまったく新しい概念が生まれるケース以外では考えられず、余分な責務を持っているという認識です。
日々の機能追加では大半が別アプリ側での実装となります。
請求業務上で新しい概念を追加する場合でも、スコープを絞って新制度のみの対応で済ますということも出来ます。 [4]
バグ対応についてですが、旧制度のアプリは長期運用がされて十分枯れており対応するケースは極稀です。 [5]

繰り返しになりますがドメイン分割され、それぞれのドメインがシンプルになるので、たとえ2重で修正する場合にでもトータルのメンテナンスコストは下がります。
新しいメンバーが増えた際に実感したのですが、旧制度の詳細な内容を説明していなくても、開発をスタートできたというのは大変ありがたかったです。

2つ目になりますが、ドメイン分割によりアプリが複数となりデプロイが複雑になり、インフラコストも上がりました。
ただ課題でも上げましたが、 デグレを発生させてはいけない、また品質担保する為のコスト という面で考えるとトレードオフの関係になっているという認識です。
ただインフラコストは開発者やQAメンバーがテストする際のコストよりも十分安いです。また品質担保の為のテストは法改正に限定されずシステム改修の度に行います。
もしリリースの度に旧制度と新制度ともにリグレッションテストを行うことになったらQAメンバーを今の2倍にしないと難しいです。
リグレッションテスト単体だけ考えてもインフラコストの増加分は十分ペイできます。テストにかかる時間を圧縮できるというメリットもあります。[6]

前編まとめ

実はこのドメイン分割のアプローチについては、サービス構築当初にチーム内で話し合われておりコンセプトとして存在していました。
今回まとめた内容はそのコンセプトを実現した際に自分なりに感じたことや、振り返って整理したものとなります。
ただコンセプトとしてあったものの、メンバーがそれぞれなんとなくのイメージを持っているだけで課題や具体的な実装方法までドキュメントとして纏まっていませんでした。
法改正プロジェクトが始まる前の自分自身のシステム全体のドメイン理解が薄かったり、そもそも法改正に対応する経験がなかったりと不安を抱えていました。
サービスがリリースされてから小規模な改正に対応した実績はありましたが、大規模な改正はプロダクトとしては初になります。  
後編で書くつもりですがドメイン分割が形になるまでは色々課題があり、悩みながら実装をすすめて大変ばたばたでしたw
なので次回の法改正では、私自身や新しいメンバーが少しでも安心して取り組めるように本記事が役に立てばという思いで書きました。

  • ドメイン分割しちゃって本当に大丈夫?
  • サービス間の連携で問題にならない?
  • 気をつけないといけないところは?
    などなど

最後に、自分なりに法改正プロジェクトを振り返るとマイクロサービスでなければ、複雑なシステムをこの短期間で改修することは出来なかったと思います。
またドメイン分割のアプローチは正解だったと実感しています!

最初にコンセプトを掲げ、責務を明確にしドメインを設計してくれたメンバーに感謝したいと思います。
この複雑な業務を如何に一つの関心事として閉じ込めるか?という所に心血を注いでくれたおかげで、プロジェクトを乗り越えることができました!

最後に

後編は24日に投稿予定です。おたのしみに!

明日もアドカレ続きます。

@YudaiTsukamoto が何か書いてくれます!


追記:
後編を投稿しました

https://zenn.dev/katzumi/articles/confronting-law-amends-with-microservices2

脚注
  1. 業務で使っていたり、興味を持ってくれている人に読んでもらえると嬉しいです ↩︎

  2. LITALICO自身も含まれます ↩︎

  3. 正確な情報が出揃ってからシステム改修していては間に合わないという側面があります ↩︎

  4. 実際に、現在開発中の機能で旧制度はスコープ外としました。ビジネスサイドも関心事が別れているという認識を持っているので調整は大変しやいです ↩︎

  5. 旧制度の利用は誤請求に対してのみになるので利用頻度も下がります ↩︎

  6. もしドメイン分割しなかったらテストケース数も倍になり、CIの待ち時間も倍増していただろうと考えています ↩︎

Discussion