Files
hiveops-guide/backend/src/main/resources/content/devices/sw-deploy/architect.md
T
johannes 2f94d62769 content(guide): role-tabs (Internal/Architect/Claude) for all 63 customer modules (DRAFT, Refs #1 #3)
Full role-tab rollout: every customer module now has Customer/Internal/
Architect/Claude tabs, grounded per-module in real code. Backend serves 296
docs / 96 modules. Grounding surfaced ~20 real bugs across services (filed
separately after verification).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 12:14:54 -04:00

5.9 KiB

module, title, tab, order, audience
module title tab order audience
devices.sw-deploy Software Deployment Architect 30 internal

Internal · architecture. Written 2026-07-01 from hiveops-devices/frontend + hiveops-fleet/backend. Verify against code before relying on specifics.

Ownership — this feature lives in Fleet, rendered by Devices

The SW Deploy tab is a Devices SPA view (DeviceSoftwareTab.svelte) but the domain — software download/install tasks — is owned entirely by hiveops-fleet. Devices contributes only the device identity and the UI shell. See [platform.service-ownership].

Concern Owner
Tab UI / atm object hiveops-devices (frontend, port 5177)
SOFTWARE / SOFTWARE_INSTALL task lifecycle, storage, dispatch hiveops-fleet (backend, port 8097, DB hiveiq_fleet)
Agent auth / device identity source of truth hiveops-devices backend (atms) → mirrored to fleet device_summary via Kafka

Data flow

1. Read path (rendering the tab)

DeviceSoftwareTabfleetAPI.getTasksPaginated({ atmId, taskKind:['SOFTWARE','SOFTWARE_INSTALL'] }) → gateway /fleet/tasks/paginatedFleetApiController.getFilteredFleetTaskService.getFilteredPaginatedFleetTaskSpecification.withFilters over the live fleet_tasks table. Frontend derives the two step cards (latestDownload, latestInstall) and the history table client-side.

2. Create path (Schedule Install)

fleetAPI.createTask({ atmIds:[id], taskKind:'SOFTWARE_INSTALL', scheduledAt? })POST /fleet/tasksFleetTaskService.createTask:

  • Resolves each atmId against device_summary (deviceSummaryRepository.findById); skips if missing, offline (>15 min since lastHeartbeat), or out of institution scope.
  • SOFTWARE/SOFTWARE_INSTALL (and HOTFIX/HOTFIX_INSTALL) are created with initial status PENDING_APPROVAL.
  • If no scheduledAt and kind is SOFTWARE_INSTALL, defers to the device's assigned patch window (PatchWindowService.nextOccurrence).
  • Persists to fleet_tasks, then FleetTaskEventPublisher.publishCreated → Kafka.

3. Approval → dispatch

POST /fleet/tasks/{id}/approve (FLEET_APPROVER / BCOS_ADMIN) moves the task PENDING_APPROVAL → PENDING. The agent (via agent-proxy, role INTERNAL) polls GET /api/internal/fleet/tasks/next?atm={atmId}&kind=...; getNextPendingTaskOfKind returns the oldest PENDING task whose scheduledAt is null/past, marks it QUEUED, and returns artifact metadata (name, version, sha256, CDN url + token) for SOFTWARE. SOFTWARE_INSTALL carries no artifact — the agent runs softwareinstall.cmd against its staged software/ dir.

4. Status reporting → archival (executor → record-store)

Agent reports progress via POST /api/internal/fleet/tasks/{taskId}/status (downloadOffset, totalSize, status) → FleetTaskService.updateTaskStatus:

  • RUNNING sets startedAt; COMPLETED/FAILED set completedAt; download progress percent is derived from offset/total.
  • Every update publishes FleetTaskEventPublisher.publishStatusUpdate.
  • On COMPLETED, the row is archived to fleet_task_history and deleted from fleet_tasks (archiveAndDelete, also emits publishArchived). A @Scheduled sweep every 5 min archives stray COMPLETED/CANCELLED/REJECTED; history is purged after 30 days. This is the classic live-table + archived-record-store split. See [platform.data-architecture].

Kafka

Topic Direction Class Notes
hiveops.fleet.task.events produced by fleet FleetTaskEventPublisher / FleetTaskKafkaConfig.FLEET_TASK_EVENTS_TOPIC eventTypes TASK_CREATED, TASK_STATUS, TASK_ARCHIVED; keyed per task. Consumed downstream by devices (FleetTaskEventConsumerdevice_fleet_tasks mirror).
hiveops.device.events consumed by fleet DeviceEventConsumer (group hiveops-fleet-device-sync) Upserts/deletes device_summary from devices' DEVICE_CREATED/UPDATED/DELETED. This is how fleet knows the device exists, its institutionKey, and lastHeartbeat seed.

See [platform.kafka].

Tables (DB hiveiq_fleet)

Table Entity Role in this feature
fleet_tasks FleetTask Live SOFTWARE/SOFTWARE_INSTALL rows — the tab's read source
fleet_task_history FleetTaskHistory Archived terminal tasks (completed installs/downloads land here)
device_summary DeviceSummary Fleet's mirror of devices; target resolution, online check, institution scope
fleet_artifacts FleetArtifact Software package metadata for SOFTWARE downloads (enabled flag, CDN url, sha256)
patch window tables PatchWindow / PatchWindowDevice Auto-schedule for SOFTWARE_INSTALL

Key endpoints

Method + Path Purpose Auth
GET /api/fleet/tasks/paginated Tab read (filter taskKind, atmId) USER…BCOS_ADMIN
POST /api/fleet/tasks Create install/download task ADMIN/MSP_ADMIN/BCOS_ADMIN
POST /api/fleet/tasks/{id}/approve | /reject Approve gate FLEET_APPROVER / BCOS_ADMIN
POST /api/fleet/tasks/{id}/cancel | /retry Lifecycle ADMIN/MSP_ADMIN/BCOS_ADMIN
GET /api/fleet/tasks/history Archived (completed) tasks USER…BCOS_ADMIN
GET /api/internal/fleet/tasks/next Agent poll/dispatch INTERNAL
POST /api/internal/fleet/tasks/{id}/status Agent status/progress INTERNAL

Architectural note (see uncertainties)

The tab reads the live fleet_tasks table, but COMPLETED tasks are archived+deleted immediately. Completed software history therefore lives only in fleet_task_history / the /tasks/history endpoint, which this tab does not query. Treat the tab as "in-flight + failed" state; use history for the completed record.

Cross-links: [platform.data-architecture] · [platform.kafka] · [platform.service-ownership]