Contracts
ss-keel-core/contracts is the stable boundary between the Keel runtime and infrastructure integrations.
This reference tracks ss-keel-core v0.11.0.
The runtime depends on contracts, official addons implement contracts, and applications can build their own adapters on top of the same interfaces. This is the layer that keeps Keel modular without leaking infrastructure details into ss-keel-core.
Why the contracts layer exists
Section titled “Why the contracts layer exists”The contracts package exists to:
- keep
core.Appindependent from database, cache, auth, and broker implementations - let addons depend on stable abstractions instead of application packages
- give generated and hand-written modules a shared abstraction surface
- keep clear boundaries between the core runtime, contracts, and addons
The official persistence addons prove compatibility against the shared repository contract at compile time:
var _ contracts.Repository[any, any, httpx.PageQuery, httpx.Page[any]] = (*database.GormRepository[any, any])(nil)
var _ contracts.Repository[any, any, httpx.PageQuery, httpx.Page[any]] = (*mongo.MongoRepository[any, any])(nil)Module
Section titled “Module”Basic application registration unit.
type Module[A any] interface { Register(app A)}core.App.Use(...) and core.Group.Use(...) both accept contracts.Module[*core.App].
Controller
Section titled “Controller”Route provider used by the runtime.
type Controller[R any] interface { Routes() []R}Helper:
type ControllerFunc[R any] func() []RKeel uses contracts.Controller[httpx.Route].
Repository
Section titled “Repository”Generic persistence contract.
type Repository[T any, ID any, Q any, P any] interface { FindByID(ctx context.Context, id ID) (*T, error) FindAll(ctx context.Context, q Q) (P, error) Create(ctx context.Context, entity *T) error Update(ctx context.Context, id ID, entity *T) error Patch(ctx context.Context, id ID, patch *T) error Delete(ctx context.Context, id ID) error}The official persistence addons both implement:
contracts.Repository[T, ID, httpx.PageQuery, httpx.Page[T]]type Cache interface { Get(ctx context.Context, key string) ([]byte, error) Set(ctx context.Context, key string, value []byte, ttl time.Duration) error Delete(ctx context.Context, key string) error Exists(ctx context.Context, key string) (bool, error)}Authentication and authorization middleware contract.
type Guard interface { Middleware() fiber.Handler}Implemented by: ss-keel-jwt
TokenSigner
Section titled “TokenSigner”Contract for signing a JWT after a successful authentication flow (e.g. OAuth callback).
type TokenSigner interface { Sign(subject string, data map[string]any) (string, error)}subject is a unique identifier for the user, typically "<provider>:<user-id>" (e.g. "google:1234567890").
data is an arbitrary claims map embedded in the token payload under the "data" key.
Implemented by: ss-keel-jwt · Used by: ss-keel-oauth
Base contract implemented by every addon.
type Addon interface { ID() string}ID() returns the stable addon identifier used across the runtime, CLI, and docs, for example gorm, redis, or devpanel.
Manifestable
Section titled “Manifestable”Contract for addons that expose machine-readable metadata to the CLI and dev panel.
type EnvVar struct { Key string ConfigKey string Description string Required bool Secret bool Default string Source string}
type AddonManifest struct { ID string Version string Capabilities []string Resources []string EnvVars []EnvVar}
type Manifestable interface { Manifest() AddonManifest}Use Manifest() when an addon needs to publish its capabilities, resources, and config-facing environment variables.
Debuggable and PanelRegistry
Section titled “Debuggable and PanelRegistry”Contracts used by ss-keel-devpanel to collect live addon events.
type PanelEvent struct { Timestamp time.Time AddonID string Label string Detail map[string]any Level string}
type Debuggable interface { PanelID() string PanelLabel() string PanelEvents() <-chan PanelEvent}
type PanelRegistry interface { RegisterAddon(d Debuggable)}Debuggable addons stream events to the panel, while PanelRegistry is the contract implemented by the panel itself so addons can register during their own setup.
PanelComponent and DebuggableWithView
Section titled “PanelComponent and DebuggableWithView”Optional contracts for addons that want a custom panel view instead of the default event table.
type PanelComponent interface { Render(ctx context.Context, w io.Writer) error}
type DebuggableWithView interface { Debuggable PanelView() PanelComponent}PanelComponent is intentionally minimal so ss-keel-core does not need to depend on a specific UI package. Any compatible renderer can satisfy it through Go’s structural typing.
Publisher and Subscriber
Section titled “Publisher and Subscriber”Messaging contracts.
type Message struct { Topic string Key []byte Payload []byte Headers map[string]string}
type MessageHandler func(ctx context.Context, msg Message) error
type Publisher interface { Publish(ctx context.Context, msg Message) error Close() error}
type Subscriber interface { Subscribe(ctx context.Context, topic string, handler MessageHandler) error Close() error}Mailer
Section titled “Mailer”type MailAttachment struct { Filename string ContentType string Data []byte}
type Mail struct { From string To []string CC []string BCC []string Subject string HTMLBody string TextBody string Attachments []MailAttachment}
type Mailer interface { Send(ctx context.Context, mail Mail) error}Storage
Section titled “Storage”type StorageObject struct { Key string Size int64 ContentType string LastModified time.Time}
type Storage interface { Put(ctx context.Context, key string, r io.Reader, size int64, contentType string) error Get(ctx context.Context, key string) (io.ReadCloser, error) Delete(ctx context.Context, key string) error URL(ctx context.Context, key string, expiry time.Duration) (string, error) Stat(ctx context.Context, key string) (*StorageObject, error)}Scheduler
Section titled “Scheduler”type Job struct { Name string Schedule string Handler func(ctx context.Context) error}
type Scheduler interface { Add(job Job) error Start() Stop(ctx context.Context)}HealthChecker
Section titled “HealthChecker”Contract used by /health.
type HealthChecker interface { Name() string Check(ctx context.Context) error}database.NewHealthChecker(...) and mongo.NewHealthChecker(...) are the current official persistence implementations.
MetricsCollector and Tracer
Section titled “MetricsCollector and Tracer”type RequestMetrics struct { Method string Path string StatusCode int Duration time.Duration}
type MetricsCollector interface { RecordRequest(m RequestMetrics)}
type Span interface { SetAttribute(key string, value any) RecordError(err error) End()}
type Tracer interface { Start(ctx context.Context, name string) (context.Context, Span)}Translator
Section titled “Translator”type Translator interface { T(locale, key string, args ...any) string Locales() []string}Logger
Section titled “Logger”Addon-facing logging contract.
type Logger interface { Info(format string, args ...interface{}) Warn(format string, args ...interface{}) Error(format string, args ...interface{}) Debug(format string, args ...interface{})}The built-in logger.Logger in ss-keel-core/logger satisfies this contract and can be passed into addon configs such as database.Config.Logger and mongo.Config.Logger.
See Architecture for the ecosystem layout and Persistence for the official persistence integrations.