# Architecture Decision Records We record every significant architectural decision as an ADR following the [Michael Nygard format](https://cognitect.com/blog/2011/11/15/documenting-architecture-decisions): **Context → Decision → Consequences**, plus a status line. Statuses: `Proposed` → `Accepted` → (`Deprecated` | `Superseded by ADR-XXXX`). ADRs are immutable once accepted; to change course, write a new ADR that supersedes the old one. New ADRs are proposed via pull request and accepted by maintainer consensus. ## Index | ADR | Title | Status | |---|---|---| | [0001](0001-monorepo-layout.md) | Monorepo with separate backend and frontend apps | Accepted | | [0002](0002-django-backend.md) | Django 5.2 LTS + DRF over FastAPI for the backend | Accepted | | [0003](0003-nextjs-frontend.md) | Next.js + TypeScript + Tailwind + shadcn/ui for the frontend | Accepted | | [0004](0004-postgresql-primary-store.md) | PostgreSQL as the single primary datastore | Accepted | | [0005](0005-structured-json-content.md) | Structured JSON block content over raw HTML or MDX source files | Accepted | | [0006](0006-immutable-version-snapshots.md) | Immutable full-snapshot versioning with fork lineage | Accepted | | [0007](0007-meilisearch.md) | Meilisearch for MVP search | Accepted | | [0008](0008-redis-celery.md) | Redis + Celery for cache and background jobs | Accepted | | [0009](0009-iframe-widget-sandbox.md) | Sandboxed cross-origin iframes + postMessage for widgets | Accepted | | [0010](0010-code-execution-sandbox.md) | Dedicated judge service with container isolation for code challenges | Accepted | | [0011](0011-auth-strategy.md) | Django session auth + django-allauth OAuth; token auth for the public API | Accepted | | [0012](0012-agplv3-platform-license.md) | AGPLv3 for platform code | Accepted | | [0013](0013-cc-by-sa-content-license.md) | CC BY-SA 4.0 as the default content license | Accepted | | [0014](0014-katex-math-rendering.md) | KaTeX over MathJax for math rendering | Accepted | | [0015](0015-s3-compatible-storage.md) | S3-compatible object storage (MinIO dev / R2 or S3 prod) | Accepted | | [0016](0016-i18n-strategy.md) | Translations as sibling content versions; UI catalogs via standard i18n tooling | Accepted | | [0017](0017-audit-log-postgres.md) | Append-only audit log in partitioned PostgreSQL tables | Accepted | | [0018](0018-rest-over-graphql.md) | REST + OpenAPI over GraphQL for the public API | Accepted | | [0019](0019-spaced-repetition-sm2.md) | SM-2 variant for spaced repetition scheduling | Accepted | | [0020](0020-docker-compose-deployment.md) | Docker Compose for dev; single-host Docker prod first, Kubernetes optional | Accepted | ## Template ```markdown # ADR-NNNN: Title - Status: Proposed | Accepted | Superseded by ADR-XXXX - Date: YYYY-MM-DD - Deciders: ## Context ## Decision ## Consequences ### Positive ### Negative / risks ### Alternatives considered ```