Skip to content

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.

The contracts package exists to:

  • keep core.App independent 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)

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].

Route provider used by the runtime.

type Controller[R any] interface {
Routes() []R
}

Helper:

type ControllerFunc[R any] func() []R

Keel uses contracts.Controller[httpx.Route].

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

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.

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.

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.

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.

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
}
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
}
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)
}
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)
}

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.

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)
}
type Translator interface {
T(locale, key string, args ...any) string
Locales() []string
}

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.