Skip to content

Feature flags & module enablement (Reference)

This page explains what can be enabled/disabled without code changes across the entire platform.

1) Module enablement (verticals)

The platform supports enabling/disabling major modules ("verticals") independently:

Module Description Key functionality
Occurrences Citizen issue reporting Submit, triage, workflow, SLAs
Equipment Asset management Inventory, maintenance, inspections, reservations
Occupancy Public space monitoring Sensors, POIs, live dashboards, alerts

How module enablement works

Modules are enabled via the ENABLED_MODULES setting:

ENABLED_MODULES = ['occurrences', 'equipment', 'occupancy']

When a module is disabled: - Its API routes are not registered - Admin sidebar links are hidden - Related functionality is not accessible - Other modules continue to work independently

Module dependencies

Some modules have soft dependencies: - Occupancy can optionally integrate with Equipment for sensor asset management - If Equipment is disabled, Occupancy works standalone

Checking module status

Behind the scenes: - Module checks: apps/utils/module_registry.pyis_module_enabled() - API routes: Registered conditionally in config/api_router.py - Admin visibility: Controlled via Unfold admin configuration


2) Occurrences module flags

Within the Occurrences module, workflow features can be toggled using environment variables.

These are collected into OCCURRENCES_WORKFLOW_FEATURES in config/settings/base.py.

Available flags

Flag Default Description
OCCURRENCES_ENABLE_TEMPLATES True Response templates for staff
OCCURRENCES_ENABLE_CUSTOM_STATES True Custom workflow states
OCCURRENCES_ENABLE_SLA_TRACKING True Priority-based SLA deadlines
OCCURRENCES_ENABLE_ESCALATIONS False SLA breach notifications
OCCURRENCES_ENABLE_ROUTING False External system routing
OCCURRENCES_ENABLE_DUPLICATE_DETECTION True Similar report detection
  1. Start with templates (low risk, high value)
  2. Enable custom states if teams need structured stage tracking
  3. Add SLA tracking when you have defined response targets
  4. Turn on escalations gradually to avoid alert fatigue
  5. Enable routing only after external integrations are tested

Setting flags

Via environment variables:

OCCURRENCES_ENABLE_TEMPLATES=true
OCCURRENCES_ENABLE_ESCALATIONS=false

Or in Django settings:

OCCURRENCES_WORKFLOW_FEATURES = {
    'enable_templates': True,
    'enable_custom_states': True,
    'enable_sla_tracking': True,
    'enable_escalations': env.bool('OCCURRENCES_ENABLE_ESCALATIONS', False),
    'enable_routing': env.bool('OCCURRENCES_ENABLE_ROUTING', False),
    'enable_duplicate_detection': True,
}

3) Equipment module flags

The Equipment module has fewer feature flags, focusing on core functionality.

Available flags

Flag Default Description
EQUIPMENT_ENABLE_RESERVATIONS True Reservation/booking system
EQUIPMENT_ENABLE_INSPECTIONS True Inspection records
EQUIPMENT_ENABLE_MAINTENANCE_REMINDERS True Automated maintenance alerts
EQUIPMENT_ENABLE_WARRANTY_ALERTS True Warranty expiration notifications

Background task flags

Equipment background tasks (Celery) can be individually enabled:

EQUIPMENT_CELERY_TASKS = {
    'check_maintenance_due': True,
    'check_warranty_expiring': True,
    'check_inspection_due': True,
}

4) Occupancy module flags

The Occupancy module has configuration for data ingestion and alerting.

Available flags

Flag Default Description
OCCUPANCY_ENABLE_ALERTS True Capacity and sensor alerts
OCCUPANCY_ENABLE_PUBLIC_DASHBOARD True Public-facing occupancy display
OCCUPANCY_ENABLE_WEBSOCKET True Real-time updates via WebSocket
OCCUPANCY_ENABLE_EQUIPMENT_SYNC False Sync sensors with Equipment module

Data ingestion settings

Setting Default Description
OCCUPANCY_INGESTION_ENABLED True Enable data ingestion from lakehouse
OCCUPANCY_DATA_RETENTION_DAYS 30 How long to keep raw sensor readings
OCCUPANCY_CACHE_TTL_SECONDS 300 Occupancy calculation cache duration

Alert thresholds

Configurable via settings:

OCCUPANCY_ALERT_THRESHOLDS = {
    'capacity_warning_percent': 80,
    'capacity_critical_percent': 95,
    'sensor_offline_minutes': 30,
}

5) Dynamic Forms flags

Dynamic forms have their own configuration.

Available flags

Flag Default Description
DYNAMIC_FORMS_ENABLE_HYDRATION True Map form data to model records
DYNAMIC_FORMS_ENABLE_FILE_UPLOADS True File upload fields in forms
DYNAMIC_FORMS_ENABLE_DRAFT_PREVIEW True Preview draft forms before publishing

6) Cross-module permissions

The module registry also handles permission checking:

MODULE_PERMISSIONS = {
    'occurrences': {
        'view': ['public', 'staff', 'manager', 'admin'],
        'create': ['public', 'staff', 'admin'],
        'update': ['staff', 'manager', 'admin'],
        'delete': ['admin'],
    },
    'equipment': {
        'view': ['staff', 'manager', 'admin'],
        'create': ['staff', 'admin'],
        'update': ['staff', 'manager', 'admin'],
        'delete': ['admin'],
    },
    'occupancy': {
        'view': ['public', 'staff', 'manager', 'admin'],
        'create': ['staff', 'admin'],
        'update': ['staff', 'admin'],
        'delete': ['admin'],
    },
}

7) Checking configuration

Via admin

Platform administrators can view enabled modules and features in Django Admin.

Via API

GET /api/config/modules/

Returns:

{
  "enabled_modules": ["occurrences", "equipment", "occupancy"],
  "features": {
    "occurrences": {"templates": true, "sla_tracking": true, ...},
    "equipment": {"reservations": true, "inspections": true, ...},
    "occupancy": {"alerts": true, "public_dashboard": true, ...}
  }
}

Via code

from apps.utils.module_registry import is_module_enabled

if is_module_enabled('equipment'):
    # Equipment-specific logic
    pass

Behind the scenes (grounded in code)

  • Module registry: apps/utils/module_registry.py
  • Settings: config/settings/base.py
  • API router: config/api_router.py (conditional registration)
  • Admin: Unfold admin configuration checks module enablement