Skip to main content

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.

Python3.12 (python:3.12-slim image)
SettingsEMAW_BACKEND/settings/{base,development,production,test}.py
URL rootEMAW_BACKEND/urls.py
Celery appEMAW_BACKEND/celery.py
Testspytest + pytest-django, pytest.ini, root conftest.py
Repo docsCLAUDE.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.

AppPurposeModels (main)Own README
EMAWCore 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 historyBook, Week, Question, QuietTime, QuietTimeEntry, Answer, UserProgress, Collection, MemoryVerse, UserMemoryVerse, VerificationCode, SocialIdentity, AppHandoffCode, UserUsageCLAUDE.md
eventsPublic 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, attendanceEvent, EventSeries, TicketType, Registration, RegistrationGuest, GoogleAccount, MeetSpace, MeetParticipantevents/README.md
storeGuest-checkout book store replacing UltraCart: catalogue, orders, dynamic shipping, inventory, warehouse hand-off, staff orders/inventory/analytics APIProduct, Order, OrderItem, OrderShipment, InventoryLevel, InventorySnapshot, WarehouseOrder, WarehouseOrderLine, FulfillmentShipment, ShippingRate, ShippingRegionFactorstore/README.md
donationsOne-time and recurring gifts via Stripe Checkout / Subscriptions, card + ACH, cover-the-fee, billing portal, receiptsDonationFund, Donation, DonationPaymentdonations/README.md
paymentsShared Stripe client and the single webhook endpoint that dispatches to events, store and donationsnonepayments/README.md
shippingRate quoting: box packing, UPS and USPS clients, flat fallbacknoneshipping/README.md
deposcoDeposco 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
resourcesWebsite resource library (articles, devotionals, audio, video, documents) with media in Cloudflare R2; public API and staff CRUDResourceresources/README.md
biblesMetadata and endpoints for the downloadable per-version SQLite Bibles (manifest, chapters, search, compare, download)BibleVersion, BibleBuild
notesBible reader annotations storing references only: highlights, notes, tagsHighlight, Note, Tag, TaggedVerse
bible_searchMeaning-based verse search and "similar verses": OpenAI embeddings + Qdrantnoneqdrant_storage/README.md
aiLLM verse finder and a moderation helpernone
crmContacts (system of record for people, replacing Planning Center), groups, tags, roles, regions and areas, notes, activities, geocoding, geo targeting, PCO importers, capability-based staff accessContact, ContactGroup, ContactTag, MembershipRole, Region, Area, NoteCategory, ContactNote, ContactActivity, SavedRegion, PcoImportRun, PcoImportError, GeographyAssignRuncrm/README.md
campaignsMarketing email via Azure Communication Services: templates with visual designs, AI drafts, audience builder, batched send pipeline, reporting, unsubscribe, Event Grid webhooksEmailTemplate, Campaign, CampaignRecipient, AiTemplateDraft, EmailImagecampaigns/README.md

Third-party apps: rest_framework, rest_framework_simplejwt (+ token_blacklist), storages, corsheaders.

note

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​

ModuleUse
base.pyEverything shared: apps, DRF, JWT, Celery, caches, storages, logging, env-driven feature config, CELERY_BEAT_SCHEDULE, origin lists
development.pyDEBUG=True, Postgres from env, localhost CORS, lower log level, REDIS_URL default redis://localhost:6379/0
production.pyDEBUG=False, Postgres with sslmode=require, hard-coded ALLOWED_HOSTS, SSL redirect and secure cookies, JSON-only renderer, AI search on
test.pydevelopment minus external services: locmem cache and email, eager Celery, TEST_DB_* overrides. Used by pytest.
local_verify.pyThrowaway 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 set AllowAny. Throttle scopes are in EMAW/throttles.py, rates in REST_FRAMEWORK["DEFAULT_THROTTLE_RATES"].
  • Staff access is capability based. Use CrmAccessViewMixin / HasCrmAccess("<capability>") and scope_contacts(); see Authentication.
  • One logging config built by EMAW_BACKEND/logging_utils.py. RequestLoggingMiddleware sets X-Request-ID. Log user ids, never emails, tokens, codes or bodies. Use %s formatting 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.