認証と権限 Auth & permissions

管理者ポータルは Supabase Auth を使った JWT ベース認証と、ロール/権限キーによる画面側フィルタリングで構成されています。

The admin portal uses Supabase Auth for JWT-based login, plus a role / permission-key system that filters the UI client-side.

ログインフロー Login flow

sequenceDiagram
  participant U as Admin
  participant FE as Admin Portal
  participant SB as Supabase Auth
  participant DB as PostgreSQL
  U->>FE: email + password
  FE->>SB: signInWithPassword()
  SB-->>FE: session (JWT)
  FE->>DB: SELECT admins WHERE user_id = auth.uid()
  DB-->>FE: admin row + role_id
  FE->>DB: SELECT role_permissions WHERE role_id = ?
  DB-->>FE: permission_keys[]
  FE-->>U: Dashboard (nav filtered by permission_keys)
  Note over FE,DB: Subsequent requests include Authorization: Bearer {jwt}

関連コンポーネント Components involved

Security: service_role キーは強力です。配布物に埋め込まず、本ポータルでも UI ビルドに含めない運用が前提です。 The service_role key is powerful and must never be bundled into an unprivileged client. Treat it as secret even within the portal build pipeline.

ロール Roles

ロールは roles テーブルで定義され、各ロールに対する権限キーは role_permissions で管理されます。

Roles live in the roles table, with permission keys per role stored in role_permissions.

Role想定担当Intended ownerアクセス範囲Scope
Super Adminシステム管理者Platform admin全権限All permissions
Ops Manager運用マネージャーOps manager駐車場・ユーザー・売上・サポートParking, users, revenue, support
Content Managerコンテンツ担当Content team記事・広告・ゲーミ・カスタマイズArticles, ads, gamification, theming
Support AgentCS担当Customer supportサポートチケット・誤情報報告Support tickets + error reports

権限キーマトリクス Permission key matrix

30以上の権限キーが定義されており、Roles 画面でチェックボックスで一括管理できます。

There are 30+ permission keys, manageable as a checkbox matrix on the Roles screen.

カテゴリCategory キーKeys
Dashboarddashboard.view
Parkingparking.view · parking.edit · tags.view · tags.edit · reviews.view · reviews.moderate
Usersusers.view · users.edit
Opsplans.view · plans.edit · support.view · support.respond · notifications.view · notifications.send · sales.view
Ownersowners.view · owners.edit
Contentarticles.view · articles.edit · articles.publish · ads.view · ads.edit
Gamificationgamification.view · gamification.edit
Adminsadmins.view · admins.edit · roles.view · roles.edit
Systemsettings.view · settings.edit

アクセス制御の実装レイヤ Enforcement layers

  1. クライアント: AuthContext が権限キーを保持、サイドバー / ボタンを hasPermission('parking.edit') で表示制御。
  2. Client: AuthContext exposes permission keys; the sidebar and action buttons gate on hasPermission('parking.edit').
  3. RLS ポリシー: Supabase の Row Level Security を各テーブルに設定し、テーブル単位でアクセスを制御。
  4. RLS policies: Supabase Row Level Security on each table restricts access server-side.
  5. service_role: 管理者アカウント作成や削除など、強い操作のみ supabaseAdmin (service_role) で実行。
  6. service_role: Only privileged flows (create / delete admin) go through supabaseAdmin with the service_role key.
注意Caveat: 本ポータルは信頼できる運用者向けに設計されています。UI 非表示は UX 上のガードであり、厳密な権限分離が必要な場合は RLS ポリシーを強化してください。 The portal is built for trusted operators. UI hiding is a UX guard; harden the RLS policies if you need strict enforcement.

管理者アカウント作成フロー Admin account creation flow

sequenceDiagram
  participant SA as Super Admin
  participant FE as Admins page
  participant SBA as supabaseAdmin (service_role)
  participant Auth as Supabase Auth
  participant DB as admins table
  SA->>FE: Fill form + submit
  FE->>FE: Generate 12-char random password
  FE->>SBA: admin.createUser(email, password, email_confirm: true)
  SBA->>Auth: POST /auth/v1/admin/users
  Auth-->>SBA: user
  SBA->>DB: INSERT into admins (user_id, name, email, role_id)
  DB-->>SBA: row
  SBA-->>FE: created admin
  FE-->>SA: Display initial password (one-time, copy button)

初期パスワードは画面上でのみ表示され、閉じた後は再表示できません。 リセット時は resetAdminPassword() が新しいパスワードを生成 → Auth 更新 → 画面表示 の流れになります。

The initial password is shown once and never again. A reset flow regenerates a password, updates Auth, and surfaces the new value via resetAdminPassword().