バックオフィスの全体像 Backoffice at a glance
駐車場シェアリング事業「Parky」の運営をすべてカバーする統合管理ツール。 32の画面・100を超えるAPI関数・高度なゲーミフィケーション/カスタマイズシステムを持ち、 Supabase (PostgreSQL + Auth + Realtime + Cloudflare Workers) の上に React + Vite + TypeScript で構築されています。
A unified backoffice that covers every operational aspect of the Parky parking-sharing service. It contains 32 screens, 100+ API helpers, and a rich gamification / customization system, built on React + Vite + TypeScript on top of Supabase (PostgreSQL + Auth + Realtime + Cloudflare Workers).
このドキュメントの読み方 How to use this documentation
画面カタログScreen catalog
全32画面の一覧。パス・目的・主要UI・操作・呼び出しAPIを完全網羅。
Every one of the 32 screens — path, purpose, UI, actions, and called APIs.
機能カテゴリFeature categories
駐車場・ユーザー・売上・ゲーミ等、機能を論理グループ別に把握。
Logical groupings across parking, users, revenue, gamification, and more.
注目機能Highlights
料金エンジン、バッジ条件エンジン、着せ替え、Realtimeなどの深堀り。
Deep dives into the fee engine, badge conditions, theming, realtime, and more.
データモデルData model
主要テーブル、フィールド定義、ER図によるリレーション可視化。
Core tables, field definitions, and an ER diagram of the relationships.
APIリファレンスAPI reference
Workers BFF (/v1/*)・Supabase Auth/Realtime・外部API(Mapbox 等)の一覧。対話的ビューは Swagger UI / Redoc。
PostgREST, RPCs, Cloudflare Workers, Realtime, and external APIs.
認証と権限Auth & permissions
Supabase Auth によるログインフローとロール・権限マトリクス。
Login flow via Supabase Auth and the role / permission matrix.
ポータルの位置づけ Where this portal sits
flowchart LR
subgraph Users["利用者 / Consumers"]
EndUser["エンドユーザー
End users"]
Owner["駐車場オーナー
Lot owners"]
end
subgraph Clients["クライアント / Clients"]
Mobile["モバイルアプリ
Mobile app"]
OwnerPortal["オーナーポータル
Owner portal"]
AdminPortal["管理者ポータル
Admin portal
(this doc)"]
end
subgraph Backend["バックエンド / Backend (Supabase)"]
PG[(PostgreSQL
PostGIS)]
Auth[Auth]
RT[Realtime]
Edge[Cloudflare Workers]
end
S3[(Cloudflare R2
assets)]
Map[Mapbox]
EndUser --> Mobile
Owner --> OwnerPortal
AdminPortal -- manages --> Mobile
AdminPortal -- manages --> OwnerPortal
Mobile --> Auth
OwnerPortal --> Auth
AdminPortal --> Auth
Auth --> PG
Mobile --> PG
OwnerPortal --> PG
AdminPortal --> PG
AdminPortal --> RT
AdminPortal --> Edge
Edge --> PG
AdminPortal --> S3
AdminPortal --> Map
対象ユーザー Who uses the portal
| ロールRole | 役割Responsibility |
|---|---|
| システム管理者 (Super Admin)Super Admin | 全機能への無制限アクセス。管理者アカウントやロール定義も行う。 Unrestricted access. Manages admin accounts and role definitions. |
| オペレーションマネージャーOps Manager | 駐車場・ユーザー・売上を日々監視。サポート対応も担当。 Day-to-day monitoring of lots, users, and revenue; handles support escalations. |
| コンテンツマネージャーContent Manager | 記事・広告・ゲーミフィケーション・着せ替えの運営。 Runs articles, ads, gamification, and customization themes. |
| サポートエージェントSupport Agent | サポートチケットと誤情報報告への一次対応。 Front-line handling of support tickets and misinformation reports. |
技術スタック Technology stack
| レイヤLayer | 採用技術Technology |
|---|---|
| フレームワークFramework | React 19 + Vite |
| 言語Language | TypeScript |
| ルーティングRouting | React Router DOM 7 |
| 状態管理State | AuthContext, CodeProvider, PageTitleProvider (React Context) |
| UI | Bootstrap 5.3 + Lucide Icons |
| バックエンドBackend | Cloudflare Workers BFF (/v1/*) + Supabase (Auth / Realtime / PostgreSQL via Hyperdrive) |
| DB | PostgreSQL 17 + PostGIS |
| 認証Auth | Supabase Auth (JWT) |
| ストレージStorage | Cloudflare R2 (画像・アセットimages / assets) |
| 地図Maps | Mapbox Geocoding + GL JS |
ディレクトリ構造 Directory layout
parky/web/portal/admin/
├── src/
│ ├── App.tsx ルート定義 (全32ページ)Route table (all 32 pages)
│ ├── main.tsx エントリーポイントEntry point
│ ├── auth/
│ │ ├── AuthContext.tsx 認証状態とログイン/アウトAuth state + login/out
│ │ └── RequireAuth.tsx 保護ルートProtected routes
│ ├── lib/
│ │ ├── api.ts APIヘルパー (100+)API helpers (100+)
│ │ ├── supabase.ts Supabase client
│ │ ├── codes.tsx マスターコードMaster codes
│ │ └── PageTitleContext.tsx
│ ├── components/
│ │ ├── layout/ AppLayout, Header, Sidebar
│ │ ├── VirtualTable.tsx 仮想スクロールテーブルVirtualized table
│ │ ├── ListFilterBar.tsx 共通フィルタバーUniversal filter bar
│ │ ├── ParkingMap.tsx Mapbox visualizer
│ │ ├── ActivityLogFeed.tsx Realtime feed
│ │ ├── FileUpload.tsx Cloudflare R2 upload
│ │ ├── MarkdownEditor.tsx TinyMCE editor
│ │ └── MasterDetailLayout.tsx
│ ├── hooks/
│ │ ├── usePaginatedList.ts ページング + 無限スクロールPagination + infinite scroll
│ │ └── useTableSort.ts
│ └── pages/ 32ページ (全て lazy ロード)32 pages (all lazy loaded)
├── API_SPECIFICATION.md
└── README.md
最初のログインフロー First login flow
sequenceDiagram participant U as Admin participant FE as Admin Portal (React) participant SB as Supabase Auth participant PG as PostgreSQL U->>FE: email + password FE->>SB: signInWithPassword() SB-->>FE: JWT session FE->>PG: SELECT admins, roles, role_permissions (RLS) PG-->>FE: current admin + permission keys FE-->>U: Dashboard with permitted nav items
React.lazy() で遅延ロードされるため、初回バンドルは小さく、ナビゲーション時にページ単位でコードが取得されます。
Every page is behind React.lazy(), so the initial bundle stays small and code is fetched per-page on navigation.