First steps after it’s running¶
So the server is up at {{ dev_url }} and you can log in. Here’s how to actually
do development on Midsummer — where things live, how to make a change, and the
gates you must keep green.
Where the code lives¶
midsummer/ # Django project: settings, root URLconf, ASGI/WSGI, middleware
midsummer/common/ # Cross-app shared code (ui.py menus, permissions, triggers, SPA shell)
accounts/ event/ register/ vendors/ staff/ schedule/ shop/ tenant/ kioskos/
# The tenant + shared Django apps (see Systems)
ui/ # MAIN event SPA — Angular 21 + PrimeNG 21 (+ Kendo scheduler)
tenantui/ # Tenant-management SPA — Angular 19 + PrimeNG 19
front/ # Public-schema landing pages (serves built SPA assets via WhiteNoise)
documentation/ # Authoritative deep-dive docs (mirrored from the memory bank)
guides/ # Operational runbooks (tenants, domains, metrics)
scripts/ # Standalone helper scripts
Each backend app follows the Django convention: models.py, views.py,
urls.py, serializers.py, admin.py, tests.py, migrations/, plus (where
needed) services/, consumers.py, routing.py, tasks.py.
The canonical build + run command¶
When in doubt, this single invocation rebuilds both frontends and starts the
server (it is also what AGENTS.md documents as authoritative):
export MIDSUMMER_PROD=false && ./render-ui-elements.sh && ./render-tenant-ui-elements.sh && ./entrypoint.sh
MIDSUMMER_PROD=falsekeeps you in dev mode. Always leave thisfalselocally.render-ui-elements.shbuilds theui/SPA into Django static files.render-tenant-ui-elements.shbuilds thetenantui/SPA likewise.entrypoint.shrunscollectstatic, re-applies shared migrations, then launches Hypercorn on{{ dev_port }}.
You only need to re-run the render scripts when frontend code changes.
Making a backend change¶
Edit the relevant app (
register/,vendors/, …). REST endpoints live in each app’surls.py, mounted under/app/<module>/.If you change a model, generate and apply a schema migration:
python manage.py makemigrations <app> python manage.py migrate_schemas # note: migrate_schemas, not migrate (django-tenants)
Keep the gates green (see Build & test gates below).
See the Concepts section for the patterns you’ll be working with: the JSON form-builder, the permission model, audit logging, etc.
Making a frontend change¶
There are two Angular projects with different versions — don’t assume they share code:
Project |
Framework |
Purpose |
|---|---|---|
|
Angular 21 + PrimeNG 21 (+ Kendo) |
The event app (register, vendors, schedule, staff, shop) |
|
Angular 19 + PrimeNG 19 |
Tenant/org admin (events, settings, domains, memberships) |
After editing, rebuild the affected SPA into Django static files:
./render-ui-elements.sh # after editing ui/
./render-tenant-ui-elements.sh # after editing tenantui/
For a faster inner loop while iterating on a single SPA, you can run its dev
server directly, but the Django-served app expects the built static assets, so
a final render-* is required before testing inside the running Midsummer app.
Build & test gates¶
These are the checks the project relies on. Run them before considering a change done.
# Django system check (should be 0 errors; ~19 pre-existing warnings are normal)
python manage.py check
# Migration drift check for the app you touched (should report "no changes")
python manage.py makemigrations <app> --check
# Frontend type-check (exit 0 = pass), for the SPA you edited
cd ui && npx ngc --noEmit -p tsconfig.app.json
# (or) full build
cd ui && npx ng build
A note on the test database¶
DB-backed tests (python manage.py test) are not runnable in the standard dev
environment — the remote Postgres lacks the test_midsummerpool test database
(a pre-existing constraint). Pure-helper unit tests (no DB) do run, and are
preferred for new business logic. When you can’t run a DB test locally, lean on
manage.py check, the migration-drift check, and the frontend type-check above.
Multi-tenancy in practice (local)¶
Midsummer is schema-isolated per tenant. Locally you typically have a
defaultdev tenant with one event. Two things to remember:
Migrations that touch shared tables run with
migrate_schemas --shared.To operate on tenant data from a shell/management command, run it inside the owning tenant’s schema (the management tooling handles context for the configured tenant). The registration metrics export command, for example, must run inside the owning tenant’s schema so it writes data to the correct path.
Read the multi-tenancy concept page for the full model.
Where to go next¶
Systems — what each app actually does.
Concepts & Theory — the why behind the code.
Reference — every management command, the API, the data model.