Backend API service for Armonía del Ser—a holistic therapy, meditation, and personal growth center founded by Jasmin in Mexico.
Built with FastAPI and Turso (libSQL) to serve as the operational source of truth between Google Calendar, Turso, and the Admin Dashboard (armonia-dashboard) protected with a server-side allowlist for Google OAuth.
[Clients / Landing UI] [Admin Dashboard (Jasmin & Assistant)]
│ │ (Google OAuth + Turso Allowlist)
▼ ▼
┌──────────────────────────────────────────────────────────┐
│ FastAPI Core Service │
│ - Separated Booking & Payment State Engine │
│ - 48-Hour Payment Follow-Up Queue & Delayed Exceptions │
│ - Deliberate Slot Release & Audit Trail │
│ - Google OAuth2 + Turso Allowlist Guard │
└──────────────┬─────────────────────────────┬─────────────┘
│ │
▼ ▼
[Turso Database] [Google Calendar API]
(SQLite / libSQL at edge) (Schedule coordination &
recoverable sync health)
- Separated Booking & Payment States:
booking_status(RESERVED,RELEASED,CANCELLED,COMPLETED,NO_SHOW) is modeled orthogonally frompayment_arrangement(PREPAID_DEFAULT,DELAYED_ALLOWED,PACKAGE_REDEEMED) andpayment_status(AWAITING_ACKNOWLEDGMENT,ACKNOWLEDGED,NOT_APPLICABLE).
- Prepayment by Default, Explicit Delayed-Payment Exceptions:
- Most bookings require prepayment (
PREPAID_DEFAULT). Authorized administrators can explicitly authorize a delayed-payment exception (DELAYED_ALLOWED), keepingpayment_status = 'AWAITING_ACKNOWLEDGMENT'until payment is actually settled.
- Most bookings require prepayment (
- Deliberate Slot Release & 48-Hour Follow-Up Visibility:
- Bookings never expire automatically on a timer. At 48 hours prior to a session, unacknowledged bookings appear in
GET /bookings/follow-up-queueso the assistant can manually follow up via WhatsApp and either acknowledge payment, authorize delayed payment, or deliberately release the slot (RELEASED).
- Bookings never expire automatically on a timer. At 48 hours prior to a session, unacknowledged bookings appear in
- Google OAuth + Turso Allowlist:
- Administrative endpoints verify the caller's Google OAuth session against Turso's
admin_allowlisttable on every request and record all mutations inadmin_audit_log.
- Administrative endpoints verify the caller's Google OAuth session against Turso's
- Zero-Cost Infrastructure:
- Runs containerized on Google Cloud Run free tier (scale-to-zero, $0/month).
- Data stored in Turso free tier, with local fallback to file-based SQLite (
file:local.db).
| Entity | Purpose |
|---|---|
admin_allowlist |
Authorized administrator emails (OWNER, ASSISTANT, ADMIN), active status, and last login timestamp. |
services |
Catalog of offerings (Círculos de Cacao, Meditaciones, Constelaciones, Psicoterapia), format (ONLINE / PRESENCIAL), type (GROUP / INDIVIDUAL), capacity, mandatory buffer, and price in MXN. |
clients |
Client directory (name, phone / WhatsApp, email, notes). |
bookings |
Appointments tracking booking_status, payment_arrangement, payment_status, folio (ADS-XXXX), exception/release/acknowledgment audit metadata, and Google Calendar sync health. |
payments |
Audit record of SPEI/OXXO/cash payment acknowledgment (acknowledged_by, acknowledged_at, notes). |
admin_audit_log |
Immutable log of administrative actions (ACKNOWLEDGE_PAYMENT, AUTHORIZE_DELAYED_PAYMENT, RELEASE_BOOKING, etc.). |
- Python 3.13+
uv
cp .env.example .envBy default, .env uses DATABASE_URL=file:local.db for zero-configuration local SQLite testing.
uv syncuv run python -m app.db.init_dbuv run uvicorn app.main:app --reload --port 8000Interactive API docs are available at http://localhost:8000/docs.
All changes must pass local verification before proposing commits:
uv run ruff format --check .
uv run ruff check .
uv run pyright
uv run pytest