|
| 1 | +# MIT xPRO - Agent Instructions |
| 2 | + |
| 3 | +Django + Wagtail + React monolith for MIT xPRO professional education. Integrates with Open edX, HubSpot, Google Sheets, and CyberSource/Stripe payments. |
| 4 | + |
| 5 | +## Architecture |
| 6 | + |
| 7 | +- **Backend**: Django + DRF REST API + Wagtail CMS + Celery task queue + PostgreSQL + Redis |
| 8 | +- **Frontend**: React 16 + Redux (redux-query) + Flow types + SCSS, bundled with Webpack 5 |
| 9 | +- **Entry points**: `static/js/entry/{root,header,style,django}.js` |
| 10 | +- **CMS API**: Wagtail REST API v2 at `/api/v2/` |
| 11 | +- **Auth**: Social auth + OAuth2 toolkit + custom User model (`users.User`) |
| 12 | +- **Settings**: Single file `mitxpro/settings.py`, env-var driven via `mitol.common.envs` helpers (`get_string()`, `get_bool()`, `get_int()`) |
| 13 | +- **Feature flags**: PostHog via `mitxpro/features.py` |
| 14 | + |
| 15 | +### Key Django Apps |
| 16 | + |
| 17 | +| App | Purpose | |
| 18 | +| ---------------- | ------------------------------------------------------------------------------------------------------------ | |
| 19 | +| `courses` | Courses, programs, enrollments, certificates, runs | |
| 20 | +| `cms` | Wagtail CMS pages + REST API — see [cms/README.md](cms/README.md) | |
| 21 | +| `ecommerce` | Orders, products, coupons, CyberSource payments, tax | |
| 22 | +| `b2b_ecommerce` | B2B ordering and enrollment | |
| 23 | +| `courseware` | Open edX integration, user sync, API tokens | |
| 24 | +| `sheets` | Google Sheets automation for enrollment codes, refunds, deferrals — see [sheets/README.md](sheets/README.md) | |
| 25 | +| `authentication` | OAuth2, social auth pipelines, JWT (djoser) | |
| 26 | +| `users` | Custom User model | |
| 27 | +| `compliance` | Audit logging, data consent | |
| 28 | +| `mail` | Email templates, Mailgun integration | |
| 29 | +| `hubspot_xpro` | HubSpot CRM sync | |
| 30 | + |
| 31 | +## Build and Test |
| 32 | + |
| 33 | +### Python |
| 34 | + |
| 35 | +```sh |
| 36 | +uv run pytest # Run all tests (with coverage) |
| 37 | +uv run pytest path/to/test_file.py -k test_name # Run specific test |
| 38 | +uv run ./scripts/test/python_tests.sh # Full suite (migration checks + tests) |
| 39 | +uv run ./scripts/test/detect_missing_migrations.sh |
| 40 | +pre-commit run --all-files # Ruff, shfmt, yamllint, detect-secrets |
| 41 | +``` |
| 42 | + |
| 43 | +### JavaScript |
| 44 | + |
| 45 | +```sh |
| 46 | +npm run test # Mocha tests |
| 47 | +npm run lint-check # ESLint |
| 48 | +npm run lint-fix # ESLint auto-fix |
| 49 | +npm run fmt # Prettier format |
| 50 | +npm run fmt:check # Prettier check |
| 51 | +npm run flow # Flow type check |
| 52 | +npm run scss-lint # SCSS lint |
| 53 | +``` |
| 54 | + |
| 55 | +### Docker (primary dev environment) |
| 56 | + |
| 57 | +```sh |
| 58 | +docker-compose up # Start all services |
| 59 | +docker-compose run --rm web pytest # Tests in container |
| 60 | +docker-compose run --rm watch npm run lint-check # JS lint in container |
| 61 | +``` |
| 62 | + |
| 63 | +Services: `db` (:5432), `redis` (:6379), `web` (:8051), `watch` (:8052), `nginx` (:8053), `celery` |
| 64 | + |
| 65 | +## Code Style |
| 66 | + |
| 67 | +- **Python**: Ruff (formatting + linting via pre-commit). No additional config needed — pre-commit handles it. |
| 68 | +- **JavaScript**: ESLint (`eslint-config-mitodl`) + Prettier. Flow for type checking (not TypeScript). |
| 69 | +- **SCSS**: Stylelint via `npm run scss-lint`. |
| 70 | +- **Secrets**: `detect-secrets` baseline at `.secrets.baseline` — update baseline if adding test secrets. |
| 71 | + |
| 72 | +## Conventions |
| 73 | + |
| 74 | +### Project structure per app |
| 75 | + |
| 76 | +``` |
| 77 | +app_name/ |
| 78 | + models.py # Django models |
| 79 | + api.py # Business logic / service layer |
| 80 | + views.py # DRF ViewSets and views |
| 81 | + serializers.py # DRF serializers |
| 82 | + factories.py # Factory Boy test factories (DjangoModelFactory) |
| 83 | + *_test.py # Tests colocated (models_test.py, api_test.py, views_test.py) |
| 84 | + tasks.py # Celery tasks (if any) |
| 85 | + constants.py # App-level constants |
| 86 | + admin.py # Django admin config |
| 87 | + migrations/ # Auto-generated Django migrations |
| 88 | +``` |
| 89 | + |
| 90 | +### Testing |
| 91 | + |
| 92 | +- Test files live alongside source: `models_test.py`, `api_test.py`, `views_test.py` |
| 93 | +- Use **Factory Boy** for test data — factories in each app's `factories.py` |
| 94 | +- Use `@pytest.mark.django_db` for database access |
| 95 | +- Celery tasks are eager in tests (`CELERY_TASK_ALWAYS_EAGER=True`) |
| 96 | +- Tests run in parallel with `pytest-xdist` in CI (`-n logical`) |
| 97 | +- Root `conftest.py` sets up shared fixtures |
| 98 | + |
| 99 | +### API patterns |
| 100 | + |
| 101 | +- DRF ViewSets + Serializers with paginated responses (default 20/page) |
| 102 | +- Business logic in `api.py`, not in views |
| 103 | +- Wagtail content via REST API: `/api/v2/pages/?type=cms.CoursePage` |
| 104 | + |
| 105 | +### Environment variables |
| 106 | + |
| 107 | +- All config is env-var driven — never hardcode secrets or URLs |
| 108 | +- Required: `MITXPRO_BASE_URL`, `SECRET_KEY`, `MITXPRO_ENVIRONMENT` |
| 109 | +- Access via `mitol.common.envs`: `get_string("VAR_NAME", "default")` |
| 110 | + |
| 111 | +### Dependencies |
| 112 | + |
| 113 | +- **Python**: Managed with `uv` — `uv sync --frozen` (lockfile: `uv.lock`) |
| 114 | +- **Node**: Managed with `yarn` — `yarn install --immutable` (lockfile: `yarn.lock`) |
| 115 | + |
| 116 | +### Issue and PR management |
| 117 | + |
| 118 | +All issue and pull request templates are centralized in the [mitodl/.github](https://github.com/mitodl/.github) repository. Use those templates when creating issues or PRs. |
| 119 | + |
| 120 | +## Further Reading |
| 121 | + |
| 122 | +- [docs/rfcs/](docs/rfcs/) — Architecture decision records (ecommerce, auth, course data) |
| 123 | +- [courses/docs/external-course-sync.md](courses/docs/external-course-sync.md) — External course sync |
| 124 | +- [docs/configure_digital_credentials.md](docs/configure_digital_credentials.md) — Digital credentials setup |
0 commit comments