Admin and Commands
ScannerSky admin functionality is implemented in core/admin/.
Admin Areas
| Area | Modules |
|---|---|
| Dashboard | dashboard_admin.py |
| Academics | base_admin.py, class_admin.py, event_admin.py |
| Records | person_admin.py, record_admin.py |
| ID Cards | idcard_admin.py (IDCardAdmin, IDCardPrintLogAdmin) |
| Devices | base_admin.py |
| Authentication | auth_admin.py |
| Audit Logs | auth_admin.py (UserLoginEventAdmin, UserActivityAdmin) |
| Super Features | dataset_admin.py (DatasetAdmin), auth_admin.py (MCPAPIKeyAdmin) |
Notable Admin Capabilities
- Device online and offline indicators from latest DeviceLog data
- Permission-gated remote node actions for supported devices
- Class attendance workflows with export and filtering
- Class student roster management: accessible via the "Manage Students" action on Class objects, supporting bulk importing/mapping from Excel, filtering/adding by group, and paginated lists (100 per page) with inline student avatar thumbnails
- Event attendance workflows and exports
- Person import and registration workflows
- Person archiving & deactivation: "Deactivate Person" row/detail custom action on PersonAdmin that opens a dedicated confirmation page detailing consequences (enrolled classes, event registrations, active ID cards, preserved attendance records, and scanner access revocation) before setting
is_archived = True; archived persons are excluded from active class/event roster management, scanner devices, and autocomplete dropdowns; changelist includes an Active status column and Archived list filter - ID card lifecycle: the ID Registration page issues
IDCardrecords with lifecycle status (draft,active,lost,damaged,expired). "Save and Print Card" opens a modal to choose a print reason and review print history before confirming; each print writes anIDCardPrintLogentry.Person.active_cardFK is updated automatically. - IDCard admin (
idcard_admin.py): read/edit card lifecycle status, view front/back image previews, filter by status and template. - IDCardPrintLog admin (
idcard_admin.py): append-only audit log (add and change blocked); displays combined Person Name & ID column; filterable by reason, printed-by, and date range; features a dedicated Print Analytics dashboard page (/analytics/) with KPI stat cards, semester/date range/reason/department filters, interactive Chart.js print timeline and distribution charts, and department print breakdown summary tables. - Record admin (
record_admin.py): central attendance scan history with avatar previews, School ID / department / device / area / date-range / user filters; includes batch dropdown actions "Assign selected to class" and "Assign selected to event" with intermediate preview confirmation pages for reassigning unassigned or misattributed scans. - Device real-time monitoring & watchdog: zero-polling live SSE updates on Device and DeviceLog changelists. Background thread
DeviceHealthWatchdogmonitors node heartbeat thresholds (90s Stale, 180s Offline), automatically generating system alertNotificationentries (scoped withrequired_permission="core.view_device") and SSE events upon node disconnection or recovery. - Device Analytics dashboard (
/admin/core/device/analytics/): dedicated analytics tab onDeviceAdmindisplaying live KPI metric cards (Total Nodes, Online %, Stale/Offline counts, Check-in frequency), interactive Chart.js activity timeline (daily/monthly auto-switch), operational health doughnut distribution, activity by campus area chart, device uptime matrix, and automated alert audit history with semester and date filters. - Super Features & Datasets (
dataset_admin.py): Superuser-only section containing Datasets and MCP API Keys. Datasets provide a dynamic mechanism for generating ML/visualization datasets in CSV, Excel, and SQL formats across 13 system models with strict zero-trust PII sanitization. Features asynchronous background queueing, live row count estimation, auto-refreshing SSE changelist updates, streaming downloads, reusable templates, and automated 7-day MinIO TTL cleanup. - Superuser-only read-only audit log of user logins (
UserLoginEvent) with IP, user agent, and source - Superuser-only read-only audit log of user page visits (
UserActivity) with path, IP, and user agent; debounced viaUserVisitationMiddleware - All changeforms display a dynamic title ("Add / Edit [Model]") and subtitle (object name when editing, creation prompt when adding) above the form fields, rendered via the shared
admin/base_change_form.htmltemplate (persons use a custom override) - All changeforms include a Cancel/Close button (
change_form_show_cancel_button = Trueset on every ModelAdmin) - All changelists show a title and descriptive subtitle header; when filters are active the subtitle is replaced by an active-filter summary; templates live in
core/templates/admin/
Attendance Visibility Permissions
Class and Event visibility in admin can be expanded beyond instructor or facilitator assignment using custom model permissions defined in core/models.py and enforced in core/admin/class_admin.py and core/admin/event_admin.py.
| Permission Codename | Scope | Effect in Admin |
|---|---|---|
core.view_all_classes | Class | Allows non-superusers to view all class rows and class detail pages in the Class admin |
core.view_all_events | Event | Allows non-superusers to view all event rows in the Event admin |
Person Action Permissions
The Person model defines custom permissions in core/models.py to gate specific management workflows:
| Permission Codename | Purpose |
|---|---|
core.import_persons | Allows importing person records from files |
core.scan_persons | Allows access to the Scan Persons page itself (used only to grant page/view access) |
core.person_id_registration | Allows registering new IDs |
core.migrate_card_numbers | Allows migrating card numbers from legacy files |
AI Agent Permission
The AIAgent model defines custom permissions in core/models.py to control access to AI features:
| Permission Codename | Purpose |
|---|---|
core.access_ai_agent | Allows access to the Onyx AI chat widget in the admin portal |
Notification Visibility & Permissions
The Notification model supports permission-aware delivery via the required_permission field. While public notices (is_public=True) and group notices target audience accounts, setting required_permission ensures that only accounts possessing the specified Django permission codename (e.g. core.view_device) can view the notification in their notification feed, hero widgets, and unread counters.
| Permission Codename | Purpose & Effect |
|---|---|
core.view_device | Scopes automated 🚨 Device Offline and ✅ Device Recovered watchdog alerts exclusively to personnel authorized to inspect scanner hardware |
- Admin Queryset & IDOR Protection: The Notification admin changelist, row actions, and AJAX read-receipt endpoints strictly enforce the user's permission-scoped queryset (
NotificationQuerySet.for_user), returning HTTP 404 on unauthorized access attempts.
Management Commands
Custom commands are under core/management/commands/.
| Command | Purpose |
|---|---|
| assign_employee_images | Bulk assign employee image paths |
| monitor_devices | Run the Device Health Watchdog in foreground daemon mode or evaluate device statuses once (--once) |
| run_worker | Run the ScannerSky Background Worker Coordinator daemon managing scheduled tasks (device watchdog, dataset queue processing, and artifact cleanup) |