{"id":44488254,"url":"https://github.com/mt4110/postal_converter_ja","last_synced_at":"2026-02-13T02:20:13.386Z","repository":{"id":258029536,"uuid":"863515930","full_name":"mt4110/postal_converter_ja","owner":"mt4110","description":"High-performance Japanese Postal Code Converter \u0026 API. Auto-updating, DB-agnostic (MySQL/PostgreSQL), written in Rust \u0026 Next.js.日本郵便局のデータを自動更新機能付き、Rustの非同期クローリングシステム。最加速で最新の郵便番号データの更新化がされます。","archived":false,"fork":false,"pushed_at":"2026-02-09T23:42:17.000Z","size":4200,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-10T04:11:01.824Z","etag":null,"topics":["api","crawler","docker","mysql","nextjs","nix","postgresql","react","rust"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mt4110.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-09-26T12:34:25.000Z","updated_at":"2026-02-09T23:42:14.000Z","dependencies_parsed_at":"2024-10-22T18:19:26.622Z","dependency_job_id":null,"html_url":"https://github.com/mt4110/postal_converter_ja","commit_stats":null,"previous_names":["mt4110/postal_converter_ja"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/mt4110/postal_converter_ja","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mt4110%2Fpostal_converter_ja","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mt4110%2Fpostal_converter_ja/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mt4110%2Fpostal_converter_ja/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mt4110%2Fpostal_converter_ja/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mt4110","download_url":"https://codeload.github.com/mt4110/postal_converter_ja/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mt4110%2Fpostal_converter_ja/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29393348,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-13T00:53:09.511Z","status":"online","status_checked_at":"2026-02-13T02:00:10.076Z","response_time":78,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","crawler","docker","mysql","nextjs","nix","postgresql","react","rust"],"created_at":"2026-02-13T02:20:12.436Z","updated_at":"2026-02-13T02:20:13.376Z","avatar_url":"https://github.com/mt4110.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 郵便番号自動最新化システム (Postal Converter JA)\n\n![Version](https://img.shields.io/badge/version-0.2.0-blue.svg)\n![Status](https://img.shields.io/badge/status-beta-orange.svg)\n\nEnglish README: [ENGLISH_README.md](./docs/ENGLISH_README.md)\n\nこのプロジェクトは、日本郵便のデータを自動的に取得・更新し、常に最新の郵便番号データを提供するシステムです。\nRust 製のバックエンド（Crawler + API）と、Next.js 製のフロントエンドで構成されています。\n\n## 特徴\n\n- **自動更新**: Crawler が定期的に（デフォルト 24 時間）日本郵便の CSV を取得し、データベースを更新します。\n- **差分更新**: 廃止された郵便番号の自動削除や、変更があったデータの更新を効率的に行います。\n- **高速な API**: Rust (Axum)製の API サーバーが、郵便番号検索や住所検索を提供します。\n- **モダンなフロントエンド**: Next.js (React) + TypeScript + Tailwind CSS によるサンプル実装が含まれています。\n- **ハイブリッド環境**: Nix による再現性の高い開発環境と、Docker による手軽な DB 構築を組み合わせています。\n- **DB 切り替え対応**: MySQL と PostgreSQL の両方に対応。環境変数で切り替え可能です。\n\n## アーキテクチャ\n\n- **Frontend**: Next.js (React), TypeScript, Tailwind CSS, Radix UI\n- **Backend API**: Rust (Axum), tokio-postgres, mysql_async\n- **Crawler**: Rust, Tokio, Reqwest, CSV\n- **Database**: MySQL \u0026 PostgreSQL (両対応、環境変数で選択)\n- **Infrastructure**: Docker Compose (DB), Nix (Rust/Node environment)\n\n## 前提条件\n\n以下のツールが必要です：\n\n- **Nix**: 開発環境の構築に使用します（Rust ツールチェーン、ビルドツールなど）\n- **Docker**: データベースの実行に使用します\n- **補足**: Node.js / Yarn / Go / Rust は `nix develop` で提供されます（Nix 前提）\n\n### Nix のインストール\n\nまだ Nix をインストールしていない場合は、以下のコマンドでインストールしてください：\n\n```bash\n# 公式インストーラー\nsh \u003c(curl -L https://nixos.org/nix/install)\n\n# または Determinate Systems インストーラー（推奨）\ncurl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install\n```\n\n---\n\n## 🚀 クイックスタート (Launcher)\n\nGo 製の CLI ランチャーを使って、簡単に環境を起動できます。\n\n```bash\ncd launcher\nnix develop --command go run main.go\n```\n\nまたは、ビルドして実行：\n\n```bash\ncd launcher\nnix develop --command go build -o postal-launcher\n./postal-launcher\n```\n\nランチャーから以下の操作が可能です：\n\n- データベースの起動/停止 (Docker)\n- Crawler, API, Frontend の一括起動 (新しいターミナルで開きます)\n\n---\n\n## 🛠 手動セットアップ \u0026 実行\n\n### 一括導入 (onboard.sh)\n\nプロファイル付きでローカル導入を一括実行できます。\n\n```bash\n./scripts/onboard.sh --profile dev\n```\n\n詳細は `docs/ONBOARDING_PROFILES.md` を参照してください。\n\n### 環境セットアップ自動化 (Nix + Docker)\n\nNix / Docker 前提のセットアップを自動化する場合:\n\n```bash\n./scripts/setup_nix_docker.sh --profile dev\n```\n\n詳細は `docs/SETUP_NIX_DOCKER_AUTOMATION.md` を参照してください。\n\n### Docker イメージビルド (マルチステージ)\n\nAPI / Crawler はマルチステージDockerfileで軽量ランタイムイメージを生成できます。\n\n```bash\n# API\ndocker build -f worker/api/Dockerfile -t postal-api:multistage .\n\n# Crawler\ndocker build -f worker/crawler/Dockerfile -t postal-crawler:multistage .\n```\n\n実行例:\n\n```bash\ndocker run --rm -p 3202:3202 \\\n  -e DATABASE_TYPE=postgres \\\n  -e POSTGRES_DATABASE_URL=postgres://postgres:postgres_password@host.docker.internal:3205/zip_code_db \\\n  postal-api:multistage\n```\n\n## セットアップと実行\n\n\u003e **重要**: 以下の手順を**必ず順番通り**に実行してください。\n\n### 1. データベースの起動\n\n**最初に**Docker コンテナを起動してデータベースを初期化します：\n\n```bash\n# プロジェクトルートで実行\ndocker-compose up -d\n\n# DBコンテナが起動したことを確認\ndocker ps\n```\n\nMySQL（ポート 3204）と PostgreSQL（ポート 3205）の両方が起動します。\n\nRedis キャッシュを使う場合は、以下で Redis も起動できます（オプション）:\n\n```bash\ndocker compose --profile cache up -d redis\n```\n\n### 2. 環境変数の設定\n\nCrawler と API の `.env` ファイルを作成します：\n\n```bash\n# Crawler用\ncp worker/crawler/.env.example worker/crawler/.env\n\n# API用\ncp worker/api/.env.example worker/api/.env\n```\n\n`.env` ファイルで `DATABASE_TYPE` を設定します（デフォルト: `postgres`）：\n\n```bash\n# PostgreSQLを使用する場合（デフォルト）\nDATABASE_TYPE=postgres\n\n# MySQLを使用する場合\nDATABASE_TYPE=mysql\n\n# SQLiteを使用する場合（read-only PoC）\nDATABASE_TYPE=sqlite\nSQLITE_DATABASE_PATH=storage/sqlite/postal_codes.sqlite3\n\n# Redis キャッシュ（オプション）\nREDIS_URL=redis://127.0.0.1:3206\nREDIS_CACHE_TTL_SECONDS=300\n\n# Readiness 厳密化（オプション）\n# true: REDIS_URL が設定されている時、Redis疎通失敗で /ready=503\n# false: Redis疎通失敗でも /ready=200（cache=\"error\"）\nREADY_REQUIRE_CACHE=false\n\n# IP制限（オプション）\n# TRUST_PROXY_HEADERS=true の場合、X-Forwarded-For / X-Real-IP を優先して判定\nTRUST_PROXY_HEADERS=false\n# 例: IP_ALLOWLIST=203.0.113.10,10.0.0.0/24,2001:db8::/64\nIP_ALLOWLIST=\n\n# SSOヘッダ認証（最小構成）\n# none: 認証なし（デフォルト）\n# sso_header: IdP連携済みリバースプロキシが付与するヘッダを必須化\nAUTH_MODE=none\nAUTH_USER_HEADER=x-auth-request-email\n# 任意（未設定可）\nAUTH_GROUPS_HEADER=\n# 認証をスキップするパス（prefix判定、カンマ区切り）\nAUTH_ANONYMOUS_PATHS=/health,/ready,/openapi.json,/docs\n```\n\n\u003e [!NOTE]\n\u003e `DATABASE_TYPE=sqlite` は API の read-only PoC 向けです。Crawler から SQLite への直接更新は未対応です。\n\n### SQLite DB 生成（PoC）\n\nPostgreSQL に取り込まれたデータから SQLite DB を生成できます:\n\n```bash\nnix develop --command bash -lc \"./scripts/build_sqlite_from_postgres.sh\"\n```\n\nSQLite 配布アーティファクト（DB + checksum + manifest）を作る場合:\n\n```bash\nnix develop --command bash -lc \"./scripts/package_sqlite_release.sh\"\n```\n\n`artifacts/sqlite/` に以下が生成されます。\n\n- `postal_codes-YYYYMMDD.sqlite3`\n- `checksums-YYYYMMDD.txt`\n- `manifest-YYYYMMDD.txt`\n\n### 3. Crawler の実行（郵便番号データの自動取得・更新）\n\n**Nix 環境に入ってから**Crawler を起動します：\n\n```bash\nnix develop --command bash -lc \"cd worker/crawler \u0026\u0026 cargo run --release --bin crawler\"\n```\n\n1サイクルだけ実行して終了したい場合（CI/バッチ向け）:\n\n```bash\nnix develop --command bash -lc \"cd worker/crawler \u0026\u0026 CRAWLER_RUN_ONCE=true cargo run --release --bin crawler\"\n```\n\n初回実行時は以下の処理が行われます：\n\n- 日本郵便から CSV データをダウンロード\n- データベースへの初期データ投入（約 12 万件）\n\nその後、設定された間隔（デフォルト 24 時間）で自動的にデータを更新し続けます。\n`REDIS_URL` が設定されている場合、更新後に Redis キャッシュを自動失効します。\n\n### 版指定ロールバック（最小CLI）\n\nCrawler が保存した `data_version` を指定して、`postal_codes` をスナップショットから復元できます。\n\n```bash\nnix develop --command bash -lc \"cd worker/crawler \u0026\u0026 cargo run --release --bin rollback -- --database-type postgres --data-version v20260213002038361\"\n```\n\nMySQL の場合:\n\n```bash\nnix develop --command bash -lc \"cd worker/crawler \u0026\u0026 cargo run --release --bin rollback -- --database-type mysql --data-version v20260213002038361\"\n```\n\n`data_version` は `data_update_audits` テーブルで確認できます。\n\n### 4. API サーバーの起動\n\n**別のターミナルで**、Nix 環境に入ってから API を起動します：\n\n```bash\nnix develop --command bash -lc \"cd worker/api \u0026\u0026 cargo run --release --bin api\"\n```\n\nAPI サーバーは `http://localhost:3202` で起動します。\n\n### 5. フロントエンドの起動\n\nさらに**別のターミナルで**、Nix 環境経由でフロントエンドを起動します：\n\n```bash\nnix develop --command bash -lc \"cd frontend \u0026\u0026 yarn install \u0026\u0026 yarn dev\"\n```\n\nブラウザで `http://localhost:3203` にアクセスすると、以下の導入サンプルを切り替えて確認できます。\n\n- EC 配送先自動補完フォーム\n- 会員登録フォーム（郵便番号検索 + 住所キーワード検索）\n\nSDK 実装サンプルは `frontend/src/lib/postal-sdk.ts` を参照してください。\n\n## トラブルシューティング\n\n👉 **トラブルシューティングについてはこちら:** [TROUBLESHOOTING.md](./docs/TROUBLESHOOTING.md)\n\n## 開発者向け情報\n\n👉 **API ドキュメント（OpenAPI JSON）:** `http://localhost:3202/openapi.json`\n\n👉 **Swagger UI:** `http://localhost:3202/docs`\n\n👉 **Readiness:** `http://localhost:3202/ready`\n\n`/ready` の判定方針:\n\n- `READY_REQUIRE_CACHE=false`（デフォルト）: DB 接続が正常なら Ready。Redis 障害時は `cache=\"error\"` を返す\n- `READY_REQUIRE_CACHE=true`: `REDIS_URL` が設定されている場合、Redis 障害時は `503`（`{\"error\":\"cache not ready\"}`）\n\nIP制限（`IP_ALLOWLIST`）:\n\n- 未設定: IP 制限なし\n- 設定あり: 許可IP/CIDR 以外は `403 {\"error\":\"forbidden\"}`\n- `TRUST_PROXY_HEADERS=true` の場合、`X-Forwarded-For` / `X-Real-IP` を優先して判定（Cloud Run 想定）\n\nSSOヘッダ認証（`AUTH_MODE=sso_header`）:\n\n- `AUTH_USER_HEADER` が存在しない場合は `401 {\"error\":\"unauthorized\"}`\n- 最小構成は「SAML IdP -\u003e 認証プロキシ（oauth2-proxy など）-\u003e API」\n- `/health` `/ready` `/openapi.json` `/docs` は既定で匿名アクセスを許可\n- 匿名許可パスは `AUTH_ANONYMOUS_PATHS` で調整可能（prefix判定）\n\n👉 **Metrics(JSON):** `http://localhost:3202/metrics`\n\n👉 **仕様書（補助ドキュメント）:** [API_SPEC.md](./API_SPEC.md)\n👉 **SSO最小構成設計:** [SAML_SSO_MINIMAL_DESIGN.md](./docs/SAML_SSO_MINIMAL_DESIGN.md)\n\n👉 **開発者向け情報についてはこちら:** [DEVELOPMENT.md](./docs/DEVELOPMENT.md)\n\n👉 **CI/CD 設計についてはこちら:** [CI_DESIGN.md](./docs/CI_DESIGN.md)\n\n👉 **デプロイ骨格（GitHub Actions + Terraform）はこちら:** [DEPLOY.md](./docs/DEPLOY.md)\n👉 **GitHub OIDC 設定スクリプト:** `./scripts/setup_github_oidc_vars.sh`\n👉 **Terraform workflow 実行スクリプト:** `./scripts/run_terraform_workflow.sh`\n\n👉 **SQLite read-only PoC についてはこちら:** [SQLITE_READONLY_POC.md](./docs/SQLITE_READONLY_POC.md)\n\n👉 **SQLite 配布ワークフロー（GitHub Actions 手動実行）:** `.github/workflows/sqlite-release.yml`\n\n👉 **販売準備ロードマップ（2026年4月目標）はこちら:** [SALES_READINESS_PLAN_2026Q2.md](./docs/SALES_READINESS_PLAN_2026Q2.md)\n\n## ライセンスと商用利用について\n\n本プロジェクトは、**デュアルライセンス**（Dual Licensing）を採用する予定です。\n\n1.  **個人利用・非営利・オープンソース開発**:\n\n    - **MIT License** の下、自由に利用・改変・再配布が可能です。\n    - 学習目的や個人プロジェクトでぜひご活用ください。\n\n2.  **法人利用・商用サービスへの組み込み**:\n    - 企業での業務利用や、商用製品への組み込みを行う場合は、**商用ライセンス**の契約、または**GitHub Sponsors**等による継続的な支援をお願いすることを想定しています。\n    - （現在はプレビュー版のため、評価目的での利用は無償です。本格導入の際はご連絡ください）\n\nこのモデルにより、オープンソースとしての発展と、持続可能な開発体制の両立を目指しています。\n\n\u003e [!NOTE]\n\u003e 個人受託を先行しやすくするための「条件付きフリーライセンス案」は、`docs/SALES_READINESS_PLAN_2026Q2.md` を参照してください。\n\n## ロードマップ (TODO)\n\n詳細な実行計画（優先度・日付入り）は `docs/SALES_READINESS_PLAN_2026Q2.md` を参照してください。\n\n- [x] **CI/CD パイプラインの構築**: GitHub Actions による自動テスト・ビルド\n- [x] **ランチャーの UX 改善**: 実行順序の制御と視覚的フィードバック\n- [ ] **環境構築の完全自動化**: Nix + Docker 前提のインストールとセットアップ\n- [ ] **マルチプラットフォーム デプロイ基盤**: GitHub Actions + Terraform による環境展開（クラウド別ターゲット対応）\n- [ ] **MySQL/PostgreSQL の自動テスト**: 両 DB でのインテグレーションテスト追加\n- [x] **Docker イメージの軽量化**: マルチステージビルドの最適化（API/Crawler）\n- [ ] **Kubernetes 連携**: コンテナ連携・オーケストレーション対応（Helm/Kustomize 含む）\n- [x] **API ドキュメントの拡充**: Swagger/OpenAPI による仕様書生成\n\n## バージョン\n\n**v0.2.0 (Beta)** - Enhanced Developer Experience \u0026 Robustness\n\n## 貢献について (Contributing)\n\nPostal Converter JA はオープンソースプロジェクトであり、皆様からの貢献を歓迎します！\nバグ報告、機能追加、ドキュメント改善など、どんな形でも構いません。\n\n詳細なガイドラインについては、[CONTRIBUTING.md](CONTRIBUTING.md) をご覧ください。\nまた、コミュニティの行動規範として [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) を定めています。\n\n\u003e [!NOTE]\n\u003e 依存関係の更新は **Dependabot** によって毎週（Weekly）自動的にチェックされ、PR が作成されます。\n\n## スポンサー募集\n\n本プロジェクトの安定的かつ継続的な運用のために、スポンサー企業様を募集しています。\n\n### 📮 日本郵便株式会社（Japan Post）様へ\n\n本システムは、貴社の郵便番号データをより扱いやすく、現代的な Web 開発の現場で活用しやすくするために開発されました。\nもし本プロジェクトの趣旨にご賛同いただけるようでしたら、公式なスポンサー、あるいは技術的なパートナーシップをご検討いただければ幸いです。\n正確で使いやすい住所データインフラを、共に構築できることを願っております。\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmt4110%2Fpostal_converter_ja","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmt4110%2Fpostal_converter_ja","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmt4110%2Fpostal_converter_ja/lists"}