リポジトリ構成 Repository layout
Parky は単一リポジトリ(モノレポ)で管理されています。 プロダクト別のディレクトリに分かれ、それぞれが専用の GitHub Actions ワークフローで個別にデプロイされます。
Parky lives in a single monorepo. Each product sits in its own directory and has its own GitHub Actions workflow for deployment.
ディレクトリ構成Directory layout
parky/
├── web/ # npm workspace root for web packages
│ ├── home/ # 公開ポータル (Astro 5 + Islands) — @parky/home
│ │ └── src/pages/media/ # TOKYO CAR LIFE (Supabase articles 駆動)
│ ├── portal/
│ │ ├── admin/ # 管理者ポータル (React 19 + Vite) — @parky/admin
│ │ ├── owner/ # オーナーポータル (React 19 + Vite) — @parky/owner
│ │ └── marketing/ # マーケティングポータル (React 19 + Vite) — @parky/marketing
│ └── packages/ # 共有パッケージ (workspace)
│ ├── api-client/ # Supabase クライアントラッパー
│ ├── api-types/ # openapi-typescript で生成した型定義
│ ├── bff-client/ # /v1/* 用 fetch ラッパー (全 SPA / Astro 共通)
│ ├── domain/ # ドメイン型・バリデータ
│ ├── i18n/ # ロケール辞書
│ ├── logger/ # 構造化ロガー
│ ├── portal-common/ # 3 ポータル共通 React 部品
│ ├── seo/ # SEO ユーティリティ (JSON-LD / meta)
│ └── ui/ # 共有 React コンポーネント
│
├── mobileapp/
│ ├── prototype/
│ │ ├── flutter/ # Flutter プロトタイプ本体
│ │ └── web/ # Web 版モック (dev-app-mock.parky.co.jp)
│ └── api/ # モバイル専用 API スタブ
│
├── api/ # Cloudflare Workers BFF — @parky/api
│ ├── src/
│ │ ├── bff/{mobile,web,admin,owner,marketing,owner-public,webhooks}/
│ │ │ # Layer-First の HTTP I/O 層 (channel × screen)
│ │ ├── core/ # capability / business rules
│ │ ├── data/ # 1 ファイル 1 table cluster (postgres.js)
│ │ ├── schema/{domain,view,row}/ # Zod / TS 型 (camel/snake split)
│ │ ├── routes/ # legacy ルート (新規追加禁止 — bff/ に作る)
│ │ ├── cron/ # Cron Triggers ハンドラ
│ │ ├── queue/ # Queues consumer (store-sync / fcm-dispatch / places-refresh / x-ai-generate, admin Worker が consume)
│ │ ├── durable-objects/ # RateLimiterDO
│ │ ├── shared/{lib,middleware,schema}/
│ │ ├── lib/ # db / r2 / fcm / oauth / sentry など
│ │ ├── middleware/ # auth / cache / rate-limit / error-handler
│ │ ├── app/ + app-core.ts # routes-manifest / dispatcher
│ │ ├── index.ts # monolith entrypoint (legacy)
│ │ ├── index-public.ts # public Worker entrypoint
│ │ ├── index-admin.ts # admin Worker entrypoint
│ │ ├── index-marketing.ts # marketing Worker entrypoint
│ │ └── cron-constants.ts # CRON_JOBS SSoT
│ ├── wrangler.toml # legacy monolith (deploy 不可、scaffold のみ)
│ ├── wrangler.public.toml # parky-api-public
│ ├── wrangler.admin.toml # parky-api-admin (+ all crons + 全 queue consumers: store-sync / FCM / Places / X_AI)
│ ├── wrangler.marketing.toml # parky-api-marketing
│ └── wrangler.shared-bindings.toml # binding ID SSoT (deploy しない / ADR-0010)
│ # 2026-05-11: wrangler.store-sync.toml / src/store-sync-worker/ は Phase 1 skeleton のため削除済。
│ # Phase 2 (2026-Q3) で再分離する際は git 履歴から復元。詳細: api/docs/store-sync-worker-migration.md
│
├── infra/
│ ├── supabase/
│ │ ├── baseline/{public,admin,marketing,analytics,bff_only,infra,auth_helpers}/
│ │ │ # schema/table 単位 split (snapshot strategy / ADR-0003)
│ │ ├── migrations/ # README のみ (snapshot baseline 採用後は migration 持たない)
│ │ ├── seeds/ # シード SQL + generator/
│ │ ├── tests/ # pgTAP RLS テスト
│ │ ├── scripts/ # refresh-baseline / split-baseline 等
│ │ └── config.toml
│ ├── r2/ # R2 bucket 構成メモ
│ ├── terraform/ # インフラ宣言 (modules / envs / scripts)
│ └── turbo-cache/ # self-hosted turbo remote cache Worker
│
├── tests/ # workspace 横断 e2e
│ ├── e2e/{owner,admin,public,marketing,manifest,scripts}/
│ └── load/ # k6 負荷テスト
│
├── docs/ # 本ドキュメントサイト (dev-docs.parky.co.jp)
│ ├── index.html / architecture.html / data-model.html / tech-stack.html /
│ │ conventions.html / repository.html
│ ├── adr/ # Lightweight ADR (0001–0012)
│ ├── assets/ # 共通 CSS/JS
│ ├── portal-admin/ portal-owner/ portal-marketing/
│ ├── mobile-app/ web-app/
│ ├── bff/ api/ db/ kpi/ i18n/ qa/ plans/ internal/ ops/
│ └── ops/ # 運用手順メモ
│
├── scripts/ # 汎用スクリプト (adr/audit/db/deploy/secrets/dora/...)
├── shared/ # 全プロジェクト共通設定 (password-policy.json 等)
├── .github/workflows/ # CI/CD (75 workflows)
├── .changeset/ # Changesets リリース管理
├── CLAUDE.md / README.md / ONBOARDING.md
├── package.json + package-lock.json # npm workspace root
├── pnpm-workspace.yaml # 互換用 (実体は npm workspace)
├── turbo.json # Turborepo task pipeline
├── biome.json / biome.jsonc # フォーマッタ設定
└── tsconfig.base.json
補足:
Notes:
ルート
package.json は npm workspaces (api / web/* / infra/turbo-cache) を採用。
web/package.json は nested workspace(admin/owner/marketing/home/packages*)として残存しており、Phase 3 で root に統合予定(parky/CLAUDE.md § 依存管理)。
infra/supabase/migrations/ は実 SQL を持たず、snapshot baseline 戦略(ADR-0003)に従い infra/supabase/baseline/ が SSoT。
The root package.json uses npm workspaces (api / web/* / infra/turbo-cache). A nested web/package.json still exists (admin/owner/marketing/home/packages*) and will be folded into the root in Phase 3 (see parky/CLAUDE.md §dependency management).
infra/supabase/migrations/ is intentionally empty of SQL — the snapshot-baseline strategy (ADR-0003) makes infra/supabase/baseline/ the SSoT.
デプロイパイプラインDeployment pipelines
フロントエンド (Cloudflare Pages)Frontends (Cloudflare Pages)
| 対象 | Target | Workflow | トリガー | Trigger | 配置先 | Deploy to |
|---|---|---|---|---|---|---|
| 管理者ポータル (dev) | Admin portal (dev) | deploy-admin.yml |
dev push on web/portal/admin/** |
dev-admin.parky.co.jp |
||
| 管理者ポータル (prod) | Admin portal (prod) | deploy-admin-prod.yml |
main push / 手動実行 |
main push / manual |
admin.parky.co.jp |
|
| オーナーポータル (dev) | Owner portal (dev) | deploy-portal-owner-dev.yml |
dev push on web/portal/owner/** |
dev-owner.parky.co.jp |
||
| オーナーポータル (prod) | Owner portal (prod) | deploy-portal-owner-prod.yml |
main push / 手動実行 |
main push / manual |
owner.parky.co.jp |
|
| マーケティングポータル (dev) | Marketing portal (dev) | deploy-portal-marketing.yml |
dev push on web/portal/marketing/** |
dev-marketing.parky.co.jp |
||
| マーケティングポータル (prod) | Marketing portal (prod) | deploy-portal-marketing-prod.yml |
main push / 手動実行 |
main push / manual |
marketing.parky.co.jp |
|
| 公開ポータル (dev) | Public web app (dev) | deploy-public-dev.yml |
dev push on web/home/**, web/packages/** |
dev.parky.co.jp |
||
| 公開ポータル (prod) | Public web app (prod) | deploy-public-home-prod.yml |
main push / 手動実行 |
main push / manual |
parky.co.jp |
|
| ドキュメント | Docs | deploy-admin-docs.yml |
dev push on docs/** |
dev-docs.parky.co.jp |
||
| App モック | App mockup | deploy-app-mock.yml |
dev push on mobileapp/prototype/web/** |
dev-app-mock.parky.co.jp |
BFF (Cloudflare Workers / ADR-0010 で 4 Worker に分割)BFF (Cloudflare Workers — split into 4 workers per ADR-0010)
| Worker | Workflow | wrangler config | 役割 | Role |
|---|---|---|---|---|
parky-api-public |
deploy-api-dev.yml / deploy-api-public-prod.yml |
wrangler.public.toml |
end-user 向け /v1/* (mobile / web) |
End-user /v1/* (mobile / web) |
parky-api-admin |
deploy-api-admin-prod.yml |
wrangler.admin.toml |
管理者 /v1/admin/* + 全 cron + 全 queue consumer |
Admin /v1/admin/* + all crons + all queue consumers |
parky-api-marketing |
deploy-api-marketing-prod.yml |
wrangler.marketing.toml |
マーケ /v1/marketing/* + OAuth callback |
Marketing /v1/marketing/* + OAuth callbacks |
| — | deploy-api-pr.yml / deploy-api-stg.yml / deploy-api-prod.yml |
— | PR preview / staging / 全 Worker prod 一括 (canary 込) | PR preview / staging / batch prod deploy across all workers (with canary) |
補足:
Note:
dev 環境の Web アセットはすべて Cloudflare Pages に個別プロジェクトとして配置する(dev / dev-admin / dev-owner / dev-marketing / dev-docs / dev-app-mock)。binding ID の SSoT は
wrangler.shared-bindings.toml で管理し、CI で各 Worker 設定との drift を block。
Every dev web asset lives as its own Cloudflare Pages project (dev / dev-admin / dev-owner / dev-marketing / dev-docs / dev-app-mock). Binding-ID SSoT lives in wrangler.shared-bindings.toml; CI blocks drift between it and each Worker config.
デプロイフロー図Deployment flow
flowchart LR
dev[dev branch push] --> GHA{GitHub Actions}
main[main branch push] --> GHA
GHA --> WF1[deploy-admin.yml]
GHA --> WF2[deploy-portal-owner-dev.yml]
GHA --> WF3[deploy-portal-marketing.yml]
GHA --> WF4[deploy-public-dev.yml]
GHA --> WF5[deploy-admin-docs.yml]
GHA --> WF6[deploy-app-mock.yml]
GHA --> WF7[deploy-api-dev.yml]
GHA --> WF8[deploy-api-*-prod.yml]
WF1 --> CFP[(Cloudflare Pages)]
WF2 --> CFP
WF3 --> CFP
WF4 --> CFP
WF5 --> CFP
WF6 --> CFP
WF7 --> CFW[(Cloudflare Workers)]
WF8 --> CFW
CFP --> URLS[*.parky.co.jp Pages projects]
CFW --> APIS["api.parky.co.jp / admin-api.parky.co.jp / marketing-api.parky.co.jp"]
CANARY{canary-deploy-*.yml
+ auto-rollback-*.yml} -.- WF8
シークレット管理Secrets
- ワークフローは 1Password Service Account トークン経由で SSH 鍵・認証情報を取得
- Workflows pull SSH keys and creds via a 1Password Service Account token.
- GitHub リポジトリの
OP_SERVICE_ACCOUNT_TOKENのみを設定すれば動作 - Only
OP_SERVICE_ACCOUNT_TOKENneeds to be configured in GitHub secrets.