Skip to main content
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 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 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)

EndpointMethodPurpose
/api/metricsGETDashboard KPIs (active subscribers, new 24h, messages today, most popular timezone, etc.).
/api/usersGETList all users (id, phone, display name, city, country, timezone, status, last message, etc.).
/api/users/<id>GETFull user details.
/api/users/<id>PUTUpdate 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>/messagesGETMessage history for the user (from MessageLog).
/api/timezonesGETTimezone distribution (count per timezone).
/api/activity-logGETActivity log entries (e.g. recent events).
/api/geographic-insightsGETAggregates by country and by city (user counts).
/api/system-healthGETSystem health metrics (from DB and/or mock).
/api/logs/datesGETList available log backup dates.
/api/logs/filesGETList files for a given date.
/api/logs/contentGETContent of a specific log file.
/api/logs/errorsGETError lines from logs.
/api/logs/downloadGETDownload 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.
EndpointMethodPurpose
/send-panchang-allPOSTProxy to web: send panchangam to all eligible users.
/send-panchang-timezone/<timezone>POSTProxy to web: send to users in that timezone.
/send-panchang-user/<user_id>POSTSend panchangam to a single user (may call web or run in admin context).
/send-test-message/<user_id>POSTSend a test message to the user.
/unsubscribe-user/<user_id>POSTMark user unsubscribed (set obsoleted_on etc.).
/api/test/whatsapp/usersGETProxy to web: list users for test dropdown.
/api/test/whatsapp/generate/<phone_number>GETProxy to web: generate panchangam for user, save to file (no send).
/api/test/whatsapp/generate-coordsPOSTProxy to web: generate from coordinates (no user required).
/api/test/whatsapp/generate-short/<phone_number>GETProxy to web: generate short template params for user.
/api/test/whatsapp/send/<phone_number>GETProxy to web: send panchangam template to that phone.
/api/test/whatsapp/send-tst-msg/<phone_number>GETProxy to web: send test message.
/api/test/whatsapp/infoGETProxy to web: template/config info.
/api/test/country-templatesGETProxy to web: country-to-template mapping.
Details of the generate and send test routes (request/response, file output) are in 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 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 and Caddy).