meme-backend / docs /ARCHITECTURE.md
shaileshrv1432's picture
Upload 59 files
2247b5f verified
|
Raw
History Blame Contribute Delete
5.77 kB
# Architecture
## Overview
Meme Jockey is a two-part system: a **FastAPI** backend that does image/GIF
processing + auth + storage, and a **React Native** mobile app.
```
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” HTTPS / JSON Β· form-encoded β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Mobile app (RN) β”‚ ───────────────────────────────────────▢ β”‚ FastAPI backend β”‚
β”‚ Android (0.80) β”‚ Bearer JWT on every protected call β”‚ (Hugging Face Space, β”‚
β”‚ β”‚ ◀─────────────────────────────────────── β”‚ Docker, port 8000) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β–Ό β–Ό β–Ό β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ PostgreSQL β”‚ β”‚ Object store β”‚ β”‚ OpenAI β”‚ β”‚ Giphy β”‚
β”‚ (Neon) β”‚ β”‚ (Backblaze β”‚ β”‚ (captions)β”‚ β”‚ (GIF search)β”‚
β”‚ users, β”‚ β”‚ B2 / MinIO) β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚ otps, β”‚ β”‚ uploads + β”‚
β”‚ media, β”‚ β”‚ generated β”‚
β”‚ subs β”‚ β”‚ memes β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
```
## Backend layout (`backend/`)
| Path | Responsibility |
|---|---|
| `main.py` | App wiring, middleware, meme/media/profile/admin endpoints |
| `routers/auth.py` | OTP, PIN, refresh, Google login, profile (`/auth/*`) |
| `routers/subscriptions.py` | Razorpay order/verify/status, receipts, history, PDF, config-check (`/subscriptions/*`) |
| `utils/receipt.py` | Renders a payment receipt as a PDF (Pillow-only) |
| `auth/security.py` | JWT mint/verify, phone normalize, hashing, guest config |
| `auth/deps.py` | `current_user_id` dependency (Bearer β†’ user id) |
| `auth/sms_provider.py`, `utils/sms_fast2sms.py` | OTP delivery (Fast2SMS, or log) |
| `utils/ai_overlay.py` | OpenAI suggestions + Giphy/Tenor search |
| `utils/storage_minio.py` | S3-compatible put/get/presign |
| `db/postgres_client.py` | All DB access (asyncpg + SQLAlchemy), per-request session |
| `db/database.py` | Engine/driver selection from env |
| `db/models.py` | SQLAlchemy models (users, otps, media_assets, …) |
| `db/init.sql` | Schema bootstrap (run in Neon SQL editor) |
> `db/supabase_client.py` is legacy/unused β€” the app uses `postgres_client`.
## Data model (key tables)
- **users** β€” `id`, `phone_e164` (unique key; Google users keyed `google:<sub>`),
`name`, `email`, `avatar_url`, `pin_hash`, `is_active`, `is_guest`,
`account_type`, and subscription fields: `subscription_plan` (default `free`),
`subscription_status` (default `inactive`), `subscription_expires_at`.
- **otps** β€” hashed OTPs with `expires_at` / `consumed`.
- **media_assets** β€” `object_key`, `content_type`, `kind` (`upload` | `meme`), owner.
- **memes** — links input→output assets + `format`; drives daily-quota counts.
- **payments** β€” one row per successful Razorpay payment (`plan`, `amount` paise,
`currency`, `status`, `method`, `razorpay_order_id`, `razorpay_payment_id`,
`expires_at`). Powers the receipt PDF and transaction history.
## Request auth flow
1. App calls `/auth/request-otp` β†’ `/auth/verify-otp` β†’ gets `access` + `refresh`.
2. App stores tokens; an axios interceptor adds `Authorization: Bearer <access>`.
3. On `401`, the interceptor calls `/auth/refresh` once and retries; if that
fails, the session-expired handler logs the user out.
4. Returning users can `/auth/set-pin` then `/auth/login-pin` to skip OTP.
5. Guests (`GUEST_MODE_ENABLED`) get a short-lived guest session and skip PIN.
## Meme generation flow
1. `POST /upload` (image) β†’ stored in object storage + initial suggestions.
2. App opens the editor; user places GIF/image overlays.
3. `POST /compose/layout` with the JSON layout β†’ server renders the meme,
stores it (`kind=meme`), returns `object_key` + URL.
4. `GET /memes` lists creations; `GET /memes/{object_key}` serves them via a
permanent cached proxy URL.
## Deployment
- **Backend** β†’ Hugging Face Space (Docker, `app_port: 8000`). Push to the Space
repo to rebuild. Secrets/Variables set in Space settings.
- **Database** β†’ Neon (run `db/init.sql` once; re-run after schema changes β€” it's
idempotent `add column if not exists`).
- **Object storage** β†’ Backblaze B2 (S3-compatible) with a bucket-scoped
Read+Write app key.
- See [DEPLOYMENT.md](../DEPLOYMENT.md) and [ACCOUNTS_AND_SERVICES.md](ACCOUNTS_AND_SERVICES.md).