Phase 1 scaffold: auth for all apps
- Backend: Fastify with two listeners (public + internal), routes, services, DB migration + seed - client_app: Flutter with BLoC, all auth screens (welcome, display name, register, OTP, force-register) - mitra_app: Flutter with BLoC, OTP-only login - control_center: React + Vite, email/password login, mitra/user management, anonymity settings - Docs: phase1 plan, API contract, client app mockup - CLAUDE.md and shared memory for all subprojects Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
119
requirement/phase1-plan.md
Normal file
119
requirement/phase1-plan.md
Normal file
@@ -0,0 +1,119 @@
|
||||
# Phase 1 Plan — Authentication
|
||||
|
||||
## Overview
|
||||
Three separate auth flows across three apps, backed by one Fastify backend, Firebase Auth, and PostgreSQL.
|
||||
|
||||
---
|
||||
|
||||
## Database Schema
|
||||
|
||||
### `customers`
|
||||
| Column | Type | Notes |
|
||||
|---|---|---|
|
||||
| `id` | UUID PK | |
|
||||
| `firebase_uid` | VARCHAR | null if anonymous |
|
||||
| `phone` | VARCHAR | null if anonymous |
|
||||
| `display_name` | VARCHAR | user-chosen, never from social |
|
||||
| `is_anonymous` | BOOLEAN | true until phone/social linked |
|
||||
| `created_at` | TIMESTAMP | |
|
||||
|
||||
### `mitras`
|
||||
| Column | Type | Notes |
|
||||
|---|---|---|
|
||||
| `id` | UUID PK | |
|
||||
| `firebase_uid` | VARCHAR | set on first login |
|
||||
| `phone` | VARCHAR | primary identifier |
|
||||
| `display_name` | VARCHAR | |
|
||||
| `is_active` | BOOLEAN | toggled by control center |
|
||||
| `created_at` | TIMESTAMP | |
|
||||
|
||||
### `control_center_users`
|
||||
| Column | Type | Notes |
|
||||
|---|---|---|
|
||||
| `id` | UUID PK | |
|
||||
| `firebase_uid` | VARCHAR | |
|
||||
| `email` | VARCHAR | |
|
||||
| `display_name` | VARCHAR | |
|
||||
| `role_id` | FK → `roles` | |
|
||||
| `created_at` | TIMESTAMP | |
|
||||
|
||||
### `roles`
|
||||
| Column | Type | Notes |
|
||||
|---|---|---|
|
||||
| `id` | UUID PK | |
|
||||
| `name` | VARCHAR | e.g. `super_admin`, `operator` |
|
||||
| `permissions` | JSONB | flexible permissions object |
|
||||
| `created_at` | TIMESTAMP | |
|
||||
|
||||
---
|
||||
|
||||
## Backend (`/backend`)
|
||||
|
||||
### Public routes (port 3000)
|
||||
- `POST /api/shared/customer/anonymous` — create anonymous customer with display name
|
||||
- `POST /api/shared/customer/link` — link phone/social to existing anonymous customer
|
||||
- `POST /api/client/auth/verify` — verify Firebase JWT, return customer profile
|
||||
- `POST /api/mitra/auth/verify` — verify Firebase JWT, return mitra profile
|
||||
|
||||
### Internal routes (port 3001)
|
||||
- `POST /internal/mitras` — create mitra record
|
||||
- `PATCH /internal/mitras/:id/status` — activate/deactivate mitra
|
||||
- `POST /internal/control-center-users` — create control center user
|
||||
- `GET /internal/control-center-users` — list users
|
||||
- `POST /internal/auth/verify` — verify Firebase JWT, return CC user + role + permissions
|
||||
- `GET /internal/config/anonymity` — get anonymity setting
|
||||
- `PATCH /internal/config/anonymity` — toggle anonymity on/off
|
||||
|
||||
---
|
||||
|
||||
## client_app (`/client_app`)
|
||||
|
||||
**Screens:**
|
||||
1. **Welcome** — "Continue as Guest" or "Register"
|
||||
2. **Pick Display Name** — shown to all users (anonymous and registering)
|
||||
3. **Register** — phone OTP or social login (Google/Apple)
|
||||
4. **Force Register Wall** — shown after session ends if anonymity is disabled; display name pre-filled
|
||||
|
||||
**Firebase Auth flows:**
|
||||
- Phone OTP via `firebase_auth`
|
||||
- Google Sign-In via `google_sign_in`
|
||||
- Apple Sign-In via `sign_in_with_apple`
|
||||
|
||||
---
|
||||
|
||||
## mitra_app (`/mitra_app`)
|
||||
|
||||
**Screens:**
|
||||
1. **Login** — phone number input
|
||||
2. **OTP Verification**
|
||||
3. **Home** (post-login, Phase 1 placeholder)
|
||||
|
||||
**Notes:**
|
||||
- No self-register screen — login only
|
||||
- If phone not found in `mitras` table → show error "Account not found. Contact your administrator."
|
||||
- If mitra `is_active = false` → show error "Account is inactive. Contact your administrator."
|
||||
|
||||
---
|
||||
|
||||
## control_center (`/control_center`)
|
||||
|
||||
**Screens:**
|
||||
1. **Login** — email + password (Firebase Auth)
|
||||
2. **Mitra Management** — create mitra, toggle active/inactive
|
||||
3. **Control Center User Management** — create users, assign roles
|
||||
4. **Settings** — toggle anonymity on/off
|
||||
|
||||
---
|
||||
|
||||
## Seed Script
|
||||
- Creates first `super_admin` role with full permissions
|
||||
- Creates first control center user (email + password via Firebase Auth + DB record)
|
||||
|
||||
---
|
||||
|
||||
## Out of Scope for Phase 1
|
||||
- Mitra onboarding flow (documents, verification)
|
||||
- Chat / session features
|
||||
- Payment / trial period
|
||||
- Real-time features
|
||||
- Specific role definitions (RBAC scaffolded, roles defined later)
|
||||
Reference in New Issue
Block a user