# 🚀 AUTONOMOUS BUILD PROMPT — Fenesta GBP Dashboard
**Last Updated**: April 27, 2026 | 12:52 PM (IST)

> **Copy everything below this line and paste it as the FIRST message to Gemini Flash.**
> **No further input from you is needed until Flash finishes Phase 5.**

---

## YOUR MISSION

You are building the **Fenesta GBP Dealer Dashboard** — an agency-grade SaaS tool with a 3-tier hierarchy (Agency → Client → Dealer) for monitoring Google Business Profile data. You will build Phases 0 through 5 **completely autonomously** using mock data. Do NOT stop to ask questions — all answers are in the reference files.

---

## STEP 1: READ THESE FILES (IN THIS EXACT ORDER)

Before writing ANY code, read and internalize these files from the project root. They are your complete source of truth:

| Order | File | What You Get From It |
| --- | --- | --- |
| 1 | `human_inputs.md` | All config values (DB creds, emails, secrets). Use defaults for blank fields. |
| 2 | `architecture.md` | Database schema (exact SQL), API endpoints, role permissions, tech stack. |
| 3 | `gemini_flash_execution_guide.md` | Step-by-step code blocks, exact file paths, validation commands. |
| 4 | `flash_build_roadmap.md` | Phase overview, mock data strategy, what's deferred to later. |

**Last Updated**: April 27, 2026 | 12:52 PM (IST)

**Do NOT read** `roadmap.md`, `google_login_guide.md`, or `gmb_codebase_analysis.md` — those are human reference docs, not build instructions.

---

## STEP 2: USE THESE DEFAULT VALUES

The `human_inputs.md` file has some blank fields. Use these hardcoded defaults and **keep building**:

```text
DB_NAME       = fenesta_db
DB_USER       = postgres
DB_PASSWORD   = hnny1436
DB_HOST       = 127.0.0.1
DB_PORT       = 5432
JWT_SECRET    = xK9mP2qL7vR4tY8wN3bJ6hF1cA5dG0eZ9sU2iO7pM4kR8nQ1wX5vB3jH6fT0yL2
USE_MOCK_DATA = true

ADMIN_EMAIL      = admin@hashtagorang.in
ADMIN_NAME       = HO Admin
ADMIN_PASSWORD   = Admin@123

CLIENT_NAME      = Fenesta
CLIENT_EMAIL     = fenesta@example.com

GOOGLE_CLIENT_ID     = (leave blank)
GOOGLE_CLIENT_SECRET = (leave blank)
```

### Mock Dealer Data (seed these in Phase 4)

| # | Dealer Name | City | State | Email | Location ID |
| --- | --- | --- | --- | --- | --- |
| 1 | Fenesta Dealer Gurugram | Gurugram | Haryana | `dealer.gurugram@fenesta.com` | mock-location-001 |
| 2 | Fenesta Dealer Noida | Noida | Uttar Pradesh | `dealer.noida@fenesta.com` | mock-location-002 |
| 3 | Fenesta Dealer Jaipur | Jaipur | Rajasthan | `dealer.jaipur@fenesta.com` | mock-location-003 |

All mock dealer passwords: `Dealer@123` (forced to change on first login).

---

## STEP 3: EXECUTION METHOD

### How to Work

1. **Read before editing** — ALWAYS read a file's current contents before modifying it
2. **One phase at a time** — complete every step in a phase before starting the next
3. **Validate after each phase** — run the validation check listed at the end of each phase
4. **Never ask for input** — use the defaults above for any blank field
5. **Keep mock data working** — the `USE_MOCK_DATA=true` path must work at all times
6. **Use existing tools** — the project already uses `pg8000`, `FastAPI`, `Uvicorn`, `Chart.js`, `TailwindCSS CDN`

### Codebase You're Starting With

```text
GMB/
├── backend/
│   ├── .env                    ← DB credentials (keep, extend)
│   ├── requirements.txt       ← Dependencies (replace with expanded list)
│   ├── venv/                   ← Python virtual env (don't touch)
│   └── app/
│       ├── __init__.py
│       ├── database.py         ← DB connection via pg8000 (refactor)
│       ├── google_api.py       ← Mock metrics (move to google/mock_api.py)
│       ├── routes.py           ← EMPTY file (delete)
│       └── server.py           ← Old FastAPI app (replace with main.py)
├── frontend/
│   ├── index.html              ← Login + Dashboard SPA (rebuild)
│   ├── app.js                  ← Client JS (rebuild)
│   └── style.css               ← Empty (keep using TailwindCSS CDN)
├── client_secret.json          ← Empty placeholder (ignore)
└── Postgre.txt                 ← Reference note (ignore)
```

### Target Structure After Phase 0

```text
backend/app/
├── main.py               ← FastAPI entry point with CORS + router mounts
├── config.py             ← Settings from .env with defaults
├── models.py             ← Pydantic request/response models
├── database.py           ← Refactored DB connection (same pg8000)
├── auth/
│   ├── __init__.py
│   ├── routes.py         ← Login + change-password endpoints
│   ├── jwt_handler.py    ← Token create/verify (PyJWT + HS256)
│   └── google_oauth.py   ← STUB — auto-activates when creds provided later
├── agency/
│   ├── __init__.py
│   └── routes.py         ← Client CRUD (role=agency only)
├── client/
│   ├── __init__.py
│   └── routes.py         ← Dealer CRUD + cumulative dashboard
├── dealer/
│   ├── __init__.py
│   └── routes.py         ← Own dashboard + posting
├── google/
│   ├── __init__.py
│   ├── mock_api.py       ← Moved from google_api.py + direction_clicks added
│   ├── gbp_api.py        ← STUB for real API (activated later)
│   └── sync.py           ← STUB for metric sync (activated later)
└── middleware/
    ├── __init__.py
    └── auth.py           ← JWT verification + role checker
```

---

## STEP 4: BUILD PHASES (Execute In Order)

### PHASE 0 — Cleanup & Restructure

1. **Clean V1 code**: Remove commented-out V1 blocks from `frontend/index.html` (lines 1–85) and `frontend/app.js` (lines 1–63). Active code starts after these blocks.
2. **Create folder structure**: Build the target structure shown above with empty `__init__.py` files.
3. **Create `config.py`**: Load all `.env` values with sensible defaults. Include `USE_MOCK_DATA`, `JWT_SECRET`, `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET`.
4. **Update `.env`**: Add `JWT_SECRET`, `USE_MOCK_DATA=true`, blank Google fields. Keep existing DB vars.
5. **Create `main.py`**: FastAPI app with CORS + mount auth, agency, client, dealer routers. Add `/api/health` endpoint.
6. **Update `requirements.txt`**: Add `PyJWT`, `bcrypt`, `authlib`, `httpx`, `google-api-python-client`, `google-auth`, `google-auth-oauthlib`, `python-multipart`, `email-validator`.
7. **Move mock data**: Copy `google_api.py` contents → `google/mock_api.py`. ADD `direction_clicks: random.randint(80, 350)` to the metrics dict.
8. **Delete old files**: Remove `server.py`, `google_api.py` (original), `routes.py` (empty).
9. **Run**: `pip install -r requirements.txt`

**✅ Validate**: `uvicorn app.main:app --reload` starts clean. `GET /api/health` → `{"status":"ok"}`

---

### PHASE 1 — Database Schema & Seed

1. **Create `backend/schema.sql`**: The 4-table schema is defined exactly in `architecture.md` Section 5. Use it verbatim. Tables: `users`, `clients`, `dealers`, `metrics_cache`. All metric columns including `direction_clicks`.
2. **Run schema**: Execute the SQL against `fenesta_db`. Connect using the DB credentials from `.env`. If the existing `dealers` table conflicts, DROP it (the old one used plaintext passwords — it's being replaced).
3. **Create `backend/seed.py`**: Seed the agency admin:
   - Email: `admin@hashtagorang.in`
   - Password: `Admin@123` (bcrypt hashed, NOT plaintext)
   - Role: `agency`
   - `is_first_login: true`
4. **Run seed**: Execute seed.py.

**✅ Validate**: `SELECT email, role, is_first_login FROM users` → 1 row: agency admin with `is_first_login=true`.

---

### PHASE 2 — Authentication System

1. **JWT Handler** (`auth/jwt_handler.py`): `create_token(user_id, email, role)` → JWT string. `verify_token(token)` → payload or None. Use `HS256`, expire 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_password + new_password → hash → update DB → set is_first_login=false
4. **Google OAuth Stub** (`auth/google_oauth.py`):
   - `GET /api/auth/google` — if `GOOGLE_CLIENT_ID` is empty → return `{"detail": "Google login not configured. Use email + password."}`
   - If set → redirect to Google consent. This is a **working stub** — it activates automatically when credentials are provided later. No code changes needed.
   - `GET /api/auth/google/callback` — exchange code → check user exists → issue JWT
5. **Frontend Login Page**: Rebuild `frontend/index.html` as a single-page app:
   - Single unified login form (email + password) for ALL roles
   - "Sign in with Google" button (shows friendly message if not configured)
   - On success: store JWT in `localStorage`, detect role from JWT payload, route to correct dashboard
   - If `is_first_login=true` → show password change form FIRST
   - Logout → clear localStorage, show login
   - **Design**: Use TailwindCSS CDN for styling. Make it look professional — dark theme, gradient accents, clean card layout.

**✅ Validate**: Login with `admin@hashtagorang.in` / `Admin@123` → forced password change → after changing, see empty agency dashboard.

---

### PHASE 3 — Agency Dashboard

1. **Agency Routes** (`agency/routes.py`):
   - `GET /api/agency/clients` — requires role=agency, returns list of clients joined with user data + dealer count
   - `POST /api/agency/clients` — creates `users` row (role=client) + `clients` row. Generates temp password with `secrets.token_urlsafe(8)`. Returns the temp password in the response.
   - `DELETE /api/agency/clients/{id}` — soft delete (set `is_active=false` on both user and client records)
2. **Agency Frontend View**:
   - Client table: Name | Email | # Dealers | Status | Actions
   - "Add Client" button → modal with: Client Name, Email, GBP Account ID (optional)
   - After creation: show temp password in a success toast/modal so agency can share it
   - Edit/Deactivate buttons per row
3. **Auto-seed Fenesta**: After the agency frontend works, programmatically add the Fenesta client:
   - Name: `Fenesta`, Email: `fenesta@example.com`
   - Or let the user add it via the UI — either way, it should be in the DB at the end of Phase 3.

**✅ Validate**: Login as agency → See "Add Client" button → Add "Fenesta" → See it in the table → Copy temp password → Log out → Log in as Fenesta with temp password → Forced password change.

---

### PHASE 4 — Client Dashboard

1. **Client Routes** (`client/routes.py`):
   - `GET /api/client/dealers` — list dealers for THIS client only (filter by client_id from JWT)
   - `POST /api/client/dealers` — 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 this client's 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 verify** the dealer belongs to this client!
2. **Mock Data Integration**: When `USE_MOCK_DATA=true`, all metric endpoints call `get_mock_google_metrics()` from `google/mock_api.py`. Each dealer gets independently randomized mock data.
3. **Client Frontend View**:
   - **Tab 1 — Overview**: 7 KPI cards (Views, Search, Maps, Website, Calls, **Direction Clicks**, Rating) + 6-month trend chart (Chart.js)
   - **Tab 2 — Dealers**: Table with mini-metrics per dealer. Click a dealer row to drill down.
   - **Tab 3 — Manage**: Add/edit/deactivate dealers form
4. **Auto-seed 3 test dealers** under Fenesta using the mock dealer data table from Step 2 above.

**✅ Validate**: Login as Fenesta → See 3 dealers → Cumulative dashboard shows aggregated numbers → Click a dealer → See individual metrics → Direction Clicks KPI visible.

---

### PHASE 5 — Dealer Dashboard (Refactor)

1. **Dealer Routes** (`dealer/routes.py`):
   - `GET /api/dealer/dashboard` — fetches metrics for THIS dealer's location_id only (from JWT user_id → dealers table lookup)
   - `POST /api/dealer/post` — accepts post content, logs to console (mock). Returns success.
2. **Dealer Frontend View**:
   - **7 KPI cards**: Views, Search Impressions, Map Views, Website Clicks, Calls, **Direction Clicks** (teal/cyan accent), Average Rating
   - 6-month trend chart (Chart.js line chart)
   - "Create Post" button → modal to write and submit a Google Post (mock)
   - **NO access** to client/agency pages — role-based routing enforced in frontend
3. **Security Enforcement**:
   - Dealer can ONLY call `/api/dealer/*` endpoints
   - Backend verifies the `user_id` from JWT matches the dealer record
   - `/api/agency/*` and `/api/client/*` return 403 for dealer role
   - Frontend hides all non-dealer navigation

**✅ Validate**: Login as test dealer → See 7 KPIs including Direction Clicks → Cannot access `/api/agency/clients` (403) → Cannot access `/api/client/dealers` (403) → Create Post modal works.

---

## STEP 5: AFTER PHASE 5 — STOP AND REPORT

When all 5 phases are complete, output this exact message:

> **Phases 0–5 complete.** The Fenesta GBP Dashboard is fully functional with mock data.
>
> **What works:**
>
> - ✅ Agency login → manage clients
> - ✅ Client login → manage dealers + cumulative dashboard
> - ✅ Dealer login → individual dashboard with 7 KPIs (including Direction Clicks)
> - ✅ JWT auth + forced password change on first login
> - ✅ Role-based access control (agency/client/dealer)
> - ✅ Google OAuth stub (activates when credentials provided)
>
> **To connect real Google data:** Fill in Sections 6 and 7 of `human_inputs.md` and tell me to proceed with Phase 6.

**DO NOT start Phase 6 (real Google API). That requires human-provided credentials that are not available yet.**

---

## CRITICAL RULES (READ THESE LAST)

1. **ONE login page** for all roles. Do NOT create separate login pages.
2. **Passwords are ALWAYS bcrypt hashed**. NEVER store plaintext.
3. **JWT in localStorage**, attached as `Authorization: Bearer <token>` to every API call.
4. **Client can only see their OWN dealers** — always filter by `client_id` derived from JWT.
5. **Dealer can only see their OWN data** — always verify `user_id` matches the dealer record.
6. **Keep `USE_MOCK_DATA=true`** as default. Never break the mock data path.
7. **Google OAuth is a stub** — code it fully, but it auto-activates when creds are added to `.env`. Do NOT stop and ask for Google credentials.
8. **Use parameterized queries** (`%s` placeholders with pg8000). No string interpolation in SQL.
9. **Close DB connections** in `try/finally` blocks.
10. **Frontend uses TailwindCSS CDN + Chart.js CDN + Vanilla JS**. No React, no Vue, no frameworks.
11. **`direction_clicks`** must appear in: mock data function, database schema, all 3 dashboard views, and KPI cards.
12. **Cumulative rating** must be a WEIGHTED AVERAGE (weighted by `total_reviews` per dealer), not a simple average.

---

## QUICK REFERENCE: FILE → PURPOSE MAP

| File You READ | What You Get |
| --- | --- |
| `human_inputs.md` | Config values, defaults for blanks |
| `architecture.md` Section 5 | Exact SQL for all 4 tables |
| `architecture.md` Section 6 | All API endpoint contracts |
| `architecture.md` Section 2 | Role permissions matrix |
| `gemini_flash_execution_guide.md` Phase 0–5 | Exact Python code blocks |
| `flash_build_roadmap.md` | High-level phase goals + mock data strategy |

| File You WRITE | What Goes In It |
| --- | --- |
| `backend/app/config.py` | Settings class loading .env |
| `backend/app/main.py` | FastAPI app + router mounts |
| `backend/app/auth/jwt_handler.py` | create_token / verify_token |
| `backend/app/middleware/auth.py` | get_current_user / require_role |
| `backend/app/auth/routes.py` | POST /login, POST /change-password |
| `backend/app/auth/google_oauth.py` | GET /google, GET /google/callback (stub) |
| `backend/app/agency/routes.py` | Client CRUD |
| `backend/app/client/routes.py` | Dealer CRUD + cumulative dashboard |
| `backend/app/dealer/routes.py` | Own dashboard + post creation |
| `backend/app/google/mock_api.py` | Mock metrics with direction_clicks |
| `backend/schema.sql` | 4-table PostgreSQL schema |
| `backend/seed.py` | Agency admin seeder |
| `frontend/index.html` | Rebuilt SPA with all 3 dashboard views |
| `frontend/app.js` | Rebuilt JS with JWT auth + role routing |

**BEGIN. Read `human_inputs.md` first, then proceed with Phase 0.**
