httpui

package
v0.6.0 Latest Latest
Warning

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

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

Documentation

Overview

Package httpui is the demo console's web layer: the router, the handlers, the templates they render, and the one stylesheet those templates load.

Every page is HTML the handler wrote. The console ships no JavaScript, so no page carries a script element or an event handler attribute, and it loads exactly one asset, /static/console.css. What a viewer sees is what the handler rendered, and a page that shows a number read that number itself. Sorting and filtering a table are links and a form that reload the page with the table's state in the query string, and the theme is a form that posts the choice to /theme, which is not a page: it keeps the choice in a cookie and sends the viewer back. /statement.json, /run.json and /kickbacks.json are not pages either: they serve the files the JSON export writes for a statement and for a run, as the export's own bytes rather than as HTML.

Every identifier travels in a query parameter rather than in a path segment. A cloud name, a resource id and a statement key may each carry a slash, and a path segment would either split such an identifier in two or hide it behind an escape that a proxy in front of the console is free to normalize away.

Nothing here writes to either side. The pages read the Reporting API for projects, resources, lifecycles, stats and refused events, and the engine database for everything monetary. A failure of either side reaches the viewer as one error page naming what failed, and the same wrapped error goes to the log.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewRouter

func NewRouter(opts Options) (http.Handler, error)

NewRouter parses the pages and assembles the console. It fails when a template does not parse, which keeps a broken build from starting a server whose pages only fail once someone opens them.

Types

type API

type API interface {
	ListProjects(ctx context.Context, q reporting.ProjectsQuery) (httpapi.ProjectList, reporting.Request, error)
	GetProject(ctx context.Context, id uuid.UUID) (httpapi.Project, reporting.Request, error)
	ListProjectRelations(
		ctx context.Context, id uuid.UUID, q reporting.RelationsQuery,
	) (httpapi.RelationList, reporting.Request, error)
	ListRelatedProjects(ctx context.Context, id uuid.UUID) (httpapi.RelatedProjectList, reporting.Request, error)
	GetProjectSummary(
		ctx context.Context, id uuid.UUID, from, to time.Time,
	) (httpapi.ProjectSummary, reporting.Request, error)
	ListResources(ctx context.Context, q reporting.ResourcesQuery) (httpapi.ResourceList, reporting.Request, error)
	GetLifecycle(
		ctx context.Context, cloud, resourceType, resourceID string,
	) (httpapi.Lifecycle, reporting.Request, error)
	ResourceStats(ctx context.Context, groupBy []string, status string) (httpapi.ResourceStatsList, reporting.Request, error)
	EventStats(
		ctx context.Context, groupBy []string, interval string, from, to time.Time,
	) (httpapi.EventStatsList, reporting.Request, error)
	ListRejectedEvents(ctx context.Context, limit int) (httpapi.DeadLetterList, reporting.Request, error)
}

API is the part of the Reporting API client the pages call. It is declared here rather than taken from the client package so a test can serve a page from canned answers, and *reporting.Client satisfies it as it is.

type Options

type Options struct {
	// Logger takes one line per failed page. A nil logger falls back to
	// slog.Default().
	Logger *slog.Logger
	// API reads the Reporting API and Store the engine database. The console
	// serves no page without both.
	API   API
	Store Store
	// Now is the clock the windowed reads are built from: the overview's event
	// window and the summary month of a project page. A nil Now is time.Now,
	// and a test pins it to a fixed instant.
	Now func() time.Time
}

Options is what the console needs to serve its pages.

type Source

type Source struct {
	Kind string
	Text string
}

Source is one read a page made: which side answered it, and what was asked.

type Store

type Store interface {
	ListPeriods(ctx context.Context) ([]store.Period, error)
	GetPeriod(ctx context.Context, from time.Time) (store.Period, error)
	ListRunsForPeriod(ctx context.Context, from time.Time) ([]store.Run, error)
	ListRunTotalsForPeriod(ctx context.Context, from time.Time) ([]store.RunTotal, error)
	ListRuns(ctx context.Context, limit int32) ([]store.Run, error)
	GetRun(ctx context.Context, id uuid.UUID) (store.Run, error)
	ListStatements(ctx context.Context, runID uuid.UUID) ([]store.StatementRow, error)
	GetStatement(ctx context.Context, runID uuid.UUID, key string) (store.Statement, error)
	ListStatementsForProject(ctx context.Context, key string) ([]store.ProjectStatementRow, error)
	ListKickbacksForBeneficiary(ctx context.Context, beneficiary string) ([]store.Kickback, error)
	ListPricingModels(ctx context.Context) ([]store.PricingModel, error)
	GetPricingModel(ctx context.Context, version string) (store.PricingDocument, error)
	LatestRunWithResource(ctx context.Context, cloud, resourceType, resourceID string) (uuid.UUID, bool, error)
	ListResourceSegments(
		ctx context.Context, runID uuid.UUID, cloud, resourceType, resourceID string,
	) ([]store.Segment, error)
	ListCorrectionDeltas(ctx context.Context, runID uuid.UUID) ([]store.Delta, error)
	LoadRunExport(ctx context.Context, runID uuid.UUID) (export.Run, error)
}

Store is the part of the engine read store the pages call, declared here for the reason API is. *store.Store satisfies it as it is.

Jump to

Keyboard shortcuts

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