建設業の一人親方向け業務管理アプリ - 閲覧境界を認可層で強制する設計
建設業の一人親方(独立した職人)向けに、請求・経費・書類・期限管理をスマートフォン1台で完結できる業務アプリを開発しました。費用を負担するのは元請、実際に使うのは職人という B2B2C 構造を取っており、「元請に見せてよい情報」と「職人が見せたくない情報」を分ける境界の設計が、このプロジェクトの中心でした。
プロジェクト概要
- 一人親方向けモバイルアプリ(請求書作成・経費記録・書類管理・期限通知)
- 元請向けの管理画面(専属パートナーの書類提出状況と資格期限の把握)
- 職人がアカウントとデータを所有し、元請は配布と費用負担を担う構造
- 元請の閲覧範囲を認可層で強制する「閲覧境界」の実装
依頼者の目指した目標と解決したい課題
建設業の一人親方は、現場で働きながら、請求書の作成、経費の記録、資格や保険の更新、元請へ提出する安全書類の管理までを自分ひとりで抱えています。これらは紙とスマートフォンの写真に散らばりがちで、期限切れに気づかず現場に入れない、といったことが起きていました。
一方、元請(サブコン)にも動機があります。専属で動いてもらう職人の資格や保険が切れていないか、安全書類が提出済みかを把握できなければ、現場の管理責任を果たせません。
そこで「元請が費用を負担して職人にアプリを配布する」という座組が成立します。ただしこの構造には、そのままでは実現できない前提がありました。職人にとって、売上や経費、納税予測は元請に見られたくない情報だからです。他の元請からいくら受け取っているか、資金繰りがどうなっているかを、費用を負担しているというだけで元請が見られる設計にすれば、職人はそもそもこのアプリを使いません。
「元請にとって必要な情報は見せる、しかし職人の経営情報は見せない」——この線引きをどう担保するかが、プロダクトの成否を決める課題でした。
開発したシステムの特徴
閲覧境界(data viewing boundary) を中心に据えています。
| 元請に見せてよい | 元請に見せない |
|---|---|
| 安全書類の提出済/未提出 | 他社からの売上 |
| 資格・保険の有効期限 | 経費の明細 |
| 自社案件での稼働状況 | 納税予測額・口座情報 |
| 自社宛ての請求書 | 他の元請の案件・資金繰り |
重要なのは、この境界をUIの出し分けではなく認可層で強制している点です。元請向けのデータ取得は必ず認可のスコープを通し、既定は拒否としています。画面に出していないだけの実装では、URLを直接叩かれた場合や、将来の改修で画面を追加した場合に境界が崩れます。認可層に置くことで、境界を破る実装のほうが書きにくくなります。
さらに、元請に見せる情報は専用の読み取り専用オブジェクトに集約しました。このオブジェクトは境界内の項目しか公開せず、たとえば「稼働中かどうか」は請求書の存在だけで判定し、金額には一切触れません。「見せてよいものだけを組み立てる」形にすることで、うっかり金額を混ぜてしまう余地を消しています。
その他の主な機能:
- 職人アプリ(モバイルPWA): 請求書作成を最上位の導線に配置。売上・経費・納税予測のカードには「元請には非公開」のバッジを表示し、納税予測には「目安であり税務判断ではない」旨を明示
- 元請本部(PC): 専属パートナーの一覧を境界内の項目だけで表示し、期限が近い資格・保険のリマインドを送付。個人の確定申告の進捗は保持しない
- 期限管理: 資格・保険の有効期限を追跡し、期限が近づくと通知
- 監査ログ: 誰がどの情報にアクセスしたかを記録
技術的背景
Ruby on Rails 8 をベースに、Hotwire(Turbo / Stimulus)と importmap で構築しています。Node のバンドラを使わず、JavaScript フレームワークも導入していません。職人アプリは Rails の PWA 対応を使い、スマートフォンのホーム画面から起動できる形にしています。
バックグラウンド処理・キャッシュ・WebSocket はいずれも Solid Queue / Solid Cache / Solid Cable を使い、データベースに寄せています。Redis を別途運用しないぶん、インフラの構成要素が減り、小規模なチームでも運用を続けやすくなります。
認可には Pundit を採用しました。前述の閲覧境界を、画面ではなく policy として記述するためです。境界の定義が1か所にまとまるため、「元請は何を見られるのか」という問いにコードで答えられます。テストも policy 単位で書けるため、境界そのものを検証対象にできます。
ホスティングは Fly.io の東京リージョンを使用しています。職人の氏名・口座・納税に関わる個人データを扱うため、個人情報保護法および越境移転の観点から、データを国内に保持する判断です。
テストは RSpec(モデル / リクエスト / policy / system)と Playwright による E2E で構成しています。policy のテストを独立して持っている点が、このプロジェクトの性格を表しています。
解決された問題
職人は、請求から書類・期限までをスマートフォン1台で扱えるようになりました。元請は、現場管理に必要な書類の提出状況と資格の有効期限を把握できるようになりました。
そのうえで、職人の売上・経費・納税に関わる情報は元請から見えません。費用を負担する側と使う側が異なるプロダクトで、使う側のプライバシーを構造的に守ることができています。この分離があるからこそ、職人が安心してデータを入れられ、結果として元請にとっても書類管理の実効性が上がる、という関係になっています。
チーム構成
- (KW) プロジェクトマネージャー
- (KW) バックエンドエンジニア×2
- (KW) フロントエンドエンジニア
- (KW) QAエンジニア
(KW) はKaito Wingsが担当
プロジェクト期間
- 要件定義・業務ヒアリング - 2ヶ月
- 開発・テスト - 5ヶ月
- 試験導入・改善 - 継続
システム構成
- Ruby on Rails 8 / PostgreSQL
- Hotwire (Turbo, Stimulus) / importmap
- Slim / Tailwind CSS
- Pundit(認可・閲覧境界)
- Solid Queue / Solid Cache / Solid Cable
- RSpec / Playwright
- RuboCop / Brakeman
- Fly.io(東京リージョン)