Documentation
¶
Overview ¶
Package host wires the workflow-plugin-cms components into a single http.Handler suitable for a standalone multisite host binary.
The CMS plugin still ships as an external gRPC plugin (cmd/), but for the gocodealone-multisite host the engine runs in-process — this package exposes the same component set without the gRPC boundary.
Per gocodealone-multisite SPEC.md §I and T13/T14/T16/T28/T31/T32.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct {
// PreviewSubdomainBase is the FQDN suffix for preview subdomains
// (e.g. "preview.gocodealone.com"). Empty disables preview-fallback
// in the tenant resolver AND disables auto-provision of preview
// domain rows on tenant create.
PreviewSubdomainBase string
// BundleRoot is the directory the static-serve middleware walks to
// find <tenant>/current/<path>. Required.
BundleRoot string
// HMACSecret signs ingest webhooks (SPEC V8). Required for the
// ingest endpoint to function; if empty, the endpoint returns 503.
HMACSecret string
// AdminHost, when set, moves the admin UI to https://<AdminHost>/
// and requires all admin API/media/UI requests to use that host.
// This avoids exposing admin under public tenant paths such as
// /admin on the marketing site.
AdminHost string
// AdminAuth gates admin UI/API/media requests. Production should
// wire this to workflow-plugin-auth session/JWT validation. When
// AdminHost is set and AdminAuth is nil, admin requests fail closed.
AdminAuth func(*http.Request) bool
// OnIngest is called with the verified payload. Production wires
// this to a Fetcher; tests typically pass a no-op.
OnIngest func(bundle.IngestPayload) error
// Stores. Defaults are in-memory; production passes postgres-backed
// implementations.
TenantsAdmin store.TenantAdminStore
Pages store.PageStore
// TenantResolverStore is the read-side tenant lookup interface used
// by the resolver middleware. If both this and TenantsAdmin are
// nil, a memory-backed store is created and shared between them
// via a thin adapter.
TenantResolverStore TenantResolverStore
// AnalyticsConfigForTenant returns the per-tenant analytics config
// (gtag measurement_id + anonymize_ip). Nil disables injection.
AnalyticsConfigForTenant func(tenantID int64) analytics.TenantConfig
// HealthCheck reports liveness (DB ping, etc.). Nil → always OK.
HealthCheck func(ctx context.Context) error
// MediaBackend persists tenant-scoped uploads. Nil disables the
// upload endpoint (returns 503).
MediaBackend media.Backend
// AuditSignKey signs audit-chain entries. Empty disables audit
// recording. Audit entries are emitted for tenant + page mutations.
AuditSignKey string
}
Config controls the host wiring.
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server is the assembled multisite host.
func (*Server) AdminAPI ¶
AdminAPI returns the underlying admin handler (for tests + advanced wiring).
func (*Server) Metrics ¶
func (s *Server) Metrics() *monitoring.Counters
Metrics returns the Counters (for /metrics) — exposed so the host binary can mount it on a separate path if needed.
func (*Server) ServeHTTP ¶
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request)
ServeHTTP routes a single request. Order of resolution:
- /healthz (always served, even without a Host header match)
- /metrics — Prometheus exposition
- /api/v1/admin/* — handed to AdminAPI (+ media upload subroute)
- /api/v1/ingest/release — handed to IngestHandler (HMAC)
- Everything else → tenant resolve → static-serve → 404 if neither
Every request increments the per-tenant request counter (V30) keyed on the resolved tenant slug (or "_unresolved" for admin/system routes).
type TenantInfo ¶
type TenantInfo = internal.TenantInfo
TenantInfo mirrors internal.TenantInfo so callers don't need to import internal.
type TenantResolverStore ¶
type TenantResolverStore interface {
Lookup(ctx context.Context, host string) (TenantInfo, bool)
LookupBySlug(ctx context.Context, slug string) (TenantInfo, bool)
}
TenantResolverStore is the read-side tenant lookup interface — it is satisfied by `internal.TenantStore` (the resolver expects this shape).