A Django application for managing clinical patients, imaging records, and simple analytics.
- Django 5.2 LTS
- SQLite for local development
- Bootstrap 5 for basic UI
- D3 for interactive analytics
- uv for dependency and virtual environment management
Bootstrap and D3 are loaded from CDN links in the templates; they are not vendored in this repository.
- Patient and scan pages require login.
- Users can change their password after signing in.
- Scan records can be searched across patients, reasons, and diagnoses.
- Scan image uploads are limited to PNG/JPEG files under 2 MB.
- Scan image files are removed when their records are deleted.
- Patient deletion is restricted to staff users.
- Scan edit and delete actions are restricted to the clinician who created the scan.
- D3 charts read authenticated JSON endpoints.
- Sample records and scan images can be generated locally.
uv sync
uv run python manage.py migrate
uv run python manage.py load_sample_data
uv run python manage.py runserverTo replace existing sample records:
uv run python manage.py load_sample_data --resetThe sample data command creates a clinician account:
- Username:
docy - Password:
V7qN4pX9rL2m
Open http://127.0.0.1:8000 and sign in.
SQLite is used by default. To use PostgreSQL, install the project dependencies and set DATABASE_URL:
Create the PostgreSQL database and user first, then run migrations with the same DATABASE_URL.
DATABASE_URL=postgresql://clinical_ims:password@localhost:5432/clinical_ims
uv run python manage.py migrateuv run python manage.py testEnd-to-end checks use Playwright:
uv run --group e2e python -m playwright install --with-deps chromium
uv run --group e2e python tests/e2e_smoke.pyGitHub Actions runs the Django test suite against SQLite and PostgreSQL, plus the Playwright smoke test.
Manual checks:
- Create, edit, search, and delete patients.
- Add, search, filter, view, edit, and delete scan records.
- Confirm scan uploads reject invalid files and dates.
- Change the signed-in user's password.
- Open Analytics and change the sex filter.