メインコンテンツへスキップ
友田 陽大
経済産業大臣賞 受賞プロダクト

経済産業大臣賞受賞 | 木材流通業界のDXを実現したB2BサブスクリプションSaaS

電話・FAX・Excelによるアナログ取引を、Web上で一元管理するSaaS化に成功

クライアント

某木材流通関連企業(本プロダクトにて経済産業大臣賞を受賞) | 業界: 木材サプライチェーン(林業・市場・製材所・プレカット・工務店・メーカーをまたぐB2B流通) | モデル: 招待制 B2B サブスクリプション SaaS(Stripe Connect によるマーケットプレイス決済)

私の役割

テクニカル・アーキテクト 兼 フルスタック・デベロッパー(要件定義・基本設計からフロントエンド・バックエンド・インフラ構築・セキュリティ監査対応・運用保守まで、プロダクト開発の全工程を一人で担当)

課題(Situation & Task)

木材業界は、電話・メール・FAX・Excelでの受発注が主流の、極めてアナログな業界でした。流通には「林業」「市場」「製材所」「プレカット」「工務店」「メーカー」といった多様な業種が多段でつながり、商流や利害関係が複雑に絡み合っていました(業界のしがらみ)。各業種で実行できる操作や閲覧できる情報が異なるうえ、企業をまたいで取引するため、テナント間のデータ分離と決済の正当性を同時に担保する必要がありました。従来は関係性のある既存の取引先としか取引できず、情報も閉鎖的でした。

木材サプライチェーン特有の複雑な課題として、以下の4点が存在していました。

  1. 業界の根本課題: 電話・FAX・Excelでの受発注が主流で、デジタル化が大幅に遅れていました。在庫情報はExcelで管理され常に最新が不明。FAXでの発注は記録が残らず、電話での確認作業に毎日数時間を要していました。

  2. 多段商流と業種ベースの認可: 「林業 → 市場 → 製材所 → プレカット → 工務店 → メーカー」と多様な業種(さらに『製材所兼プレカット』のような複合属性、閲覧・管理ロール)がつながり、業種ごとに実行可能な機能・閲覧範囲が異なります。そのため、API単位での厳格な業種ベース認可が必須でした。

  3. 企業横断のデータ分離(マルチテナント): 企業をまたいで相手を探し取引するため、企業横断の検索・閲覧で相手企業のPII(メール・電話・法人番号など)が漏れないテナント分離が要件でした。

  4. 決済の正当性と冪等性: 継続課金に加えて取引ごとの精算が発生するマーケットプレイス決済(Stripe Connect)では、金額改ざん・二重課金・Webhookの重複処理が許されず、冪等性と整合性の担保が必須でした。

技術選定の理由(Rationale)

  • Python 3.11 / Flask / SQLAlchemy 2.0 / Marshmallow 3 / PostgreSQL 16: 帳票生成・Excel取り込み・複雑な多段商流のロジックに最適。Router → UseCase → Repository → Model の厳格な層分離で、変更容易性(ETC)と単一責任(SRP)を担保

  • React 18 / TypeScript 5.9 / Vite 7 / MUI 7 / TanStack Query 5: 業種ごとに異なる複雑なUI制御と大量データ操作のため採用。any/let を禁止し Zod で境界検証する型安全規律と、107ルートの遅延ロードで初期バンドルを最小化

  • AWS(ECS Fargate / RDS / Cognito / Lambda / CloudFront / S3 / SQS / EventBridge / DynamoDB): スケーラブルなSaaS基盤。Webhook・帳票・Excel取り込みなど重い/非同期処理は Lambda へ分離しイベント駆動化

  • Terraform(IaC 100%): VPC〜Cognito〜ECS〜RDS〜CloudFront〜12 の Lambda までを17モジュールでコード化。再現性・レビュー可能性・コスト制御・無停止移行を担保し、S3 ネイティブロックで state を管理

  • AWS Cognito(JWT RS256): 7業種+閲覧/管理ロールの認証基盤。API Gateway のオーソライザーで全エンドポイントを保護し、業種ベース認可はルーター層で厳格化

  • Stripe Connect: 継続課金+取引精算+銀行振込に対応するマーケットプレイス決済。金額はサーバ側で解決し、Webhook は冪等化、課金調整はトランザクショナル・アウトボックスで確実に反映

実施したこと(Action)

  • 【業種ベースのマルチテナント認可】 業種コードを機能ごとの frozenset ホワイトリストで定義し、認可判定はルーター層に一元化(不一致は 403、IDの列挙攻撃を抑止)。企業横断の検索・閲覧ではPIIを除外した公開スキーマ(UserPublicSchema)に限定し、相手企業のメール・電話・法人番号が漏れない二層スキーマ境界を実装

  • 【認証基盤 Cognito RS256 + JWKS】 API Gateway のオーソライザーで全 221 エンドポイントを保護。バックエンドは RS256 で JWT を検証し exp/iat/iss/aud/token_use を必須化、token_use==id 以外を拒否。JWKS は二重チェックロックのシングルトンでキャッシュし、6時間間隔で更新(起動時プリウォーム)

  • 【冪等な決済 Stripe Connect】 サブスク状態は User に保持し、Stripe ID 形式を DB の CHECK 制約で検証(cus_/sub_/acct_)。金額はサーバ側で解決して改ざんを排除。Webhook は 3 つの Lambda に分離し、DynamoDB の条件付き書き込み(attribute_not_exists・30日TTL)で重複排除。課金調整はトランザクショナル・アウトボックス+整合化 Lambda(EventBridge 定期実行)で確実に反映

  • 【重い処理の並列化】 注文書・納品書・請求書の Excel/PDF を ThreadPoolExecutor で同時生成(各スレッドに専用アプリコンテキスト、selectinload で N+1 回避、with_for_update で競合防止)。Excel→DB 取り込みは S3 イベント駆動の Lambda で一括投入し、50MB 上限・数式インジェクション無害化(CWE-1236)を実装。フロントは指数バックオフ+Page Visibility 対応のポーリングで背面タブの API 浪費を抑制

  • 【DBの効率と信頼性】 不足していた 48 本の FK インデックスを CREATE INDEX CONCURRENTLY で無停止追加。コネクションプールは (5+5)×8タスク < RDS上限 で枯渇を予防。日報の N+1(サイト数に比例する flush)を定数化。テストはセーブポイント分離で全件を約 11 秒で実行

  • 【セキュリティ監査 4ラウンド】 静的監査 → ライブ診断 → ブラックボックス+ホワイトボックス・ペネトレを実施。実在 15 ロールでの第三者ペネトレ(R4)で全 221 エンドポイントの認証欠落 0 件を実証。クロステナント PII 漏洩・決済金額改ざん・平文資格情報(→ Secrets Manager 移行)・Webhook 冪等性の fail-open(→ fail-closed)等の Critical/High 指摘を全て Close。HSTS/CSP/X-Frame-Options 等のセキュリティヘッダも整備

  • 【可観測性と回復性】 構造化ログ+ERROR の Slack 通知(恒久/一時失敗を分類し指数バックオフでリトライ)。Slack 配信失敗は単一行 JSON マーカーで検知してログインジェクションによるアラーム偽装を防止し、CloudWatch メトリクスフィルタ → SNS メールで Slack 非依存の経路にエスカレーション。マーカー契約はバックエンド/Lambda/Terraform 間で契約テストにより機械的に同期

  • 【IaC・CI/CD・品質ゲート】 GitHub Actions OIDC(長期キーなし)で ECR → ECS 強制デプロイ、S3 同期+CloudFront 無効化。Terraform は plan(PRで tfsec)/apply(権限境界付きロール)/drift 検知(定期 cron → Issue 起票)を自動化。pre-commit/pre-push の二段ゲートで ruff・mypy・Bandit・Vulture・deptry・pip-audit・ESLint・Prettier・tsc・npm audit・Trivy・gitleaks を実行し、Dependabot で 6 エコシステムを継続更新

本プロダクトは B2B・決済・複数企業のデータが交差するため、セキュリティと整合性を最優先に設計しました。

テナント分離とPII保護: 取引相手の情報は、相互に取引関係がある場合のみ詳細スキーマで返し、企業横断の検索・閲覧ではPIIを除外した公開スキーマに限定しました。第三者ペネトレでクロステナントPII漏洩(B-1, HIGH)を検出した際は、即日修正・再診断で0件を確認しています。

決済の冪等性: 金額はサーバ側で解決し、Stripe へのリクエストはコンテンツアドレス方式の冪等キー、Webhook は別 Lambda + DynamoDB の条件付き書き込みで重複排除します。課金調整はアウトボックス+整合化により、ネットワーク断やリトライ下でも二重課金・取りこぼしを防ぎます。

重い処理とUX: 帳票生成はスレッド並列、Excel 取り込みはイベント駆動 Lambda に分離し、フロントは指数バックオフ+可視状態連動のポーリングで完了を待機。重い処理でも管理画面の操作性を損なわない設計です。

運用に耐える基盤: インフラは 100% Terraform 化し、staging/production をコードで再現。停止期間は environment_active 一つで課金リソースをゼロに畳むコスト設計とし、Graviton/Fargate Spot/単一 NAT で平常時コストも最適化しています。

技術選定の理由

  • React 18 + TypeScript 5.9 + TanStack Query 5:型安全なUIと効率的なデータフェッチ/キャッシュ

  • Flask + SQLAlchemy 2.0 + Marshmallow 3:層分離アーキテクチャと境界での厳格バリデーション

  • AWS ECS Fargate + Cognito + Lambda + Terraform:IaCで再現可能・イベント駆動なSaaS基盤

  • Stripe Connect + DynamoDB:冪等なマーケットプレイス決済とWebhook重複排除

  • PostgreSQL 16:複雑な多段商流をリレーショナルに表現

担当領域

  • 要件定義・アーキテクチャ設計
  • フロントエンド開発(React / TypeScript / MUI)
  • バックエンド開発(Python / Flask / SQLAlchemy)
  • インフラ構築・運用(AWS / Terraform / IaC)
  • データベース設計(PostgreSQL)
  • セキュリティ監査・ペネトレーションテスト対応
  • CI/CD・品質ゲート整備(GitHub Actions)

使用技術

Python 3.11
Flask
Flask-RESTful
SQLAlchemy 2.0
Marshmallow
Alembic
PostgreSQL 16
pytest
React 18
TypeScript 5.9
Vite 7
MUI 7
TanStack Query 5
React Hook Form
Zod
AWS Amplify
Vitest
AWS ECS Fargate
AWS Fargate Spot
API Gateway
NLB / ALB
AWS Cognito
AWS RDS (Graviton)
AWS Lambda
Amazon S3
CloudFront
DynamoDB
Amazon SQS
EventBridge
AWS SES
Secrets Manager
AWS KMS
Stripe Connect
Terraform
Docker
GitHub Actions (OIDC)
Ruff
mypy
Bandit
Trivy
gitleaks
tfsec
Dependabot
CloudWatch

数字で見る成果

認証欠落の検出数
0件全221エンドポイントをCognito認可で保護。実在15ロールでの第三者ペネトレーションテスト(R4)で認証バイパス0件を実証
セキュリティ監査
4ラウンド静的監査→ライブ診断→ブラックボックス+ホワイトボックス・ペネトレ。クロステナントPII漏洩・決済改ざん等のCritical/High指摘を全てClose
自動テスト(バックエンド)
2,153件セーブポイント分離で全件を約11秒で実行。Router/UseCase/Schema各層を網羅
DBマイグレーション
204世代Alembicで版管理。48本のFKインデックスはCREATE INDEX CONCURRENTLYで無停止適用
Terraformモジュール
17個VPC・Cognito・ECS・RDS・CloudFront・12のLambdaまでインフラを100%コード化(IaC)
本番APIエンドポイント
221本Flask-RESTfulで実装。Router→UseCase→Repository→Modelの4層を厳格分離し変更容易性を担保

成果

  • 【最大の成果】クライアントはこのプロダクトで「経済産業大臣賞」を受賞
  • 公的認定の取得: 本プロダクトは京都府認定を取得し、自治体に認められた信頼性の高いDX基盤として運用
  • 業界のDX実現: 電話/FAX/Excelで行われていたアナログな取引を、Web上で一元管理するSaaS化に成功(受発注は9状態のステートマシンとして実装)
  • 新たなビジネス機会の創出: 従来の閉鎖的な取引から脱却し、企業をまたいで取引相手を検索・取引できるマーケットプレイスを実現(製材所が市場に足を運ばずとも取引可能に)
  • トレーサビリティと信頼の向上: 産地証明(合法木材)・注文連動チャット・0〜5段階の企業評価により、透明性の高い取引を実現
  • 業務効率化: 「見積書・納品書・請求書」のExcel/PDFをスレッド並列でワンクリック生成し、既存ExcelはS3イベント駆動Lambdaで自動DB化
  • 実証されたセキュリティ: 第三者ペネトレーションテスト(実在15ロール)で全221エンドポイントの認証欠落0件を確認。クロステナントPII漏洩・決済改ざん等のCritical/High指摘を全てClose
  • 冪等なマーケットプレイス決済: Stripe Connect+DynamoDBによるWebhook重複排除とトランザクショナル・アウトボックスで、二重課金・取りこぼしを防止
  • 運用に耐える基盤: インフラを100% Terraform化(17モジュール・12 Lambda)、GitHub Actions OIDCで自動デプロイ、構造化ログとSlack/CloudWatchの多重アラートで可観測性を担保

同様の課題、抱えていませんか?

あなたのビジネス課題も、最新の技術で解決できます。 まずは30分の無料技術相談から、状況をお聞かせください。

自社の課題もSaaS化できるか相談する

プロジェクト単位(請負)・技術顧問、どちらにも対応可能です

全ケーススタディを見る