Client applicationNative macOSSwiftUI / AppKit
DeviceESP32-S3ESP-IDF 5.5.2 / LVGL
Cloud coreNestJS + PostgreSQLModular monolith
On this page

01System context#

From client to cloud

The Mac communicates with hardware over USB. Nginx routes HTTPS traffic to the API, Admin and public website. The API uses PostgreSQL and private R2; the Desktop downloads firmware through an authorized, short-lived URL.

The API is not a fleet of microservices: authentication, devices, pairing, releases and business modules share one NestJS deployment. The current topology does not require Redis, a message broker or Kubernetes.

02Component responsibilities#

LayerResponsibilityBoundary
macOSTasks, focus, habits and notes; USB transport; firmware verification.SwiftUI / AppKit. Local data and Keychain.
ESP32-S3Display, touch, animation, identity proof and OTA flash writes.Flash-write authority stays on the device.
Cloud APIPairing, inventory, ownership, firmware policy, heartbeat and audit.DTO validation, authentication and role enforcement.
AdminOperational management, release lifecycle, customers and orders.Uses the API; receives no database credentials.
PostgreSQLSystem of record for devices and cloud operations.Prisma schema, constraints and transactions.
R2Verified immutable firmware and release artifacts.Private bucket; temporary signed downloads.

03Local-first data boundaries#

Tasks, habits and notes are stored by the native app’s local persistence layer. The current cloud API has no general synchronization contract for this personal content. This should not be interpreted as an existing multi-device cloud-sync feature.

  • Internet is needed for pairing, cloud status checks and new firmware downloads.
  • USB carries Desktop–device commands, identity proofs and normal OTA transport.
  • Keychain stores the Mac installation private key and pairing credential.
  • Local persistence is not a guarantee of application-level or full-disk encryption; host policy still matters.

04Trust boundaries & pairing#

Device pairing sequence

The server issues a five-minute challenge. The device computes an HMAC proof over the nonce, serial and installation ID. The API verifies the one-time claim code and proof, then issues a pairing credential.

MaterialProtection
Device secretHeld in the device identity namespace; encrypted with AES-256-GCM on the server. The normal runtime protocol does not export it.
Claim codeStored as a peppered HMAC hash; marked consumed after pairing.
Admin sessionRandom token, hashed server-side; Secure / HttpOnly / SameSite Strict cookie.
Firmware signing keyRemains offline/local. The server, website and R2 never receive the private signing key.

05Core data model#

Device, ownership and release relationships

Customers relate to devices through ownership records. A device may have multiple Mac installations. FirmwareInstallation belongs to a device–release pair and records the update outcome.

Unique constraints bound duplicates for serials, device–installation pairs and device–release pairs. Release identity combines version, build, hardware and channel. Heartbeats update the latest Device state while historical samples are retained at 15-minute intervals.

06Scaling & assurance boundaries#

The production inspection observed one host, Nginx and Docker Compose services. This provides a small operational footprint, but is not a guarantee of multi-zone high availability or autoscaling.

  • Next scaling gate: API replicas, shared rate-limit state, managed/replicated database and tested restores.
  • An independent penetration test, compliance certification, SLA or completed disaster-recovery drill is not asserted.
  • Observed dependency-security findings require patching and regression verification.
Sources & evidence

This reference is based on the current source snapshot and read-only infrastructure inspection. Hashes identify the reviewed files; this is not an independent audit opinion.

  • apps/api/src/app.module.ts
  • apps/api/src/common/crypto.service.ts
  • apps/api/src/pairing/pairing.service.ts
  • apps/api/src/devices/devices.service.ts
  • apps/api/prisma/schema.prisma
  • hamroh-macos-native/HamrohNative/Services/PersistenceService.swift
  • hamroh-macos-native/HamrohNative/Services/CloudServices.swift
  • infra/docker-compose.production.yml
Download: evidence.json
Next documentAPI reference
Hamroh IO · Technical documentation · 2026-09-10

Search documentation