Skip to content

release: fleet observability Phase 2 — /admin/fleet panel + ingest route (#69) - #71

Merged
mahmutkaya merged 1 commit into
mainfrom
develop
Jul 20, 2026
Merged

mahmutkaya merged 1 commit into
mainfrom
develop

Conversation

@mahmutkaya

Copy link
Copy Markdown
Contributor

Release: fleet observability Phase 2 (sofra side)

Promotes the single unreleased develop commit — the fleet observability control-plane view layer (#69) — to production main.

Contents (1 commit): feat(fleet): sofra /admin/fleet panel + bearer ingest route (#69)

  • Prisma FleetSummary + FleetDevice models + handwritten migration 20260720013000_fleet_observability (two new tables — additive).
  • POST /api/telemetry/fleet bearer ingest route (503 until PRINTER_TELEMETRY_SECRET set — inert).
  • /admin/fleet admin page (requireAdmin; shows registered tenants + their device roster; empty until the backend push is configured).
  • i18n keys in all 6 locales.

Risk: low, additive. No changes to any existing surface; the new page is admin-only and shows the empty state until PRINTER_TELEMETRY_SECRET + the backend FleetPush config are set.

Deploy steps (post-merge, manual — founder-run)

Merge builds ghcr.io/piwas-21/sofra:migrate + :latest. Then on the staging box (/opt/rumi/deploy):

  1. docker pull ghcr.io/piwas-21/sofra:migrate
  2. docker run --rm --network deploy_rumi -e DATABASE_URL="postgresql://sofra:<pw>@postgres:5432/sofra" ghcr.io/piwas-21/sofra:migrate (= prisma migrate deploy)
  3. docker compose -f docker-compose.prod.yml up -d sofra
  4. Verify https://sofrapiwas.com/admin/fleet renders.

🤖 Generated with Claude Code

…servability Phase 2) (#69)

* feat(fleet): sofra /admin/fleet panel + bearer ingest route (fleet observability Phase 2)

Adds the control-plane VIEW layer for fleet observability: each tenant backend
(next slice) pushes a compact per-tenant snapshot to a bearer-authed ingest route,
sofra stores it in its own DB, and /admin/fleet renders the fleet — device
liveness, order-feed state, and missed-order counts, joined to the tenant registry
for owner/tenant identity.

- Prisma FleetSummary (per tenant, tenantSlug @unique — keyed not FK, like
  TenantBilling) + FleetDevice (unique [tenantSlug, deviceId]); handwritten
  migration 20260720013000_fleet_observability.
- lib/fleet.ts: zod fleetPushSchema (non-PII, all fields bounded to the DB columns)
  + ingestFleetPush (one transaction: upsert summary, then reconcile the device
  roster — upsert reported, prune the rest, scoped to the tenant).
- app/api/telemetry/fleet/route.ts: constant-time PRINTER_TELEMETRY_SECRET bearer
  (cloned from cron/retention), 503-when-unset, 401/400 before any write, never
  echoes the payload. Documented shared-secret trust model + per-tenant-binding
  follow-up for the backend push slice.
- app/(control)/admin/fleet/page.tsx: requireAdmin, force-dynamic registry read,
  derives online/offline + stale-feed at the presentation layer (craft tokens).
- i18n: fleet keys added to all 6 locales (parity) + nav.fleet.

Why: fleet observability Phase 2 (asks #2 owner/tenant, #6 manage from admin panel).
The backend FleetSummaryPushService (producer) is the follow-up slice; until it
ships the panel shows the empty state.

Deploy note (sofra §5.2): schema change — run the :migrate one-off on the box
BEFORE rolling the app. Set PRINTER_TELEMETRY_SECRET (else the route 503s, inert).

- 4 vitest cases for fleetPushSchema (coerce dates, defaults, reject bad input);
  typecheck + next build green (both routes compile)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* refactor(fleet): dedup+sort ingest devices, readonly props, extract ternaries, early-return (PR #69 review)

Gemini + Sonar review on the Phase 2 panel:
- ingestFleetPush dedups devices by deviceId + sorts deterministically, so a
  repeated id can't double-upsert and concurrent same-tenant pushes lock rows in
  the same order (no deadlock).
- page.tsx: mark component props Readonly (S6759); extract the liveness/feed
  nested ternaries into helper functions (S3358); early-return when the registry
  is unavailable (skips the DB reads + removes the outer JSX ternary).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a printer fleet observability feature, allowing tenant backends to push compact, non-PII device telemetry and summaries to a central dashboard. This includes database schemas (FleetSummary and FleetDevice), an API endpoint (/api/telemetry/fleet) with bearer token authentication, an admin dashboard page (/admin/fleet), and multi-language localization support. Feedback on the changes suggests optimizing database queries on the admin fleet page by filtering fleetDevice and fleetSummary retrievals to only include active tenants from the registry, preventing unnecessary data loading as the system scales.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread app/(control)/admin/fleet/page.tsx
@mahmutkaya
mahmutkaya merged commit 1bec77c into main Jul 20, 2026
35 of 36 checks passed
mahmutkaya added a commit that referenced this pull request Jul 20, 2026
…#71 follow-up) (#72)

Filter fleetDevice/fleetSummary findMany by the registry's active tenant slugs so
orphaned/decommissioned rows aren't loaded as the fleet grows. No-op at the current
single-tenant scale; the deferred optimization from the #71 release review.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant