Skip to content

Architecture

This page describes the high-level architecture of MedUX. Understanding these building blocks will help you navigate the codebase and develop plugins.

Layer Overview

┌────────────────────────────────────────────────┐
│                   Browser                      │
│          Tabler.io / Bootstrap 5 / HTMX        │
├────────────────────────────────────────────────┤
│              Django Templates                  │
│          Conjunto layout & widgets             │
├────────────────────────────────────────────────┤
│               Django Views                     │
│        (CBVs, HTMX partials, modals)           │
├────────────────────────────────────────────────┤
│               Django Models                    │
│        (Patient, Encounter, Tenant…)           │
├────────────────────────────────────────────────┤
│               GDAPS Plugin System              │
│        (Interfaces, Implementations)           │
├────────────────────────────────────────────────┤
│         Conjunto (Settings, Menus, Auth)       │
│         Django Channels (WebSocket)            │
├────────────────────────────────────────────────┤
│              PostgreSQL / SQLite               │
└────────────────────────────────────────────────┘

Plugin System (GDAPS)

MedUX uses GDAPS (Generic Django Apps Plugin System) for its modular architecture. Every major feature area is a plugin — even the built-in ones.

Plugins are registered via Python entry points in pyproject.toml:

[project.entry-points."medux.plugins"]
core = "medux.core:apps.CoreConfig"

At startup, PluginManager.alter_installed_apps() discovers all registered plugins and adds them to INSTALLED_APPS. URL patterns from plugins are similarly collected via PluginManager.urlpatterns().

All plugin AppConfig classes inherit from MeduxPluginAppConfig (defined in medux.common.api), which provides:

  • groups_permissions — dict for automatic permission setup
  • initialize() — called by the initialize management command
  • compatibility_errors / compatibility_warnings — cached properties for startup checks

See Plugin Development for details on creating your own plugins.

Conjunto

Conjunto is the UI and framework layer that MedUX builds on top of. It provides:

  • Layout system — base templates with topbar, sidebar, offcanvas, and statusbar regions
  • Menu system — hierarchical menus defined as Python classes (IMenuItem)
  • Scoped settings — per-scope configuration overlays
  • Tenant supportTenantModelMixin, tenant-aware middleware
  • Form widgets — enhanced Django form fields for Tabler.io
  • HTMX utilitiesHtmxFormViewMixin, modal lifecycle management, toast notifications

Core Apps

MedUX ships with these built-in apps:

medux.common

The foundation app. Provides:

  • Tenant model — multi-tenancy support
  • User modelCommonUser (used as AUTH_USER_MODEL)
  • Administration framework — extensible admin area at /administration/
  • InterfacesIAdministrationURL, IAdministrationSection, ITenantSection, ILoginFormExtension, IWebsocketURL
  • Menu items — sidebar and administration rail entries

medux.core

The medical domain app. Provides:

  • Patient — patient demographics and management
  • Encounter — clinical encounters
  • Geo models — address and geographic data
  • Medication — medication records
  • Observation — clinical observations (FHIR-inspired)
  • Dashboard — extensible dashboard with IDashboardSection
  • Device middleware — tracks the device making requests
  • CommandsICommand for quick-access command palette

medux.employees

Workforce management. Provides:

  • Employee model — linked to the user model
  • WorkingContract — employment contracts
  • Employee middleware — attaches employee to request

medux.notifications

Real-time notifications via Django Channels:

  • Alerts — notification system
  • WebSocket — push updates to the browser

medux.plugins.wiki

A built-in wiki plugin for internal documentation.

Multi-Tenancy

MedUX supports multiple tenants (practices) on a single installation. Each tenant has isolated data, and users can be members of multiple tenants with different roles.

Tenancy is enforced through:

  • conjunto.middleware.ConjuntoMiddleware — binds request.tenant
  • TenantModelMixin / OptionalTenantModelMixin — model-level scoping
  • TenantMembership — role-based access per tenant

See Tenant Management for administrator-level details and Administration Sections for the developer perspective.

Scoped Settings

Configuration in MedUX follows a priority chain:

USER > DEVICE > GROUP > TENANT > VENDOR

Each level can override settings from the level below. Settings are registered at startup in a scoped_settings.py module and accessed via request.scoped_settings.get("namespace", "key") or in templates with {{ request.scoped_settings.namespace.key }}.

See Scoped Settings for the developer guide.

Interfaces

Plugins extend MedUX by implementing interfaces. The key interfaces are:

Interface Module Purpose
IAdministrationURL medux.common.api Add URL patterns under /administration/
IAdministrationSection medux.common.api Full admin screen with menu & permissions
ITenantSection medux.common.api Tenant administration section
ILoginFormExtension medux.common.api Extend the login form
IWebsocketURL medux.common.api Add WebSocket URL patterns
IGlobalJavascript medux.core.api Inject JavaScript globally
ICommand medux.core.api Register a command palette entry
IDashboardSection medux.core.api Add a dashboard widget
IMenuItem conjunto.menu Add a menu entry
ISettingsSection conjunto.api Add a settings form

See Interfaces Reference for full documentation.