> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lokpanchang.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Admin portal

> How the admin portal works: Flask API, Next.js frontend, test routes, and admin capabilities

The **admin portal** is a separate application for managing users, viewing metrics, triggering sends, and running test routes. It is built as a **Flask** backend that exposes REST and proxy endpoints, plus a **Next.js** frontend (dashboard, user management, testing UI, log viewer). In production it runs as the **admin-portal** Docker service (port 5002) and is exposed at **admin.lokpanchang.com** via Caddy.

## Purpose

* **User management** — List users, view and edit details (phone, display name, location, timezone, subscription state). When an admin updates latitude/longitude, the backend uses the same [reverse geocoding](/geocoding/reverse-geocoding) as the main app (`get_timezone_hybrid`, `get_city_hybrid`) to fill timezone and city.
* **Metrics and insights** — Dashboard KPIs (active subscribers, new subscribers 24h, messages sent/failed today, most popular timezone), timezone distribution, activity log, geographic insights (by country/city), and system health.
* **Send actions** — Trigger panchangam sends: to all users, to a timezone, or to a single user; send a test message; unsubscribe a user.
* **Test routes** — Proxies to the main **web** service for generating/sending test WhatsApp messages (by user phone or by coordinates). Used to validate panchangam and templates without going through the WhatsApp webhook. See [Testing routes](/guides/testing-routes) for the full list and request formats.
* **Logs** — List and view log backup dates and files (Docker and application logs from the shared `/backups/logs` volume), view content and errors, and download archives.

## Stack

* **Backend:** Flask app in **`admin_portal/app.py`**. Uses the same **`db`** and **models** as the main app (same `DATABASE_URL`). Flask-Admin is mounted at **`/flask-admin`** for direct CRUD on `UserDetail`, `CityDetail`, and other models.
* **Frontend:** Next.js app in **`admin_portal/frontend/`**. Build output is served by the Flask app (static files and catch-all route for the SPA). Pages include dashboard (`app/page.tsx`), testing (`app/testing/page.tsx`), and shared components (dashboard, testing, log-viewer, log-errors, layout).
* **Deployment:** Single Docker service **admin-portal** that runs the Flask app; the app serves the built Next.js assets and proxies API and send/test requests. It needs **DATABASE\_URL** and **OPENCAGE\_API\_KEY** (for geocoding when updating user location). Test and send endpoints in the admin portal **proxy** to the main **web** service (e.g. `http://web:5050`) so the actual panchangam generation and WhatsApp sends run in the main app.

## Main API endpoints (Flask)

| Endpoint                   | Method | Purpose                                                                                                                                                                                      |
| -------------------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `/api/metrics`             | GET    | Dashboard KPIs (active subscribers, new 24h, messages today, most popular timezone, etc.).                                                                                                   |
| `/api/users`               | GET    | List all users (id, phone, display name, city, country, timezone, status, last message, etc.).                                                                                               |
| `/api/users/<id>`          | GET    | Full user details.                                                                                                                                                                           |
| `/api/users/<id>`          | PUT    | Update user (display name, lat/lon, timezone, state, city, country, subscription). Backend auto-runs geocoding when lat/lon change and can set `state` to `active` when location is present. |
| `/api/users/<id>/messages` | GET    | Message history for the user (from MessageLog).                                                                                                                                              |
| `/api/timezones`           | GET    | Timezone distribution (count per timezone).                                                                                                                                                  |
| `/api/activity-log`        | GET    | Activity log entries (e.g. recent events).                                                                                                                                                   |
| `/api/geographic-insights` | GET    | Aggregates by country and by city (user counts).                                                                                                                                             |
| `/api/system-health`       | GET    | System health metrics (from DB and/or mock).                                                                                                                                                 |
| `/api/logs/dates`          | GET    | List available log backup dates.                                                                                                                                                             |
| `/api/logs/files`          | GET    | List files for a given date.                                                                                                                                                                 |
| `/api/logs/content`        | GET    | Content of a specific log file.                                                                                                                                                              |
| `/api/logs/errors`         | GET    | Error lines from logs.                                                                                                                                                                       |
| `/api/logs/download`       | GET    | Download a log file or archive.                                                                                                                                                              |

## Send and test endpoints (proxy or direct)

These are used by the dashboard and testing UI to trigger sends or run test flows. Several **proxy** to the main web service so that generation and WhatsApp calls happen in the main app.

| Endpoint                                           | Method | Purpose                                                                  |
| -------------------------------------------------- | ------ | ------------------------------------------------------------------------ |
| `/send-panchang-all`                               | POST   | Proxy to web: send panchangam to all eligible users.                     |
| `/send-panchang-timezone/<timezone>`               | POST   | Proxy to web: send to users in that timezone.                            |
| `/send-panchang-user/<user_id>`                    | POST   | Send panchangam to a single user (may call web or run in admin context). |
| `/send-test-message/<user_id>`                     | POST   | Send a test message to the user.                                         |
| `/unsubscribe-user/<user_id>`                      | POST   | Mark user unsubscribed (set obsoleted\_on etc.).                         |
| `/api/test/whatsapp/users`                         | GET    | Proxy to web: list users for test dropdown.                              |
| `/api/test/whatsapp/generate/<phone_number>`       | GET    | Proxy to web: generate panchangam for user, save to file (no send).      |
| `/api/test/whatsapp/generate-coords`               | POST   | Proxy to web: generate from coordinates (no user required).              |
| `/api/test/whatsapp/generate-short/<phone_number>` | GET    | Proxy to web: generate short template params for user.                   |
| `/api/test/whatsapp/send/<phone_number>`           | GET    | Proxy to web: send panchangam template to that phone.                    |
| `/api/test/whatsapp/send-tst-msg/<phone_number>`   | GET    | Proxy to web: send test message.                                         |
| `/api/test/whatsapp/info`                          | GET    | Proxy to web: template/config info.                                      |
| `/api/test/country-templates`                      | GET    | Proxy to web: country-to-template mapping.                               |

Details of the **generate** and **send** test routes (request/response, file output) are in [Testing routes](/guides/testing-routes). Those routes live on the **main API** (`app.py`); the admin portal exposes them under `/api/test/...` by proxying to the web service.

## Admin capabilities (summary)

* **View** — All users, per-user details and message history, metrics, timezone and geographic breakdowns, system health, log backup dates and files.
* **Edit** — User profile and location (lat/lon, timezone, city, state, subscription). Geocoding runs automatically when coordinates change.
* **Actions** — Send panchangam to all, to a timezone, or to one user; send test message; unsubscribe user.
* **Testing** — Use the Testing page to generate messages by user or by coordinates, and optionally send test messages, without using the WhatsApp webhook. All generation and send logic runs on the main app via proxy.
* **Logs** — Browse and download Docker and application logs from the shared backup volume (see [Logging](/logging) for how backups are produced).

## Where it lives and how to run

* **Code:** **`admin_portal/`** at repo root — **`app.py`** (Flask + API + proxy), **`frontend/`** (Next.js app and components), **`Dockerfile`** (builds and runs the Flask app; frontend is built and served as static).
* **Local:** From repo root, run the stack with `docker compose up`; the admin-portal service listens on port 5002. Or run Flask and the Next.js dev server separately for development.
* **Production:** **admin.lokpanchang.com** → Caddy → admin-portal:5002 (see [Infrastructure](/infrastructure) and [Caddy](/infrastructure/caddy)).
