技術スタック Tech stack

Parky で採用している主要技術とその役割、配置場所の一覧です。 どのプロダクトがどれを使っているかを素早く把握するためのリファレンスです。

The major technologies Parky uses, their responsibilities, and which product relies on them. A quick reference to see which client consumes what.

BFF(クライアントが叩く唯一の API 層)BFF (the only API surface clients hit)

技術Tech 用途Purpose 使用プロダクトUsed by
Cloudflare Workers 全クライアント共通の BFF ランタイム。/v1/* を単一 API 層として提供。東京 PoP で Supabase ap-northeast-1 と至近 Shared BFF runtime serving /v1/* as the single API surface. Tokyo PoP colocated near Supabase ap-northeast-1 All (Flutter / Web / Admin)All (Flutter / Web / Admin)
Hono Workers 上のルーティング・ミドルウェア。@hono/zod-openapi で OpenAPI と実装を連動 Routing/middleware on Workers. @hono/zod-openapi keeps implementation in sync with the spec
OpenAPI 3.1 + Zod API 契約の Single Source of Truth(packages/api-spec/)。CI で TS / Dart クライアントを自動生成 Single source of truth for the API contract (packages/api-spec/). TS and Dart clients are regenerated in CI
Cloudflare Cache API 公開 GET のエッジキャッシュ。middleware/cache.tsGET+200max-age=300 を付け、それ以外は no-cache Edge cache for public GET. middleware/cache.ts sets max-age=300 for GET+200, no-cache otherwise
Cloudflare KV (parky-cache) isolate 跨ぎキャッシュ。FCM OAuth access_token を 2 層キャッシュ(isolate Map + KV / TTL 55分)で共有 Cross-isolate cache. FCM OAuth access_token uses a 2-tier cache (isolate Map + KV, TTL 55 min)
Cloudflare Rate Limiting binding ユーザー単位のレート制限(RATE_LIMIT_USER)。/v1/search/ai で 10 req / 60 秒 Per-user rate limiting via the RATE_LIMIT_USER binding. 10 req / 60 s for /v1/search/ai
Cloudflare Analytics Engine (parky_ai_usage) AI 呼出のテレメトリ集計。現行は PG ai_usage_logs と dual write、段階的に AE 単独化 Telemetry dataset for AI calls. Dual-writes with PG ai_usage_logs today; moving to AE-only
Cloudflare Logpush / Workers Observability 構造化ログ、req/sec、エラー率、レイテンシ分布([observability] enabled = true Structured logs, req/sec, error rate, latency ([observability] enabled = true)

バックエンド(Workers から呼ばれるコア基盤)Backend (core, called from Workers)

技術Tech 用途Purpose 使用プロダクトUsed by
Supabase (PostgreSQL 15) 全データの永続化。PostGIS 拡張で位置検索。Workers が Service Role で接続 Primary datastore with PostGIS for geo queries. Workers connect with the Service Role key AllAll
Supabase Auth 認証(メール+PW、OAuth、電話番号)。クライアントは SDK 経由で直接利用(例外①)、Workers は JWT 検証のみ Auth (email+password, OAuth, phone). Clients use the SDK directly (exception 1); Workers only verify JWTs AllAll
Supabase Realtime テーブル変更のライブ購読。クライアント直接接続(例外②) Live table subscriptions. Clients connect directly (exception 2) Admin, MobileAdmin, Mobile
Cloudflare Hyperdrive (parky-db) Workers → Supabase Postgres の接続プール+グローバルキャッシュ。lib/db.ts の postgres.js が env.HYPERDRIVE.connectionString で接続(Direct Connection 経由、Supavisor は使わない) Connection pool + global cache for Workers → Supabase Postgres. lib/db.ts uses postgres.js via env.HYPERDRIVE.connectionString (Direct Connection; Supavisor bypassed) InternalInternal
Cloudflare Cron Triggers 定期ジョブ。*/10 * * * *handleSponsorProximity を起動。pg_cron は使わず wrangler.toml[triggers] crons に集約 Scheduled jobs — */10 * * * * invokes handleSponsorProximity. No pg_cron; schedules live in [triggers] crons InternalInternal
Cloudflare Queues parky-store-sync(Google Play / App Store Connect API → DB upsert)と parky-fcm-dispatch(FCM 通知 fan-out)。各 DLQ 配線・max_retries=3 parky-store-sync (Google Play / App Store Connect APIs → DB upsert) and parky-fcm-dispatch (FCM fan-out). DLQs wired, max_retries=3 InternalInternal
Cloudflare Workers AI エッジ推論(env.AI)。Instagram tool で DETR 物体検出を使って顔/ナンバープレート候補領域を検出 Edge inference (env.AI). Used by the Instagram tool for DETR object detection (face / license-plate candidate regions) InternalInternal
Cloudflare D1 (parky-instagram) SQLite at edge。Instagram tool 専用(Parky 本体の Supabase とは分離) SQLite at edge for the Instagram tool (isolated from Parky's main Supabase) Instagram toolInstagram tool

オブジェクトストレージObject storage

技術Tech 用途Purpose 使用プロダクトUsed by
Cloudflare R2 (S3 互換) 駐車場画像・アバター・バッジ/テーマアセット・PDF など全バイナリの保管(bucket: parky)。旧 Wasabi は 2026-04-19 に廃止。Instagram tool 用に parky-instagram-assets 別 bucket も配線。 Holds all binary assets (bucket: parky) — parking images, avatars, badge/theme assets, PDFs. Wasabi was retired on 2026-04-19. A separate parky-instagram-assets bucket is wired for the Instagram tool. AllAll
R2 Custom Domain cdn.parky.co.jp 匿名公開 GET 用のカスタムドメイン。R2_PUBLIC_BASE が未設定だと account-private endpoint(署名必須)にフォールバック Custom domain for anonymous public GET. If R2_PUBLIC_BASE is unset, falls back to the account-private endpoint (signature required) AllAll
Workers /v1/storage/upload-url R2 の presigned PUT URL を発行し、assets テーブルに s3_key を含むメタデータを登録するブリッジ。JWT 検証・user_id スコープで発行。クライアントは presigned URL に直接 PUT する(バイト列は Workers を経由しない) Mints R2 presigned PUT URLs and registers metadata (including s3_key) in the assets table. JWT-verified and scoped to user_id. Clients PUT bytes directly — bytes skip Workers Admin (write), All (read)Admin (write), All (read)
R2_ENDPOINT / R2_BUCKET / R2_ACCESS_KEY_ID / R2_SECRET_ACCESS_KEY / R2_PUBLIC_BASE Workers に必要なシークレット。wrangler secret put で登録 Secrets required by Workers, registered via wrangler secret put

フロントエンドFrontend

プロダクトProduct スタックStack ホスティングHosting
管理者ポータルAdmin portal React 19 + Vite + TypeScript + Lucide Icons Cloudflare Pages (parky-admin-devdev-admin.parky.co.jp / parky-admin-prodadmin.parky.co.jp)
モバイルアプリMobile app Flutter (Dart) — mobileapp/prototype/flutter/ App Store / Google Play(将来) App Store / Google Play (future)
Web版 (一般向け)Web app (public) Astro 5 + React 19 (islands) + Tailwind CSS v4 + MDX + Pagefind + Mapbox GL JS Cloudflare Pages (parky-home-devdev.parky.co.jp)
メディア (記事)Media (articles) Astro content collection(旧 WordPress 子テーマ blogsy-child は廃止) Astro content collection (legacy WordPress blogsy-child retired) dev.parky.co.jp/media/ (Cloudflare Pages)
LPLP 静的HTMLStatic HTML Cloudflare Pages (parky-lp-prodparky.co.jp)
Docs(本サイト)Docs (this site) 静的 HTML + MermaidStatic HTML + Mermaid Cloudflare Pages (parky-docs-devdev-docs.parky.co.jp)
Mobile Web MockMobile Web Mock 単一 HTML + Mapbox GL JSSingle HTML + Mapbox GL JS Cloudflare Pages (parky-app-mock-devdev-app-mock.parky.co.jp)

地図・位置情報Maps & geo

検索Search

AI・LLMAI & LLM

通知・決済・外部サービスNotifications, payments & externals

ドキュメント・周辺ツールDocs & tooling

メモ: Note: クライアントが叩く API は Cloudflare Workers 上の /v1/* に一元化しています(2026-04-17 設計変更、Phase 2 に向けて)。Supabase Edge Functions は Parky では採用せず、FCM 配信・LLM 呼び出し・ストア同期・定期ジョブまですべて Workers 内に実装します。例外は Auth / Realtime / Storage presigned PUT のみ(データ面の最適化)。バイナリは Supabase Storage ではなく R2 に格納します(コスト・エグレス料金最適化のため)。 Clients hit a single unified API surface: Cloudflare Workers /v1/* (design change 2026-04-17, ahead of Phase 2). Supabase Edge Functions are not used in Parky — FCM delivery, LLM calls, store syncs, and scheduled jobs all live inside Workers. The exceptions are Auth, Realtime, and Storage presigned PUTs — data-plane optimizations. Binary assets live in R2, not Supabase Storage (chosen for cost and egress).