# 🗺️ Flash Build Roadmap (Autonomous)

**Last Updated**: April 27, 2026 | 12:52 PM (IST)

> **📋 WHY THIS FILE EXISTS**: This is the MASTER roadmap you hand to Gemini Flash.
> It consolidates ALL instructions into one linear, no-questions-needed execution plan.
> Flash reads this file and builds the entire application from Phase 0 through Phase 4
> using mock data only — ZERO human intervention required after you fill in `human_inputs.md`.
> The "Add Later" section at the bottom tells YOU what to provide when you're ready for real data.

---

## Pre-Flight Checklist

Before handing this to Flash, ensure you have filled these 4 fields in `human_inputs.md`:

| # | Field | Default if Blank |
| --- | --- | --- |
| 1 | DB Password | `hnny1436` (from existing `.env`) |
| 2 | Admin Email | `admin@hashtagorang.in` |
| 3 | JWT Secret | Auto-generate with `secrets.token_urlsafe(48)` |
| 4 | Fenesta Email | `fenesta@example.com` (mock) |

> If ANY of these are blank, Flash will use the defaults above and proceed.

---

## Files Flash Must Read (In Order)

| Order | File | What Flash Gets From It |
| --- | --- | --- |
| 1 | `human_inputs.md` | All user-provided values (DB creds, emails, secrets) |
| 2 | `architecture.md` | DB schema, API endpoints, role permissions |
| 3 | `gemini_flash_execution_guide.md` | Step-by-step code blocks with validation checks |
| 4 | THIS FILE | High-level roadmap, mock data strategy, what's deferred |

---

## Build Order (Phases 0–4: Full Mock Data)

### PHASE 0: Cleanup & Restructure

**Goal**: Transform the prototype into a modular, production-ready codebase.

**Steps**:

1. **Clean commented code** — Remove V1 comment blocks from `frontend/index.html` (lines 1–85) and `frontend/app.js` (lines 1–63)
2. **Create folder structure** — Set up modular backend:

```text
backend/app/
├── main.py           ← New FastAPI entry point
├── config.py         ← Loads .env settings
├── models.py         ← Pydantic request/response models
├── database.py       ← Refactored DB connection
├── auth/
│   ├── routes.py     ← Login + change-password endpoints
│   ├── jwt_handler.py ← Token create/verify
│   └── google_oauth.py ← Stub (activated later)
├── agency/
│   └── routes.py     ← Client CRUD
├── client/
│   └── routes.py     ← Dealer CRUD + cumulative dashboard
├── dealer/
│   └── routes.py     ← Own dashboard + posting
├── google/
│   ├── mock_api.py   ← Current mock data (move here)
│   ├── gbp_api.py    ← Stub (activated later)
│   └── sync.py       ← Stub (activated later)
└── middleware/
    └── auth.py       ← JWT verification + role checking
```

1. **Create `config.py`** — Load all `.env` values with sensible defaults
2. **Update `.env`** — Add `JWT_SECRET`, `USE_MOCK_DATA=true`, blank Google fields
3. **Create `main.py`** — FastAPI app with CORS + router mounting
4. **Update `requirements.txt`** — Add PyJWT, bcrypt, authlib, httpx, google libs
5. **Move mock data** — Copy `google_api.py` → `google/mock_api.py`, add `direction_clicks`
6. **Delete old files** — Remove `server.py`, `google_api.py`, `routes.py`

**Validation**: `uvicorn app.main:app --reload` starts clean. Health check returns OK.

**Mock Data**: `direction_clicks: random.randint(80, 350)` added to mock response.

---

### PHASE 1: Database Schema & Seed

**Goal**: Set up the 4-table schema and seed the agency superuser.

**Steps**:

1. **Create `schema.sql`** — 4 tables: `users`, `clients`, `dealers`, `metrics_cache`
   - Schema is defined in `architecture.md` Section 5
   - All metric columns including `direction_clicks`

2. **Run schema** — Execute against `fenesta_db`:

```sql
-- Flash runs this via the database connection
-- Or tells user to run via pgAdmin if connection fails
```

1. **Create `seed.py`** — Seeds the agency admin:
   - Email: from `human_inputs.md` Section 2 (default: `admin@hashtagorang.in`)
   - Password: `Admin@123` (bcrypt hashed)
   - Role: `agency`
   - `is_first_login: true`

2. **Run seed** — Execute `python -m seed` from `backend/`

**Validation**: `SELECT email, role FROM users` returns 1 row.

---

### PHASE 2: Authentication System

**Goal**: Unified login for all 3 roles with JWT + forced password change.

**Steps**:

1. **JWT Handler** (`auth/jwt_handler.py`)
   - `create_token(user_id, email, role)` → JWT string
   - `verify_token(token)` → payload dict or None
   - Uses `HS256`, expires in 24 hours

2. **Auth Middleware** (`middleware/auth.py`)
   - `get_current_user()` — extracts JWT from `Authorization: Bearer` header
   - `require_role(*roles)` — returns 403 if role doesn't match

3. **Auth Routes** (`auth/routes.py`)
   - `POST /api/auth/login` — email + password → bcrypt verify → JWT + role + `is_first_login`
   - `POST /api/auth/change-password` — old + new password → update DB → set `is_first_login=false`

4. **Google OAuth Stub** (`auth/google_oauth.py`)
   - `GET /api/auth/google` — checks if `GOOGLE_CLIENT_ID` is set
   - If NOT set → returns `{"detail": "Google login not configured. Use email + password."}`
   - If set → redirects to Google consent screen
   - `GET /api/auth/google/callback` — exchanges code, checks user exists, issues JWT
   - **This is a working stub** — activates automatically when credentials are provided later

5. **Frontend Login Page** — Rebuild `frontend/index.html`:
   - Single login page for all roles
   - Email + password form
   - "Sign in with Google" button (shows helpful message if not configured)
   - On success: store JWT in `localStorage`, route by role:
     - `agency` → agency dashboard
     - `client` → client dashboard
     - `dealer` → dealer dashboard
   - If `is_first_login` → show password change form first
   - Logout → clear `localStorage`, show login

**Validation**: Login with `admin@hashtagorang.in` / `Admin@123` → forced password change → agency dashboard.

---

### PHASE 3: Agency Dashboard

**Goal**: Agency can add/manage clients. Each client gets a user account.

**Steps**:

1. **Agency Routes** (`agency/routes.py`):
   - `GET /api/agency/clients` — list all clients (requires role=agency)
   - `POST /api/agency/clients` — create client:
     - Creates `users` row (role=client) + `clients` row
     - Generates temp password: `secrets.token_urlsafe(8)`
     - Returns the temp password in the response (so agency can share it)
   - `DELETE /api/agency/clients/{id}` — soft delete (`is_active=false`)

2. **Frontend — Agency View**:
   - Client table: Name | Email | # Dealers | Status | Actions
   - "Add Client" modal: Client Name, Email, GBP Account ID (optional)
   - After creation: show temp password in a success toast/modal
   - Edit/Deactivate buttons per row

3. **Auto-seed Fenesta** — After Phase 3 code is built:
   - Create a test client "Fenesta" with email from `human_inputs.md` Section 4
   - If blank, use `fenesta@example.com`

**Validation**: Login as agency → Add "Fenesta" → See it in the table → Copy temp password.

---

### PHASE 4: Client Dashboard

**Goal**: Fenesta can manage dealers and see cumulative + individual metrics.

**Steps**:

1. **Client Routes** (`client/routes.py`):
   - `GET /api/client/dealers` — list dealers under THIS client only
   - `POST /api/client/dealers` — create dealer:
     - Creates `users` row (role=dealer) + `dealers` row
     - Generates temp password
     - Requires: `dealer_name`, `city`, `state` (optional: `google_location_id`)
   - `GET /api/client/dashboard/cumulative` — aggregate metrics across ALL dealers:
     - **SUM**: total_views, search_impressions, map_views, website_clicks, calls_made, direction_clicks
     - **WEIGHTED AVG**: average_rating (weighted by total_reviews per dealer)
     - **SUM**: total_reviews
     - **COMBINED**: trend data (sum per month across dealers)
   - `GET /api/client/dashboard/dealer/{id}` — single dealer metrics (MUST belong to this client!)

2. **Mock Data Integration**:
   - When `USE_MOCK_DATA=true`, all metric endpoints call `get_mock_google_metrics()`
   - Each dealer gets independently randomized mock data
   - Cumulative view aggregates mock data from all dealers

3. **Frontend — Client View**:
   - **Tab 1 — Overview**: 7 KPI cards (Views, Search, Maps, Website, Calls, **Directions**, Rating) + trend chart
   - **Tab 2 — Dealers**: Table with mini-metrics per dealer, click to drill down
   - **Tab 3 — Manage**: Add/edit/deactivate dealers

4. **Auto-seed 3 test dealers** (if `human_inputs.md` Section 5 is blank):

| # | Name | City | State | Location ID |
| --- | --- | --- | --- | --- |
| 1 | Fenesta Dealer Gurugram | Gurugram | Haryana | `mock-location-001` |
| 2 | Fenesta Dealer Noida | Noida | Uttar Pradesh | `mock-location-002` |
| 3 | Fenesta Dealer Jaipur | Jaipur | Rajasthan | `mock-location-003` |

**Validation**: Login as Fenesta → See 3 dealers → Cumulative dashboard shows aggregated numbers → Drill into individual dealer.

---

### PHASE 5: Dealer Dashboard (Refactor)

**Goal**: Dealers see their own data only. 7 KPI cards including Direction Clicks.

**Steps**:

1. **Dealer Routes** (`dealer/routes.py`):
   - `GET /api/dealer/dashboard` — fetches metrics for THIS dealer's location_id only
   - `POST /api/dealer/post` — mock post creation (logs to console)

2. **Frontend — Dealer View**:
   - 7 KPI cards: Views, Search, Maps, Website, Calls, **Direction Clicks** (teal/cyan border), Rating
   - Trend chart (6-month view data)
   - "Create Post" button + modal (same as existing, but with JWT auth)
   - **No access** to client/agency pages (role-based routing enforced)

3. **Security enforcement**:
   - Dealer can only call `/api/dealer/*` endpoints
   - Backend verifies `user_id` matches the dealer record
   - Frontend hides all non-dealer navigation

**Validation**: Login as test dealer → See 7 KPIs → Cannot access `/api/agency/*` (403) → Cannot access `/api/client/*` (403).

---

## STOP HERE — Everything Below Requires Human Input Later

Flash STOPS after Phase 5 and tells the user:

> *"Phases 0–5 complete. The dashboard is fully functional with mock data. To connect real Google data, fill in Sections 6 and 7 of `human_inputs.md` and tell me to proceed with Phase 6."*

---

## What You Add Later (And What Happens When You Do)

### 🟡 Google OAuth Credentials (Optional — Section 6 of `human_inputs.md`)

**When you provide**: OAuth Client ID + Secret

**What Flash does**:

1. Updates `backend/.env` with the credentials
2. The Google OAuth stub in `auth/google_oauth.py` **automatically activates** — no code changes needed
3. "Sign in with Google" button starts working

**Impact**: Users get an alternate login method. Everything else stays the same.

---

### 🟡 Real Dealer Data (Optional — Section 5 of `human_inputs.md`)

**When you provide**: Dealer names, cities, Google Location IDs

**What Flash does**:

1. Creates new `users` + `dealers` rows in the database
2. Assigns temp passwords to each dealer
3. If `USE_MOCK_DATA=true`, they still see mock data (but properly linked to their accounts)
4. If `USE_MOCK_DATA=false` and Section 7 is done, they see real Google data

**Impact**: Real dealers can log in. No architecture changes.

---

### 🔴 Google Business Profile API (Required for Real Data — Section 7 of `human_inputs.md`)

**When you provide**: Service Account JSON key + confirmed API access approval

**What Flash does**:

1. Builds `google/gbp_api.py` — real API wrapper:
   - `get_locations(account_id)` → list of locations
   - `get_performance_metrics(location_id, start, end)` → metrics dict
   - `create_post(location_id, content)` → post response
2. Builds `google/sync.py` — metric sync service:
   - Iterates all active dealers
   - Fetches real metrics from Google Performance API
   - Upserts into `metrics_cache` table
3. Sets `USE_MOCK_DATA=false` in `.env`
4. Runs first sync to populate `metrics_cache` with real data
5. All dashboard views automatically switch from mock → real (they read from `metrics_cache`)

**Impact**: Real Google data flows into every dashboard. Mock data path is preserved as fallback.

---

## File Map — What's In Each Doc

| File | Why It Exists |
| --- | --- |
| `human_inputs.md` | Single source of ALL human-provided values. Fill before building. |
| `architecture.md` | System design reference — schema, endpoints, permissions. Flash reads this for design decisions. |
| `gemini_flash_execution_guide.md` | Step-by-step code blocks with exact Python/SQL. Flash follows this for implementation. |
| `roadmap.md` | Phased development plan with timelines. For human project tracking. |
| `google_login_guide.md` | Explains both Google integrations (user login vs API data). Human reference only. |
| `gmb_codebase_analysis.md` | Audit of the existing prototype. Historical context for what was there before. |
| **THIS FILE** (`flash_build_roadmap.md`) | Master execution roadmap. The single file you hand to Flash to build everything. |

---

## Flash Execution Rules (Recap)

1. **Read `human_inputs.md` FIRST** — use filled values, default blanks
2. **Follow `gemini_flash_execution_guide.md`** for exact code blocks
3. **Reference `architecture.md`** for schema and API design
4. **USE MOCK DATA** for everything — `USE_MOCK_DATA=true` throughout
5. **NEVER stop to ask** for Google credentials — they come later
6. **VALIDATE every phase** before moving to the next
7. **Seed test data** — 1 agency admin, 1 client (Fenesta), 3 mock dealers
8. **All 3 dashboards must work** end-to-end with mock data before stopping
9. **Google OAuth is a STUB** — code it, but it activates automatically later
10. **Stop after Phase 5** — tell the user what to provide for Phase 6
