Help us shape the future of Go! Take the 2026 Go Developer Survey

orbit

package module
v1.20.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 18, 2026 License: Apache-2.0 Imports: 13 Imported by: 0

README

Orbit

The pluggable admin product for the Nucleus framework.

Go Reference Go

Orbit is a self-contained admin panel — Data Studio, a live request/SQL feed, a session viewer, RBAC management, and system metrics — that mounts in-process into any Nucleus application through the framework's extension/module API. It is a separate Go module with its own release cadence, extracted from the framework core per nucleus ADR-019 so the core stays lean and the admin can evolve as its own product.

You add one dependency and one Mount(...) call; orbit reads everything it needs from the running app's Runtime and serves its embedded React SPA — no separate asset deployment, no out-of-process sidecar, no database of its own.


Framework floor. Orbit builds against Nucleus and moves in lockstep with the certified suite set. The exact version it requires is in go.mod — that file is the source of truth, so this note cannot go stale.

Features

Module What it does
Data Studio Browse, create, edit, and delete records for every model in the app's registry — tenant-aware, with import/export.
Live runtime inspector Real-time feed of incoming HTTP requests and executed SQL across the whole app (sourced from the framework's observability event bus), with optional cross-node aggregation.
Session viewer List active server-side sessions — whose, from what device, which one is you — and revoke one or every session of an account.
Access control (RBAC) Inspect and manage the Casbin policies and roles backing the app's authorizer.
System metrics Runtime and resource consumption — CPU, memory, goroutines, database pool.
Audit log A durable trail of admin actions, with retention, export and per-record history.
Overview & Health Dashboard and health at a glance.

The UI ships embedded in the binary (go:embed), version-pinned to the orbit module — a consumer who mounts orbit gets the full admin offline, in a single binary.

Install

go get github.com/jcsvwinston/orbit@latest

The current tagged release is v1.20.1; pin that tag for reproducible builds.

v1.0 promise: the public surfaces (the root module and datasource) are frozen for the life of v1.x — enforced by contracts/freeze_test.go (see docs/V1_GATE.md).

Requires Go 1.26+ and a Nucleus application to mount into.

Quick start

Mount orbit on the application builder:

import (
    "os"

    "github.com/jcsvwinston/nucleus/pkg/nucleus"
    "github.com/jcsvwinston/orbit"
)

func main() {
    app, err := nucleus.New().
        FromConfigFile("nucleus.yml").
        Mount(orbit.Module(orbit.Config{
            Prefix:            "/admin",
            Title:             "Acme Admin",
            BootstrapUsername: "admin",
            BootstrapEmail:    "admin@acme.test",
            // When BootstrapPassword is empty, bootstrapping is skipped —
            // provision the admin user another way (e.g. nucleus createuser).
            BootstrapPassword: os.Getenv("ADMIN_BOOTSTRAP_PASSWORD"),
        })).
        Build()
    if err != nil {
        panic(err)
    }
    _ = nucleus.Run(app)
}

Start the app, open /admin, and sign in with the bootstrap user. Orbit self-registers its prefix with the framework's default-deny RBAC and enforces its own session-based auth below that prefix.

The zero value is valid too — orbit.Module(orbit.Config{}) mounts under /admin with sensible defaults.

Signing in against your directory

If the host application declares an authentication chain, the admin panel uses it:

auth_backends: [ldap, local]

Orbit ships no LDAP client. It asks the framework's chain, so whatever the operator configured for the application applies to the panel too.

Authentication is delegated; authorization is not. The chain answers who the credentials belong to; this panel's own admin table still decides whether that person may enter. A directory account that is not an administrator here is refused — otherwise connecting a corporate directory would quietly make every employee in the company an administrator of your admin panel.

That also means a local admin row is not a bypass: with a chain configured, the chain still has to accept the password, so a revoked directory account cannot get in through a stale row.

Without auth_backends, nothing changes: the panel validates against its own table exactly as before.

Configuration

orbit.Config is bound from the modules.orbit.* subtree of your nucleus.yml (or set it directly in Go). All fields are optional.

Precedence: the YAML subtree is overlaid on whatever you passed to orbit.Module(...), key by key — so Go supplies the base and nucleus.yml wins for the keys it sets. The one exception is prefix: the framework mounts the module before it binds the subtree, so modules.orbit.prefix cannot move the panel. Setting it to something other than the mount point fails at startup, naming both values, rather than serving a panel whose own links point elsewhere.

Key (modules.orbit.*) Type Default Description
prefix string /admin URL path orbit mounts under. Must agree with the prefix passed to orbit.Module(...); see the precedence note above.
title string — Heading shown in the UI.
environment string — Label shown in the UI (e.g. production).
bootstrap_username string — Admin user created on first boot.
bootstrap_email string — Email for the bootstrap user.
bootstrap_password string — Password for the bootstrap user; empty → bootstrapping is skipped (provision the admin user another way, e.g. nucleus createuser).
auth_database string app default DB alias whose handle backs admin auth + the bootstrap user (use a dedicated DB for the admin user store).
migrations_path string migrations Directory the migrations view reads.
audit_max_size int 10000 In-memory audit-log ring size.
multitenant_enabled bool false Confine Data Studio (list, get, create, update, delete, bulk, CSV export, exports and their jobs, imports, fixtures) to the tenant the host app resolves for the request; a request with no resolved tenant and no default is a 403. ?tenant=<id> / ?tenant=all are accepted only from a superuser or a subject granted the tenant_switch RBAC action, and audited as tenant.override. The host's resolution must not be client-controlled (a header the client sets) for the confinement to hold.
multitenant_default string — Tenant applied when the host resolves none; without it such a request is refused unless the operator may switch tenants.
multitenant_ids []string — Known tenant IDs for the selector UI.
live_exclude_patterns []string — Path patterns excluded from the live HTTP feed.
trace_url_template string — External trace-explorer URL template (supports {trace_id}).
cluster_enabled bool false Aggregate the live feed across nodes via a Redis relay.
cluster_redis_url string — Redis URL for the live-telemetry relay.
cluster_channel string nucleus:admin:live:v1 Pub/sub channel for the relay.
cluster_node_id string runtime id Explicit node identifier in the relay.
cluster_token string — Shared secret to reject untrusted relay messages.
# nucleus.yml
modules:
  orbit:
    prefix: /admin
    title: Acme Admin
    environment: production
    bootstrap_username: admin
    bootstrap_email: admin@acme.test

How it works

Orbit is a nucleus.ModuleSpec. On startup it captures the app's Runtime and builds its panel from the framework's public accessors — the model registry, all managed database handles, the session manager, the RBAC enforcer, the live event bus, and storage. It never reaches into framework internals:

  • In-process — it sees live runtime state (sessions, SQL, model registry, metrics) that an out-of-process sidecar could not, without any IPC surface.
  • Self-contained auth — it owns a session-based login (DatabaseAdminAuth) against the nucleus_admin_users table and self-registers its prefix with the framework's default-deny RBAC, so the framework middleware never double-gates it.
  • Embedded SPA — the React UI is built into the module and served under the mount prefix.

Cluster observability (optional)

For fleet-wide live telemetry, orbit ships sibling modules that are releasable independently:

Module Role
orbit/proto Connect-RPC contract + generated stubs.
orbit/agent In-process agent (agent.NewExtension) that ships events to an admin server.
orbit/server Standalone admin-server binary that receives them.

Most applications only need the root orbit module for the in-process panel.

Relationship to Nucleus

Orbit is a "dogfooding" consumer of Nucleus: mounting a real, deep admin exercises and hardens the framework's extension/Runtime surface. The admin used to live in the framework core as pkg/admin; ADR-019 extracted it here as a clean break. Nucleus itself no longer ships any admin code.

Requirements

  • Go 1.26+
  • A Nucleus application to mount into.
  • (Optional) Redis — only for the cross-node live-telemetry relay.

Development

go work sync          # Go workspace: ./ ./agent ./proto ./quarkbridge ./quarkdatasource ./server
make build            # go build ./... in every module
make test             # go test ./... in every module

That is the quick inner loop. CI additionally builds and tests each of the six modules standalone (GOWORK=off, the way a consumer's toolchain resolves them), verifies the protobuf stubs and the two web UIs, and runs the repository guards. CONTRIBUTING.md walks through all of it — read it before opening a PR. Security reports go through SECURITY.md, never a public issue.

Documentation

Overview

Package orbit is the pluggable admin product for the Nucleus framework.

Orbit is a separate Go module that mounts in-process into a Nucleus application via the framework's extension/module API, and serves a self-contained admin UI (Data Studio, live request/SQL feed, session viewer, RBAC, system metrics). It was extracted from the framework core per nucleus ADR-019 so it can ship, version, and evolve as its own product while the core stays lean. Mount it explicitly:

app, err := nucleus.New().
    FromConfigFile("nucleus.yml").
    Mount(orbit.Module(orbit.Config{Prefix: "/admin"})).
    Build()

Orbit reads everything it needs from the nucleus Runtime — the model registry, the managed database handles, the session manager, the RBAC enforcer, the live event bus, storage (the accessors added in nucleus ADR-019 Slice 1/2) — so it never reaches into the framework's internals.

Index

Constants

View Source
const (
	ActionFieldText    = admin.ActionFieldText
	ActionFieldNumber  = admin.ActionFieldNumber
	ActionFieldBoolean = admin.ActionFieldBoolean
	ActionFieldSelect  = admin.ActionFieldSelect
	ActionFieldDate    = admin.ActionFieldDate
)

The types an ActionField may declare.

View Source
const (
	ActionOnSelection          = admin.ActionOnSelection
	ActionOnRecord             = admin.ActionOnRecord
	ActionOnSelectionAndRecord = admin.ActionOnSelectionAndRecord
)

The places a ModelAction can be offered.

View Source
const (
	// WidgetStat reads Widget.Stat: a headline figure and its change.
	WidgetStat = admin.WidgetKindStat
	// WidgetLine reads Widget.Series and draws a line chart.
	WidgetLine = admin.WidgetKindLine
	// WidgetBar reads Widget.Series and draws a bar chart.
	WidgetBar = admin.WidgetKindBar
	// WidgetTable reads Widget.Table: columns and rows of text.
	WidgetTable = admin.WidgetKindTable
	// WidgetRecords lists the newest rows of the model Widget.Records
	// names, read by the panel as the operator who is looking.
	WidgetRecords = admin.WidgetKindRecords
)

The kinds of card a Widget draws (Widget.Kind). An empty Kind is the value card A6 shipped, read from Load.

View Source
const DefaultPrefix = "/admin"

DefaultPrefix is the URL path orbit mounts under when Config.Prefix is empty.

Variables

This section is empty.

Functions

func Module

func Module(cfg Config) nucleus.ModuleSpec

Module returns orbit as a nucleus ModuleSpec, mountable on an application via the builder's Mount(...). It is self-contained: it declares its own URL prefix and acquires every framework service it needs from the Runtime in OnStart, then mounts the admin panel's own router under the prefix in Routes.

Types

type ActionDownload added in v1.19.0

type ActionDownload = admin.ActionDownload

ActionDownload is a file a ModelAction answers with (EXT-03): a name, a declared media type and the bytes the action produced. The panel sends it as an attachment, refuses one over its size ceiling rather than sending it truncated, and never opens a path on the action's behalf.

type ActionField added in v1.19.0

type ActionField = admin.ActionField

ActionField is one input a ModelAction asks for before it runs (EXT-01): a name, a label, a type, whether it is required and, for a select, its options. The panel draws the fields as a form, refuses a call whose input does not match them — naming the field — before the function runs, and hands the function the values typed in ActionRequest.Input. A field the panel cannot draw (an unknown type, a select with no options) refuses to start.

type ActionFieldType added in v1.19.0

type ActionFieldType = admin.ActionFieldType

ActionFieldType is what an ActionField asks for.

type ActionInput added in v1.19.0

type ActionInput = admin.ActionInput

ActionInput is what the operator entered in an action's form, typed by its fields: text and select as string, number as float64, boolean as bool, date as time.Time.

type ActionOption added in v1.19.0

type ActionOption = admin.ActionOption

ActionOption is one choice of a select ActionField: the value posted and the label read.

type ActionPlacement added in v1.19.0

type ActionPlacement = admin.ActionPlacement

ActionPlacement says where the panel offers a ModelAction (EXT-02): over the grid's selection, on one record — its record view and its row's menu — or both. The zero value is the selection, where every action was offered before it could say. The placement is enforced by the server, not only drawn: an action offered only on a record receives exactly that record's id.

type ActionRequest added in v1.10.0

type ActionRequest = admin.ActionRequest

ActionRequest is what a ModelAction is told about the call: the model, the selected ids, the operator, the tenant in force and the database alias the grid was reading.

type ActionResult added in v1.10.0

type ActionResult = admin.ActionResult

ActionResult is what a ModelAction reports back — a message for the operator, how many rows it changed, and anything else the screen should get. Every field is optional. Besides a message, an action can answer with a page of the panel to go to (Redirect, a path relative to the panel; anything else is refused when it answers) or a file to download (Download).

type Branding added in v1.10.0

type Branding = admin.Branding

Branding is the logo, favicon and accent colour an application gives the panel (CUST-02), the theme it opens in and the palette of each theme (EXT-09, EXT-10). Every field is optional.

type Cache added in v1.10.0

type Cache = admin.Cache

Cache is what an application implements to give the panel a cache it can inspect and empty (OR-49): a name for the view, a count of entries, and a flush. It is an ALIAS of the panel's own interface, so an implementation satisfies both without the application naming an internal package.

The panel never reads or writes entries through it. Counting and emptying is the whole of what an operator does to a cache from a screen, and a contract that could also read entries would put cached values — session data, rendered fragments, whatever the application caches — behind a panel permission that was never meant to cover them.

type ClientCode added in v1.19.0

type ClientCode = admin.ClientCode

ClientCode is the application's own code for the browser side of the panel (EXT-06, EXT-07): the files it is read from, the scripts and stylesheets the panel's document loads after its own bundle, and the names of the field renderers the scripts register with window.orbit.registerFieldRenderer.

type Config

type Config struct {
	// Prefix is the URL path orbit mounts under (default DefaultPrefix).
	Prefix string `yaml:"prefix" koanf:"prefix"`
	// Title is the heading shown in the admin UI.
	Title string `yaml:"title" koanf:"title"`

	// Bootstrap admin user, created on first start if it does not exist. When
	// BootstrapPassword is empty, bootstrapping is skipped (the operator is
	// expected to provision the admin user another way).
	BootstrapUsername string `yaml:"bootstrap_username" koanf:"bootstrap_username"`
	BootstrapEmail    string `yaml:"bootstrap_email" koanf:"bootstrap_email"`
	BootstrapPassword string `yaml:"bootstrap_password" koanf:"bootstrap_password"`

	// AuthDatabase optionally names a managed database alias whose handle backs
	// admin authentication and the bootstrap user. Empty means use the default
	// database. The panel itself (Data Studio etc.) always runs on the default
	// handle; only the auth/bootstrap *sql.DB is redirected.
	AuthDatabase string `yaml:"auth_database" koanf:"auth_database"`

	// Multi-tenant: set these to match the host application so Data Studio is
	// confined to the tenant the app resolves for each request (list, get,
	// create, update, delete, bulk, exports, imports, fixtures). Only a
	// superuser or a subject granted the tenant_switch RBAC action can look at
	// another tenant (?tenant=<id>) or at all of them (?tenant=all), and every
	// switch is audited. Leave disabled for single-tenant apps.
	MultiTenantEnabled bool     `yaml:"multitenant_enabled" koanf:"multitenant_enabled"`
	MultiTenantDefault string   `yaml:"multitenant_default" koanf:"multitenant_default"`
	MultiTenantIDs     []string `yaml:"multitenant_ids" koanf:"multitenant_ids"`

	// Row ownership: which column of a model says WHICH OPERATOR a row
	// belongs to, keyed by model name, with "*" as the default for every
	// model that carries the same column. It is what makes an RBAC policy on
	// admin:<Model>#own enforceable — the grant every editorial admin needs
	// ("an author edits their own posts"): lists are filtered by the column,
	// another operator's row is reported as not found, and a create stamps
	// it. A #own grant on a model that has no entry here is refused, never
	// widened to every row.
	//
	// RowOwnerSubject names which name of the operator the column holds:
	// "username" (default) or "id".
	RowOwnerFields  map[string]string `yaml:"row_owner_fields" koanf:"row_owner_fields"`
	RowOwnerSubject string            `yaml:"row_owner_subject" koanf:"row_owner_subject"`

	// FieldWidgets declares how a field is edited when its type cannot say
	// it: "Model.Field" (or "Model.column") to one of json, richtext, file
	// or image. A JSON document is inferred from the type and needs no
	// entry; "this string is HTML" and "this string is a storage key" are
	// claims about intent that no column type carries, so the application
	// makes them here. A file field gets an upload route
	// (POST /api/models/{model}/upload) that stores the bytes in the
	// application's own storage and answers with the key the form writes.
	// An entry the panel cannot apply — a widget outside those four, or a
	// key that names no field of the application — refuses to start.
	FieldWidgets map[string]string `yaml:"field_widgets" koanf:"field_widgets"`

	// Environment is a label shown in the UI (e.g. "production"). Optional.
	Environment string `yaml:"environment" koanf:"environment"`
	// MigrationsPath is the directory the migrations view reads (default "migrations").
	MigrationsPath string `yaml:"migrations_path" koanf:"migrations_path"`
	// AuditMaxSize caps the in-memory audit log ring buffer; zero or negative
	// means the default of 10000 entries. It bounds the MEMORY store only: a
	// trail kept in the database is bounded by AuditRetentionDays.
	AuditMaxSize int `yaml:"audit_max_size" koanf:"audit_max_size"`

	// AuditStore selects where the audit trail is kept: "database" (the
	// default when the application has a database) writes a table the panel
	// owns and creates, so the trail survives restarts and is shared by every
	// replica; "memory" keeps the process-lifetime ring instead.
	AuditStore string `yaml:"audit_store" koanf:"audit_store"`

	// AuditRetentionDays drops trail entries older than that many days,
	// applied at mount and at most hourly afterwards. Zero keeps them until
	// somebody clears the log. It is a PERIOD, which is what a compliance
	// window is; AuditMaxSize is a count and answers a different question.
	AuditRetentionDays int `yaml:"audit_retention_days" koanf:"audit_retention_days"`

	// LiveExcludePatterns lists path patterns excluded from the live HTTP
	// capture feed (e.g. health checks, the admin's own polling endpoints).
	LiveExcludePatterns []string `yaml:"live_exclude_patterns" koanf:"live_exclude_patterns"`
	// ClusterEnabled turns on cluster-aware live telemetry: live request/SQL
	// events are relayed between nodes over Redis so the feed shows the whole
	// fleet, not just the local node. Best-effort — a relay failure never blocks
	// startup.
	ClusterEnabled bool `yaml:"cluster_enabled" koanf:"cluster_enabled"`
	// ClusterRedisURL is the Redis URL backing the live telemetry relay.
	ClusterRedisURL string `yaml:"cluster_redis_url" koanf:"cluster_redis_url"`
	// ClusterChannel is the Redis pub/sub channel the relay publishes on
	// (default nucleus:admin:live:v1).
	ClusterChannel string `yaml:"cluster_channel" koanf:"cluster_channel"`
	// ClusterNodeID is an explicit node identifier for this instance in the
	// relay (defaults to the runtime identity).
	ClusterNodeID string `yaml:"cluster_node_id" koanf:"cluster_node_id"`
	// ClusterToken is a shared secret the relay uses to reject untrusted
	// (cross-tenant or spoofed) messages on the channel.
	ClusterToken string `yaml:"cluster_token" koanf:"cluster_token"`
	// TraceURLTemplate is an external trace-explorer URL template surfaced in
	// the UI; it supports a {trace_id} placeholder.
	TraceURLTemplate string `yaml:"trace_url_template" koanf:"trace_url_template"`

	// Cache is the cache this application wants the panel to show and be
	// able to empty. Nil — the default — means the panel says there is no
	// cache here rather than offering a button that refuses.
	//
	// Nothing in the framework owns an application's cache (pkg/cache is a
	// library an application builds with, not a service the app wires), so
	// there is nothing for the panel to discover: the application is the
	// only thing that can say which cache the operator is looking at.
	// Go-only wiring; not bindable from YAML.
	Cache Cache `yaml:"-" koanf:"-"`

	// Actions are the verbs this application defines for its own models —
	// "publish these three drafts", "retry these payments" — which the
	// panel draws on the model's grid, on one record's view, or both (see
	// ActionPlacement), and runs under the same authorization, tenant and
	// row confinement as its own bulk verbs.
	// Nothing here can be discovered: the panel cannot know that a column
	// called status makes "publish" meaningful, so the application names
	// the verb and supplies the function. Go-only wiring; not bindable
	// from YAML. A declaration the panel cannot honour — an unknown model,
	// a duplicate verb, one of the panel's own — refuses to start.
	Actions []ModelAction `yaml:"-" koanf:"-"`

	// Pages are screens of this application's own, mounted inside the
	// panel: under its prefix, behind its session, gated by its RBAC and
	// listed in its navigation. The application writes the handler; the
	// panel supplies everything around it. Go-only wiring; not bindable
	// from YAML.
	Pages []Page `yaml:"-" koanf:"-"`

	// Branding is how the panel wears the application's clothes: the logo
	// on the sidebar and the login screen, the icon in the browser tab, the
	// accent colour, the theme the panel opens in and the palette of each
	// theme. Empty fields keep Orbit's own. Unlike Actions and Pages it is
	// plain configuration, so it binds from nucleus.yml too.
	Branding Branding `yaml:"branding" koanf:"branding"`

	// Widgets are the cards this application puts on the panel's overview:
	// its own numbers, which the panel cannot discover. Go-only wiring;
	// each widget carries the function that reads its value, and its Kind
	// says what the card draws — a value, a figure and its change, a line
	// or bar chart, a table, or the newest rows of a model.
	Widgets []Widget `yaml:"-" koanf:"-"`

	// Dashboards are screens of cards beside the overview — the finance
	// numbers, the support queue — each listed in the navigation and gated
	// as a whole by its own permission (view on admin:dashboard:<id>). The
	// overview is not one of them and does not change. Go-only wiring,
	// like Widgets. A declaration the panel cannot draw — an unknown kind,
	// a kind without its function, a dashboard with no cards — refuses to
	// start, naming it.
	Dashboards []Dashboard `yaml:"-" koanf:"-"`

	// Client is the application's own code for the browser side of the
	// panel: scripts and stylesheets the panel serves under its prefix and
	// its document loads after the panel's bundle, each named with the
	// digest of its bytes, so the Content-Security-Policy's script-src
	// stays 'self'; and the field renderers those scripts register, which
	// FieldWidgets may name to draw a field the application's way in the
	// list and on the record view. Go-only wiring: it carries a file
	// system. A declaration the panel cannot serve — a file that is not
	// there, a path that climbs out of Files, a renderer no script was
	// declared to register — refuses to start, naming it.
	Client ClientCode `yaml:"-" koanf:"-"`

	// Locale is the language the panel's own chrome opens in ("es",
	// "pt-BR"). It covers the panel's words — navigation, buttons, empty
	// states — and never the application's data: a model called Invoice is
	// called Invoice in every language. Empty means English.
	Locale string `yaml:"locale" koanf:"locale"`

	// Messages adds to or overrides the chrome's phrases, by locale and
	// key, including for a language the panel does not ship. A phrase
	// nobody translated reads in English rather than as its key.
	Messages map[string]map[string]string `yaml:"messages" koanf:"messages"`

	// DataSource overrides the source Data Studio browses and edits (ADR-001).
	// Nil means the default: a Nucleus-backed adapter over the application's
	// model registry and database handles. Set it to browse another backend —
	// e.g. an app that runs the Quark ORM passes a quarkdatasource adapter
	// (QADR-0006, Caso 2). Go-only wiring; not bindable from YAML. When set,
	// the runtime field-metadata editor is disabled (it mutates the Nucleus
	// registry, which a custom source does not necessarily have).
	//
	// The default leaves at Orbit 2.0 with Nucleus's pkg/model
	// (DEP-2026-002): the panel then reads Quark models only, and a nil
	// DataSource is a configuration error. An application still on the
	// default is told so at start, with one WARN.
	DataSource datasource.DataSource `yaml:"-" koanf:"-"`
}

Config configures the orbit admin module. The zero value is valid (orbit mounts under DefaultPrefix); bound from the `modules.orbit.*` subtree of the application config when mounted on a config-file app.

The struct is flat, but its fields serve two different modes — do not let the cluster vocabulary scare a plain panel setup:

  • Panel (what almost every app uses): Prefix, Title, Bootstrap*, AuthDatabase, MultiTenant*, Environment, MigrationsPath, AuditMaxSize, LiveExcludePatterns, TraceURLTemplate. Nothing else is required: a prefix, a title and the bootstrap fields are a complete production shape.
  • Cluster live-feed relay (opt-in, off by default): the Cluster* fields. They only matter once ClusterEnabled is true; in particular, NO Redis is needed to run the panel — ClusterRedisURL is read exclusively by the relay. The standalone fleet plane (agent/, server/) is configured on its own binaries, not here.
  • Go-only: DataSource (not bindable from YAML).

Grouping the Cluster* fields into a nested sub-struct would make this split structural, but the flat yaml keys (cluster_enabled, ...) are part of the frozen surface below, so that reshuffle is deliberately deferred to a hypothetical v2; within v1.x the split lives in this comment and in the configuration docs.

Config is a frozen v1.0 surface (docs/V1_GATE.md §A-3): every field keeps its name, yaml key, type, and zero-value behavior for the life of v1.x. Fields may be added; none is removed or renamed without a major. The freeze is enforced by contracts/freeze_test.go.

type Dashboard added in v1.19.0

type Dashboard = admin.Dashboard

Dashboard is a screen of cards beside the overview, listed in the navigation and gated by its own permission on admin:dashboard:<id>.

type ModelAction added in v1.10.0

type ModelAction = admin.ModelAction

ModelAction is an action an application defines for one of its own models (DS-09): the verb on the wire and in the RBAC policy, the label on the button, and the function that runs it over the rows an operator selected. It is an ALIAS of the panel's own type, so an application declares one without naming an internal package.

The ids the function receives are already confined to what that operator may touch. That is the reason the action runs through the panel instead of being an endpoint of the application's own: it inherits the row and tenant policies the panel enforces, and the audit entry, rather than being the way around them.

type Operator added in v1.10.0

type Operator = admin.Operator

Operator is who is looking at an application Page.

func OperatorFromContext added in v1.10.0

func OperatorFromContext(ctx context.Context) (Operator, bool)

OperatorFromContext returns the panel operator a Page request was authenticated as.

type Page added in v1.10.0

type Page = admin.Page

Page is a screen of the application's own, mounted inside the panel (CUST-04). The handler is ordinary net/http; the panel authenticates the request, authorizes it against admin:page:<id>, puts the operator on the context (OperatorFromContext) and lists the page in the navigation.

It is a link, not a frame: the panel refuses to be framed (X-Frame-Options: DENY), and its Content-Security-Policy applies to the page too — so a page's scripts come from files, not from inline <script>.

type Palette added in v1.19.0

type Palette = admin.Palette

Palette is the colours of one theme of the panel — its accent, its surface and its text — as Branding.Light and Branding.Dark declare them. Each is checked at startup against the ground it is drawn on in that theme.

type RecordList added in v1.19.0

type RecordList = admin.RecordList

RecordList names the model a "records" card lists, its columns, its order and how many rows.

type Series added in v1.19.0

type Series = admin.Series

Series is one named sequence of a chart.

type SeriesValue added in v1.19.0

type SeriesValue = admin.SeriesValue

SeriesValue is what a "line" or "bar" card draws: labels along the horizontal axis and one value per label for each Series.

type StatValue added in v1.19.0

type StatValue = admin.StatValue

StatValue is what a "stat" card shows: a figure, its change as the application formats it, which way it went, and whether that is good news.

type TableValue added in v1.19.0

type TableValue = admin.TableValue

TableValue is what a "table" card shows: columns and rows of text.

type Widget added in v1.10.0

type Widget = admin.Widget

Widget is one card an application puts on the panel's overview (CUST-03): a title and the function that reads the value. The panel supplies the screen, the authorization (admin:dashboard), a timeout, and a card that says it could not be read rather than a screen that drops it.

type WidgetItem added in v1.10.0

type WidgetItem = admin.WidgetItem

WidgetItem is one row of a list widget.

type WidgetValue added in v1.10.0

type WidgetValue = admin.WidgetValue

WidgetValue is what a Widget shows: a headline value, a smaller detail line, or a short list of rows.

Directories

Path Synopsis
agent module
datasource module
internal
admin
Package admin provides an auto-generated administration panel for Nucleus, similar to Django's contrib.admin.
Package admin provides an auto-generated administration panel for Nucleus, similar to Django's contrib.admin.
proto module
quarkbridge module
server module
ui module

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL