# ⚙️ GMB Dashboard System Workflow

> **Last Updated**: April 27, 2026 — 4:30 PM IST

---

## 1. Data Flow Architecture

### A. Data Acquisition (Mock in Phase 5, Real in Phase 6)

1. **Trigger**: `sync_location_metrics(location_id)` is called when a dealer is created
2. **Mock Path** (`USE_MOCK_DATA=true`): `google/mock_api.py` generates randomized metrics
3. **Real Path** (Phase 6): `google/gbp_api.py` calls the Google Business Profile Performance API
4. **Storage**: All 8 metrics are stored as key-value rows in `metrics_cache` table

### B. Login & Authentication Lifecycle

```text
User → POST /api/auth/login (email + password)
     → Backend: bcrypt verify → JWT issued (24h HS256)
     → Response: { access_token, role, needs_password_change, full_name }
     → Frontend: if needs_password_change → show change-password form
               else → route to role-specific dashboard
```

### C. Request Lifecycle (Authenticated)

```text
Frontend → fetch('/api/dealer/dashboard', { Authorization: Bearer <jwt> })
         → Backend middleware: decode JWT → verify user exists + is_active
         → require_role(['dealer']): check role matches
         → Route handler: query metrics_cache by location_id
         → Response: JSON { dealer_name, location_id, metrics: {...} }
```

---

## 2. Database Design (Key-Value Metrics)

Instead of a columnar `metrics` table, this project uses a **key-value** design in `metrics_cache`:

```sql
-- Each metric is a separate row
INSERT INTO metrics_cache (location_id, metric_name, metric_value)
VALUES ('mock-location-001', 'total_views', 15234);
VALUES ('mock-location-001', 'direction_clicks', 280);
VALUES ('mock-location-001', 'average_rating', 4.7);
```

**Advantages**: No schema migration needed when adding new metrics.
**Client Cumulative**: Uses `SUM()` across all location_ids belonging to the client's dealers.
**Weighted Avg Rating**: `SUM(rating * reviews) / SUM(reviews)` across all dealers.

---

## 3. Developer Workflow

### Adding a New Metric

1. **Mock API**: Add the metric to `google/mock_api.py` → `get_mock_google_metrics()`
2. **Sync**: Already handled — `sync.py` iterates all keys in `metrics["metrics"]`
3. **Frontend**: Add a new KPI card in `index.html`, bind it in `app.js`
4. No database migration needed (key-value design)

### Adding a New Role

1. **Schema**: Update the `CHECK` constraint in `schema.sql` and `database.py`
2. **Middleware**: Add the role to the allowed list in `middleware/auth.py`
3. **Backend**: Create a new `routes.py` in a new package (e.g., `app/superadmin/`)
4. **Frontend**: Create a new container div in `index.html`, add `showDashboard` case in `app.js`
5. **Main.py**: Mount the new router

---

## 4. Technology Stack

| Layer | Technology | Purpose |
| --- | --- | --- |
| Backend | FastAPI + Uvicorn | Async API server with auto-docs (Swagger) |
| Database | PostgreSQL + pg8000 | Relational data with pure-Python driver |
| Auth | PyJWT + bcrypt | HS256 tokens + password hashing |
| Frontend | Vanilla JS + TailwindCSS CDN | No build step, instant iteration |
| Charts | Chart.js CDN | 6-month trend line charts |
| Mock Data | `google/mock_api.py` | Randomized realistic metrics |
