🏗️ 補助金情報システム - アーキテクチャ図

Version 4.0
最終更新: 2025年12月6日
変更内容: MySQL移行、履歴・復元機能、エラー原因分析、URL正規化、config.py追加
1. システム全体構成図
graph TB subgraph "Frontend (Port 5002)" UI[Web UI
6 Templates] JS[JavaScript
chatbot.js
municipality-search.js] CSS[Bootstrap 5
Responsive UI] end subgraph "Backend (Flask + config.py)" FLASK[Flask Application
app.py
18 Routes] CONFIG[Configuration
config.py
環境変数管理] SCRAPER[Scraper Module
scraper.py
ボット対策検出] FILE_DL[File Downloader
file_downloader.py
インテリジェント選別] PDF[PDF Analyzer
pdf_analyzer.py
キャッシュ対応] end subgraph "Database (MySQL)" DB[(MySQL 8.0
5 Tables)] SUBSIDY[subsidy_info
主テーブル] FILES[subsidy_file
ファイル情報] HISTORY[subsidy_info_history
履歴・復元] CACHE[pdf_analysis_cache
PDF解析キャッシュ] ERROR[error_analysis
エラー原因分析] end subgraph "External Services" OPENAI[OpenAI API
GPT-4o-mini] MUNICIPALITY[自治体Webサイト
スクレイピング対象] end subgraph "Storage & Logs" MINIO[MinIO
オブジェクトストレージ] LOGS[Log Files
app/error/scraping/ai_analysis] end UI --> FLASK JS --> FLASK FLASK --> CONFIG FLASK --> DB FLASK --> SCRAPER FLASK --> FILE_DL FLASK --> PDF DB --> SUBSIDY DB --> FILES DB --> HISTORY DB --> CACHE DB --> ERROR SCRAPER --> OPENAI SCRAPER --> MUNICIPALITY FILE_DL --> MINIO FILE_DL --> MUNICIPALITY PDF --> OPENAI FLASK --> LOGS style UI fill:#dbeafe style OPENAI fill:#fee2e2 style MUNICIPALITY fill:#fef3c7 style DB fill:#dcfce7 style MINIO fill:#e0e7ff style CONFIG fill:#f0fdf4
モジュール構成
モジュール 主な機能 行数
app.py Flask本体、18ルート、4モデル定義、URL正規化 ~2000行
config.pyNEW 環境変数一元管理、デフォルト値設定 ~150行
scraper.py Webスクレイピング、ボット対策検出、エラー原因分析 ~1700行
file_downloader.py ファイルDL、インテリジェント選別、ブラックリスト ~600行
pdf_analyzer.py PDF解析、DBキャッシュ、GC対応 ~500行
2. データフロー図(6フェーズ処理)
┌─────────────────────────────────────────────────────────────────────────┐ │ USER ACTION │ │ URL追加 or スクレイピング実行 │ └────────────────────────────────┬────────────────────────────────────────┘ │ ▼ Phase 1: URL登録・正規化 ┌─────────────────────────────────────────────────────────────────────────┐ │ POST /add_url │ │ ・URL正規化: normalize_url() │ │ - TRACKING_PARAMS削除(utm_*, fbclid, gclid等) │ │ - コンテンツパラメータ保持(content, id, hdnKey等) │ │ ・重複チェック(正規化後URLで比較) │ │ ・排他制御開始(同一ID同時実行防止) │ └────────────────────────────────┬────────────────────────────────────────┘ │ ▼ Phase 2: スクレイピング ┌─────────────────────────────────────────────────────────────────────────┐ │ SubsidyInfoExtractor.process_url() │ │ ・HTTPリクエスト(User-Agent偽装、タイムアウト制御) │ │ ・ボット対策検出(Incapsula, Cloudflare, reCAPTCHA, Akamai等) │ │ → 検出時: needs_review=2(緊急)、review_reason設定 │ │ ・HTMLパース(BeautifulSoup + lxml) │ │ ・ファイルリンク抽出 │ │ ・scraping_time記録 │ └────────────────────────────────┬────────────────────────────────────────┘ │ ▼ Phase 3: ファイルダウンロード ┌─────────────────────────────────────────────────────────────────────────┐ │ FileDownloader.download_files() │ │ ・対象: PDF, Excel, Word │ │ ・除外: DOCX(分析不要) │ │ ・ブラックリストチェック(様式、申請書、マニュアル等除外) │ │ ・インテリジェント選別(IntelligentFileFilter): │ │ - high: 要領・要綱・ガイドライン │ │ - medium: 手引き・案内・お知らせ │ │ - low: Q&A・FAQ・よくある質問 │ │ - skip: 様式・申請書・記入例 │ │ ・MinIOに保存(ローカル環境) │ │ ・subsidy_fileテーブルに登録 │ │ ・file_download_time記録 │ └────────────────────────────────┬────────────────────────────────────────┘ │ ▼ Phase 4: PDF解析 ┌─────────────────────────────────────────────────────────────────────────┐ │ PDFAnalyzer.analyze() │ │ ・対象: analysis_priority='high' or 'medium' │ │ ・スキップ: low優先度 && 5MB超 │ │ ・キャッシュチェック(pdf_analysis_cacheテーブル) │ │ ・pdfplumber/PyMuPDFでテキスト抽出 │ │ ・タイムアウト: 5分(環境変数で設定可能) │ │ ・ガベージコレクション(10ページごと + 終了時) │ │ ・pdf_analysis_time記録 │ └────────────────────────────────┬────────────────────────────────────────┘ │ ▼ Phase 5: AI解析 ┌─────────────────────────────────────────────────────────────────────────┐ │ OpenAI GPT-4o-mini API │ │ ・レート制限対応(指数バックオフリトライ) │ │ ・抽出項目: │ │ - 自治体名、自治体名かな(pykakasi併用) │ │ - 継続状況(ongoing/ended/unconfirmed) │ │ - 補助金額、申請期間、対象商品 │ │ - 問い合わせ先、補助条件 等 │ │ ・信頼度スコア算出(0-100) │ │ → 閾値以下: needs_review=1(要レビュー) │ │ ・ai_analysis_time記録 │ └────────────────────────────────┬────────────────────────────────────────┘ │ ▼ Phase 6: 結果保存 ┌─────────────────────────────────────────────────────────────────────────┐ │ ・subsidy_info更新(data JSON, status='analyzed') │ │ ・履歴記録(subsidy_info_historyにdata_snapshot保存) │ │ ・処理時間集計(total_processing_time算出) │ │ ・終了通知準備(status変更検知: ongoing→ended) │ │ ・排他制御解除 │ └─────────────────────────────────────────────────────────────────────────┘
3. デプロイメントアーキテクチャ
設計方針: ソースコードは本番・ローカル完全同一。環境差異は .env / .env.prod で吸収。
3.1 共通ソースコード
graph TB subgraph "共通ソースコード" SRC[app.py, scraper.py, file_downloader.py
pdf_analyzer.py, config.py
templates/*, static/*] end SRC --> LOCAL[ローカル環境
.env + docker-compose.yml
./start-local.sh] SRC --> PROD[本番環境
.env.prod + docker-compose.prod.yml
./start-prod-ocr-subsidy.sh] style SRC fill:#f0fdf4 style LOCAL fill:#dbeafe style PROD fill:#fee2e2
3.2 環境別設定
設定項目 ローカル 本番
MinIO ✅ 有効(Docker) ✅ 有効(Docker)
Adminer ✅ 有効(ADMINER_REPLICAS=1) 🔧 必要時のみ有効化
Debug Mode ✅ True ❌ False
Log Level DEBUG INFO / WARNING
3.3 ローカル環境
graph TB subgraph "Docker Compose" WEB[web
Port 5002
Flask App] MYSQL[mysql
Port 3306
MySQL 8.0] MINIO[minio
Port 9000/9001
MinIO] ADMINER[adminer
Port 8081
DB管理] end WEB --> MYSQL WEB --> MINIO ADMINER --> MYSQL style WEB fill:#dbeafe style MYSQL fill:#dcfce7 style MINIO fill:#e0e7ff style ADMINER fill:#fef3c7
3.4 本番環境(さくらクラウド)
graph TB subgraph "Internet" USER[ユーザー
ブラウザ] end subgraph "enex-dev.ie-pro.net (153.125.139.110)" subgraph "Apache2" APACHE[Apache2
Port 80/443
Let's Encrypt] end subgraph "Docker Compose" WEB_PROD[web
Port 5002
Flask App] MYSQL_PROD[mysql
Port 3306
MySQL 8.0] MINIO_PROD[minio
Port 9000/9001
MinIO] end end subgraph "External" OPENAI_API[OpenAI API] end USER --> APACHE APACHE -->|ProxyPass| WEB_PROD WEB_PROD --> MYSQL_PROD WEB_PROD --> MINIO_PROD WEB_PROD --> OPENAI_API style USER fill:#dbeafe style APACHE fill:#dcfce7 style WEB_PROD fill:#dbeafe style MYSQL_PROD fill:#dcfce7 style MINIO_PROD fill:#e0e7ff style OPENAI_API fill:#fee2e2
4. データベース構成NEW
MySQL 8.0 / 文字セット: utf8mb4_unicode_ci / タイムゾーン: Asia/Tokyo (JST)
erDiagram subsidy_info ||--o{ subsidy_file : "has" subsidy_info ||--o{ subsidy_info_history : "has" subsidy_info ||--o{ pdf_analysis_cache : "has" subsidy_info ||--o{ error_analysis : "has" subsidy_info { int id PK varchar url varchar normalized_url varchar municipality varchar municipality_kana varchar prefecture varchar continuation_status json data varchar status datetime scraped_at float total_processing_time float scraping_time float file_download_time float pdf_analysis_time float ai_analysis_time int needs_review text review_reason } subsidy_file { int id PK int subsidy_info_id FK varchar original_filename varchar stored_filename varchar file_type int file_size varchar analysis_priority text analysis_reason } subsidy_info_history { int id PK int subsidy_info_id FK varchar change_type json data_snapshot int needs_review text review_reason datetime created_at } pdf_analysis_cache { int id PK int subsidy_info_id FK varchar file_hash json analysis_result datetime created_at } error_analysis { int id PK int subsidy_info_id FK int http_status varchar bot_protection_type varchar page_status json ai_analysis text error_cause text recommendation int confidence_score }
テーブル詳細
テーブル 用途 レコード例
subsidy_info 補助金情報メインテーブル(22項目編集可能) URL、自治体名、継続状況、処理時間等
subsidy_file 関連ファイル情報 PDF、Excel、Wordファイルのメタデータ
subsidy_info_historyNEW 変更履歴・復元用スナップショット 変更前データの完全保存、復元機能
pdf_analysis_cacheNEW PDF解析結果キャッシュ ファイルハッシュ→解析結果
error_analysisNEW エラー原因分析結果 HTTP状態、ボット対策種別、AI分析結果
5. 機能一覧NEW
📥 データ収集
  • ✅ URL追加・一括追加
  • ✅ URL正規化(トラッキングパラメータ除去)
  • ✅ Webスクレイピング(BeautifulSoup)
  • ✅ ボット対策検出(5種類対応)
  • ✅ ファイル自動ダウンロード
  • ✅ インテリジェント選別(4段階)
  • ✅ PDF解析・テキスト抽出
🤖 AI解析
  • ✅ OpenAI GPT-4o-mini
  • ✅ 構造化データ抽出
  • ✅ 継続状況判定
  • ✅ 信頼度スコア算出
  • ✅ レート制限対応
  • ✅ エラー原因AI分析NEW
📊 データ管理
  • ✅ 一覧表示・検索・フィルタ
  • ✅ 詳細表示・編集(22項目)
  • ✅ 履歴表示・復元NEW
  • ✅ 緊急フラグ(needs_review=2)
  • ✅ 自治体名サジェスト
  • ✅ かな変換(pykakasi)
🔧 システム管理
  • ✅ 環境変数一元管理(config.py)NEW
  • ✅ 処理時間追跡(5種類)
  • ✅ 4種類ログファイル
  • ✅ 排他制御(同時実行防止)
  • ✅ Adminer(DB管理)
  • ✅ Docker healthcheck
6. APIエンドポイント(18ルート)
メソッド エンドポイント 機能
GET/一覧表示
POST/add_urlURL追加
GET/detail/<id>詳細表示
GET/edit_result/<id>編集画面表示
POST/edit_result/<id>編集保存
GET/scrape/<id>スクレイピング実行
POST/delete/<id>削除
GET/download/<id>/<filename>ファイルダウンロード
GET/api/municipalities自治体名一覧API
GET/api/history/<id>履歴取得APINEW
POST/api/restore/<id>/<history_id>復元APINEW
POST/api/analyze_error/<id>エラー原因分析NEW
GET/api/error_analysis/<id>エラー分析結果取得NEW
GET/chatbotチャットボット画面
POST/api/chatbot/queryチャットボットAPI
POST/scrape_all一括スクレイピング
GET/export/csvCSVエクスポート
GET/static/architecture.htmlアーキテクチャ図
7. インフラ構成NEW
Docker設定
設定 web mysql minio adminer
restart on-failure:3 on-failure:3 unless-stopped unless-stopped
healthcheck ✅ HTTP ✅ mysqladmin ping ✅ curl -
メモリ制限 - 512MB - -
ログ制限 max-size: 10m, max-file: 3
ログファイル
ファイル 内容
data/logs/app.logアプリケーション全般ログ
data/logs/error.logエラーログ(WARNING以上)
data/logs/scraping.logスクレイピング詳細ログ
data/logs/ai_analysis.logAI解析詳細ログ
起動スクリプト
スクリプト 用途 主な処理
start-local.sh ローカル起動 ポート競合解決、MinIO起動、DBマイグレーション
start-prod-ocr-subsidy.sh 本番起動 OCR + 補助金システム統合起動、Apache連携
8. 技術スタックUPDATED
レイヤー 技術 バージョン/詳細
Frontend HTML5, Bootstrap 5, JavaScript 6テンプレート、2 JSファイル
Backend Python, Flask, Flask-SQLAlchemy Python 3.9, Flask 2.3.3
Database MySQLUPDATED MySQL 8.0, PyMySQL
AI OpenAI API GPT-4o-mini
File Storage MinIO オブジェクトストレージ(ローカル・本番両方)
PDF Processing pdfplumber, PyMuPDF テキスト・テーブル抽出
Web Scraping requests, BeautifulSoup4, lxml HTMLパース・抽出
Text Processing pykakasi 漢字→ひらがな変換
Containerization Docker, Docker Compose 4コンテナ構成(ローカル)
Web Server Apache2 Reverse Proxy, Let's Encrypt
Infrastructure さくらのクラウド Ubuntu 22.04
📝 変更履歴
バージョン 日付 変更内容
4.0 2025-12-06 MySQL移行、履歴・復元機能、エラー原因分析、URL正規化、config.py追加、
DB構成図・機能一覧・インフラ構成セクション新規追加
3.0 2025-11-04 さくらクラウドデプロイ、MinIO統合
2.0 2025-10-27 PDF解析機能、ファイルダウンロード機能追加
1.0 2025-10-24 初版作成(Flask + SQLite構成)

最終更新: 2025年12月6日
バージョン: 4.0