Backend overview
emaw-django-app is a Django 5 / Django REST Framework project that serves every EMAW client under one /rest/ prefix. It also runs Celery for background work and ships as a Docker Compose stack.
| Python | 3.12 (python:3.12-slim image) |
| Settings | EMAW_BACKEND/settings/{base,development,production,test}.py |
| URL root | EMAW_BACKEND/urls.py |
| Celery app | EMAW_BACKEND/celery.py |
| Tests | pytest + pytest-django, pytest.ini, root conftest.py |
| Repo docs | CLAUDE.md (architecture, every env var), ONBOARDING.md (machine setup), docs/, one README.md per app |
The apps
Fourteen local Django apps. The first is the original mobile-app backend; the rest were added for the website, store, events and CRM.
| App | Purpose | Models (main) | Own README |
|---|---|---|---|
EMAW | Core app API: auth (JWT, signup, verification, password reset, Google sign-in, app hand-off), curriculum (books, weeks, questions, quiet times, progress), memory verses and collections with TTS and recitation analysis, legacy Bible tables, analytics, contact form, website account history | Book, Week, Question, QuietTime, QuietTimeEntry, Answer, UserProgress, Collection, MemoryVerse, UserMemoryVerse, VerificationCode, SocialIdentity, AppHandoffCode, UserUsage | CLAUDE.md |
events | Public event catalogue and group registration (buyer + guests, ticket tiers, free or Stripe-paid, capacity guard); staff API with check-in, CSV export, recurring series; Google Meet rooms, invites, recordings, attendance | Event, EventSeries, TicketType, Registration, RegistrationGuest, GoogleAccount, MeetSpace, MeetParticipant | events/README.md |
store | Guest-checkout book store replacing UltraCart: catalogue, orders, dynamic shipping, inventory, warehouse hand-off, staff orders/inventory/analytics API | Product, Order, OrderItem, OrderShipment, InventoryLevel, InventorySnapshot, WarehouseOrder, WarehouseOrderLine, FulfillmentShipment, ShippingRate, ShippingRegionFactor | store/README.md |
donations | One-time and recurring gifts via Stripe Checkout / Subscriptions, card + ACH, cover-the-fee, billing portal, receipts | DonationFund, Donation, DonationPayment | donations/README.md |
payments | Shared Stripe client and the single webhook endpoint that dispatches to events, store and donations | none | payments/README.md |
shipping | Rate quoting: box packing, UPS and USPS clients, flat fallback | none | shipping/README.md |
deposco | Deposco WMS integration: submit paid orders, poll shipments and tracking, sync inventory and all-channel order history (Celery beat) | none (writes store models) | deposco/README.md |
resources | Website resource library (articles, devotionals, audio, video, documents) with media in Cloudflare R2; public API and staff CRUD | Resource | resources/README.md |
bibles | Metadata and endpoints for the downloadable per-version SQLite Bibles (manifest, chapters, search, compare, download) | BibleVersion, BibleBuild | |
notes | Bible reader annotations storing references only: highlights, notes, tags | Highlight, Note, Tag, TaggedVerse | |
bible_search | Meaning-based verse search and "similar verses": OpenAI embeddings + Qdrant | none | qdrant_storage/README.md |
ai | LLM verse finder and a moderation helper | none | |
crm | Contacts (system of record for people, replacing Planning Center), groups, tags, roles, regions and areas, notes, activities, geocoding, geo targeting, PCO importers, capability-based staff access | Contact, ContactGroup, ContactTag, MembershipRole, Region, Area, NoteCategory, ContactNote, ContactActivity, SavedRegion, PcoImportRun, PcoImportError, GeographyAssignRun | crm/README.md |
campaigns | Marketing email via Azure Communication Services: templates with visual designs, AI drafts, audience builder, batched send pipeline, reporting, unsubscribe, Event Grid webhooks | EmailTemplate, Campaign, CampaignRecipient, AiTemplateDraft, EmailImage | campaigns/README.md |
Third-party apps: rest_framework, rest_framework_simplejwt (+ token_blacklist), storages, corsheaders.
questions is not an app; curriculum questions live in EMAW/models/curriculum.py. embeddings/ is a data directory for the downloaded parquet file, not an app. qdrant_storage/ holds only a README.
How the pieces fit
Commerce apps never write to the CRM before payment; a Celery task links the buyer afterwards.
Settings modules
| Module | Use |
|---|---|
base.py | Everything shared: apps, DRF, JWT, Celery, caches, storages, logging, env-driven feature config, CELERY_BEAT_SCHEDULE, origin lists |
development.py | DEBUG=True, Postgres from env, localhost CORS, lower log level, REDIS_URL default redis://localhost:6379/0 |
production.py | DEBUG=False, Postgres with sslmode=require, hard-coded ALLOWED_HOSTS, SSL redirect and secure cookies, JSON-only renderer, AI search on |
test.py | development minus external services: locmem cache and email, eager Celery, TEST_DB_* overrides. Used by pytest. |
local_verify.py | Throwaway sqlite settings for the root verify_*.py scripts |
manage.py, wsgi.py and celery.py default to development; set DJANGO_SETTINGS_MODULE=EMAW_BACKEND.settings.production in production.
Conventions that every change must respect
- Deny by default.
DEFAULT_PERMISSION_CLASSES = IsAuthenticated. Public views setAllowAny. Throttle scopes are inEMAW/throttles.py, rates inREST_FRAMEWORK["DEFAULT_THROTTLE_RATES"]. - Staff access is capability based. Use
CrmAccessViewMixin/HasCrmAccess("<capability>")andscope_contacts(); see Authentication. - One logging config built by
EMAW_BACKEND/logging_utils.py.RequestLoggingMiddlewaresetsX-Request-ID. Log user ids, never emails, tokens, codes or bodies. Use%sformatting in log calls. - Tests ship with the ticket in
<app>/tests/test_*.py, factories in<app>/tests/factories.py. - Use the venv's Python (
.venv\Scripts\python.exe) for every command; the system Python may have a different Django.