> ## 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.

# Backend

> Flask app, WhatsApp webhook flow, main modules, and entrypoints for the Lok Panchang API

The main backend is a **Flask** application that receives WhatsApp webhooks, manages users and location, generates panchangam data, and sends messages via the Meta Graph API. Background jobs (daily 6:30 AM sends) are handled by **Celery** and **Beat**; see [Scheduling](/scheduling) for that flow.

## High-level flow

1. **Webhook** — Meta sends POST requests to `/webhook` (e.g. `https://api.lokpanchang.com/webhook`) for every user message and status update.
2. **Verification** — GET `/webhook` with `hub.mode=subscribe` and `hub.verify_token=<token>` is used by Meta to verify the endpoint; the app responds with `hub.challenge`.
3. **Message handling** — For each incoming message, the app deduplicates by message ID, then routes by type:
   * **Text** (e.g. "start", "stop", "help") → create/update user, send reply or request location.
   * **Location** → resolve timezone and city (OpenCage + fallback), save to user, generate panchangam, send template message and confirmation.
4. **Panchangam** — Generated in-process via `generate_panchangam_with_timezone()` (see [Core Panchangam calculation](/panchangam/core-calculation)), then formatted as WhatsApp template parameters and sent using `messaging.send_panchangam_template()` or similar.
5. **Daily sends** — Celery Beat runs a JIT planner every 10 minutes; it enqueues `send_for_timezone` tasks so each user gets panchangam at 6:30 AM local time. Those tasks run in Celery workers and use the same panchangam generation and messaging code.

<Callout type="info" title="Verify token">
  Meta webhook verification uses **`VERIFY_TOKEN = "test123"`** (defined in `app.py`). When configuring the webhook in the Meta developer app, set the verify token to this value.
</Callout>

## Main modules and files

| File / folder      | Role                                                                                                                                                                                                                                                                                           |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`app.py`**       | Flask app: webhook routes (GET/POST `/webhook`), request logging, message deduplication, `get_or_create_user`, `handle_location_message`, `handle_text_message`, `generate_panchangam_with_timezone`, and many test/admin endpoints (e.g. `/test-db`, `/test/whatsapp/*`, `/send-panchang-*`). |
| **`messaging.py`** | WhatsApp API wrapper: `send_whatsapp_message` (text, respects `ENV` for mock), `send_panchangam_template`, `send_whatsapp_template_message`, `send_location_request_message`, template parameter builders. Uses `WHATSAPP_PHONE_NUMBER_ID`, `WHATSAPP_ACCESS_TOKEN`, and Meta Graph API URL.   |
| **`tasks.py`**     | Celery app, Beat schedule, and tasks: `jit_planner`, `send_for_timezone`, log backup, S3 upload, metrics, etc. Imports panchangam formatting and messaging from `app` and `messaging`.                                                                                                         |
| **`db.py`**        | Single SQLAlchemy instance (`db`) used across the app.                                                                                                                                                                                                                                         |
| **`models/`**      | SQLAlchemy models: `UserDetail`, `CityDetail`, `MessageLog`, `DailyMetrics`, `SystemHealthLog`, `ApiDetail`, `RituDetail`, `AyanamDetail`, `ApiUsageLog`. Used by `app.py`, `tasks.py`, and the admin portal. See [Database](/database).                                                       |
| **`panchangam/`**  | Panchangam calculation (Swiss Ephemeris, tithi/nakshatra/yoga/karana, day divisions). `app.py` calls into `panchangam.panchangam_main` via `generate_panchangam_with_timezone`.                                                                                                                |
| **`helpers/`**     | Geocoding (`hybrid_geocoding.py`, `city_utils.py`), timezone fallback, metrics, log collection, S3 upload, etc.                                                                                                                                                                                |

## Webhook routes

* **`GET /webhook`** — Meta subscription verification. Query params: `hub.mode`, `hub.verify_token`, `hub.challenge`. Returns `hub.challenge` with 200 if `hub.verify_token == VERIFY_TOKEN`; otherwise 403.
* **`POST /webhook`** — Receives all WhatsApp events. Only entries with `messages` are processed; status updates are skipped. For each message, deduplication is applied, then:
  * **`type == "location"`** → `handle_location_message` (timezone, city, save user, generate panchangam, send template + optional text).
  * **`type == "text"`** → `handle_text_message` ("start" → request location; "stop"/"unsubscribe" → unsubscribe; "help" → help text; etc.).
  * Other types (e.g. image) → log and optionally ask for location if user is in `awaiting_location`.

All other routes in `app.py` are for health checks, testing, or admin (e.g. `/test-db`, `/test/whatsapp/generate/<phone_number>`, `/send-panchang-user/<user_id>`). The admin portal and test routes are documented in [Admin portal](/admin-portal) and [Testing routes](/guides/testing-routes).

## Entrypoints

* **Web server** — The Flask app runs as the main process in the `web` Docker service. Default command is `flask run --host=0.0.0.0 --port=5050` (see root `Dockerfile`). In production, a WSGI server such as Gunicorn may be used behind Caddy.
* **Celery worker** — `celery -A tasks.celery worker` (see `docker-compose.yml` for the `celery` service).
* **Celery Beat** — `celery -A tasks.celery beat` (see `beat` service). Schedules `jit_planner` and other periodic tasks.

## Dependencies

* **Flask** — Web framework.
* **Flask-SQLAlchemy, Flask-Migrate** — Database and migrations.
* **Celery, Redis** — Task queue and broker.
* **requests** — HTTP calls to Meta Graph API (from `messaging.py`).
* **panchangam** — Uses `pyswisseph`, `astral`, `pytz`, and other libs (see [Core Panchangam calculation](/panchangam/core-calculation)).

For a full list, see `requirements.txt` in the repo root.
