engine

package
v0.0.0-...-ddef314 Latest Latest
Warning

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

Go to latest
Published: May 6, 2026 License: MIT Imports: 26 Imported by: 0

Documentation

Overview

templ: version: v0.3.1001

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AvailableTables

func AvailableTables(db *sql.DB) ([]string, error)

AvailableTables returns all non-internal, non-sqlite tables in the database.

func CheckHealthProbe

func CheckHealthProbe(url string) error

CheckHealthProbe is the client counterpart to ServeHealthProbe: it issues an HTTP GET against url and returns nil iff the response status is 200.

func ClientError

func ClientError(w http.ResponseWriter, title, message string, code int)

ClientError renders a styled HTML error page with the given title, message, and status code.

func FormatTimeAgo

func FormatTimeAgo(ts time.Time, fallbackAfter time.Duration, fallbackLayout string) string

FormatTimeAgo returns a human-readable relative time string like "just now", "3 minutes ago", "2 hours ago", or "5 days ago". If fallbackAfter is positive and the duration exceeds it, the time is formatted using fallbackLayout instead. Pass 0 for fallbackAfter to always use relative formatting.

func HandleError

func HandleError(w http.ResponseWriter, err error) bool

HandleError returns true if err is non-nil, logging the error and sending a 500 response. This allows cleaner error handling in handlers:

if engine.HandleError(w, err) {
    return
}

func MustMigrate

func MustMigrate(db *sql.DB, migration string)

MustMigrate applies a migration to the database, panicking on error.

func OpenDB

func OpenDB(path string) (*sql.DB, error)

OpenDB opens a SQLite database at the given path.

func OpenTestDB

func OpenTestDB(t *testing.T) *sql.DB

OpenTestDB creates a test database in a temporary directory.

func ServeHealthProbe

func ServeHealthProbe(db *sql.DB) http.HandlerFunc

ServeHealthProbe returns an HTTP handler that verifies db is reachable by opening and rolling back an empty transaction. It responds 200 on success and 500 on any error.

func SystemError

func SystemError(w http.ResponseWriter, msg string, args ...any)

SystemError logs the given message+args while returning a styled 500 error page.

Types

type App

type App struct {
	ProcMgr
	Router *Router
	// contains filtered or unexported fields
}

App is a wrapper around the process manager and http router/server concepts defined by this pkg. It represents a set of "modules": types that can run workers or handle http routes. Just load up modules with .Add() and then run the thing with .ProcMgr.Run().

func NewApp

func NewApp(httpAddr string, router *Router, db *sql.DB) *App

NewApp constructs an App that listens on httpAddr, serves the given router, and persists module configuration in db. The HTTP server is registered as a proc on the embedded ProcMgr and starts when Run is called.

func (*App) Add

func (a *App) Add(mod any)

Add registers mod with the App. The module may optionally implement any of:

  • AttachRoutes(*Router) to register HTTP handlers,
  • AttachWorkers(*ProcMgr) to register background procs,
  • ConfigSpec() config.Spec to advertise a configuration schema.

Modules that implement none of these are accepted but contribute nothing.

func (*App) ConfigStore

func (a *App) ConfigStore() *config.Store

ConfigStore returns the shared config store for typed config loading.

func (*App) Configs

func (a *App) Configs() *config.Registry

Configs returns the shared config registry into which modules register their specs.

type Authenticator

type Authenticator interface {
	WithAuthn(http.HandlerFunc) http.HandlerFunc
	WithLeadership(http.HandlerFunc) http.HandlerFunc
}

Authenticator decorates http.HandlerFuncs with authentication and leadership checks. WithAuthn enforces that a request is authenticated; WithLeadership additionally restricts to users acting in a leadership role. The default Router uses a no-op implementation; replace it to enable auth.

type EventLogger

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

EventLogger provides centralized event logging for a specific module.

func NewEventLogger

func NewEventLogger(db *sql.DB, module string) *EventLogger

NewEventLogger creates a new EventLogger for the specified module and applies the required migration.

func (*EventLogger) LogEvent

func (e *EventLogger) LogEvent(ctx context.Context, memberID int64, eventType, entityID, entityName string, success bool, details string)

LogEvent records an event to the module_events table.

Parameters:

  • memberID: the member ID if applicable, 0 for no member association
  • eventType: the type of event (e.g., "WebhookReceived", "RoleSync")
  • entityID: module-specific external ID (e.g., stripe_customer_id, discord_user_id, printer_serial)
  • entityName: optional display name (e.g., printer_name)
  • success: whether the operation succeeded
  • details: additional details about the event

type FormHandler

type FormHandler struct {
	Query  string
	Fields []string
}

FormHandler backs an HTTP form POST with a single SQL Exec. Query is run using sql.Named parameters: "route_id" is bound from the request path value "id", and each name in Fields is bound from the corresponding form value.

func (*FormHandler) Handler

func (f *FormHandler) Handler(db *sql.DB) http.HandlerFunc

Handler returns an http.HandlerFunc that executes f.Query against db using the bindings described on FormHandler, then redirects (303) back to the request's Referer. Errors are surfaced via SystemError.

type LocalTime

type LocalTime struct {
	Time time.Time
}

LocalTime is a time.Time wrapper that implements sql.Scanner for columns stored as int64 Unix epoch seconds (UTC). Scanned values are converted to the America/Chicago time zone.

func (*LocalTime) Scan

func (l *LocalTime) Scan(src any) error

Scan implements sql.Scanner. It expects src to be an int64 Unix epoch (UTC) and stores it in l.Time converted to America/Chicago local time.

type PollingFunc

type PollingFunc func(context.Context) bool

PollingFunc is invoked on every tick of a Poll/DynamicPoll loop. It should return true if it processed an item and wants to be invoked again immediately (e.g. to drain a queue), or false to wait for the next interval.

func Cleanup

func Cleanup(db *sql.DB, name, query string, args ...any) PollingFunc

Cleanup returns a PollingFunc that periodically runs a DELETE query. It logs errors and successful cleanups (when rows are affected).

func PollWorkqueue

func PollWorkqueue[T any](wq Workqueue[T]) PollingFunc

PollWorkqueue implements a very basic workqueue. For every call to the returned polling func: - The next item is found (if any) - The item is processed - The item is either marked as complete or failed

The polling func always returns true after processing an item so that the next visible item will be picked up without waiting for the polling interval. So it's important to either return a nil item or sql.ErrNoRows from GetNext when no more items are ready to be processed.

Items might be logged so it's recommended that T is a stringer.

type Proc

type Proc func(context.Context) error

Proc is a long-running worker function managed by a ProcMgr. A Proc is expected to run until its context is canceled; returning early (with or without an error) before cancellation is treated as a fatal bug.

func DynamicPoll

func DynamicPoll(intervalFn func() time.Duration, fn PollingFunc) Proc

DynamicPoll is like Poll but accepts a function that returns the interval, allowing the interval to be changed at runtime.

func Poll

func Poll(interval time.Duration, fn PollingFunc) Proc

Poll is a Proc that polls a given function regularly. If the function returns true, it will be called again immediately. This is useful for polling a queue for new items.

type ProcMgr

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

ProcMgr is like a fancy implementation of sync.WaitGroup: it owns a set of Procs, runs them concurrently, and waits for all of them to exit.

func (*ProcMgr) Add

func (p *ProcMgr) Add(proc Proc)

Add appends proc to the set of workers that will be launched by Run.

func (*ProcMgr) Run

func (p *ProcMgr) Run(ctx context.Context)

Run starts every registered proc in its own goroutine and blocks until ctx is canceled and all procs have returned.

type Router

type Router struct {

	// Authenticator can be used to pass an authenticator implementation to other handlers.
	Authenticator
	// contains filtered or unexported fields
}

Router wraps http.ServeMux to add request-level access logging, styled error pages, and an embedded Authenticator. The package's static assets directory is automatically mounted at "/".

func NewRouter

func NewRouter() *Router

NewRouter constructs a Router with a fresh ServeMux, mounts the embedded assets/ filesystem at "/", and installs a no-op Authenticator that callers can replace by assigning to the embedded field.

func (*Router) HandleFunc

func (r *Router) HandleFunc(route string, fn http.HandlerFunc)

HandleFunc registers fn as the handler for route, wrapping it with response status capture and structured slog access logging (path, method, user agent, latency, status).

func (*Router) Serve

func (r *Router) Serve(addr string) Proc

Serve wires up the stdlib http server to the engine.

func (*Router) ServeHTTP

func (r *Router) ServeHTTP(w http.ResponseWriter, rr *http.Request)

ServeHTTP implements http.Handler by delegating to the underlying ServeMux.

type StreamMux

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

StreamMux multiplexes a single data source to multiple subscribers. It lazily starts the source when the first subscriber connects and automatically stops it when the last subscriber disconnects.

func NewStreamMux

func NewStreamMux(source func(ctx context.Context) (io.ReadCloser, error)) *StreamMux

NewStreamMux constructs a StreamMux backed by source. The source function is invoked lazily on the first Subscribe call; the context it receives is canceled when the last subscriber disconnects (or Stop is called).

func (*StreamMux) ClientCount

func (s *StreamMux) ClientCount() int

ClientCount returns the current number of subscribers.

func (*StreamMux) Running

func (s *StreamMux) Running() bool

Running returns whether the source is currently active.

func (*StreamMux) Stop

func (s *StreamMux) Stop()

Stop cancels the source and closes all client channels.

func (*StreamMux) Subscribe

func (s *StreamMux) Subscribe() chan []byte

Subscribe returns a channel that receives stream data. The caller must call Unsubscribe when done to avoid resource leaks. If the source fails to start, returns nil.

func (*StreamMux) Unsubscribe

func (s *StreamMux) Unsubscribe(ch chan []byte)

Unsubscribe removes a client from the stream. When the last client unsubscribes, the source is stopped.

type TokenClaimsFunc

type TokenClaimsFunc func() *jwt.RegisteredClaims

TokenClaimsFunc returns a freshly populated claims struct each time the OAuth2 TokenSource needs to mint a new token.

type TokenIssuer

type TokenIssuer struct {
	Key *rsa.PrivateKey
}

TokenIssuer signs and verifies JWTs using an RSA private key (RS256).

func NewTokenIssuer

func NewTokenIssuer(keyFile string) *TokenIssuer

NewTokenIssuer returns a TokenIssuer whose key is loaded from keyFile. If the file does not exist, a fresh 2048-bit RSA key is generated and written to keyFile with mode 0600. Any I/O or parse error panics.

func (*TokenIssuer) OAuth2

OAuth2 adapts the issuer to an oauth2.TokenSource. Each refresh signs a new JWT built from tcf(); the result is wrapped in oauth2.ReuseTokenSource so the same token is reused until it expires.

func (*TokenIssuer) Sign

func (t *TokenIssuer) Sign(claims *jwt.RegisteredClaims) (string, error)

Sign returns a JWT signed with the issuer's RSA key (RS256) for claims.

func (*TokenIssuer) Verify

func (t *TokenIssuer) Verify(tok string) (*jwt.RegisteredClaims, error)

Verify parses and validates tok against the issuer's public key, returning the embedded registered claims. It returns an error if the signature is invalid or the token is otherwise unacceptable.

type Workqueue

type Workqueue[T any] interface {
	GetItem(context.Context) (T, error)
	ProcessItem(context.Context, T) error
	UpdateItem(ctx context.Context, item T, success bool) error
}

Workqueue is the generic interface consumed by PollWorkqueue and WithRateLimiting. Implementations supply an item source (GetItem), a per-item processor (ProcessItem), and an outcome reporter (UpdateItem) invoked with success=true iff ProcessItem returned nil.

func WithRateLimiting

func WithRateLimiting[T any](wq Workqueue[T], rps int) Workqueue[T]

WithRateLimiting rate limits calls to ProcessItem of the given workqueue.

Directories

Path Synopsis
Package config provides a declarative configuration system for modules.
Package config provides a declarative configuration system for modules.
Package oauthlogin extracts the common Discord/Google OAuth2 login flow.
Package oauthlogin extracts the common Discord/Google OAuth2 login flow.

Jump to

Keyboard shortcuts

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