『みらい まる見え政治資金』を支える技術-国政政党がリリースしたOSSの技術選定と実装について
はじめまして。チームみらい 永田町エンジニアチームの伊藤と申します!エンジニアチームではエディと呼ばれています。
先日チームみらいでは、政治資金の流れを透明性を持って公開するプラットフォーム「みらい まる見え政治資金」をリリース、ソースコードも OSS として公開し、サービス開始から約2日で20万PVと、大きな反響をいただきました。
このサービスがどういったものなのか、なぜ公開するのかについてはこちらの記事に譲るとして、この記事では、ソフトウェアエンジニア向けに振り切った記事として、サービス構成と工夫した部分を紹介しようと思います。
また、関連記事として、「どのようにして95%以上のコードをLLMに書かせることができたのか」についても記事にしているので、よければ合わせてお読みください。
国政政党の提供するサービスとして意識したポイント
公共性のあるサービスとして
「みらいまる見え政治資金」は、国政政党がリリースする、ある種公共性のあるサービスとなるため、まず安定してサービスを提供できること、その上でなるべく多様な方にサービスを使っていただけることを重視して設計・開発を行いました。
結果としては、公開から2日で約20万PVと多くのアクセスをいただきながら、ダウンタイムや目立った不具合はなく、また表示速度・アクセシビリティ・SEO評価などについても各種評価ツールで高いスコアを実現できており、この点はうまく設計できたのではないかと思っております。
スピードと汎用性のトレードオフの中で
また、このプロジェクトは、チームみらいが参院選で100日以内に実装することを約束した「100日プラン」の一つであり、政党と有権者の信頼関係を構築するために、スピード重視で開発し100日以内に公開することは必須と考えていました。
しかし一方、長期でみると、チームみらいだけがうまく使えれば良いという性質のツールではありません。今後、複数の政治団体に利用されていくことを見据えたコードですので、汎用性を高め特定のサービスに依存しすぎない設計も重視しました。
この、スピードと汎用性のトレードオフについては、のちのち変更が効きにくいデータベースまわりはしっかりと設計・抽象化しつつ、変更の効きやすい表示層にはチームみらい独自のロジックのベタ書きを許容するなど、濃淡を付けた抽象化を心がけたことで、一定の拡張性を保ちながら100日以内での公開ができたと考えています。
工夫した点のご紹介
ここからは、特に工夫した点として、以下の4つをピックアップし、内容をご紹介していきたいと思います。
スピードと汎用性を両立するための技術選定
安定したサービスを提供するためのキャッシュ戦略
なるべく多くの方に利用いただくためのアクセシビリティ対応
より多様な角度からお金の流れを理解いただくためのデータ構造
開発スピードと汎用性を両立するための技術選定
この章では、みらいまる見え政治資金の技術スタックとサービスの構成についてご紹介していきます。
構成図は下記の通り。アプリケーションはNext.js+Vercel、DB層としてSupabase(Postgres)を使い、ユーザー画面と管理画面を、それぞれ異なる環境でホスティングしています。
技術選定の背景
このサービスを作る前に、永田町エンジニアチームで複数のサービスを作っていくにあたっての技術選定ポリシーについてディスカッションを行いました。本サービスも、そこで定められたポリシーに合わせる形で技術選定をしています。(他サービスも、特別な理由がなければ類似した構成にすることで開発者のスイッチングコストを抑える方針としています。)
アプリケーション: Next.js + Vercel
選定した理由は、特別な設定無しにSEOに適した構成を作りやすいことです。
Next.js + Vercelの構成にすることで、デフォルトの状態でサーバーコンポーネントやSSRが活用でき、また簡潔な記述でキャッシュ設定もできる点から、リッチなUIを実現しつつ検索エンジンからの流入を見込めるサイトを短期間で実装するのに適していると判断しました。
またスタックとして利用事例が多いため、慣れているエンジニアが多かったり、AIコーディングツールがベストプラクティスに従った実装をしやすいという点も評価ポイントでした。
BaaS: Supabase
データベース層と管理画面の認証に利用しています。選定した理由は、スピード感を出しやすいことと、ロックイン性の低さです。Supabaseの機能として、ほとんど設定無しにデータベースをブランチごとに用意できることが短期間の開発においては大きな魅力となりました。
また、代替技術の少ないFirebaseのようなドキュメント志向DBと比較し、Supabaseは伝統的なRDBであるPostgresが採用されており別の環境へのポート可能性が高いと考えました。
そのうえで、データベースへのアクセスを行うRepository層は必ずInterfaceを噛ませることをルールとし、MySQLなどPostgres以外への移行も実現できることを担保しています。
技術選定を振り返ってみて
BaaSをフル活用したことで、インフラの設定にあまり時間を使うことがなく、アプリケーションの実装にフォーカスできたことは、短期間でサービスを作り切るにあたって非常に良い選択だったと思っています。
また副次的な良さとしては、Vercel / Supabaseの機能でブランチごとにリモート環境が自動で立ち上がる機能にかなり助けられました。
簡潔な修正はDevinなどに作業依頼して、上がってきたPRを手元にPullすることなくリモート動作確認してマージする、などができたことが開発のスピード感につながりました。
安定したサービスを提供するためのキャッシュ戦略
webappにおける2層のキャッシュ戦略
ここでは、多くのリクエストが見込まれるサイトを、安定して提供するための工夫について紹介します。
政治資金データは、それほど頻繁に更新されるものではなく、更新から反映までのタイムラグがあっても問題が起きにくい性質の情報なので、キャッシュが有効と考えました。
前提として、webappの側はデータ取得を全てサーバー関数に寄せ、クライアントサイドのfetchは一切使わないルールで実装を行っています。
そのうえで、トップページでは、上記の図のように二段階のキャッシュを設定しています。体験を最速にするために、メインのキャッシュ戦略としてHTMLレベルのキャッシュ(ISR: Incremental Static Regeneration)を行いつつ、想定外のパスがあっても問題ないように、サーバー関数のレイヤーでもキャッシュを設定しています。
いっぽう取引一覧ページでは、ソートやフィルターをGETパラメータを通じて行うことからISRは設定できないため、サーバーキャッシュをメインのキャッシュ戦略としており、パラメータごとにキャッシュキーを発行しています。
結果的に、98.3%と高いキャッシュヒット率となっており、安定して高速なサービスを提供することができました。
なるべく多くの方に利用いただくためのアクセシビリティ対応
また、国政政党として公開する以上、なるべく多くの方に利用いただけることを重視し、以下のような点にはこだわって実装しています。
アクセシビリティ設定
まず、画面を視覚的に把握することや、マウスの操作が難しい方のために、キーボードナビゲーションへの対応を行いました。下記のように、フォーカス時のデザインを設定することで、タブキーとエンターキーで操作を行うことができます。
また、スクリーンリーダー(音声読み上げなどによってブラウジングが行えるツール)用のクラスを設定することで、どのような図表があるかを読み上げ可能にしています。
このような対応の結果として、PageSpeed Insightにおける「ユーザー補助」(アクセシビリティの高さを示すスコア)でも91点と、比較的高いスコアを獲得できています。
私はスクリーンリーダー利用の当事者ではないので、今回の実装で真に利便性の高いものにできていると自信を持っては言えないですが、アクセシビリティにまつわる実装は、特にコーディングAIの支援が役立ちました。
AIはデジタルに強い人のためになるツールではなく、むしろこれまでは人的コスト的に難しかった対応が可能になることによって、あらゆる人のためになる技術であるということをあらためて感じた開発でした。
より多様な角度からお金の流れを理解いただくためのデータ構造
単式簿記と複式簿記の世界をどう接合するか
会計としての苦労・工夫ポイントは、会計観点をリードしていただいた寺本さんの記事に詳しいのでぜひ読んでいただきつつ、システム観点で工夫した点についても軽く紹介します。
まず、政治資金は単式簿記・現金主義で記録されますが、データソースであるMFクラウドは複式簿記です。この違いにどう対応するかが最大の技術的課題でした。
補足: 単式簿記(現金主義)と複式簿記(発生主義)について
💰 現金主義・単式簿記
・実際に現金の受け渡しが生じた時点で、収入または支出として記録する方式。
・主として現金の流れを把握することに重点を置いており、政治資金収支報告書において採用されている方法。
・例:9月に広告費の請求書を受け取り、10月に支払った場合、10月に「支出」として記録されます。
⚖️ 発生主義・複式簿記
・経済的事実が発生した時点で記録する方式
・現金の受け渡し時点とは必ずしも一致しない
・すべての取引を「借方」と「貸方」の二面から記録するため、資産・負債・純資産・収益・費用の全体像を体系的に把握できる。
・企業会計の標準的な方法であり、貸借対照表や損益計算書の作成が可能。
・例:9月に広告費の請求書を受け取った場合、支払いが10月であっても9月の時点で「広告費(費用)」を計上し、同時に「未払金(負債)」を計上します。10月の支払い時点では「未払金」と「現金」をあわせて減少させることで資金移動と資産区分の推移を合わせて表現します。
この点について、サービス上の表示の原則として、政治資金報告書との比較可能性を重視する観点から、現金主義をベースにするということにしています。
一方で、チームみらいとしては、より透明性ある形で政党や政治団体の現状を有権者に示せるように、将来的には企業会計と同様、政治資金報告書自体も複式簿記ベースになるのが適切なのではないかと考えています。
基本的には政治資金フォーマットにのっとりつつ、複式簿記を導入したらこんな表示もできるんだよ、という点を示すため、複式簿記でデータを保存し、単式簿記で表示するという方針を採用しています。
(このことによって、データのズレやミスに気づきやすいという複式簿記のメリットを享受しながら単式簿記の表示ができています)
それを図にするとこんな感じになります。
上記のデータ構造を採用したことで、このように貸借対照表を表示し、お金の流れのみならず、資産で見た財務体質も理解できるようになっております。
「気持ちが湧かない…」からの独自仕訳の追加
実は、メインとなるサンキーデータには、開発中に大きなアップデートがありました。というのも、開発初期の仕様では、メインとなるグラフはこちらのビューでした。皆さんはどのような感想を持つでしょうか?
これは「政治資金報告書」に準拠したカテゴライズなのですが、並んでいる費目を見ると「選挙関係費」「宣伝費」…とやや粗く、ある程度開発が進んできた段階で、安野を含めた開発チームでの会話でも「ぶっちゃけ気持ちがあまり湧いてこないね…」という話になりました。
…そこで、仕訳作業時に「親しみの持てるカテゴリ」も設定し、そのカテゴリで見られる画面も追加する、という大きめの意思決定を行いました。
これは、仕訳作業も実装作業も、だいぶやることが増えて大変になる意思決定ではあったのですが、しっかりとインパクトがあるツールを公開したいという思いから、皆の意見が一致しました。
いざ作ってみると「印刷代って高いんだな〜」「SNSではXが一番広告費使ってるんだね」など、見たメンバーが次々に「気持ちが湧いてくる」状態になり、個人的にはこの画面ができたあたりでかなり手応えを感じることができたのを覚えています。
多様な政党に利用してもらうための拡張性
データ構造について軽く触れておくと、今回の要件ではMFクラウドだけに対応できればよかったのですが、OSSとして多くの団体に利用いただくため、いずれ、freeeや弥生会計など、他のクラウド会計ソフトにも拡張できるように設計を行いました。
具体的には、
管理画面でのCSVの読み込み・変換処理は個別サービスに依存した処理として実装。
DBに入れる段階では、会計ソフトに依存しない、クリーンな取引形式に変換。Webapp側からは会計ソフトを意識せず利用できるように設計
というようにすることで、今後対応するクラウド会計サービスが増えても管理画面のアダプター層の実装を増やすだけで、Webapp側の対応は一切不要な作りにしています。
CSVダウンロード機能
最後に、これは自分のこだわりでファーストバージョンに実装した機能なのですが、サイト上で表示されるデータはCSVファイルとしてダウンロード可能にしています。
概要をビジュアライズしてざっくり掴めるだけでなく、手元で詳細に検証しやすいことも透明性の大事な要素だと思っております。早速csvを手元で分析し新しいビジュアライズを行ったり、内容の検証をしていただいている方を見かけ、オープンにすることの威力を感じております。
まとめ
以上、「みらいまる見え政治資金」の裏側について、
スピードと汎用性を両立するための技術選定
安定したサービスを提供するためのキャッシュ戦略
なるべく多くの方に利用いただくためのアクセシビリティ対応
より多様な角度からお金の流れを理解いただくためのデータ構造
といった観点から紹介してきました。参考になる部分があれば幸いです。
リリースしてみて、想像以上の人数にアクセスいただき、サービスが落ちないかヒヤヒヤしつつも「政治とカネ」問題にまつわる不満の大きさや、チームみらいにかけていただいている期待の大きさをあらためて肌で感じました。
永田町エンジニアチームの一員として、テクノロジーの力を使って民主主義をアップデートできるツールの開発を進めていきたいと思います。引き続き応援よろしくお願いします!
合わせておすすめ
上記の設計に沿って、95%以上のコードがLLMによって書かれています。どのように実装を進めたのか、ノウハウを知りたい方はこちらも合わせてご覧ください!



コメント