django-micboard 26.7.15__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- django_micboard-26.7.15/.env.example +23 -0
- django_micboard-26.7.15/CHANGELOG.md +561 -0
- django_micboard-26.7.15/CONTRIBUTING.md +341 -0
- django_micboard-26.7.15/LICENSE +664 -0
- django_micboard-26.7.15/MANIFEST.in +23 -0
- django_micboard-26.7.15/PKG-INFO +555 -0
- django_micboard-26.7.15/README.md +379 -0
- django_micboard-26.7.15/django_micboard.egg-info/PKG-INFO +555 -0
- django_micboard-26.7.15/django_micboard.egg-info/SOURCES.txt +483 -0
- django_micboard-26.7.15/django_micboard.egg-info/dependency_links.txt +1 -0
- django_micboard-26.7.15/django_micboard.egg-info/entry_points.txt +2 -0
- django_micboard-26.7.15/django_micboard.egg-info/requires.txt +157 -0
- django_micboard-26.7.15/django_micboard.egg-info/top_level.txt +1 -0
- django_micboard-26.7.15/micboard/__init__.py +32 -0
- django_micboard-26.7.15/micboard/admin/__init__.py +34 -0
- django_micboard-26.7.15/micboard/admin/activity_logs.py +326 -0
- django_micboard-26.7.15/micboard/admin/assignments.py +98 -0
- django_micboard-26.7.15/micboard/admin/channel_forms.py +52 -0
- django_micboard-26.7.15/micboard/admin/channels.py +331 -0
- django_micboard-26.7.15/micboard/admin/chargers.py +48 -0
- django_micboard-26.7.15/micboard/admin/configuration.py +317 -0
- django_micboard-26.7.15/micboard/admin/discovery.py +48 -0
- django_micboard-26.7.15/micboard/admin/discovery_admin.py +347 -0
- django_micboard-26.7.15/micboard/admin/display_wall.py +47 -0
- django_micboard-26.7.15/micboard/admin/forms.py +112 -0
- django_micboard-26.7.15/micboard/admin/integrations.py +282 -0
- django_micboard-26.7.15/micboard/admin/manufacturers.py +98 -0
- django_micboard-26.7.15/micboard/admin/mixins.py +310 -0
- django_micboard-26.7.15/micboard/admin/monitoring.py +359 -0
- django_micboard-26.7.15/micboard/admin/realtime.py +143 -0
- django_micboard-26.7.15/micboard/admin/receiver_inlines.py +67 -0
- django_micboard-26.7.15/micboard/admin/receivers.py +400 -0
- django_micboard-26.7.15/micboard/admin/regulatory_annotations.py +51 -0
- django_micboard-26.7.15/micboard/admin/secret_fields.py +23 -0
- django_micboard-26.7.15/micboard/admin/settings.py +344 -0
- django_micboard-26.7.15/micboard/admin/sortable.py +118 -0
- django_micboard-26.7.15/micboard/admin/templates/admin/dashboard.html +428 -0
- django_micboard-26.7.15/micboard/admin/users.py +26 -0
- django_micboard-26.7.15/micboard/apps.py +185 -0
- django_micboard-26.7.15/micboard/chargers/__init__.py +0 -0
- django_micboard-26.7.15/micboard/checks.py +26 -0
- django_micboard-26.7.15/micboard/context_processors.py +10 -0
- django_micboard-26.7.15/micboard/decorators.py +51 -0
- django_micboard-26.7.15/micboard/discovery/__init__.py +0 -0
- django_micboard-26.7.15/micboard/discovery/limits.py +18 -0
- django_micboard-26.7.15/micboard/discovery/network_utils.py +63 -0
- django_micboard-26.7.15/micboard/exceptions.py +276 -0
- django_micboard-26.7.15/micboard/filters.py +48 -0
- django_micboard-26.7.15/micboard/fixtures/band_plans.yaml +78 -0
- django_micboard-26.7.15/micboard/fixtures/device_specifications.yaml +253 -0
- django_micboard-26.7.15/micboard/forms/assignments.py +33 -0
- django_micboard-26.7.15/micboard/forms/configuration.py +32 -0
- django_micboard-26.7.15/micboard/forms/dashboard.py +25 -0
- django_micboard-26.7.15/micboard/forms/integrations.py +42 -0
- django_micboard-26.7.15/micboard/forms/settings.py +380 -0
- django_micboard-26.7.15/micboard/forms/settings_admin.py +200 -0
- django_micboard-26.7.15/micboard/integrations/sennheiser/client.py +73 -0
- django_micboard-26.7.15/micboard/integrations/sennheiser/device_client.py +48 -0
- django_micboard-26.7.15/micboard/integrations/sennheiser/discovery_client.py +100 -0
- django_micboard-26.7.15/micboard/integrations/sennheiser/exceptions.py +24 -0
- django_micboard-26.7.15/micboard/integrations/sennheiser/plugin.py +87 -0
- django_micboard-26.7.15/micboard/integrations/sennheiser/sse_client.py +214 -0
- django_micboard-26.7.15/micboard/integrations/sennheiser/transformers.py +233 -0
- django_micboard-26.7.15/micboard/integrations/shure/client.py +140 -0
- django_micboard-26.7.15/micboard/integrations/shure/device_client.py +98 -0
- django_micboard-26.7.15/micboard/integrations/shure/discovery_client.py +140 -0
- django_micboard-26.7.15/micboard/integrations/shure/exceptions.py +11 -0
- django_micboard-26.7.15/micboard/integrations/shure/plugin.py +88 -0
- django_micboard-26.7.15/micboard/integrations/shure/transformers.py +297 -0
- django_micboard-26.7.15/micboard/integrations/shure/websocket.py +209 -0
- django_micboard-26.7.15/micboard/management/__init__.py +0 -0
- django_micboard-26.7.15/micboard/management/commands/__init__.py +0 -0
- django_micboard-26.7.15/micboard/management/commands/archive_audit_logs.py +44 -0
- django_micboard-26.7.15/micboard/management/commands/audit_admin.py +139 -0
- django_micboard-26.7.15/micboard/management/commands/audit_regulatory_coverage.py +159 -0
- django_micboard-26.7.15/micboard/management/commands/diagnostic_api_health_check.py +219 -0
- django_micboard-26.7.15/micboard/management/commands/discovery_add_devices.py +82 -0
- django_micboard-26.7.15/micboard/management/commands/import_devices.py +136 -0
- django_micboard-26.7.15/micboard/management/commands/import_efis_regulations.py +99 -0
- django_micboard-26.7.15/micboard/management/commands/init_settings.py +208 -0
- django_micboard-26.7.15/micboard/management/commands/poll_devices.py +158 -0
- django_micboard-26.7.15/micboard/management/commands/realtime_status.py +113 -0
- django_micboard-26.7.15/micboard/management/commands/set_logging_mode.py +34 -0
- django_micboard-26.7.15/micboard/management/commands/sse_subscribe.py +68 -0
- django_micboard-26.7.15/micboard/management/commands/sync_discovery.py +118 -0
- django_micboard-26.7.15/micboard/management/commands/websocket_subscribe.py +76 -0
- django_micboard-26.7.15/micboard/metrics.py +235 -0
- django_micboard-26.7.15/micboard/migrations/0001_initial.py +1143 -0
- django_micboard-26.7.15/micboard/migrations/0002_settingdefinition_setting.py +56 -0
- django_micboard-26.7.15/micboard/migrations/0003_building_campus_id_building_organization_id.py +23 -0
- django_micboard-26.7.15/micboard/migrations/0004_remove_manufacturerapiserver_verify_ssl.py +17 -0
- django_micboard-26.7.15/micboard/migrations/0005_setting_setting_exactly_one_scope_and_more.py +34 -0
- django_micboard-26.7.15/micboard/migrations/__init__.py +0 -0
- django_micboard-26.7.15/micboard/model_lifecycle.py +335 -0
- django_micboard-26.7.15/micboard/models/__init__.py +18 -0
- django_micboard-26.7.15/micboard/models/audit/__init__.py +1 -0
- django_micboard-26.7.15/micboard/models/audit/activity_log.py +279 -0
- django_micboard-26.7.15/micboard/models/audit/configuration_log.py +88 -0
- django_micboard-26.7.15/micboard/models/band_plans.py +238 -0
- django_micboard-26.7.15/micboard/models/base_managers.py +330 -0
- django_micboard-26.7.15/micboard/models/device_specs.py +150 -0
- django_micboard-26.7.15/micboard/models/discovery/__init__.py +1 -0
- django_micboard-26.7.15/micboard/models/discovery/configuration.py +92 -0
- django_micboard-26.7.15/micboard/models/discovery/manufacturer.py +38 -0
- django_micboard-26.7.15/micboard/models/discovery/queue.py +260 -0
- django_micboard-26.7.15/micboard/models/discovery/registry.py +213 -0
- django_micboard-26.7.15/micboard/models/hardware/__init__.py +1 -0
- django_micboard-26.7.15/micboard/models/hardware/charger.py +250 -0
- django_micboard-26.7.15/micboard/models/hardware/display_wall.py +279 -0
- django_micboard-26.7.15/micboard/models/hardware/wireless_chassis.py +387 -0
- django_micboard-26.7.15/micboard/models/hardware/wireless_unit.py +326 -0
- django_micboard-26.7.15/micboard/models/integrations.py +187 -0
- django_micboard-26.7.15/micboard/models/locations/__init__.py +1 -0
- django_micboard-26.7.15/micboard/models/locations/structure.py +176 -0
- django_micboard-26.7.15/micboard/models/mixins.py +7 -0
- django_micboard-26.7.15/micboard/models/monitoring/__init__.py +1 -0
- django_micboard-26.7.15/micboard/models/monitoring/alert.py +205 -0
- django_micboard-26.7.15/micboard/models/monitoring/group.py +79 -0
- django_micboard-26.7.15/micboard/models/monitoring/performer.py +158 -0
- django_micboard-26.7.15/micboard/models/monitoring/performer_assignment.py +181 -0
- django_micboard-26.7.15/micboard/models/realtime/__init__.py +1 -0
- django_micboard-26.7.15/micboard/models/realtime/connection.py +85 -0
- django_micboard-26.7.15/micboard/models/rf_coordination/__init__.py +1 -0
- django_micboard-26.7.15/micboard/models/rf_coordination/compliance.py +164 -0
- django_micboard-26.7.15/micboard/models/rf_coordination/rf_channel.py +238 -0
- django_micboard-26.7.15/micboard/models/settings/__init__.py +1 -0
- django_micboard-26.7.15/micboard/models/settings/registry.py +320 -0
- django_micboard-26.7.15/micboard/models/telemetry/__init__.py +1 -0
- django_micboard-26.7.15/micboard/models/telemetry/health.py +39 -0
- django_micboard-26.7.15/micboard/models/telemetry/sessions.py +72 -0
- django_micboard-26.7.15/micboard/models/users/__init__.py +1 -0
- django_micboard-26.7.15/micboard/models/users/user_profile.py +107 -0
- django_micboard-26.7.15/micboard/models/users/user_views.py +29 -0
- django_micboard-26.7.15/micboard/multitenancy/__init__.py +1 -0
- django_micboard-26.7.15/micboard/multitenancy/admin.py +215 -0
- django_micboard-26.7.15/micboard/multitenancy/apps.py +14 -0
- django_micboard-26.7.15/micboard/multitenancy/middleware.py +190 -0
- django_micboard-26.7.15/micboard/multitenancy/migrations/0001_initial.py +111 -0
- django_micboard-26.7.15/micboard/multitenancy/migrations/README.md +26 -0
- django_micboard-26.7.15/micboard/multitenancy/migrations/__init__.py +0 -0
- django_micboard-26.7.15/micboard/multitenancy/models.py +240 -0
- django_micboard-26.7.15/micboard/services/__init__.py +1 -0
- django_micboard-26.7.15/micboard/services/chargers/dashboard_dtos.py +52 -0
- django_micboard-26.7.15/micboard/services/chargers/dashboard_service.py +130 -0
- django_micboard-26.7.15/micboard/services/chargers/polling_cache.py +149 -0
- django_micboard-26.7.15/micboard/services/chargers/polling_dtos.py +91 -0
- django_micboard-26.7.15/micboard/services/chargers/polling_service.py +352 -0
- django_micboard-26.7.15/micboard/services/common/__init__.py +0 -0
- django_micboard-26.7.15/micboard/services/common/base/__init__.py +1 -0
- django_micboard-26.7.15/micboard/services/common/base/bounded_transport.py +93 -0
- django_micboard-26.7.15/micboard/services/common/base/circuit_breaker.py +93 -0
- django_micboard-26.7.15/micboard/services/common/base/client.py +392 -0
- django_micboard-26.7.15/micboard/services/common/base/plugin.py +106 -0
- django_micboard-26.7.15/micboard/services/common/base/rate_limiter.py +52 -0
- django_micboard-26.7.15/micboard/services/common/base/resilience.py +27 -0
- django_micboard-26.7.15/micboard/services/common/base/utils.py +58 -0
- django_micboard-26.7.15/micboard/services/common/network_limits.py +100 -0
- django_micboard-26.7.15/micboard/services/core/__init__.py +1 -0
- django_micboard-26.7.15/micboard/services/core/device_metadata.py +145 -0
- django_micboard-26.7.15/micboard/services/core/device_specs.py +100 -0
- django_micboard-26.7.15/micboard/services/core/hardware.py +82 -0
- django_micboard-26.7.15/micboard/services/core/hardware_lifecycle.py +211 -0
- django_micboard-26.7.15/micboard/services/core/hardware_post_save_hooks.py +111 -0
- django_micboard-26.7.15/micboard/services/core/hardware_sync.py +69 -0
- django_micboard-26.7.15/micboard/services/core/performer_assignment.py +351 -0
- django_micboard-26.7.15/micboard/services/core/performer_assignment_dtos.py +37 -0
- django_micboard-26.7.15/micboard/services/core/user_profile.py +38 -0
- django_micboard-26.7.15/micboard/services/deduplication/__init__.py +1 -0
- django_micboard-26.7.15/micboard/services/deduplication/check.py +379 -0
- django_micboard-26.7.15/micboard/services/deduplication/identity_index.py +191 -0
- django_micboard-26.7.15/micboard/services/deduplication/identity_mutation_lock.py +26 -0
- django_micboard-26.7.15/micboard/services/deduplication/identity_resolution.py +41 -0
- django_micboard-26.7.15/micboard/services/deduplication/queue_conflict_service.py +75 -0
- django_micboard-26.7.15/micboard/services/deduplication/result.py +122 -0
- django_micboard-26.7.15/micboard/services/deduplication/tracking.py +58 -0
- django_micboard-26.7.15/micboard/services/discovery/__init__.py +0 -0
- django_micboard-26.7.15/micboard/services/discovery/registry_service.py +23 -0
- django_micboard-26.7.15/micboard/services/hardware/__init__.py +1 -0
- django_micboard-26.7.15/micboard/services/hardware/chassis_admin_dtos.py +48 -0
- django_micboard-26.7.15/micboard/services/hardware/chassis_admin_service.py +175 -0
- django_micboard-26.7.15/micboard/services/hardware/chassis_lifecycle_service.py +169 -0
- django_micboard-26.7.15/micboard/services/hardware/chassis_refresh_service.py +182 -0
- django_micboard-26.7.15/micboard/services/hardware/chassis_regulatory_service.py +267 -0
- django_micboard-26.7.15/micboard/services/hardware/dtos.py +89 -0
- django_micboard-26.7.15/micboard/services/hardware/ip_ownership_service.py +82 -0
- django_micboard-26.7.15/micboard/services/hardware/receiver_browse_dtos.py +50 -0
- django_micboard-26.7.15/micboard/services/hardware/receiver_browse_service.py +109 -0
- django_micboard-26.7.15/micboard/services/hardware/rf_channel_service.py +214 -0
- django_micboard-26.7.15/micboard/services/hardware/wireless_chassis_persistence_service.py +342 -0
- django_micboard-26.7.15/micboard/services/hardware/wireless_unit_service.py +296 -0
- django_micboard-26.7.15/micboard/services/import_service.py +255 -0
- django_micboard-26.7.15/micboard/services/integrations/api_server_service.py +182 -0
- django_micboard-26.7.15/micboard/services/integrations/dtos.py +18 -0
- django_micboard-26.7.15/micboard/services/kiosk/__init__.py +1 -0
- django_micboard-26.7.15/micboard/services/kiosk/dtos.py +147 -0
- django_micboard-26.7.15/micboard/services/kiosk/health_service.py +185 -0
- django_micboard-26.7.15/micboard/services/kiosk/services.py +292 -0
- django_micboard-26.7.15/micboard/services/locations/__init__.py +0 -0
- django_micboard-26.7.15/micboard/services/locations/structure_service.py +36 -0
- django_micboard-26.7.15/micboard/services/maintenance/__init__.py +1 -0
- django_micboard-26.7.15/micboard/services/maintenance/admin_audit_checks.py +276 -0
- django_micboard-26.7.15/micboard/services/maintenance/admin_audit_dtos.py +103 -0
- django_micboard-26.7.15/micboard/services/maintenance/admin_audit_service.py +255 -0
- django_micboard-26.7.15/micboard/services/maintenance/audit.py +183 -0
- django_micboard-26.7.15/micboard/services/maintenance/efis_import.py +299 -0
- django_micboard-26.7.15/micboard/services/maintenance/logging_mode.py +62 -0
- django_micboard-26.7.15/micboard/services/maintenance/sync_audit_service.py +107 -0
- django_micboard-26.7.15/micboard/services/manufacturer/__init__.py +1 -0
- django_micboard-26.7.15/micboard/services/manufacturer/activation_service.py +14 -0
- django_micboard-26.7.15/micboard/services/manufacturer/config.py +121 -0
- django_micboard-26.7.15/micboard/services/manufacturer/plugin_registry.py +113 -0
- django_micboard-26.7.15/micboard/services/manufacturer/secret_redaction.py +133 -0
- django_micboard-26.7.15/micboard/services/manufacturer/signals.py +84 -0
- django_micboard-26.7.15/micboard/services/manufacturer/sync.py +341 -0
- django_micboard-26.7.15/micboard/services/monitoring/__init__.py +1 -0
- django_micboard-26.7.15/micboard/services/monitoring/alert_browse_dtos.py +68 -0
- django_micboard-26.7.15/micboard/services/monitoring/alert_browse_service.py +140 -0
- django_micboard-26.7.15/micboard/services/monitoring/alert_delivery_service.py +176 -0
- django_micboard-26.7.15/micboard/services/monitoring/alert_fanout_dtos.py +113 -0
- django_micboard-26.7.15/micboard/services/monitoring/alert_fanout_service.py +290 -0
- django_micboard-26.7.15/micboard/services/monitoring/alerts.py +247 -0
- django_micboard-26.7.15/micboard/services/monitoring/base_health_mixin.py +143 -0
- django_micboard-26.7.15/micboard/services/monitoring/monitoring_access.py +156 -0
- django_micboard-26.7.15/micboard/services/monitoring/poll_alert_service.py +215 -0
- django_micboard-26.7.15/micboard/services/multitenancy/organization_service.py +18 -0
- django_micboard-26.7.15/micboard/services/notification/__init__.py +1 -0
- django_micboard-26.7.15/micboard/services/notification/broadcast_service.py +347 -0
- django_micboard-26.7.15/micboard/services/notification/device_broadcast_dtos.py +25 -0
- django_micboard-26.7.15/micboard/services/notification/device_broadcast_service.py +185 -0
- django_micboard-26.7.15/micboard/services/notification/email.py +120 -0
- django_micboard-26.7.15/micboard/services/notification/realtime_routing_service.py +246 -0
- django_micboard-26.7.15/micboard/services/realtime/connection_service.py +67 -0
- django_micboard-26.7.15/micboard/services/realtime/health_dtos.py +34 -0
- django_micboard-26.7.15/micboard/services/realtime/health_service.py +115 -0
- django_micboard-26.7.15/micboard/services/realtime/shure_websocket_subscription_service.py +204 -0
- django_micboard-26.7.15/micboard/services/realtime/sse_subscription_service.py +196 -0
- django_micboard-26.7.15/micboard/services/realtime/subscription_dtos.py +39 -0
- django_micboard-26.7.15/micboard/services/realtime/subscription_lifecycle_service.py +177 -0
- django_micboard-26.7.15/micboard/services/realtime/subscription_supervisor.py +385 -0
- django_micboard-26.7.15/micboard/services/settings/__init__.py +1 -0
- django_micboard-26.7.15/micboard/services/settings/dtos.py +77 -0
- django_micboard-26.7.15/micboard/services/settings/persistence_service.py +112 -0
- django_micboard-26.7.15/micboard/services/settings/presentation_service.py +225 -0
- django_micboard-26.7.15/micboard/services/settings/registry.py +258 -0
- django_micboard-26.7.15/micboard/services/settings/settings_service.py +184 -0
- django_micboard-26.7.15/micboard/services/settings/visibility_service.py +220 -0
- django_micboard-26.7.15/micboard/services/shared/__init__.py +1 -0
- django_micboard-26.7.15/micboard/services/shared/access_policy.py +218 -0
- django_micboard-26.7.15/micboard/services/shared/api_health.py +185 -0
- django_micboard-26.7.15/micboard/services/shared/api_health_dtos.py +67 -0
- django_micboard-26.7.15/micboard/services/shared/base_dto.py +33 -0
- django_micboard-26.7.15/micboard/services/shared/rate_limiting.py +69 -0
- django_micboard-26.7.15/micboard/services/sync/__init__.py +1 -0
- django_micboard-26.7.15/micboard/services/sync/chassis_discovery_schedule_service.py +79 -0
- django_micboard-26.7.15/micboard/services/sync/device_promotion_service.py +145 -0
- django_micboard-26.7.15/micboard/services/sync/device_refresh_service.py +182 -0
- django_micboard-26.7.15/micboard/services/sync/device_update_service.py +323 -0
- django_micboard-26.7.15/micboard/services/sync/discovered_device_deletion_service.py +40 -0
- django_micboard-26.7.15/micboard/services/sync/discovered_device_service.py +89 -0
- django_micboard-26.7.15/micboard/services/sync/discovery_approval_inventory.py +192 -0
- django_micboard-26.7.15/micboard/services/sync/discovery_approval_plan.py +60 -0
- django_micboard-26.7.15/micboard/services/sync/discovery_approval_policy.py +147 -0
- django_micboard-26.7.15/micboard/services/sync/discovery_approval_resolution.py +259 -0
- django_micboard-26.7.15/micboard/services/sync/discovery_approval_service.py +359 -0
- django_micboard-26.7.15/micboard/services/sync/discovery_candidate_source_service.py +162 -0
- django_micboard-26.7.15/micboard/services/sync/discovery_claim_service.py +97 -0
- django_micboard-26.7.15/micboard/services/sync/discovery_configuration_service.py +128 -0
- django_micboard-26.7.15/micboard/services/sync/discovery_dtos.py +97 -0
- django_micboard-26.7.15/micboard/services/sync/discovery_execution_service.py +240 -0
- django_micboard-26.7.15/micboard/services/sync/discovery_queue_service.py +234 -0
- django_micboard-26.7.15/micboard/services/sync/discovery_service.py +275 -0
- django_micboard-26.7.15/micboard/services/sync/discovery_source_cursor_service.py +199 -0
- django_micboard-26.7.15/micboard/services/sync/discovery_sync_service.py +309 -0
- django_micboard-26.7.15/micboard/services/sync/discovery_trigger_service.py +200 -0
- django_micboard-26.7.15/micboard/services/sync/discovery_utils.py +248 -0
- django_micboard-26.7.15/micboard/services/sync/polling_api.py +117 -0
- django_micboard-26.7.15/micboard/services/sync/polling_dtos.py +92 -0
- django_micboard-26.7.15/micboard/services/sync/polling_service.py +158 -0
- django_micboard-26.7.15/micboard/settings/admin_theme.py +73 -0
- django_micboard-26.7.15/micboard/settings/defaults.py +11 -0
- django_micboard-26.7.15/micboard/settings/deployment_controls.py +34 -0
- django_micboard-26.7.15/micboard/settings/scope_policy.py +42 -0
- django_micboard-26.7.15/micboard/static/micboard/css/about.scss +10 -0
- django_micboard-26.7.15/micboard/static/micboard/css/accessibility.css +133 -0
- django_micboard-26.7.15/micboard/static/micboard/css/accessibility.scss +133 -0
- django_micboard-26.7.15/micboard/static/micboard/css/theme.css +15568 -0
- django_micboard-26.7.15/micboard/static/micboard/css/theme.css.map +1 -0
- django_micboard-26.7.15/micboard/static/micboard/favicon.png +0 -0
- django_micboard-26.7.15/micboard/static/micboard/images/field_unit_default.svg +8 -0
- django_micboard-26.7.15/micboard/static/micboard/images/ulxd1_wl185.svg +8 -0
- django_micboard-26.7.15/micboard/static/micboard/js/about.js +9 -0
- django_micboard-26.7.15/micboard/static/micboard/js/app.js +292 -0
- django_micboard-26.7.15/micboard/static/micboard/js/channelview.js +314 -0
- django_micboard-26.7.15/micboard/static/micboard/js/chart-smoothie.js +109 -0
- django_micboard-26.7.15/micboard/static/micboard/js/config.js +230 -0
- django_micboard-26.7.15/micboard/static/micboard/js/data.js +97 -0
- django_micboard-26.7.15/micboard/static/micboard/js/display.js +92 -0
- django_micboard-26.7.15/micboard/static/micboard/js/dnd.js +178 -0
- django_micboard-26.7.15/micboard/static/micboard/js/extended.js +114 -0
- django_micboard-26.7.15/micboard/static/micboard/js/gif.js +31 -0
- django_micboard-26.7.15/micboard/static/micboard/js/kbd.js +127 -0
- django_micboard-26.7.15/micboard/static/micboard/js/venues.js +8 -0
- django_micboard-26.7.15/micboard/static/micboard/js/web.js +8 -0
- django_micboard-26.7.15/micboard/static/micboard/logo.png +0 -0
- django_micboard-26.7.15/micboard/static/micboard/vendor/htmx/LICENSE +13 -0
- django_micboard-26.7.15/micboard/static/micboard/vendor/htmx/htmx-2.0.7.min.js +1 -0
- django_micboard-26.7.15/micboard/tasks/__init__.py +5 -0
- django_micboard-26.7.15/micboard/tasks/maintenance/__init__.py +1 -0
- django_micboard-26.7.15/micboard/tasks/maintenance/charger.py +28 -0
- django_micboard-26.7.15/micboard/tasks/monitoring/__init__.py +1 -0
- django_micboard-26.7.15/micboard/tasks/monitoring/health.py +121 -0
- django_micboard-26.7.15/micboard/tasks/monitoring/sse.py +13 -0
- django_micboard-26.7.15/micboard/tasks/monitoring/websocket.py +15 -0
- django_micboard-26.7.15/micboard/tasks/sync/__init__.py +1 -0
- django_micboard-26.7.15/micboard/tasks/sync/discovery.py +136 -0
- django_micboard-26.7.15/micboard/tasks/sync/polling.py +131 -0
- django_micboard-26.7.15/micboard/templates/admin/micboard/hardware_layout.html +106 -0
- django_micboard-26.7.15/micboard/templates/admin/micboard/receiver_change_form.html +239 -0
- django_micboard-26.7.15/micboard/templates/admin/micboard/receiver_changelist.html +11 -0
- django_micboard-26.7.15/micboard/templates/admin/micboard/settings_diff_stub.html +61 -0
- django_micboard-26.7.15/micboard/templates/micboard/about.html +26 -0
- django_micboard-26.7.15/micboard/templates/micboard/alert_detail.html +166 -0
- django_micboard-26.7.15/micboard/templates/micboard/alerts.html +137 -0
- django_micboard-26.7.15/micboard/templates/micboard/all_buildings_view.html +14 -0
- django_micboard-26.7.15/micboard/templates/micboard/all_rooms_view.html +10 -0
- django_micboard-26.7.15/micboard/templates/micboard/assignments/form.html +95 -0
- django_micboard-26.7.15/micboard/templates/micboard/assignments.html +50 -0
- django_micboard-26.7.15/micboard/templates/micboard/base.html +198 -0
- django_micboard-26.7.15/micboard/templates/micboard/charger_dashboard.html +104 -0
- django_micboard-26.7.15/micboard/templates/micboard/displaywall_list.html +20 -0
- django_micboard-26.7.15/micboard/templates/micboard/emails/alert_notification.html +155 -0
- django_micboard-26.7.15/micboard/templates/micboard/emails/alert_notification.txt +20 -0
- django_micboard-26.7.15/micboard/templates/micboard/index.html +62 -0
- django_micboard-26.7.15/micboard/templates/micboard/kiosk/display.html +82 -0
- django_micboard-26.7.15/micboard/templates/micboard/kiosk/display_content.html +69 -0
- django_micboard-26.7.15/micboard/templates/micboard/kiosk/section_list.html +22 -0
- django_micboard-26.7.15/micboard/templates/micboard/kiosk/wall_detail.html +11 -0
- django_micboard-26.7.15/micboard/templates/micboard/kiosk/wall_list.html +20 -0
- django_micboard-26.7.15/micboard/templates/micboard/partials/alert_row.html +29 -0
- django_micboard-26.7.15/micboard/templates/micboard/partials/alert_rows.html +53 -0
- django_micboard-26.7.15/micboard/templates/micboard/partials/assignment_row.html +28 -0
- django_micboard-26.7.15/micboard/templates/micboard/partials/assignment_rows.html +7 -0
- django_micboard-26.7.15/micboard/templates/micboard/partials/channel_card.html +21 -0
- django_micboard-26.7.15/micboard/templates/micboard/partials/charger_grid.html +65 -0
- django_micboard-26.7.15/micboard/templates/micboard/partials/charger_slot.html +17 -0
- django_micboard-26.7.15/micboard/templates/micboard/partials/device_tiles.html +52 -0
- django_micboard-26.7.15/micboard/templates/micboard/partials/empty.html +3 -0
- django_micboard-26.7.15/micboard/templates/micboard/partials/wall_section.html +40 -0
- django_micboard-26.7.15/micboard/templates/micboard/receiver_browse.html +70 -0
- django_micboard-26.7.15/micboard/templates/micboard/rooms_in_building_view.html +10 -0
- django_micboard-26.7.15/micboard/templates/micboard/settings/bulk_config.html +15 -0
- django_micboard-26.7.15/micboard/templates/micboard/settings/manufacturer_config.html +15 -0
- django_micboard-26.7.15/micboard/templates/micboard/settings/overview.html +92 -0
- django_micboard-26.7.15/micboard/templatetags/__init__.py +0 -0
- django_micboard-26.7.15/micboard/templatetags/micboard_tags.py +23 -0
- django_micboard-26.7.15/micboard/urls.py +126 -0
- django_micboard-26.7.15/micboard/utils/dependencies.py +88 -0
- django_micboard-26.7.15/micboard/utils/exception_logging.py +13 -0
- django_micboard-26.7.15/micboard/utils/mac_address.py +44 -0
- django_micboard-26.7.15/micboard/views/__init__.py +1 -0
- django_micboard-26.7.15/micboard/views/alerts.py +116 -0
- django_micboard-26.7.15/micboard/views/assignments.py +259 -0
- django_micboard-26.7.15/micboard/views/charger_dashboard.py +60 -0
- django_micboard-26.7.15/micboard/views/dashboard.py +193 -0
- django_micboard-26.7.15/micboard/views/kiosk.py +188 -0
- django_micboard-26.7.15/micboard/views/partials.py +90 -0
- django_micboard-26.7.15/micboard/views/settings.py +164 -0
- django_micboard-26.7.15/micboard/websockets/__init__.py +0 -0
- django_micboard-26.7.15/micboard/websockets/consumers.py +281 -0
- django_micboard-26.7.15/micboard/websockets/routing.py +12 -0
- django_micboard-26.7.15/pyproject.toml +438 -0
- django_micboard-26.7.15/setup.cfg +4 -0
- django_micboard-26.7.15/tests/test_access_security.py +589 -0
- django_micboard-26.7.15/tests/test_activity_log_admin.py +164 -0
- django_micboard-26.7.15/tests/test_admin_audit_checks.py +339 -0
- django_micboard-26.7.15/tests/test_admin_channels_coverage.py +309 -0
- django_micboard-26.7.15/tests/test_admin_chassis_refresh.py +105 -0
- django_micboard-26.7.15/tests/test_admin_configuration_discovery_coverage.py +256 -0
- django_micboard-26.7.15/tests/test_admin_custom_access.py +170 -0
- django_micboard-26.7.15/tests/test_admin_discovered_device_coverage.py +331 -0
- django_micboard-26.7.15/tests/test_admin_integrations_realtime_coverage.py +180 -0
- django_micboard-26.7.15/tests/test_admin_manufacturer_scope_coverage.py +276 -0
- django_micboard-26.7.15/tests/test_admin_mixins.py +80 -0
- django_micboard-26.7.15/tests/test_admin_settings_coverage.py +277 -0
- django_micboard-26.7.15/tests/test_admin_sortable_tenant_security.py +231 -0
- django_micboard-26.7.15/tests/test_admin_tenant_access.py +541 -0
- django_micboard-26.7.15/tests/test_admin_users.py +35 -0
- django_micboard-26.7.15/tests/test_admin_wireless_chassis_coverage.py +280 -0
- django_micboard-26.7.15/tests/test_alert_live_fragment.py +181 -0
- django_micboard-26.7.15/tests/test_alert_view_branches.py +98 -0
- django_micboard-26.7.15/tests/test_api_server_admin_security.py +126 -0
- django_micboard-26.7.15/tests/test_assignment_live_fragment.py +63 -0
- django_micboard-26.7.15/tests/test_assignment_view_branches.py +318 -0
- django_micboard-26.7.15/tests/test_async_monitoring_tasks.py +245 -0
- django_micboard-26.7.15/tests/test_audit_admin_command.py +405 -0
- django_micboard-26.7.15/tests/test_audit_regulatory_commands.py +171 -0
- django_micboard-26.7.15/tests/test_authenticated_transport_security.py +244 -0
- django_micboard-26.7.15/tests/test_bulk_settings_form_branches.py +242 -0
- django_micboard-26.7.15/tests/test_chassis_regulatory_service.py +263 -0
- django_micboard-26.7.15/tests/test_chassis_transaction_lifecycle.py +464 -0
- django_micboard-26.7.15/tests/test_ci_contracts.py +310 -0
- django_micboard-26.7.15/tests/test_configuration_admin_security.py +214 -0
- django_micboard-26.7.15/tests/test_configuration_form_branches.py +53 -0
- django_micboard-26.7.15/tests/test_core_only_host.py +31 -0
- django_micboard-26.7.15/tests/test_custom_user_host.py +30 -0
- django_micboard-26.7.15/tests/test_dashboard_access.py +138 -0
- django_micboard-26.7.15/tests/test_dashboard_view_branches.py +207 -0
- django_micboard-26.7.15/tests/test_deduplication_log_redaction.py +222 -0
- django_micboard-26.7.15/tests/test_discovery_command_coverage.py +212 -0
- django_micboard-26.7.15/tests/test_discovery_monitor_sync_command_coverage.py +90 -0
- django_micboard-26.7.15/tests/test_docs_requirements_script.py +63 -0
- django_micboard-26.7.15/tests/test_documentation_paths.py +32 -0
- django_micboard-26.7.15/tests/test_efis_init_commands.py +96 -0
- django_micboard-26.7.15/tests/test_example_settings.py +25 -0
- django_micboard-26.7.15/tests/test_exception_contracts.py +124 -0
- django_micboard-26.7.15/tests/test_factory_registry.py +212 -0
- django_micboard-26.7.15/tests/test_httpx_clients.py +349 -0
- django_micboard-26.7.15/tests/test_huey_integration.py +56 -0
- django_micboard-26.7.15/tests/test_huey_task_wrappers.py +141 -0
- django_micboard-26.7.15/tests/test_import_architecture.py +113 -0
- django_micboard-26.7.15/tests/test_import_devices_command.py +131 -0
- django_micboard-26.7.15/tests/test_import_service.py +110 -0
- django_micboard-26.7.15/tests/test_kiosk_live_refresh.py +174 -0
- django_micboard-26.7.15/tests/test_kiosk_view_branches.py +201 -0
- django_micboard-26.7.15/tests/test_lifecycle_hooks.py +402 -0
- django_micboard-26.7.15/tests/test_mac_address_utils.py +24 -0
- django_micboard-26.7.15/tests/test_maintenance_audit_service.py +124 -0
- django_micboard-26.7.15/tests/test_maintenance_command_contracts.py +35 -0
- django_micboard-26.7.15/tests/test_maintenance_efis_service.py +183 -0
- django_micboard-26.7.15/tests/test_maintenance_logging_mode_service.py +41 -0
- django_micboard-26.7.15/tests/test_manufacturer_config_validation.py +206 -0
- django_micboard-26.7.15/tests/test_manufacturer_settings_form_branches.py +88 -0
- django_micboard-26.7.15/tests/test_metrics_network_coverage.py +158 -0
- django_micboard-26.7.15/tests/test_migration_integrity_script.py +33 -0
- django_micboard-26.7.15/tests/test_model_display_audit_coverage.py +268 -0
- django_micboard-26.7.15/tests/test_model_manager_contract_coverage.py +179 -0
- django_micboard-26.7.15/tests/test_monitoring_transport_coverage.py +850 -0
- django_micboard-26.7.15/tests/test_multitenancy_admin_middleware_coverage.py +257 -0
- django_micboard-26.7.15/tests/test_multitenancy_runtime.py +752 -0
- django_micboard-26.7.15/tests/test_notification_broadcast.py +206 -0
- django_micboard-26.7.15/tests/test_notification_email_signal_connection.py +119 -0
- django_micboard-26.7.15/tests/test_notification_routing.py +145 -0
- django_micboard-26.7.15/tests/test_package_metadata.py +105 -0
- django_micboard-26.7.15/tests/test_plugin_registry.py +187 -0
- django_micboard-26.7.15/tests/test_poll_realtime_logging_commands.py +209 -0
- django_micboard-26.7.15/tests/test_polling_api_service.py +220 -0
- django_micboard-26.7.15/tests/test_query_hotpaths.py +251 -0
- django_micboard-26.7.15/tests/test_realtime_broadcast_routing.py +272 -0
- django_micboard-26.7.15/tests/test_realtime_subscription_command_coverage.py +194 -0
- django_micboard-26.7.15/tests/test_receiver_browse.py +167 -0
- django_micboard-26.7.15/tests/test_release_workflow_security.py +292 -0
- django_micboard-26.7.15/tests/test_removed_domain_reexports.py +42 -0
- django_micboard-26.7.15/tests/test_removed_forwarding_shims.py +103 -0
- django_micboard-26.7.15/tests/test_removed_model_service_shims.py +51 -0
- django_micboard-26.7.15/tests/test_restricted_superuser_tenant_access.py +312 -0
- django_micboard-26.7.15/tests/test_rf_channel_lifecycle.py +321 -0
- django_micboard-26.7.15/tests/test_runtime_contracts.py +221 -0
- django_micboard-26.7.15/tests/test_runtime_dependency_model_coverage.py +279 -0
- django_micboard-26.7.15/tests/test_settings.py +609 -0
- django_micboard-26.7.15/tests/test_settings_admin_form_branches.py +241 -0
- django_micboard-26.7.15/tests/test_settings_admin_security.py +510 -0
- django_micboard-26.7.15/tests/test_settings_and_partial_view_branches.py +177 -0
- django_micboard-26.7.15/tests/test_settings_architecture.py +39 -0
- django_micboard-26.7.15/tests/test_settings_dependency_leaves.py +103 -0
- django_micboard-26.7.15/tests/test_settings_diff_admin.py +109 -0
- django_micboard-26.7.15/tests/test_settings_registry_branch_coverage.py +88 -0
- django_micboard-26.7.15/tests/test_settings_role_access.py +166 -0
- django_micboard-26.7.15/tests/test_settings_service.py +396 -0
- django_micboard-26.7.15/tests/test_shared_runtime_coverage.py +120 -0
- django_micboard-26.7.15/tests/test_shure_discovery_sync.py +42 -0
- django_micboard-26.7.15/tests/test_shure_imports.py +15 -0
- django_micboard-26.7.15/tests/test_shure_websocket.py +153 -0
- django_micboard-26.7.15/tests/test_system_checks.py +48 -0
- django_micboard-26.7.15/tests/test_tenant_role_admin_policy.py +322 -0
- django_micboard-26.7.15/tests/test_ui_middleware_decorators_coverage.py +90 -0
- django_micboard-26.7.15/tests/test_vendor_device_clients.py +85 -0
- django_micboard-26.7.15/tests/test_vendor_discovery_and_transformers.py +229 -0
- django_micboard-26.7.15/tests/test_vendor_plugins_and_system_clients.py +232 -0
- django_micboard-26.7.15/tests/test_wall_section_partial_security.py +96 -0
- django_micboard-26.7.15/tests/test_websocket_access.py +389 -0
- django_micboard-26.7.15/tests/test_websocket_consumers.py +161 -0
- django_micboard-26.7.15/tests/test_wireless_chassis_admin_form_branches.py +57 -0
- django_micboard-26.7.15/tests/test_wireless_unit_lifecycle.py +312 -0
- django_micboard-26.7.15/tests/test_wireless_unit_service_api.py +106 -0
- django_micboard-26.7.15/tests/test_workflow_organization.py +121 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Environment consumed by example_project/settings.py.
|
|
2
|
+
#
|
|
3
|
+
# Copy this file to .env only as a local reference. Django and start-dev.sh do
|
|
4
|
+
# not load it implicitly. To use it for one command, run for example:
|
|
5
|
+
# uv run --env-file .env --no-sync python manage.py runserver
|
|
6
|
+
#
|
|
7
|
+
# Never commit a populated .env file. Production hosts should keep secrets in
|
|
8
|
+
# their platform's secret manager and use PostgreSQL; SQLite is for development.
|
|
9
|
+
|
|
10
|
+
# Django example project
|
|
11
|
+
DJANGO_SECRET_KEY=django-insecure-change-me-for-local-development
|
|
12
|
+
DJANGO_DEBUG=True
|
|
13
|
+
DJANGO_ALLOWED_HOSTS=localhost,127.0.0.1
|
|
14
|
+
|
|
15
|
+
# Leave unset for the local SQLite database.
|
|
16
|
+
# DJANGO_DATABASE_URL=postgresql://user:password@localhost:5432/micboard
|
|
17
|
+
|
|
18
|
+
# Shure System API values mapped into MICBOARD_CONFIG by the example project
|
|
19
|
+
MICBOARD_SHURE_API_BASE_URL=https://localhost:10000
|
|
20
|
+
MICBOARD_SHURE_API_SHARED_KEY=replace-with-your-shared-key
|
|
21
|
+
|
|
22
|
+
# Hostnames that Manufacturer API Server rows may contact
|
|
23
|
+
MICBOARD_API_SERVER_ALLOWED_HOSTS=localhost
|
|
@@ -0,0 +1,561 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Calendar Versioning](https://calver.org/).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [26.07.15] - 2026-07-15
|
|
11
|
+
|
|
12
|
+
2370c40 - feat(release): Default to current CalVer (#105) (bandwith)
|
|
13
|
+
eaa480d - fix(release): Make publication atomic and retryable (#104) (bandwith)
|
|
14
|
+
20049d2 - ci(release): Harden package provenance (#103) (bandwith)
|
|
15
|
+
1f8bf42 - ci(security): Protect solo-maintainer releases (#101) (bandwith)
|
|
16
|
+
5b9ce4f - ref(security): Harden tenant, service, and release boundaries (#98) (bandwith)
|
|
17
|
+
552b3ff - ci: Upgrade GitHub Actions to Node 24 (#96) (bandwith)
|
|
18
|
+
a62ca87 - ref: Eliminate cyclic lifecycle dependencies (#93) (bandwith)
|
|
19
|
+
0d67373 - fix: harden tenant-safe operational workflows (#88) (bandwith)
|
|
20
|
+
255faff - chore(deps): update dependency pillow to v12.3.0 (#86) (renovate[bot])
|
|
21
|
+
1158b54 - chore(deps): update dependency pathspec to v1.1.1 (#85) (renovate[bot])
|
|
22
|
+
3bc86d9 - test: expand service-layer coverage (#87) (bandwith)
|
|
23
|
+
0354eab - chore(deps): update dependency idna to v3.18 (#84) (renovate[bot])
|
|
24
|
+
eabf7e7 - chore(deps): update dependency certifi to v2026.6.17 (#83) (renovate[bot])
|
|
25
|
+
d40559d - test: Add complete model factory catalog (#82) (bandwith)
|
|
26
|
+
5bcd630 - chore(deps): update uv to 0.11.28 (Sam Kuonen)
|
|
27
|
+
160d00e - chore(deps): update astral-sh/setup-uv action to v8.3.2 (#80) (renovate[bot])
|
|
28
|
+
8ad8dbc - feat: Harden public reusable app boundaries (#79) (bandwith)
|
|
29
|
+
266d7e2 - Merge pull request #50 from justprosound/renovate/charset-normalizer-3.x (bandwith)
|
|
30
|
+
794b0a3 - chore(deps): update dependency charset-normalizer to v3.4.9 (renovate[bot])
|
|
31
|
+
2fcc8a8 - chore: add FUNDING.yml (bandwith)
|
|
32
|
+
4545c5c - fix: Replace pip install with uv pip install per project policy (Sam Kuonen)
|
|
33
|
+
5544b7a - feat: Add Sentry Warden AI code review (Sam Kuonen)
|
|
34
|
+
d76756a - chore: Fix pre-commit config and cleanup repository (Sam Kuonen)
|
|
35
|
+
20fe57f - refactor(models): extract band plan constants and functions from device_specs.py into band_plans.py (Sam Kuonen)
|
|
36
|
+
b91ccfd - fix(mypy): resolve 11 type errors in changed service files (Sam Kuonen)
|
|
37
|
+
5846477 - refactor: migrate integrations/common/ to services/common/base/, fix bulk_sync_devices bug (Sam Kuonen)
|
|
38
|
+
b05db6e - refactor(hardware): decompose into domain services, add settings service, fix mypy errors (Sam Kuonen)
|
|
39
|
+
f84cc5a - docs: allow f-strings in logging per user preference (Sam Kuonen)
|
|
40
|
+
1dc0de8 - refactor(admin): split configuration_and_logging.py into configuration.py and activity_logs.py (Sam Kuonen)
|
|
41
|
+
2236a8f - chore: update uv.lock (Sam Kuonen)
|
|
42
|
+
db674a7 - refactor(core): decompose HardwareLifecycleManager into DeviceAPISyncService and DeviceHealthService (Sam Kuonen)
|
|
43
|
+
e867519 - refactor(discovery): decompose DiscoveryService into 5 single-responsibility services (Sam Kuonen)
|
|
44
|
+
abe7950 - refactor: remove manufacturers shim, GenericCRUDService, and dead code; fix logging f-strings (Sam Kuonen)
|
|
45
|
+
5797f7c - docs: add 4 product requirement documents aligned with ADRs and issues (Sam Kuonen)
|
|
46
|
+
33d95b2 - docs: add codebase context doc and 8 architecture decision records (Sam Kuonen)
|
|
47
|
+
95fc1fb - fix: remove stray bold formatting in AGENTS.md Agent skills section (Sam Kuonen)
|
|
48
|
+
a1185d3 - chore: scaffold Matt Pocock's engineering skills config (Sam Kuonen)
|
|
49
|
+
46db3ca - fix: register admin modules and fix import paths (Sam Kuonen)
|
|
50
|
+
f82e3d7 - chore: remove refactoring documentation artifacts (Sam Kuonen)
|
|
51
|
+
77d4823 - refactor: complete E402 lint compliance and fix import paths (Sam Kuonen)
|
|
52
|
+
257a058 - typing(integration_patterns): add casts and guards; fix mypy issues (Sam Kuonen)
|
|
53
|
+
c3a5fd0 - typing: improve GenericCRUDService generics; cast form fields & cleaned_data fixes (Sam Kuonen)
|
|
54
|
+
1cb22cf - chore(lint): add __init__ docstrings and minor import noqa (Sam Kuonen)
|
|
55
|
+
abcc436 - Merge release prep changes (Sam Kuonen)
|
|
56
|
+
82cdbda - feat: Add 12 specialized GitHub Copilot agents from awesome-copilot (Sam Kuonen)
|
|
57
|
+
52bfd00 - Improve test coverage with proper exclusions and pragma comments (Sam Kuonen)
|
|
58
|
+
5a11d46 - fix: code standards compliance - resolve ruff violations (Sam Kuonen)
|
|
59
|
+
4127ca8 - test(coverage): improve plugin_registry coverage to 97% (Sam Kuonen)
|
|
60
|
+
b5aa9da - massive work in progress (Sam Kuonen)
|
|
61
|
+
ce575a9 - refactor(release-prep): standardize configuration, improve docs, expand tests (Sam Kuonen)
|
|
62
|
+
434233d - massive work in progress (Sam Kuonen)
|
|
63
|
+
7176b3f - checkpoint: saving state before further changes (skipped linting due to environment issues) (Sam Kuonen)
|
|
64
|
+
c21977a - chore: finalize production release preparation (Sam Kuonen)
|
|
65
|
+
334b4f7 - docs: add Phase 4.2 completion summary (Sam Kuonen)
|
|
66
|
+
3605b56 - refactor: extract common HTTP client to eliminate duplication (Sam Kuonen)
|
|
67
|
+
edb45e3 - docs: consolidate documentation and update Docker for GT live testing (Sam Kuonen)
|
|
68
|
+
e65cd4e - cleanup: remove temporary files and consolidate documentation (Sam Kuonen)
|
|
69
|
+
ee4a09c - docs: add Phase 3 completion summary and developer quick reference (Sam Kuonen)
|
|
70
|
+
cb23ff7 - refactor: integrate lifecycle manager into polling services (Phase 3) (Sam Kuonen)
|
|
71
|
+
2bd55f6 - End of day commit: Updated README to clearly state major work in progress, added comprehensive tests, fixed various issues, and improved codebase structure (Sam Kuonen)
|
|
72
|
+
91da9f6 - Fix: Resolve pre-commit hook issues and mypy errors (Sam Kuonen)
|
|
73
|
+
25f566a - Complete Django Micboard refactor: Phase 1 modularization and Phase 2 core features (Sam Kuonen)
|
|
74
|
+
6d457d5 - Phase 1: Codebase audit and modularization refactor (Sam Kuonen)
|
|
75
|
+
3116436 - Fix signals/view issues: signatures, returns, cache guard, serialization (Sam Kuonen)
|
|
76
|
+
5320d67 - Refactor: Centralize Shure discovery and polling logic into signals; prepare API to emit discovery/refresh events (Sam Kuonen)
|
|
77
|
+
efcc7e5 - Remove Windows container artifacts and related scripts; keep README docs (Sam Kuonen)
|
|
78
|
+
89b947d - Add Windows demo image support: Dockerfile updates, CI workflow, installer handling and build helper (Sam Kuonen)
|
|
79
|
+
26ebeee - docs: admin layout + health, demo: windows dockerfile, entrypoint and conditional mock data; docker-compose restart policy (Sam Kuonen)
|
|
80
|
+
22cccf9 - Apply ruff formatting fixes (Sam Kuonen)
|
|
81
|
+
50fdaa7 - style: ruff format applied (Sam Kuonen)
|
|
82
|
+
1af4001 - chore: remove shim package and initial migration files (Sam Kuonen)
|
|
83
|
+
2346787 - docs: remove dev install and test step from documentation workflow (bandwith)
|
|
84
|
+
22ba8f6 - chore: add docs extra to pyproject and regenerate pinned requirements (bandwith)
|
|
85
|
+
a4bee37 - docs: simplify Read the Docs config — update build tools, move requirements and pre-install mkdocs-material (bandwith)
|
|
86
|
+
633a4fa - docs: refine Read the Docs config - move post_install and remove setuptools install (bandwith)
|
|
87
|
+
d1192e1 - docs: add API reference pages, MkDocs macros and refine docs build/config (bandwith)
|
|
88
|
+
f4d95bf - ci: make Coveralls upload non-fatal and add coverage.lcov to .gitignore (bandwith)
|
|
89
|
+
2ebfed1 - ci: cache matrix.json and make matrix generation resilient (bandwith)
|
|
90
|
+
04da1f1 - ci: show generated matrix and add safe fallback to generate-matrix.py (bandwith)
|
|
91
|
+
a830f5a - ci: add concurrency group and limit matrix parallelism to 2 (bandwith)
|
|
92
|
+
416fbe6 - ci: add concurrency group and limit matrix parallelism to 2 (bandwith)
|
|
93
|
+
11aad95 - style: apply ruff fixes to generate-matrix.py (bandwith)
|
|
94
|
+
0595fea - ci: standardize renovate condition quoting and use job-level test timeout (bandwith)
|
|
95
|
+
c046949 - chore: use pyproject.toml for pip-compile and consolidate requirements (bandwith)
|
|
96
|
+
f2431f2 - chore: tidy typing, tests and dev deps; add types-requests & mypy hook (bandwith)
|
|
97
|
+
d0e6db5 - Add multi-manufacturer plugin architecture (bandwith)
|
|
98
|
+
8892bb8 - Add timeout to pytest in CI to prevent hanging tests (bandwith)
|
|
99
|
+
4d531be - Fix CI workflow and dependencies (bandwith)
|
|
100
|
+
aacdec3 - chore: bump pre-commit hooks & ruff, replace bandit with mypy; tidy typing and tests (bandwith)
|
|
101
|
+
bb15441 - refactor: modernize model Meta typing, tidy docs/config, tests & entrypoint (bandwith)
|
|
102
|
+
2fd8669 - docs: Replace Codecov badge with Coveralls badge (bandwith)
|
|
103
|
+
9b27e63 - ci: Prevent workflows from running on Renovate branches (bandwith)
|
|
104
|
+
ed4562c - feat: Major feature update and refactoring (bandwith)
|
|
105
|
+
eee7a51 - docs: Add comprehensive AI agent instructions (bandwith)
|
|
106
|
+
2158d67 - docs: Consolidate documentation for automated hosting (bandwith)
|
|
107
|
+
c9fd5d8 - chore: Remove legacy test files and add missing docstrings (bandwith)
|
|
108
|
+
669fd7a - refactor: Split large files into organized packages for maintainability (bandwith)
|
|
109
|
+
10580dd - refactor: Create centralized serializers module for DRY principles (bandwith)
|
|
110
|
+
c0a90ca - feat: Django reusable app optimizations - admin enhancements, model improvements, API endpoints (bandwith)
|
|
111
|
+
bb968a2 - Django reusable app optimizations: settings validation, health checks, connection pooling, comprehensive signal handlers (bandwith)
|
|
112
|
+
397443d - Dev tooling: VS Code pytest runner + debug, pytest.ini, test migrations disabled; Shure API enrichment; remove splash assets; docs and tests updated (bandwith)
|
|
113
|
+
8b3fe04 - Refactor: Update device polling and model definitions (bandwith)
|
|
114
|
+
8e7a0ca - Major refactor: split views, modernize frontend, add templates & tests, update packaging (bandwith)
|
|
115
|
+
1ae650a - Switch license to AGPL v3: stronger author protection for SaaS usage (bandwith)
|
|
116
|
+
a7c2ce4 - Update repository URLs to justprosound organization (bandwith)
|
|
117
|
+
d961693 - first commit (Sam Kuonen)
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
### Added
|
|
121
|
+
|
|
122
|
+
- **Configuration API** (`micboard.services.settings.settings_service`): Unified settings service for host,
|
|
123
|
+
feature-flag, and scoped database configuration
|
|
124
|
+
- **Architecture Documentation** (`micboard/ARCHITECTURE.md`): Comprehensive guide for developers on plugin architecture, multi-tenancy, and settings registry
|
|
125
|
+
- **Expanded Test Suite**: Tests for configuration module, plugin registry, and settings behavior
|
|
126
|
+
- **Focused `.env.example`**: Minimal example-project environment values with explicit API-server
|
|
127
|
+
destination allowlisting
|
|
128
|
+
- **Enhanced README**: Detailed reusable app integration guide with plugin architecture examples
|
|
129
|
+
- **Comprehensive CONTRIBUTING.md**: Migration guidelines, code patterns, and development workflow documentation
|
|
130
|
+
- **Settings overrides diff view**: Admin view and template for scope-level configuration diffs
|
|
131
|
+
- **Native Huey integration**: Optional `huey.contrib.djhuey` task registration, Redis-backed
|
|
132
|
+
host configuration, and an in-memory test backend
|
|
133
|
+
- **Access-control regression coverage**: User-scoped tests for alerts, assignments, chargers,
|
|
134
|
+
display walls, kiosks, and nested resources
|
|
135
|
+
- **Reusable-app host coverage**: Core-only and custom-user host settings, migration integrity,
|
|
136
|
+
package API, installed-wheel, query-budget, and WebSocket routing regression tests
|
|
137
|
+
- **Release verification**: Wheel-content validation and installed-wheel smoke testing
|
|
138
|
+
- **Dependency-change security gate**: Reject pull requests that introduce moderate-or-higher
|
|
139
|
+
vulnerabilities across runtime, development, or unknown dependency scopes, and audit the full
|
|
140
|
+
lockfile during push, pull-request, manual, and weekly CI runs
|
|
141
|
+
- **Signed release provenance**: Attest sealed wheel and source distributions with isolated
|
|
142
|
+
Sigstore-backed GitHub build provenance before either package registry can publish them
|
|
143
|
+
- **Attested release SBOMs**: Generate an SPDX JSON bill of materials, bind it to the wheel and
|
|
144
|
+
source archive with a Sigstore SBOM attestation, and ship it with the release checksums
|
|
145
|
+
- **PEP 740 package attestations**: Sign each registry upload with its environment-bound OIDC
|
|
146
|
+
identity and publish the matching attestations alongside immutable GitHub release assets
|
|
147
|
+
- **NIST SSDF workflow evidence**: Map checked-in automation controls to the final SSDF 1.1
|
|
148
|
+
practices while identifying SSDF 1.2 as a draft
|
|
149
|
+
- **Complete model factory catalog**: Domain-grouped Factory Boy adapters for every installed
|
|
150
|
+
project model, with registry completeness, persistence, validation, optional-app, and
|
|
151
|
+
swappable-user coverage
|
|
152
|
+
- **Service-layer regression coverage**: Direct Factory Boy-backed tests for discovery,
|
|
153
|
+
deduplication, hardware lifecycle, locations, performers, alerts, and connections, with every
|
|
154
|
+
targeted module at 90% coverage or higher
|
|
155
|
+
- **Import architecture gate**: Detect internal strongly connected components and reject
|
|
156
|
+
model-to-service, model-to-task, service-to-task, and service-to-app dependency reversals
|
|
157
|
+
- **Performance contracts**: Query budgets for discovery batching, alert fanout, connection health,
|
|
158
|
+
and manufacturer statistics
|
|
159
|
+
- **Admin workflow coverage**: Request-level smoke tests for tenant-scoped chassis, discovery
|
|
160
|
+
approval, monitoring summaries, settings diffs, and HTMX channel fragments
|
|
161
|
+
- **Plugin development guide**: Live registry, shared transport, discovery, transformer,
|
|
162
|
+
protocol-specific streaming, security, native Huey, and test contracts for new manufacturers
|
|
163
|
+
- **Maintenance workflow coverage**: Branch-focused tests for supported discovery, diagnostics,
|
|
164
|
+
audit, settings, metrics, and realtime subscription commands and services
|
|
165
|
+
- **Poll-to-alert lifecycle coverage**: Exercise a native Huey task through persisted API-server
|
|
166
|
+
credentials, normalized device telemetry, alert persistence, recipient delivery, replay
|
|
167
|
+
deduplication, and cross-tenant rejection
|
|
168
|
+
- **Live monitoring fragments**: Add bounded HTMX row/grid refreshes for alerts, assignments,
|
|
169
|
+
chargers, kiosks, and wall sections without history-wide polling counts
|
|
170
|
+
- **Receiver browsing coverage**: Add tenant-scoped, eager-loaded building, room, performer,
|
|
171
|
+
priority, and device-role browsing through stable primary-key routes
|
|
172
|
+
- **Movement audit coverage**: Record manufacturer-detected chassis address changes as typed
|
|
173
|
+
`DeviceMovementLog` events inside the serialized synchronization transaction
|
|
174
|
+
- **Polling audit coverage**: Persist bounded, secret-free `ServiceSyncLog` rows for supported
|
|
175
|
+
manufacturer polling runs and expose the operational history through a read-only admin
|
|
176
|
+
|
|
177
|
+
### Changed
|
|
178
|
+
|
|
179
|
+
- **Solo-maintainer release protection**: Keep pull requests mandatory without an impossible
|
|
180
|
+
self-approval requirement, preserve strict app-bound checks and signed linear history, require
|
|
181
|
+
non-bypassable Code Owners approval at the production PyPI environment, and allow only squash
|
|
182
|
+
merges
|
|
183
|
+
- **Organized GitHub Actions bootstrap**: Reuse one pinned uv/Python setup action across
|
|
184
|
+
repository-controlled jobs, retain direct immutable setup in privileged jobs, enforce explicit
|
|
185
|
+
job timeouts, expose one stable aggregate check for branch protection, assign valid code owners,
|
|
186
|
+
and document the workflow trust boundaries
|
|
187
|
+
- **Observed release checks**: Dispatch CI, dependency-review, and documentation checks for the
|
|
188
|
+
exact release head, wait for those workflow runs to succeed before merge, and separate Actions
|
|
189
|
+
dispatch, repository write, and publication dispatch permissions across jobs
|
|
190
|
+
- **Verified release promotion**: Create release metadata through GitHub's signed commit API,
|
|
191
|
+
build without workspace source overrides, verify TestPyPI digests before production approval,
|
|
192
|
+
publish production from the same sealed workflow run, make named artifacts and draft releases
|
|
193
|
+
safe to resume after job retries, and publish GitHub releases only after every integrity asset
|
|
194
|
+
is attached
|
|
195
|
+
- **Automatic release CalVer**: Default blank release dispatches to the current UTC `YY.MM.DD`
|
|
196
|
+
while retaining a validated manual override for backfills
|
|
197
|
+
- **Hardened build dependencies**: Upgrade the exactly pinned build backend to setuptools 83.0.0
|
|
198
|
+
and wheel 0.47.0, and lock Twine plus the PEP 740 signer through uv
|
|
199
|
+
- **Credential-safe workflow checkouts**: Disable persisted Git credentials for every read-only
|
|
200
|
+
checkout, scope Warden provider secrets to its trusted review step, and request maintainer review
|
|
201
|
+
for workflow, toolchain, lockfile, and agent-policy changes through CODEOWNERS
|
|
202
|
+
- **Tenant-safe chassis admin writes**: Validate final location ownership in request-bound forms,
|
|
203
|
+
reject tenant-to-platform inventory escapes, and route admin creates and updates through the
|
|
204
|
+
canonical organization-quota persistence seam
|
|
205
|
+
- **Bounded discovery approval plans**: Reject missing queue and hardware permissions before row
|
|
206
|
+
locks, cap selected and same-address conflict scopes at 100 rows and per-type inventory locks at
|
|
207
|
+
400 rows, and isolate inventory, target resolution, and conflict validation behind one plan
|
|
208
|
+
interface
|
|
209
|
+
- **Canonical service exceptions**: Move settings, admin-audit setup, and realtime lease failures
|
|
210
|
+
under `MicboardError`, reject future service-local exception roots, and translate unexpected API
|
|
211
|
+
polling failures to a fixed secret-safe public error without flattening known transport metadata
|
|
212
|
+
- **Focused vendor clients**: Remove unverified test-only enrichment endpoints, Shure forwarding
|
|
213
|
+
methods, and duplicate Sennheiser polling orchestration; production plugins continue to use the
|
|
214
|
+
shared transport, discovery, transformation, and subscription contracts directly
|
|
215
|
+
- **Bounded vendor coordination**: Scope shared rate-limit locks to each remote API endpoint and
|
|
216
|
+
reject Shure discovery updates whose merged remote and requested address list exceeds the global
|
|
217
|
+
candidate limit
|
|
218
|
+
- **Protected release pipeline**: Prepare version and changelog changes on a release pull request,
|
|
219
|
+
run the required CI, CodeQL, Bandit, package, and documentation checks before auto-merge, and
|
|
220
|
+
publish the exact protected merge commit from environment-bound OIDC jobs
|
|
221
|
+
- **Least-privilege Warden token**: Reduce repository contents access from write to read while
|
|
222
|
+
retaining only the pull-request and check scopes required for automated review
|
|
223
|
+
- **Explicit service imports**: Remove root package re-exports; import services from their owning
|
|
224
|
+
domain modules
|
|
225
|
+
- **Explicit domain imports**: Remove unused domain-package service and view re-exports so package
|
|
226
|
+
imports no longer eagerly load unrelated implementations
|
|
227
|
+
- **Explicit model imports**: Keep `micboard.models` for Django discovery only and import model
|
|
228
|
+
classes from their defining domain modules
|
|
229
|
+
- **Validated service DTOs**: Replace mutable hardware-normalization and deduplication result
|
|
230
|
+
containers with Pydantic DTOs, including a mutually exclusive deduplication outcome enum
|
|
231
|
+
- **Canonical chassis persistence**: Route manufacturer sync, discovery approval, promotion,
|
|
232
|
+
imports, refresh, realtime updates, lifecycle creation, and regulatory repair through one
|
|
233
|
+
`WirelessChassisWrite` DTO seam; remove private cross-service writers
|
|
234
|
+
- **Focused chassis ownership**: Split save lifecycle from band-plan detection and regulatory
|
|
235
|
+
coverage, return typed band-plan results, and delete the mixed wireless-chassis service module
|
|
236
|
+
- **Settings persistence boundary**: Route bulk and manufacturer setting forms through one
|
|
237
|
+
authorization-aware DTO service that performs scoped bulk definition lookup, typed
|
|
238
|
+
serialization, upsert, and cache invalidation
|
|
239
|
+
- **Canonical settings ownership**: Move scoped lookup under the settings domain, make
|
|
240
|
+
`SettingsService` the only production read/cache interface, keep deployment controls host-owned,
|
|
241
|
+
and delete the shared registry path and feature-flag facade
|
|
242
|
+
- **Bounded live projections**: Cap dashboard and kiosk sections, chargers, and slots after tenant
|
|
243
|
+
filtering; return typed truncation metadata and render explicit overflow notices
|
|
244
|
+
- **Bounded kiosk health**: Replace the unbounded connection-validation aggregator with a typed,
|
|
245
|
+
tenant-scoped health projection capped at 16 sections, 32 chargers per section, and 32 slots per
|
|
246
|
+
charger, including sentinel overflow metadata
|
|
247
|
+
- **Deep charger snapshots**: Return primitive nested Pydantic charger, slot, and performer DTOs;
|
|
248
|
+
load assignments only for occupied serial numbers and skip the query for empty grids
|
|
249
|
+
- **Database-ranked assignments**: Select one deterministic active performer assignment per
|
|
250
|
+
bounded wireless unit in SQL instead of materializing every candidate in Python
|
|
251
|
+
- **Indexed discovery approval**: Pre-index locked chassis and charger inventory by primary key,
|
|
252
|
+
API identity, and serial identity so large approval batches avoid quadratic scans while
|
|
253
|
+
preserving ambiguous matches for fail-closed validation
|
|
254
|
+
- **Organization device quotas**: Enforce finite chassis quotas under a locked organization row
|
|
255
|
+
for creates, upsert create branches, and transfers into a different owner while allowing
|
|
256
|
+
same-owner metadata updates at quota
|
|
257
|
+
- **Query-oriented services**: Split charger cache state, discovery candidate collection, and
|
|
258
|
+
bounded HTTP transport enforcement from their orchestration services
|
|
259
|
+
- **Domain package cleanup**: Remove model package re-exports, dead pagination/sync/tenant helpers,
|
|
260
|
+
the duplicate discovery-queue service, and the no-op manufacturer-default registry command path
|
|
261
|
+
- **Direct implementation calls**: Remove residual email and alert convenience functions,
|
|
262
|
+
settings, metadata, lifecycle, regulatory, and routing forwarders, the optional-dependency
|
|
263
|
+
alias, package-level feature-flag exports, the wildcard settings facade, and the no-op device
|
|
264
|
+
status synchronization hook instead of retaining shims
|
|
265
|
+
- **Complexity enforcement**: Remove every remaining McCabe and branch-count exemption after
|
|
266
|
+
simplifying the affected paths, so complexity rules now apply uniformly to production code
|
|
267
|
+
- **Hardware service cleanup**: Remove unused chassis activity/band-plan facades and dead battery,
|
|
268
|
+
capability, and asynchronous status-sync methods; callers use lifecycle, specification, and
|
|
269
|
+
band-plan implementations directly
|
|
270
|
+
- **Strict device-refresh plugins**: Call the required manufacturer plugin interface directly,
|
|
271
|
+
removing optional-method compatibility branches while retaining fail-closed vendor errors
|
|
272
|
+
- **Explicit task imports**: Remove legacy task aliases and import task functions from their
|
|
273
|
+
defining domain modules
|
|
274
|
+
- **Queued API-server checks**: Move admin-triggered vendor health checks to a hard-capped native
|
|
275
|
+
Huey batch that revalidates the initiating user's permission in the worker
|
|
276
|
+
- **Fair, bounded alert fanout**: Rotate shared-cache cursors through eligible wireless units,
|
|
277
|
+
active assignments, and active group recipients; cap assignment, recipient, and delivery work;
|
|
278
|
+
and revalidate current user, group, assignment, and tenant scope before persistence and email
|
|
279
|
+
- **Bounded manufacturer polling**: Fail closed on oversized vendor inventories, bulk-index device
|
|
280
|
+
identities instead of issuing per-device lookup queries, and chunk full-fleet realtime updates
|
|
281
|
+
- **Coalesced discovery dispatch**: Reconcile only after chassis identity changes, collapse
|
|
282
|
+
manufacturer-sync batches to one post-commit request, and suppress duplicate Huey enqueues with
|
|
283
|
+
a short fail-open shared-cache claim
|
|
284
|
+
- **Bounded charger polling**: Move native Huey charger work into a typed service, cap device,
|
|
285
|
+
station, slot, and vendor-text processing, resume list-like inventories across cached pages,
|
|
286
|
+
publish only full-cycle snapshots with a deterministic station prefix, deduplicate station
|
|
287
|
+
requests, read health once, and revalidate that queued manufacturers remain active
|
|
288
|
+
- **Service surface cleanup**: Remove unused unscoped hardware, location, performer, and
|
|
289
|
+
manufacturer query facades in favor of authenticated model managers and active service paths
|
|
290
|
+
- **Realtime event cleanup**: Remove the duplicate polling emitter and unused arbitrary error,
|
|
291
|
+
sync-completion, and discovery-approval WebSocket event paths
|
|
292
|
+
- **pyproject.toml**: Fixed package data inclusion for fixtures and migrations
|
|
293
|
+
- **MANIFEST.in**: Improved to include `.env.example` and exclude workspace-only files
|
|
294
|
+
- **.gitignore**: Enhanced to prevent tracking of development artifacts and egg-info directories
|
|
295
|
+
- **GitHub pre-commit hooks**: Reject edits or deletions of migration history, validate that new
|
|
296
|
+
migration files were generated by Django, and check model-to-migration drift for both app labels
|
|
297
|
+
- **Settings diff route**: Wire settings diff URL to the real view implementation
|
|
298
|
+
- **Supported runtimes**: Target Python 3.13 with Django 5.1, 5.2, and 6.0 CI coverage
|
|
299
|
+
- **GitHub Actions runtimes**: Upgrade checkout and artifact uploads to Node 24-based releases
|
|
300
|
+
- **Dependency management**: Standardize development, documentation, CI, and release commands on
|
|
301
|
+
locked `uv` environments
|
|
302
|
+
- **HTTP integrations**: Use `httpx` consistently with typed retry, rate-limit, and API error
|
|
303
|
+
handling
|
|
304
|
+
- **Bounded vendor transports**: Stream decoded HTTP and SSE data under configurable package
|
|
305
|
+
ceilings, clamp retry delays, reject oversized JSON responses before parsing, discard oversized
|
|
306
|
+
SSE lines and events without payload logging, and revoke queued or live vendor work when its
|
|
307
|
+
manufacturer becomes inactive while preserving the explicit `poll_devices --force` override
|
|
308
|
+
- **Public project cleanup**: Remove private-host branding, obsolete queue guidance, and stale
|
|
309
|
+
live-integration scripts
|
|
310
|
+
- **Operator tooling cleanup**: Remove destructive hard-coded seeding and vendor-specific scratch
|
|
311
|
+
diagnostics while retaining supported admin auditing, discovery, health, import, and monitoring
|
|
312
|
+
commands
|
|
313
|
+
- **Maintenance safeguards**: Bound CIDR expansion memory, fail closed outside regulatory-domain
|
|
314
|
+
limits, propagate discovery batch failures, and preserve accurate structured sync metadata
|
|
315
|
+
- **Quality floor**: Raise enforced branch coverage from 49% to 95%, inventory every distributable
|
|
316
|
+
Python module, and add behavioral contracts across services, models, commands, admin, and tasks
|
|
317
|
+
- **Discovery reconciliation**: Batch exclusivity checks and manufacturer API updates, preserve
|
|
318
|
+
remote state while configured sources are incomplete, rotate shared budgets fairly across local
|
|
319
|
+
inventory and configured scan definitions, and still remove database-proven cross-vendor
|
|
320
|
+
ownership conflicts
|
|
321
|
+
- **Monitoring queries**: Prefetch alert recipients and preferences, eager-load unhealthy
|
|
322
|
+
connection ownership, and aggregate connection statistics in two fixed queries
|
|
323
|
+
- **Settings access**: Route app startup and callers through `SettingsService`; raw
|
|
324
|
+
`MICBOARD_CONFIG` reads are isolated to the settings service
|
|
325
|
+
- **Settings dependency boundaries**: Move package defaults and exact-scope policy into
|
|
326
|
+
dependency-free modules so startup, models, and services share invariants without import cycles
|
|
327
|
+
- **Lifecycle boundaries**: Route model persistence events through explicit Django signal adapters
|
|
328
|
+
while services own validation, derived state, audit, discovery, and post-commit behavior
|
|
329
|
+
- **Realtime update persistence**: Share one service between SSE, WebSocket, and command entry
|
|
330
|
+
points, treating event payloads as partial snapshots that cannot mark unrelated devices offline
|
|
331
|
+
- **Realtime supervision**: Separate long-running SSE/WebSocket supervisors from polling, share a
|
|
332
|
+
renewable singleton lease across commands and native Huey entrypoints, and hard-bound device and
|
|
333
|
+
concurrency counts
|
|
334
|
+
- **Fair realtime supervision**: Rotate bounded inventory windows across rounds and restarts with a
|
|
335
|
+
shared-cache cursor and time-slice long-lived subscriptions through a fixed worker pool so blocked
|
|
336
|
+
or dropped connections cannot permanently starve later devices; reload eligible batches within
|
|
337
|
+
the same supervisor lifetime with configurable rotation and reconnect delays
|
|
338
|
+
- **Realtime service boundaries**: Move SSE and Shure WebSocket subscription orchestration into
|
|
339
|
+
typed services shared by thin native Huey tasks and foreground management commands
|
|
340
|
+
- **Shared realtime lifecycle**: Share eligible chassis selection, transform, persistence,
|
|
341
|
+
primitive projection, broadcast, and secret-safe error handling between SSE and WebSocket while
|
|
342
|
+
keeping transport connection and cleanup local
|
|
343
|
+
- **Post-poll alerts**: Rotate through a configurable, hard-capped set of assigned wireless units
|
|
344
|
+
instead of scanning arbitrary manufacturer inventory or permanently starving later rows
|
|
345
|
+
- **Dependency automation**: Consolidate updates under Renovate; refresh locked Click, filelock,
|
|
346
|
+
certifi, idna, Pillow, and platformdirs versions; ignore generated requirements exports; enforce
|
|
347
|
+
lock/export consistency; and run documentation checks on dependency branches
|
|
348
|
+
- **Host-aware test users**: Shared pytest fixtures now use the host project's configured user
|
|
349
|
+
model
|
|
350
|
+
- **Optional admin integrations**: Enable admin enhancements only when the host registers their
|
|
351
|
+
Django applications
|
|
352
|
+
- **Settings presentation**: Separate tenant-visible diff and overview queries from configuration
|
|
353
|
+
resolution, with a fixed query budget and fail-closed display allowlist
|
|
354
|
+
- **Settings administration**: Mask unknown values across standard admin views, disable raw
|
|
355
|
+
import/export paths, and restrict row management and form choices to the user's tenant scope
|
|
356
|
+
- **Discovery approval**: Move queue promotion into an atomic service with target-model permission
|
|
357
|
+
checks, stable row-lock ordering, bounded fallback identities, cross-model IP ownership,
|
|
358
|
+
non-destructive updates, explicit charger validation, batch conflict detection, and one write per
|
|
359
|
+
logical inventory target
|
|
360
|
+
|
|
361
|
+
### Fixed
|
|
362
|
+
|
|
363
|
+
- Apply the same tenant-role and platform-scope policy to queued API-server health checks and
|
|
364
|
+
request-time admin actions, including active/staff/permission revalidation in the worker
|
|
365
|
+
- Enforce active-Site ownership when listing or submitting monitoring groups, including
|
|
366
|
+
cross-organization superusers, and reject standalone admin relationships that combine RF
|
|
367
|
+
channels and wireless units from different chassis
|
|
368
|
+
- Resolve regulatory status once per row, eager-load the effective RF channel, annotate explicit
|
|
369
|
+
and country-fallback domains, and keep wireless-unit admin query counts constant as rows grow
|
|
370
|
+
- Eliminate duplicate lifecycle audit writes and use one alias-aware, redacting audit service for
|
|
371
|
+
model transitions, manufacturer events, and EFIS imports
|
|
372
|
+
- Keep Sennheiser SSCv2 event streaming on the authenticated GET connection while sending control
|
|
373
|
+
requests through a separate authenticated client to a validated same-origin control resource
|
|
374
|
+
- Remove per-refresh paginator counts from alert and assignment row fragments and reuse one
|
|
375
|
+
annotated discovery-device existence result across both admin status columns
|
|
376
|
+
- Prevent manufacturer movement updates from requesting a nonexistent chassis `updated_at` field
|
|
377
|
+
- Deepen live DisplayWall rendering into one typed, tenant-scoped kiosk snapshot used by initial
|
|
378
|
+
pages, periodic HTML fragments, JSON consumers, and wall-section partials while preserving a
|
|
379
|
+
bounded query count
|
|
380
|
+
- Activate pinned HTMX on built-in browser pages, route kiosk refreshes to swappable HTML, restore
|
|
381
|
+
template head extensions, and send kiosk heartbeats through Django's CSRF contract
|
|
382
|
+
- Render wall-section fragments from the current kiosk projection, with real section names,
|
|
383
|
+
charger groups, performer status, and explicit empty states
|
|
384
|
+
- Propagate failures from either realtime subscription task while cancelling its sibling, and
|
|
385
|
+
remove the remaining CodeQL warnings from branch and failure-path tests
|
|
386
|
+
- Configuration import consistency across app modules
|
|
387
|
+
- Whitespace issues in documentation and code examples
|
|
388
|
+
- Admin settings diff tests updated to validate masking and access control
|
|
389
|
+
- Preserve the public admin-audit command while moving registry selection and Unfold, media,
|
|
390
|
+
search-depth, template, eager-loading, and live query checks into typed services; quick audits now
|
|
391
|
+
skip HTTP query capture and audits no longer create a predictable persistent superuser account
|
|
392
|
+
- Restore wireless-unit admin registration and lifecycle/regulatory dispatch behavior
|
|
393
|
+
- Correct release provenance so tags and published artifacts target the release commit
|
|
394
|
+
- Enforce organization, campus, monitoring-group, and membership-role boundaries across model
|
|
395
|
+
managers, assignment services, admin views, HTTP views, and monitoring data
|
|
396
|
+
- Route real-time updates only to authorized organization and campus channel groups, including
|
|
397
|
+
collision-safe resolution for chassis and wireless-unit identifiers
|
|
398
|
+
- Bound charger, alert, and kiosk relationship loading to prevent per-row query growth
|
|
399
|
+
- Check discovery IP ownership before probing a candidate device
|
|
400
|
+
- Replace stale performer-assignment examples with the current scoped service API
|
|
401
|
+
- Stop normal Django ORM writes from emitting false deprecation warnings for required model
|
|
402
|
+
lifecycle hooks, and fail tests on future deprecation warnings
|
|
403
|
+
- Correct alert preference field lookups so battery, signal, and audio notifications are emitted
|
|
404
|
+
- Prevent persistent alert-fanout truncation from pinning work to one unit or alert class by
|
|
405
|
+
advancing the unit cursor after each attempt and alternating offline/transmitter priority
|
|
406
|
+
- Treat connected rows without a heartbeat as unhealthy and remove manufacturer-dependent query
|
|
407
|
+
growth from connection statistics
|
|
408
|
+
- Validate hardware transitions from the locked database row and support chassis without an
|
|
409
|
+
`updated_at` field
|
|
410
|
+
- Reconcile imported online devices through provisioning and roll back the complete import when
|
|
411
|
+
any lifecycle transition is rejected
|
|
412
|
+
- Require a building hierarchy when creating locations, reject cross-building rooms, serialize
|
|
413
|
+
duplicate checks for building-level locations, and prevent stale callers from restoring old data
|
|
414
|
+
- Preserve managed IPv4 and IPv6 chassis addresses when reconciling discovery candidates
|
|
415
|
+
- Restore pending-alert action routes, current hardware labels, and owner-scoped state transitions
|
|
416
|
+
- Prevent tenant-scoped settings diff and overview views from exposing foreign organization, site,
|
|
417
|
+
or manufacturer overrides and remove diff per-definition query growth
|
|
418
|
+
- Prevent discovery approval from reading nonexistent queue fields or creating chargers without
|
|
419
|
+
the required location
|
|
420
|
+
- Keep core admin changelists usable when optional admin packages are installed but not configured
|
|
421
|
+
- Preserve stable poll result keys and deterministic wireless-unit slot assignment across process
|
|
422
|
+
restarts
|
|
423
|
+
- Fail manufacturer configuration validation when its plugin cannot be imported, and never run
|
|
424
|
+
discovery network work inline when native Huey is unavailable or rejects a task
|
|
425
|
+
- Accept built-in vendor transformer identifiers, transition responding discovered hardware through
|
|
426
|
+
valid lifecycle states, and skip offline reconciliation for incomplete authoritative snapshots
|
|
427
|
+
- Group queryset deletion callbacks and suppress obsolete discovery work during manufacturer
|
|
428
|
+
cascades
|
|
429
|
+
- Require change permission for every mutating admin action and for discovery queue transitions
|
|
430
|
+
- Scope managed-device polling by API-server manufacturer and location before transport, preserve
|
|
431
|
+
embedded channel telemetry without double transformation, normalize nullable transmitter values,
|
|
432
|
+
and dispatch alerts only to their owning user's email address
|
|
433
|
+
- Keep test factories isolated from manufacturer discovery APIs while retaining explicit lifecycle
|
|
434
|
+
coverage for production task submission
|
|
435
|
+
- Keep discovery approval fail-closed when queue records disagree about API IDs, serial numbers,
|
|
436
|
+
roles, IP ownership, or explicit inventory links, while requiring only the target permission used
|
|
437
|
+
by each create or update
|
|
438
|
+
- Mask unknown stored-setting definitions regardless of their name or scalar type
|
|
439
|
+
- Defer chassis broadcasts, manufacturer registration, task submission, and grouped delete cleanup
|
|
440
|
+
until database commit, and run model lifecycle hooks exactly once through Django admin
|
|
441
|
+
- Replace stale discovery-admin fields and Django 6-incompatible one-argument `format_html()` calls,
|
|
442
|
+
and provide reachable, secret-safe settings management pages
|
|
443
|
+
- Keep persisted manufacturer API-server polling and imports bound to each row's allowlisted URL
|
|
444
|
+
and credential, with redacted failure state and deterministic client cleanup
|
|
445
|
+
- Keep lifecycle audit payloads JSON-safe when Django-native timestamps are recorded
|
|
446
|
+
- Restore platform-global and nested tenant-owned admin changelists in multi-site mode without
|
|
447
|
+
widening ordinary staff access, and register the previously unreachable accessory admin
|
|
448
|
+
- Require explicit permission for the single-site browser update stream while preserving
|
|
449
|
+
membership- and site-scoped WebSocket groups
|
|
450
|
+
- Move ORM work and blocking subscription handshakes off hardware event loops, and materialize
|
|
451
|
+
public async query results before returning them to callers
|
|
452
|
+
- Format authenticated WebSocket origins correctly for IPv4 and IPv6 literals and reject invalid
|
|
453
|
+
device ports before constructing a client
|
|
454
|
+
- Run the installed-wheel smoke contract from the local `just wheel` gate and mark its in-memory
|
|
455
|
+
SQLite host explicitly as development-only
|
|
456
|
+
- Preserve the last complete charger dashboard snapshot while resumable inventory pages accumulate,
|
|
457
|
+
retain the same vendor-order station prefix when a full cycle exceeds its station cap, and fail
|
|
458
|
+
closed when any station request makes the cycle incomplete
|
|
459
|
+
|
|
460
|
+
### Removed
|
|
461
|
+
|
|
462
|
+
- **Settings package exports**: Import `settings`, `SettingsService`, and presentation services from
|
|
463
|
+
their defining modules instead of a package-level convenience API
|
|
464
|
+
- **Compatibility exports**: Remove root model, service, task, exception, telemetry, rate-limiter,
|
|
465
|
+
and discovery-sync aliases
|
|
466
|
+
- **Model convenience shims**: Use typed wireless-unit, chassis, and RF-channel domain services and
|
|
467
|
+
template filters instead of deprecated model delegation methods
|
|
468
|
+
- **Cross-layer model delegates**: Call realtime, monitoring, organization, discovery, and plugin
|
|
469
|
+
services directly from their owning application adapters
|
|
470
|
+
- **Obsolete runtime surfaces**: Delete destructive seeding and direct-probing commands, legacy
|
|
471
|
+
polling/discovery orchestrators, unused compatibility facades, duplicate realtime emitters,
|
|
472
|
+
private middleware, and their stale templates and guides
|
|
473
|
+
- **Dead monitoring surfaces**: Delete the duplicate charger-display route and template, the
|
|
474
|
+
generic connection-validation and connection-state services, and test-only health aggregation
|
|
475
|
+
and reconnect methods; supported kiosk and realtime services remain the only runtime paths
|
|
476
|
+
- **Test-only service APIs**: Delete unused lifecycle mutation/query helpers, metadata version
|
|
477
|
+
accessors, unscoped chassis refresh, notification progress/system-email methods, health-state
|
|
478
|
+
predicates, and the settings test-mode property; active callers use the canonical typed paths
|
|
479
|
+
- **Dead admin and polling surfaces**: Delete the unregistered wireless-unit inline and stop
|
|
480
|
+
returning raw vendor device payloads from the persistence-only discovery polling service
|
|
481
|
+
|
|
482
|
+
### Security
|
|
483
|
+
|
|
484
|
+
- Update `cryptography` to 48.0.1 and `msgpack` to 1.2.1 to resolve
|
|
485
|
+
`GHSA-537c-gmf6-5ccf` and `GHSA-6v7p-g79w-8964` in the locked dependency graph
|
|
486
|
+
- Enforce the same group-to-unit tenant invariant for performer-assignment updates, deletions, and
|
|
487
|
+
deactivations, locking the authorization graph inside each mutation transaction
|
|
488
|
+
- Restrict optional sortable-admin writes to the request user's exact manageable queryset on the
|
|
489
|
+
write database, apply reorder batches atomically, and disable globally ranked page-move actions
|
|
490
|
+
- Enforce MSP `viewer`, `operator`, `admin`, and `owner` roles at generic admin, bulk-action,
|
|
491
|
+
related-widget, settings-management, and queued chassis-refresh mutation boundaries; reserve
|
|
492
|
+
host-wide catalog writes for unrestricted platform superusers
|
|
493
|
+
- Remove the stale trusted-HTML wall-section rendering path and autoescape section, charger, and
|
|
494
|
+
performer data in the HTMX fragment
|
|
495
|
+
- Clarified that `.env` files should never be committed (already in `.gitignore`)
|
|
496
|
+
- Added reminder in CONTRIBUTING.md about AGPL licensing requirements for production use
|
|
497
|
+
- Enforce monitoring-group scope on charger, kiosk, alert, performer-assignment, and HTMX lookup
|
|
498
|
+
surfaces
|
|
499
|
+
- Require authenticated POST requests for kiosk heartbeat mutation and admin user promotion
|
|
500
|
+
- Require owner or superuser scope plus CSRF-protected POST requests for alert acknowledgement and
|
|
501
|
+
resolution, and escape vendor channel snapshots in alert details
|
|
502
|
+
- Require HTTPS and certificate verification for authenticated manufacturer clients; private
|
|
503
|
+
certificate authorities use the standard `SSL_CERT_FILE` or `SSL_CERT_DIR` trust configuration
|
|
504
|
+
- Redact API keys and subscription handshake identifiers from integration logs, and hardware
|
|
505
|
+
identities and private network addresses from deduplication and probe logs
|
|
506
|
+
- Sanitize sortable payload failures and Sennheiser/Shure stream exception tracebacks so injected
|
|
507
|
+
primary keys, callback messages, transport errors, and subscription failures cannot forge logs
|
|
508
|
+
or disclose secrets
|
|
509
|
+
- Make activity and service-sync admin history strictly view-only, derive activity actor links and
|
|
510
|
+
search fields from the configured user model, and correct live sync/status badge choices
|
|
511
|
+
- Detect snake, kebab, spaced, and camel-case credential keys before metadata key truncation;
|
|
512
|
+
restore masked list secrets by stable identity and reject ambiguous or missing originals
|
|
513
|
+
- Serialize polling and import identity reads and writes behind one database lock, canonicalize
|
|
514
|
+
valid MAC addresses, discard invalid MAC placeholders, and fail closed on cross-manufacturer
|
|
515
|
+
serial, MAC, or occupied-IP conflicts in both live and dry-run imports
|
|
516
|
+
- Keep raw realtime event payloads and transport/cache exception details out of command and worker
|
|
517
|
+
output
|
|
518
|
+
- Centralize secret-safe exception metadata so traceback context remains useful without rendering
|
|
519
|
+
vendor payloads, credentials, private addresses, or forged log lines
|
|
520
|
+
- Pin GitHub Actions to immutable commits and keep coverage enforcement and reports self-contained
|
|
521
|
+
- Revalidate WebSocket authentication and current route membership immediately before every
|
|
522
|
+
outbound event, including pong replies to client pings, and close revoked connections after
|
|
523
|
+
discarding groups
|
|
524
|
+
- Build release artifacts without write or OIDC permissions, seal them with a SHA-256 manifest,
|
|
525
|
+
verify the manifest in isolated publisher jobs, and publish through native `uv` trusted
|
|
526
|
+
publishing with least-privilege permissions
|
|
527
|
+
- Treat incomplete local inventory, configured scan definitions, CIDR/FQDN expansion, and remote
|
|
528
|
+
discovery payloads as non-authoritative for removals while still clearing database-proven
|
|
529
|
+
cross-manufacturer conflicts
|
|
530
|
+
- Fail closed for unsupported or tenantless resources in MSP mode and prevent cross-tenant
|
|
531
|
+
WebSocket subscription or broadcast leakage
|
|
532
|
+
- Scope stored settings overrides to active, internally consistent organization/campus memberships
|
|
533
|
+
and visible managed manufacturers
|
|
534
|
+
- Honor restricted-superuser tenant memberships across monitoring topology, alert mutations, and
|
|
535
|
+
performer-assignment choices when cross-organization access is disabled
|
|
536
|
+
- Disable generic admin import and export routes until request-aware resources can prove tenant
|
|
537
|
+
scoping for every transferred row
|
|
538
|
+
- Scope charger and RF-channel admin inline choices to the current tenant, and reject forged
|
|
539
|
+
cross-tenant or cross-chassis relationships during formset validation
|
|
540
|
+
- Refuse same-version release retries unless the current main commit is the exact release-metadata
|
|
541
|
+
commit, preventing newer code from being published under previously prepared metadata
|
|
542
|
+
|
|
543
|
+
### Documentation
|
|
544
|
+
|
|
545
|
+
- Reusable app integration guide in README.md
|
|
546
|
+
- Migration safety and lifecycle documentation
|
|
547
|
+
- Plugin architecture and settings registry patterns explained
|
|
548
|
+
- Development workflow and commit message guidelines
|
|
549
|
+
- Management-command and plugin examples now match the installed public APIs
|
|
550
|
+
|
|
551
|
+
## [25.01.15] - 2026-01-15
|
|
552
|
+
|
|
553
|
+
### Added
|
|
554
|
+
|
|
555
|
+
- Initial beta release with multi-manufacturer support
|
|
556
|
+
- Device discovery and lifecycle management
|
|
557
|
+
- Alerting and performer assignment
|
|
558
|
+
- Real-time telemetry via WebSockets/SSE
|
|
559
|
+
- Multi-tenant support framework
|
|
560
|
+
- Settings registry with scope resolution
|
|
561
|
+
- Plugin architecture for manufacturer integration
|