# GMB Codebase Analysis — Fenesta GBP Dealer Dashboard

> **📋 WHY THIS FILE EXISTS**: This is a snapshot audit of the ORIGINAL prototype codebase
> before any restructuring began. It documents what was already built, what works, and what
> gaps exist. Flash and future developers use this to understand the starting point and avoid
> re-introducing patterns that were intentionally replaced. **This file is historical context
> — do NOT update it as the codebase evolves.**

## What You're Building

A **Dealer-facing Google Business Profile (GBP) Dashboard** for **Fenesta** (a window/door brand). The system lets individual Fenesta dealers:

1. **Log in** with their credentials
2. **View live GBP performance metrics** (views, impressions, clicks, calls, reviews)
3. **See a 6-month trend chart** of their profile views
4. **Create and publish Google Posts** directly from the dashboard

The product concept: **a white-labelled portal that gives each Fenesta dealer visibility into their own Google Business Profile data and the ability to post updates**, all managed centrally by Hashtag Orange as the agency.

---

## Architecture Overview

```text
Frontend (HTML/JS/TailwindCSS)  →  Backend (FastAPI/Uvicorn)  →  PostgreSQL (fenesta_db)
                                                               →  Google Business Profile API (Future)
```

| Layer | Tech | Status |
| --- | --- | --- |
| **Frontend** | HTML + TailwindCSS CDN + Chart.js + Vanilla JS | ✅ Functional (with mock data) |
| **Backend** | Python FastAPI + Uvicorn | ✅ Functional (with mock data) |
| **Database** | PostgreSQL via pg8000 | ✅ Connected (dealer auth) |
| **Google API** | Google Business Profile API | ❌ Not yet integrated (mock only) |
| **OAuth** | `client_secret.json` | ❌ Empty — placeholder for Google OAuth credentials |

---

## File-by-File Breakdown

### Root Level

| File | Purpose |
| --- | --- |
| `Postgre.txt` | Quick reference note — PostgreSQL password and port |
| `client_secret.json` | Empty — placeholder for Google OAuth2 client credentials |

---

### Backend (`/backend/`)

#### `.env`

PostgreSQL connection config:

- Database: `fenesta_db`
- User: `postgres` / Password: `hnny1436`
- Host: `127.0.0.1:5432`

#### `requirements.txt`

Dependencies: `pg8000`, `python-dotenv`, `fastapi`, `uvicorn`, `pydantic`

#### `app/database.py`

- Loads `.env` from the parent directory
- Exposes `get_connection()` → returns a `pg8000` PostgreSQL connection
- Used exclusively for dealer authentication

#### `app/server.py`

The main FastAPI application with **3 endpoints**:

| Endpoint | Method | What It Does |
| --- | --- | --- |
| `/api/login` | POST | Authenticates dealer via the `dealers` PostgreSQL table. Returns `dealer_name` + `google_location_id`. |
| `/api/dashboard/{location_id}` | GET | Returns GBP metrics for a dealer. **Currently calls mock data**, not the real Google API. |
| `/api/post` | POST | Accepts post content from the dealer. **Currently mocks** publishing to Google — just prints to console. |

> ⚠️ **Password storage is plaintext** — the login query checks `WHERE email = %s AND password = %s` directly. No hashing.

#### `app/google_api.py`

Contains `get_mock_google_metrics(location_id)` which returns randomized but realistic-looking data:

- **Metrics**: total_views, search_impressions, map_views, website_clicks, calls_made
- **Reviews**: average_rating (4.3–4.9), total_reviews (150–400)
- **Trend data**: 6 months of mock view counts for the chart

#### `app/google_api.py`

#### `app/routes.py`
Empty — all routes are currently defined directly in `server.py`.

---

### Frontend (`/frontend/`)

#### `index.html`
Two-screen SPA (Single Page Application):

1. **Login Screen** — Email/password form (pre-filled with `dealer1@fenesta.com` / `password123`)
2. **Dashboard Screen** (hidden until login) — Contains:
   - Welcome header with dealer name
   - **6 KPI cards**: Total Views, Search Impressions, Map Views, Website Clicks, Calls Made, Average Rating
   - **Trend chart**: 6-month view trend (Chart.js line chart)
   - **"Create Post" button** → opens a modal to write and publish a Google Post
   - **Logout button**

> 📝 Lines 1–85 contain a **commented-out V1** of the HTML (simpler, no chart, no post modal). The active version starts at line 92.

#### `app.js`

Client-side logic:

- **Login handler**: POSTs credentials to `/api/login`, switches to dashboard view on success
- **`fetchGoogleData()`**: GETs `/api/dashboard/{location_id}`, injects metrics into KPI cards and renders the trend chart
- **`renderChart()`**: Creates a Chart.js line chart with smooth curves and blue gradient fill
- **`openPostModal()` / `closePostModal()` / `submitPost()`**: Modal lifecycle for the Google Post feature
- **`logoutDealer()`**: Simple page reload

> 📝 Lines 1–63 contain a **commented-out V1** of the JS (simpler, no chart, no posting). The active version starts at line 70.

#### `style.css`

Empty — all styling is done via TailwindCSS CDN classes inline.

---

## Data Flow

```text
1. Dealer opens browser → Login Screen
2. POST /api/login {email, password}
   → Backend queries PostgreSQL `dealers` table
   → Returns {dealer_name, google_location_id}
3. Frontend switches to Dashboard view
4. GET /api/dashboard/{location_id}
   → Backend calls get_mock_google_metrics() (MOCK)
   → Returns {metrics, reviews, trend_data}
5. Frontend populates KPI cards + renders Chart.js trend chart
6. Dealer clicks "Create Post" → Modal opens
7. POST /api/post {location_id, content}
   → Backend logs to console (MOCK)
   → Returns success
```

---

## Database Schema (Inferred)

Based on the login query, the `dealers` table in `fenesta_db` has at minimum:

| Column | Type | Purpose |
| --- | --- | --- |
| `email` | VARCHAR | Dealer login email |
| `password` | VARCHAR | Plaintext password ⚠️ |
| `dealer_name` | VARCHAR | Display name shown on dashboard |
| `google_location_id` | VARCHAR | Maps to the dealer's Google Business Profile location |

---

## Current State & Maturity

| Feature | Status | Notes |
| --- | --- | --- |
| Dealer Authentication | ✅ Working | Against PostgreSQL, but plaintext passwords |
| Dashboard KPI Cards | ✅ Working | Populated from mock data |
| 6-Month Trend Chart | ✅ Working | Chart.js, mock data |
| Google Post Creation | ⚠️ Scaffolded | Frontend complete, backend just logs to console |
| Real Google API Integration | ❌ Not started | `client_secret.json` is empty, no OAuth flow |
| Password Hashing | ❌ Missing | Plain text comparison |
| Route Separation | ❌ Not done | `routes.py` is empty, everything in `server.py` |
| Custom CSS | ❌ Not done | `style.css` is empty, using TailwindCSS CDN |
| Error Handling | ⚠️ Basic | Minimal try/catch, no structured error responses |
| Multi-dealer Support | ⚠️ Designed for it | DB schema supports it, but only one test dealer exists |

---

## Key Issues & Gaps

### 🔴 Security
1. **Plaintext passwords** in the database — needs bcrypt/argon2 hashing
2. **No session/token management** — no JWT, no auth middleware. Any client can call `/api/dashboard/{id}` directly
3. **`client_secret.json` is empty** — Google OAuth credentials are not configured
4. **CORS is `allow_origins=["*"]`** — fine for dev, dangerous for production

### 🟡 Architecture

1. **All mock data** — zero real Google API integration yet
2. **No route separation** — `routes.py` exists but is empty, everything lives in `server.py`
3. **Commented-out V1 code** in both `index.html` (lines 1-85) and `app.js` (lines 1-63) — should be cleaned up
4. **No database migrations or schema file** — the `dealers` table structure is only inferred from queries
5. **`style.css` is empty** — entirely dependent on TailwindCSS CDN (which is not recommended for production by Tailwind themselves)

---

## Summary

This is an **early-stage prototype (MVP Phase 1)** of a dealer-facing GBP dashboard for Fenesta. The login + dashboard UI flow works end-to-end with mock data. The next major milestone would be **wiring up the real Google Business Profile API** using OAuth2 credentials to replace the mock layer, followed by security hardening (password hashing, JWT tokens) and production deployment.
