Documentation
¶
Index ¶
- func RegisterOpener(scheme string, fn Opener)
- type AuditEvent
- type CredentialRef
- type DevFileStore
- func (s *DevFileStore) AppendAuditEvent(event AuditEvent) error
- func (s *DevFileStore) Close() error
- func (s *DevFileStore) CredentialRef(id string) (CredentialRef, bool)
- func (s *DevFileStore) DeleteSession(id string) error
- func (s *DevFileStore) PutCredentialRef(record CredentialRef) error
- func (s *DevFileStore) PutSession(record SessionRecord) error
- func (s *DevFileStore) PutTenant(record TenantRecord) error
- func (s *DevFileStore) RetainAudit(ctx context.Context, maxAge time.Duration) (int, error)
- func (s *DevFileStore) Session(id string) (SessionRecord, bool)
- func (s *DevFileStore) Tenant(id string) (TenantRecord, bool)
- type Opener
- type Option
- type SessionRecord
- type State
- type Store
- type TenantRecord
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func RegisterOpener ¶ added in v1.0.1
RegisterOpener registers an opener for the given DSN scheme. Panics on double-register so wiring bugs surface at startup rather than silently overwriting a prior registration.
Types ¶
type AuditEvent ¶
type AuditEvent struct {
ID string `json:"id"`
At time.Time `json:"at"`
TenantID string `json:"tenantId"`
Subject string `json:"subject"`
SessionID string `json:"sessionId"`
Transport string `json:"transport,omitempty"`
Tool string `json:"tool,omitempty"`
Action string `json:"action"`
Outcome string `json:"outcome"`
Reason string `json:"reason,omitempty"`
ResourceIDs map[string]string `json:"resourceIds,omitempty"`
Metadata map[string]string `json:"metadata,omitempty"`
}
type CredentialRef ¶
type CredentialRef struct {
ID string `json:"id"`
Backend string `json:"backend"`
Reference string `json:"reference"`
Workspace string `json:"workspaceId,omitempty"`
BaseURL string `json:"baseUrl,omitempty"`
Metadata map[string]string `json:"metadata,omitempty"`
ModifiedAt time.Time `json:"modifiedAt,omitempty"`
}
type DevFileStore ¶ added in v1.0.1
type DevFileStore struct {
// contains filtered or unexported fields
}
DevFileStore is the file/memory-backed implementation of Store. It is the dev/offline fallback; production deployments should register an external backend (Postgres) via RegisterOpener and select it through the DSN scheme. The C1 guard in cmd/clockify-mcp/main.go refuses to start the streamable_http transport against this store unless MCP_ALLOW_DEV_BACKEND=1 is set, because the JSON file-rewrite write pattern and the in-process mutex do not survive a multi-process deployment.
func (*DevFileStore) AppendAuditEvent ¶ added in v1.0.1
func (s *DevFileStore) AppendAuditEvent(event AuditEvent) error
func (*DevFileStore) Close ¶ added in v1.0.1
func (s *DevFileStore) Close() error
Close releases backend-owned resources. DevFileStore has no goroutines, no connection pool, and no OS handles held between calls, so Close is a no-op that always returns nil.
func (*DevFileStore) CredentialRef ¶ added in v1.0.1
func (s *DevFileStore) CredentialRef(id string) (CredentialRef, bool)
func (*DevFileStore) DeleteSession ¶ added in v1.0.1
func (s *DevFileStore) DeleteSession(id string) error
func (*DevFileStore) PutCredentialRef ¶ added in v1.0.1
func (s *DevFileStore) PutCredentialRef(record CredentialRef) error
func (*DevFileStore) PutSession ¶ added in v1.0.1
func (s *DevFileStore) PutSession(record SessionRecord) error
func (*DevFileStore) PutTenant ¶ added in v1.0.1
func (s *DevFileStore) PutTenant(record TenantRecord) error
func (*DevFileStore) RetainAudit ¶ added in v1.0.1
RetainAudit drops audit events older than maxAge from the in-memory slice and rewrites the file. Complementary to the WithAuditCap hard-limit: the cap protects against bursty writes between reaper ticks, retention enforces the time window. maxAge <= 0 is a no-op so operators can disable retention by clearing the env var.
func (*DevFileStore) Session ¶ added in v1.0.1
func (s *DevFileStore) Session(id string) (SessionRecord, bool)
func (*DevFileStore) Tenant ¶ added in v1.0.1
func (s *DevFileStore) Tenant(id string) (TenantRecord, bool)
type Opener ¶ added in v1.0.1
Opener is the factory signature registered by external backends. Modules that ship under a build tag (e.g. `-tags=postgres`) call RegisterOpener from an init() to become dispatchable via Open.
type Option ¶ added in v1.0.1
type Option func(*DevFileStore)
Option configures a DevFileStore at construction. External backends parse configuration from DSN query parameters, so Options do not apply to them.
func WithAuditCap ¶ added in v1.0.1
WithAuditCap caps the in-memory AuditEvents slice at n entries. Zero or negative disables the cap. See DevFileStore.auditCap for the rationale.
type SessionRecord ¶
type SessionRecord struct {
ID string `json:"id"`
TenantID string `json:"tenantId"`
Subject string `json:"subject"`
Transport string `json:"transport"`
ProtocolVersion string `json:"protocolVersion,omitempty"`
ClientName string `json:"clientName,omitempty"`
ClientVersion string `json:"clientVersion,omitempty"`
CreatedAt time.Time `json:"createdAt"`
ExpiresAt time.Time `json:"expiresAt"`
LastSeenAt time.Time `json:"lastSeenAt"`
WorkspaceID string `json:"workspaceId,omitempty"`
ClockifyBaseURL string `json:"clockifyBaseUrl,omitempty"`
SessionAffinityID string `json:"sessionAffinityId,omitempty"`
}
type State ¶
type State struct {
Tenants map[string]TenantRecord `json:"tenants"`
CredentialRefs map[string]CredentialRef `json:"credential_refs"`
Sessions map[string]SessionRecord `json:"sessions"`
AuditEvents []AuditEvent `json:"audit_events"`
}
type Store ¶
type Store interface {
Tenant(id string) (TenantRecord, bool)
PutTenant(record TenantRecord) error
CredentialRef(id string) (CredentialRef, bool)
PutCredentialRef(record CredentialRef) error
Session(id string) (SessionRecord, bool)
PutSession(record SessionRecord) error
DeleteSession(id string) error
AppendAuditEvent(event AuditEvent) error
// RetainAudit drops audit events older than maxAge and returns the
// number removed. Called periodically by the retention reaper
// (B2); maxAge <= 0 is a no-op. Implementations must respect ctx
// cancellation and must not leave the store in an inconsistent
// state on partial failure.
RetainAudit(ctx context.Context, maxAge time.Duration) (int, error)
// Close releases backend-owned resources (pgxpool, file handles).
// DevFileStore has nothing to release and returns nil.
Close() error
}
Store is the durable backend for the control plane. B1 lifted this from a concrete struct to an interface so an external backend (Postgres, behind -tags=postgres) can register alongside the built-in file/memory store. See RegisterOpener for the dispatch mechanism.
func Open ¶
Open returns a Store appropriate for the DSN. Built-in schemes: "" (alias for memory), "memory", "memory://", "file://<path>", or a bare filesystem path — all produce a DevFileStore. Any other scheme dispatches to an opener registered via RegisterOpener; if none is registered the error explicitly names the scheme and points the operator at the matching build tag.
type TenantRecord ¶
type TenantRecord struct {
ID string `json:"id"`
CredentialRefID string `json:"credentialRefId"`
WorkspaceID string `json:"workspaceId,omitempty"`
BaseURL string `json:"baseUrl,omitempty"`
Timezone string `json:"timezone,omitempty"`
PolicyMode string `json:"policyMode,omitempty"`
DenyTools []string `json:"denyTools,omitempty"`
DenyGroups []string `json:"denyGroups,omitempty"`
AllowGroups []string `json:"allowGroups,omitempty"`
Metadata map[string]string `json:"metadata,omitempty"`
}