Documentation
¶
Overview ¶
Package app is the application bootstrap and dependency injection root. It creates and holds all shared infrastructure (DB pool, Redis client, Echo instance) and wires together all plugins, modules, and widgets.
Package app wires together all application dependencies.
This file holds one-time, idempotent startup backfills: data fix-ups that replay an addon's enable-effects across campaigns that enabled the addon BEFORE the effect existed. They run through the owning services (never hand-rolled SQL), so they can never drift from the service's definition of the data, and they are safe to run on every boot.
Package app — export_adapters.go provides adapter implementations that bridge plugin services to the campaign export/import interfaces. Each adapter converts plugin-specific types to the export model types defined in campaigns/export.go.
Package app wires together all application dependencies. This file implements the addons.PresetApplier interface, bridging the systems package (manifest data) and entities package (entity type creation) to auto-create entity types when a game system addon is enabled.
Package app wires together all application dependencies. This file implements the addons.SetupProvider for the Player Character Claiming addon — the first concrete extension settings/onboarding provider. It bridges the addons framework (which owns the settings page + registry) and the entities package (which owns the player-character category logic), so the addons package never imports entities (mirrors preset_applier.go).
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func StartupHealthCheckConfig ¶
func StartupHealthCheckConfig(cfg *config.Config) database.HealthCheckConfig
StartupHealthCheckConfig builds the HealthCheckConfig used at boot and on demand by the admin Health tab. The critical-column pins document which migration each column came from — a deploy missing that migration fails fast with a precise error instead of a downstream 500.
Types ¶
type App ¶
type App struct {
// Config holds the loaded application configuration.
Config *config.Config
// DB is the MariaDB connection pool shared by all plugins.
DB *sql.DB
// Redis is the Redis client shared for sessions, caching, rate limiting.
Redis *redis.Client
// Echo is the HTTP server instance.
Echo *echo.Echo
// WASMPluginManager manages loaded WASM logic extension plugins.
// Set during route registration; nil until then.
WASMPluginManager *extensions.PluginManager
// WASMHookDispatcher dispatches events to WASM plugins.
// Set during route registration; nil until then.
WASMHookDispatcher *extensions.HookDispatcher
// PluginHealth tracks which built-in plugins have healthy schemas.
// Used during route registration to skip degraded plugins.
PluginHealth *database.PluginHealthRegistry
// PluginSchemas holds the registered plugin migration configurations.
// Used by the database explorer to re-run migrations on demand.
PluginSchemas []database.PluginSchema
// contains filtered or unexported fields
}
App holds all shared dependencies and the Echo HTTP server instance. Created once at startup in main.go and used to register all routes.
func New ¶
func New(cfg *config.Config, db *sql.DB, rdb *redis.Client, pluginHealth *database.PluginHealthRegistry, pluginSchemas []database.PluginSchema) *App
New creates a new App instance with the given dependencies and configures the Echo server with global middleware and error handling.
func (*App) RegisterRoutes ¶
func (a *App) RegisterRoutes()
RegisterRoutes sets up all application routes. It registers public routes directly and delegates to each plugin's route registration function.
This is the single place where all routes are aggregated. When a new plugin is added, its routes are registered here.
func (*App) RegisteredPlugins ¶
func (a *App) RegisteredPlugins() []PluginRegistration
RegisteredPlugins returns a copy of the App's registry slice. Used by the removable-plugin test (NW-2.4 future) and by introspection (e.g. an /admin/diagnostics endpoint could list registered plugins).
Returns a copy so callers can't mutate the App's internal slice.
type PluginRegistration ¶
type PluginRegistration struct {
// Slug is the canonical identifier for this plugin. MUST match the
// owning plugin's exported PluginSlug const so the lookup is
// symmetric (slug → plugin code, plugin code → slug).
Slug string
// HealthCheck is an optional callback returning nil if the plugin
// is operational, or an error if not. Used by introspection +
// the removable-plugin test (NW-2.4). May be nil — not every
// plugin has a schema or other failable health signal.
HealthCheck func() error
// StaticFS is an optional embedded filesystem of plugin-owned
// static assets. When non-nil, App.mountPluginStatic() registers it
// with Echo at /static/plugins/<Slug>/. nil = no static assets.
StaticFS fs.FS
}
PluginRegistration is the per-plugin entry in the App's registry. Each plugin contributes exactly one entry, populated inline from RegisterRoutes at the plugin's setup point.
Fields:
- Slug: the canonical plugin identifier (matches the plugin's exported PluginSlug const). Required.
- HealthCheck: optional callback returning nil if healthy; may be nil for plugins without a schema dependency.
- StaticFS: optional embedded filesystem of static assets (JS, CSS, images). When non-nil, App.mountPluginStatic() registers it with Echo at /static/plugins/<slug>/. Use echo.MustSubFS(<embed.FS>, "static") at the registration site to strip the leading "static" dir from the embed so URLs map cleanly. Per cordinator/decisions/2026-05-25-plugin-static-assets.md.