admin

package
v0.38.1 Latest Latest
Warning

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

Go to latest
Published: Jul 21, 2026 License: MIT Imports: 42 Imported by: 0

Documentation

Overview

Package admin is a small read-only admin battery for GoFastr apps — stock screens on top of the data the framework already collects: queue jobs (when battery/queue is wired) and the audit log (when framework.WithAuditLog is set).

The battery mounts three pages:

GET /admin           index with per-section summary cards
GET /admin/queue     jobs list with ?status= filter
GET /admin/audit     audit log paged newest-first

Pages are self-contained server-rendered HTML — they don't depend on framework/uihost or the runtime, so the admin endpoints work even before any UI host is mounted. Wire your own auth middleware in front of them; nothing here gates access.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func SortDirOf

func SortDirOf(v string) string

SortDirOf normalizes a direction query value to "asc" (default) or "desc".

Types

type Battery

type Battery struct {
	// contains filtered or unexported fields
}

Battery is the framework Battery implementation.

func New

func New(cfg Config) *Battery

New constructs the Admin battery with the supplied config. Pass the result to framework.App.RegisterBattery.

func (*Battery) Init

func (b *Battery) Init(app *framework.App) error

Init implements framework.Battery. Mounts the three admin pages on the App's router under cfg.PathPrefix.

func (*Battery) Name

func (b *Battery) Name() string

Name implements framework.Battery.

func (*Battery) RegisterRoutes

func (b *Battery) RegisterRoutes(r *router.Router)

RegisterRoutes mounts the three admin pages under cfg.PathPrefix on the supplied router. Exposed so apps that compose their own router can mount the admin without going through the battery lifecycle.

type Config

type Config struct {
	// PathPrefix is the URL prefix under which admin pages mount.
	// Defaults to "/admin".
	PathPrefix string

	// Title is the title shown at the top of every admin page.
	// Defaults to "Admin".
	Title string

	// Theme supplies the shared design tokens (--color-* / --font-*) the admin
	// renders from, so the back-office matches the surface that mounts it
	// instead of looking like a separate tool. When zero, the framework
	// DefaultTheme is used. Pass the same theme the app's UI host uses for a
	// coherent experience; override any token to restyle.
	Theme style.Theme

	// FontFaceCSS is raw @font-face CSS for the app's fonts. The admin renders
	// standalone pages (its own <head>), so without this it would reference the
	// theme's --font-* families but never load their files. Pass the same
	// @font-face rules the UI host serves so the admin loads identical fonts.
	FontFaceCSS string

	// Queue is the optional Browsable queue. When set, /admin/queue is
	// active and appears in overview/navigation. When nil, it is hidden;
	// the direct page returns a "no queue wired" diagnostic so the route
	// never 404s ambiguously.
	Queue queue.Browsable

	// DB is the database connection used to read the audit log table and,
	// when entity admin is enabled, overrides the app DB for those operations.
	// When nil, Init uses the app DB; without either, /admin/audit returns a
	// "no audit log wired" stub.
	DB *sql.DB

	// AuditTable is the audit log table name. Defaults to "audit_log".
	AuditTable string

	// QueueListLimit caps rows on /admin/queue. Default 200.
	QueueListLimit int

	// AuditListLimit caps rows on /admin/audit. Default 200.
	AuditListLimit int

	// Entities lists the entity names to expose as editable CRUD screens
	// under <PathPrefix>/e/<table>. When empty (default) NOTHING is
	// exposed — an admin dropped into an app must name what it manages.
	// Set AllEntities for the whole-back-office behavior. Naming an
	// entity explicitly also works for a CRUD=false one, if you really
	// mean to. Screens proxy to each entity's own CrudHandler, so
	// validation, owner/tenant scope, hooks, and events all apply exactly
	// as on the JSON API.
	Entities []string

	// AllEntities exposes EVERY registered entity whose CRUD is enabled —
	// the explicit "generate the whole back-office" opt-in (previously the
	// implicit default when Entities was empty). CRUD-disabled entities
	// (e.g. battery/auth's users/sessions, which ship CRUD=false) are
	// skipped, so this never exposes credential tables. Ignored when
	// Entities is non-empty.
	AllEntities bool

	// Authorize gates every admin surface — both the SSR screens (via the UI
	// host's policy chain) and the RPC/form routes (via middleware). It returns
	// true to allow the request. When nil, the default authorizer requires an
	// authenticated user that holds the AdminRole (see below) — a user whose
	// GetRoles() []string includes it. Supply a custom predicate to override
	// the role check entirely (e.g. a permission lookup, an allow-list).
	Authorize func(ctx context.Context) bool

	// AdminRole is the role the default authorizer requires (when Authorize is
	// nil). Defaults to "admin". Ignored when Authorize is set.
	AdminRole string

	// EntityListLimit caps rows per page on an entity list screen. Default 50.
	EntityListLimit int

	// LoginPath, when set, redirects an UNAUTHENTICATED GET to a configured
	// login page (`LoginPath?next=<requested path>`) instead of returning a
	// bare 401. An authenticated user lacking the admin role still gets 403 —
	// they're signed in, just not allowed. Empty (default) keeps the 401.
	LoginPath string

	// Policy is the RBAC role policy the admin screens manage. When set
	// alongside GrantStore, the role→permission matrix screen is active
	// at <PathPrefix>/rbac/roles and grant/revoke persists across restarts.
	Policy *access.RolePolicy

	// GrantStore persists role→permission grants to the database. When
	// set alongside Policy, grant/revoke via the admin screens writes to
	// both the live policy and the DB. Wire it with
	// framework.NewGrantStore(db, policy) + EnsureSchema + LoadInto at boot.
	GrantStore *access.GrantStore

	// Auth is the auth manager used for the user→role assignment screen.
	// When set, the user roles screen is active at <PathPrefix>/rbac/users.
	// The underlying UserStore must implement UserLister (for listing) and
	// UpdateRoles (for assignment) — EntityUserStore does both.
	Auth *auth.AuthManager

	// EffectiveRoles optionally resolves additional roles for the user roles
	// screen. Direct auth_users.roles are always included with origin "direct";
	// hook results are unioned with them and labeled by their supplied origin.
	// When nil, the screen keeps its direct-roles-only rendering.
	EffectiveRoles func(ctx context.Context, userID string) []access.RoleWithOrigin

	// ProcessModules is the process-module supervisor the operator lifecycle
	// screen manages. When set, /admin/modules is active: list every module's
	// state (404-vs-503 surfaced in copy) plus enable/disable, bump-generation
	// (the circuit-reset / recovery lever, design §8), and per-grant revoke.
	// When nil, the screen is not mounted and the route 404s. Wire it with
	// app.ProcessModules() — the real *framework.ProcessModuleSupervisor
	// satisfies the processModuleController interface.
	ProcessModules processModuleController
}

Config configures the Admin battery.

Jump to

Keyboard shortcuts

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