← Sketches · the native app program

One image, two deployments

c1342026-11-10

The UI over the Go app over Postgres and ClickHouse, run by us as SaaS or by the customer from one Docker image; endpoints connect, people sign in.

Source: Session 1b21a3ce (Tyler Flint, 2026-11-05): the plane as SaaS and as a self-hosted Docker package on Pulse, Postgres and ClickHouse, no Firebase; Rob Genova: SaaS production-readiness does not block adoption. c134 plan.md §The shape, R1–R5, D1–D8; inventory.md (Phase 0: both apps mapped, the 30-item gap list); c131 D13 (the connect credential); c136 D1 (grants on the plane); c137 D1 (messages on the plane); kamal-prep.md.

The endpoint
◇qcontrol

the sensor; sends events and inventory; a heartbeat with version and health (gap 27)

▣The native app

connects with a base URL and a standardised credential (c131 D13, D8); read-only when connected

One image · the control plane: one Docker image, one build (R3)
▣UI

Nuxt, static; reads the API only (R1); nothing in it knows SaaS from self-hosted except by configuration (R3)

▭qdash's pages

44 pages on one data discipline (R13, R25, R31), c92–c128

▭app.qpoint.io's frame

sign-in, org, members, context, settings, install (D1)

the contract (Phase 2): the 38 routes, types/api/*, the 30 gaps
◇Go app

Pulse with a new data model, API first; Kamal's. Three plane objects the contract adds (D8):

⬓Connect endpoint

base URL plus credential exchange, enrolment, heartbeat (gap 10)

⬓Grants

mechanic access as plane objects: purpose, level, scope, window, who (c136 D1, gap 11)

⬓Message inbox

the operator's inbox and send; messages as a resource (c137 D1, gap 12)

state and events
⬒Postgres

state: orgs, members, policies, grants, messages

⬒ClickHouse

events, audit, activity

People
●Operators and viewers

SSO: OIDC added, the SAML routes kept; no Firebase (D2)

●The self-hosted admin

local accounts (D2); the first admin at first run

●Qpoint's mechanic

in only under a grant (c136)

the same image, two ways to run it
SaaS · we run it
◇One image per customer, at first

Tyler: we run that on behalf of our customers. Multi-org in one instance later (D3). The demo: c113's baked worlds (D5).

Does not block adoption

Rob: SaaS production-readiness does not hold up a customer who starts self-hosted.

Self-hosted · the customer runs it
◇docker compose up

env for the two databases and the secrets. First run: the first admin, the first endpoint, the demo world as an option; on the wizard kit, with Mark Peterson's docs.

First-class

every flow works with no Qpoint service reachable; updates and telemetry opt-in (R4). The app says where data lives and who runs it (R5).

ours to build (c134: the frame around the pages, the contract, identity, install, the port plan)exists today (qdash's pages, app.qpoint.io's frame, qcontrol)Kamal's (the Go app, the data model, the two databases)people and rules
The problem
The dashboard bundled into qcontrol costs the sensor memory and credibility, and its frame signs people in through Firebase, which cannot be self-hosted. The pages exist and the frame exists; neither runs where the roadmap puts the control plane: on our infrastructure and on the customer's, from the same build.
The core idea
One build, two deployments: the UI over the Go app over Postgres and ClickHouse, run by us or by the customer. API first, and the bible's rules hold (R13 types from the handlers, R25 staged-to-served swaps, R31 honest states), so the port is a transport swap, not a rewrite. Design's slice is the seam: the shell, the contract, identity, install, the port plan.
What is open
Where the code lives and when Kamal starts (D4, Q1). Which of Pulse's patterns survive (Q2). Who issues the session and what the native app holds (Q3). from / to on every route and the live tail's cursor (gaps 1, 2, 26); an endpoint scope on the listings (candidate row 31). Whether local keeps an API the roadmap removes. The name (c0).

Qpoint Brand Style Guide