Documentation
¶
Index ¶
- Variables
- func NewDB(cfg Config) (*gorm.DB, error)
- func NewDBWithLogger(cfg Config, logLevel logger.LogLevel) (*gorm.DB, error)
- type APIKeyFilter
- type APIKeyRepository
- type AuditFilter
- type AuditRepository
- type BudgetRepository
- type Config
- type GormAPIKeyRepository
- func (r *GormAPIKeyRepository) Create(ctx context.Context, key *types.APIKey) error
- func (r *GormAPIKeyRepository) Delete(ctx context.Context, id string) error
- func (r *GormAPIKeyRepository) Get(ctx context.Context, id string) (*types.APIKey, error)
- func (r *GormAPIKeyRepository) List(ctx context.Context, filter APIKeyFilter) ([]*types.APIKey, error)
- func (r *GormAPIKeyRepository) Update(ctx context.Context, key *types.APIKey) error
- func (r *GormAPIKeyRepository) UpdateLastUsed(ctx context.Context, id string) error
- type GormAuditRepository
- func (r *GormAuditRepository) Count(ctx context.Context, filter AuditFilter) (int, error)
- func (r *GormAuditRepository) GetByRequestID(ctx context.Context, requestID types.SignRequestID) ([]*types.AuditRecord, error)
- func (r *GormAuditRepository) Log(ctx context.Context, record *types.AuditRecord) error
- func (r *GormAuditRepository) Query(ctx context.Context, filter AuditFilter) ([]*types.AuditRecord, error)
- type GormBudgetRepository
- func (r *GormBudgetRepository) AtomicSpend(ctx context.Context, ruleID types.RuleID, unit string, amount string) error
- func (r *GormBudgetRepository) Create(ctx context.Context, budget *types.RuleBudget) error
- func (r *GormBudgetRepository) Delete(ctx context.Context, id string) error
- func (r *GormBudgetRepository) DeleteByRuleID(ctx context.Context, ruleID types.RuleID) error
- func (r *GormBudgetRepository) GetByRuleID(ctx context.Context, ruleID types.RuleID, unit string) (*types.RuleBudget, error)
- func (r *GormBudgetRepository) ListByRuleID(ctx context.Context, ruleID types.RuleID) ([]*types.RuleBudget, error)
- func (r *GormBudgetRepository) ListByRuleIDs(ctx context.Context, ruleIDs []types.RuleID) ([]*types.RuleBudget, error)
- func (r *GormBudgetRepository) MarkAlertSent(ctx context.Context, ruleID types.RuleID, unit string) error
- func (r *GormBudgetRepository) ResetBudget(ctx context.Context, ruleID types.RuleID, unit string, ...) error
- type GormRequestRepository
- func (r *GormRequestRepository) CompareAndUpdate(ctx context.Context, req *types.SignRequest, ...) error
- func (r *GormRequestRepository) Count(ctx context.Context, filter RequestFilter) (int, error)
- func (r *GormRequestRepository) Create(ctx context.Context, req *types.SignRequest) error
- func (r *GormRequestRepository) Get(ctx context.Context, id types.SignRequestID) (*types.SignRequest, error)
- func (r *GormRequestRepository) List(ctx context.Context, filter RequestFilter) ([]*types.SignRequest, error)
- func (r *GormRequestRepository) Update(ctx context.Context, req *types.SignRequest) error
- func (r *GormRequestRepository) UpdateStatus(ctx context.Context, id types.SignRequestID, status types.SignRequestStatus) error
- type GormRuleRepository
- func (r *GormRuleRepository) Count(ctx context.Context, filter RuleFilter) (int, error)
- func (r *GormRuleRepository) Create(ctx context.Context, rule *types.Rule) error
- func (r *GormRuleRepository) Delete(ctx context.Context, id types.RuleID) error
- func (r *GormRuleRepository) Get(ctx context.Context, id types.RuleID) (*types.Rule, error)
- func (r *GormRuleRepository) IncrementMatchCount(ctx context.Context, id types.RuleID) error
- func (r *GormRuleRepository) List(ctx context.Context, filter RuleFilter) ([]*types.Rule, error)
- func (r *GormRuleRepository) ListByChainType(ctx context.Context, chainType types.ChainType) ([]*types.Rule, error)
- func (r *GormRuleRepository) RunInTransaction(ctx context.Context, fn func(txRepo RuleRepository) error) error
- func (r *GormRuleRepository) Update(ctx context.Context, rule *types.Rule) error
- type GormTemplateRepository
- func (r *GormTemplateRepository) Count(ctx context.Context, filter TemplateFilter) (int, error)
- func (r *GormTemplateRepository) Create(ctx context.Context, tmpl *types.RuleTemplate) error
- func (r *GormTemplateRepository) Delete(ctx context.Context, id string) error
- func (r *GormTemplateRepository) Get(ctx context.Context, id string) (*types.RuleTemplate, error)
- func (r *GormTemplateRepository) GetByName(ctx context.Context, name string) (*types.RuleTemplate, error)
- func (r *GormTemplateRepository) List(ctx context.Context, filter TemplateFilter) ([]*types.RuleTemplate, error)
- func (r *GormTemplateRepository) Update(ctx context.Context, tmpl *types.RuleTemplate) error
- type InMemoryNonceStore
- type MemoryRuleRepository
- func (r *MemoryRuleRepository) Count(ctx context.Context, filter RuleFilter) (int, error)
- func (r *MemoryRuleRepository) Create(ctx context.Context, rule *types.Rule) error
- func (r *MemoryRuleRepository) Delete(ctx context.Context, id types.RuleID) error
- func (r *MemoryRuleRepository) Get(ctx context.Context, id types.RuleID) (*types.Rule, error)
- func (r *MemoryRuleRepository) IncrementMatchCount(ctx context.Context, id types.RuleID) error
- func (r *MemoryRuleRepository) List(ctx context.Context, filter RuleFilter) ([]*types.Rule, error)
- func (r *MemoryRuleRepository) ListByChainType(ctx context.Context, chainType types.ChainType) ([]*types.Rule, error)
- func (r *MemoryRuleRepository) RunInTransaction(_ context.Context, fn func(txRepo RuleRepository) error) error
- func (r *MemoryRuleRepository) Update(ctx context.Context, rule *types.Rule) error
- type NonceStore
- type RequestFilter
- type RequestRepository
- type RuleFilter
- type RuleRepository
- type TemplateFilter
- type TemplateRepository
- type Transactional
Constants ¶
This section is empty.
Variables ¶
var ErrBudgetExceeded = fmt.Errorf("budget exceeded")
ErrBudgetExceeded indicates the budget limit has been reached
var ErrStateConflict = fmt.Errorf("state conflict: status was modified by another request")
ErrStateConflict is returned when a compare-and-update fails because the current status does not match the expected status (concurrent modification).
Functions ¶
Types ¶
type APIKeyFilter ¶
APIKeyFilter for querying API keys
type APIKeyRepository ¶
type APIKeyRepository interface {
Create(ctx context.Context, key *types.APIKey) error
Get(ctx context.Context, id string) (*types.APIKey, error)
Update(ctx context.Context, key *types.APIKey) error
Delete(ctx context.Context, id string) error
List(ctx context.Context, filter APIKeyFilter) ([]*types.APIKey, error)
UpdateLastUsed(ctx context.Context, id string) error
}
APIKeyRepository defines the interface for API key persistence
type AuditFilter ¶
type AuditFilter struct {
RequestID *types.SignRequestID
APIKeyID *string
EventType *types.AuditEventType
ChainType *types.ChainType
StartTime *time.Time
EndTime *time.Time
// Cursor-based pagination (preferred over Offset)
// Cursor is the timestamp of the last item from previous page
Cursor *time.Time
// CursorID is the ID of the last item (for tie-breaking when timestamps are equal)
CursorID *types.AuditID
Limit int
}
AuditFilter for querying audit records
type AuditRepository ¶
type AuditRepository interface {
Log(ctx context.Context, record *types.AuditRecord) error
Query(ctx context.Context, filter AuditFilter) ([]*types.AuditRecord, error)
Count(ctx context.Context, filter AuditFilter) (int, error)
GetByRequestID(ctx context.Context, requestID types.SignRequestID) ([]*types.AuditRecord, error)
}
AuditRepository defines the interface for audit log persistence
type BudgetRepository ¶
type BudgetRepository interface {
Create(ctx context.Context, budget *types.RuleBudget) error
GetByRuleID(ctx context.Context, ruleID types.RuleID, unit string) (*types.RuleBudget, error)
Delete(ctx context.Context, id string) error
DeleteByRuleID(ctx context.Context, ruleID types.RuleID) error
// AtomicSpend atomically increments spent amount and tx count.
// Returns ErrBudgetExceeded if the spend would exceed limits.
// Uses SQL-level conditional UPDATE to prevent race conditions.
AtomicSpend(ctx context.Context, ruleID types.RuleID, unit string, amount string) error
// ResetBudget resets spent/txCount/alertSent for a new period.
// Uses conditional WHERE to ensure idempotent reset (only resets if in old period).
ResetBudget(ctx context.Context, ruleID types.RuleID, unit string, currentPeriodStart time.Time) error
ListByRuleID(ctx context.Context, ruleID types.RuleID) ([]*types.RuleBudget, error)
ListByRuleIDs(ctx context.Context, ruleIDs []types.RuleID) ([]*types.RuleBudget, error)
// MarkAlertSent sets alert_sent=true for the given rule+unit budget.
// This prevents duplicate alert notifications within the same period.
MarkAlertSent(ctx context.Context, ruleID types.RuleID, unit string) error
}
BudgetRepository defines the interface for budget persistence
type GormAPIKeyRepository ¶
type GormAPIKeyRepository struct {
// contains filtered or unexported fields
}
GormAPIKeyRepository implements APIKeyRepository using GORM
func NewGormAPIKeyRepository ¶
func NewGormAPIKeyRepository(db *gorm.DB) (*GormAPIKeyRepository, error)
NewGormAPIKeyRepository creates a new GORM-based API key repository
func (*GormAPIKeyRepository) Delete ¶
func (r *GormAPIKeyRepository) Delete(ctx context.Context, id string) error
Delete deletes an API key by ID
func (*GormAPIKeyRepository) List ¶
func (r *GormAPIKeyRepository) List(ctx context.Context, filter APIKeyFilter) ([]*types.APIKey, error)
List returns API keys matching the filter
func (*GormAPIKeyRepository) UpdateLastUsed ¶
func (r *GormAPIKeyRepository) UpdateLastUsed(ctx context.Context, id string) error
UpdateLastUsed updates the last used timestamp for an API key
type GormAuditRepository ¶
type GormAuditRepository struct {
// contains filtered or unexported fields
}
GormAuditRepository implements AuditRepository using GORM
func NewGormAuditRepository ¶
func NewGormAuditRepository(db *gorm.DB) (*GormAuditRepository, error)
NewGormAuditRepository creates a new GORM-based audit repository
func (*GormAuditRepository) Count ¶
func (r *GormAuditRepository) Count(ctx context.Context, filter AuditFilter) (int, error)
Count returns the total count of audit records matching the filter (ignoring Offset/Limit)
func (*GormAuditRepository) GetByRequestID ¶
func (r *GormAuditRepository) GetByRequestID(ctx context.Context, requestID types.SignRequestID) ([]*types.AuditRecord, error)
GetByRequestID returns all audit records for a specific request
func (*GormAuditRepository) Log ¶
func (r *GormAuditRepository) Log(ctx context.Context, record *types.AuditRecord) error
Log creates a new audit record
func (*GormAuditRepository) Query ¶
func (r *GormAuditRepository) Query(ctx context.Context, filter AuditFilter) ([]*types.AuditRecord, error)
Query returns audit records matching the filter using cursor-based pagination
type GormBudgetRepository ¶
type GormBudgetRepository struct {
// contains filtered or unexported fields
}
GormBudgetRepository implements BudgetRepository using GORM
func NewGormBudgetRepository ¶
func NewGormBudgetRepository(db *gorm.DB) (*GormBudgetRepository, error)
NewGormBudgetRepository creates a new GORM-based budget repository
func (*GormBudgetRepository) AtomicSpend ¶
func (r *GormBudgetRepository) AtomicSpend(ctx context.Context, ruleID types.RuleID, unit string, amount string) error
AtomicSpend atomically increments the spent amount and tx count for a budget. Uses conditional WHERE clause to prevent exceeding limits in concurrent scenarios. Returns ErrBudgetExceeded if the spend would exceed max_total or max_tx_count.
func (*GormBudgetRepository) Create ¶
func (r *GormBudgetRepository) Create(ctx context.Context, budget *types.RuleBudget) error
Create creates a new budget record
func (*GormBudgetRepository) Delete ¶
func (r *GormBudgetRepository) Delete(ctx context.Context, id string) error
Delete deletes a budget by ID
func (*GormBudgetRepository) DeleteByRuleID ¶
DeleteByRuleID deletes all budgets for a rule
func (*GormBudgetRepository) GetByRuleID ¶
func (r *GormBudgetRepository) GetByRuleID(ctx context.Context, ruleID types.RuleID, unit string) (*types.RuleBudget, error)
GetByRuleID retrieves a budget by rule ID and unit
func (*GormBudgetRepository) ListByRuleID ¶
func (r *GormBudgetRepository) ListByRuleID(ctx context.Context, ruleID types.RuleID) ([]*types.RuleBudget, error)
ListByRuleID returns all budgets for a specific rule
func (*GormBudgetRepository) ListByRuleIDs ¶
func (r *GormBudgetRepository) ListByRuleIDs(ctx context.Context, ruleIDs []types.RuleID) ([]*types.RuleBudget, error)
ListByRuleIDs returns all budgets for the given rule IDs
func (*GormBudgetRepository) MarkAlertSent ¶ added in v0.1.0
func (r *GormBudgetRepository) MarkAlertSent(ctx context.Context, ruleID types.RuleID, unit string) error
MarkAlertSent sets alert_sent=true for the given rule+unit budget.
func (*GormBudgetRepository) ResetBudget ¶
func (r *GormBudgetRepository) ResetBudget(ctx context.Context, ruleID types.RuleID, unit string, currentPeriodStart time.Time) error
ResetBudget resets the budget for a new period. Uses conditional WHERE on updated_at to ensure idempotent reset. Only resets if the budget was last updated before the current period start.
type GormRequestRepository ¶
type GormRequestRepository struct {
// contains filtered or unexported fields
}
GormRequestRepository implements RequestRepository using GORM
func NewGormRequestRepository ¶
func NewGormRequestRepository(db *gorm.DB) (*GormRequestRepository, error)
NewGormRequestRepository creates a new GORM-based request repository
func (*GormRequestRepository) CompareAndUpdate ¶
func (r *GormRequestRepository) CompareAndUpdate(ctx context.Context, req *types.SignRequest, expectedStatus types.SignRequestStatus) error
CompareAndUpdate atomically updates a request only if its current status matches expectedStatus. Uses a SQL WHERE clause to ensure atomicity at the database level, preventing TOCTOU race conditions. Returns ErrStateConflict if the status has been modified concurrently.
func (*GormRequestRepository) Count ¶
func (r *GormRequestRepository) Count(ctx context.Context, filter RequestFilter) (int, error)
Count returns the total count of requests matching the filter (ignoring Offset/Limit)
func (*GormRequestRepository) Create ¶
func (r *GormRequestRepository) Create(ctx context.Context, req *types.SignRequest) error
Create creates a new sign request
func (*GormRequestRepository) Get ¶
func (r *GormRequestRepository) Get(ctx context.Context, id types.SignRequestID) (*types.SignRequest, error)
Get retrieves a sign request by ID
func (*GormRequestRepository) List ¶
func (r *GormRequestRepository) List(ctx context.Context, filter RequestFilter) ([]*types.SignRequest, error)
List returns sign requests matching the filter using cursor-based pagination
func (*GormRequestRepository) Update ¶
func (r *GormRequestRepository) Update(ctx context.Context, req *types.SignRequest) error
Update updates an existing sign request
func (*GormRequestRepository) UpdateStatus ¶
func (r *GormRequestRepository) UpdateStatus(ctx context.Context, id types.SignRequestID, status types.SignRequestStatus) error
UpdateStatus updates the status of a sign request
type GormRuleRepository ¶
type GormRuleRepository struct {
// contains filtered or unexported fields
}
GormRuleRepository implements RuleRepository using GORM
func NewGormRuleRepository ¶
func NewGormRuleRepository(db *gorm.DB) (*GormRuleRepository, error)
NewGormRuleRepository creates a new GORM-based rule repository
func (*GormRuleRepository) Count ¶
func (r *GormRuleRepository) Count(ctx context.Context, filter RuleFilter) (int, error)
Count returns the total count of rules matching the filter (ignoring Offset/Limit)
func (*GormRuleRepository) IncrementMatchCount ¶
IncrementMatchCount increments the match count for a rule
func (*GormRuleRepository) List ¶
func (r *GormRuleRepository) List(ctx context.Context, filter RuleFilter) ([]*types.Rule, error)
List returns rules matching the filter
func (*GormRuleRepository) ListByChainType ¶
func (r *GormRuleRepository) ListByChainType(ctx context.Context, chainType types.ChainType) ([]*types.Rule, error)
ListByChainType returns all enabled rules for a specific chain type
func (*GormRuleRepository) RunInTransaction ¶ added in v0.1.0
func (r *GormRuleRepository) RunInTransaction(ctx context.Context, fn func(txRepo RuleRepository) error) error
RunInTransaction runs fn inside a database transaction. A new GormRuleRepository backed by the transaction is passed to fn.
type GormTemplateRepository ¶
type GormTemplateRepository struct {
// contains filtered or unexported fields
}
GormTemplateRepository implements TemplateRepository using GORM
func NewGormTemplateRepository ¶
func NewGormTemplateRepository(db *gorm.DB) (*GormTemplateRepository, error)
NewGormTemplateRepository creates a new GORM-based template repository
func (*GormTemplateRepository) Count ¶
func (r *GormTemplateRepository) Count(ctx context.Context, filter TemplateFilter) (int, error)
Count returns the total count of templates matching the filter
func (*GormTemplateRepository) Create ¶
func (r *GormTemplateRepository) Create(ctx context.Context, tmpl *types.RuleTemplate) error
Create creates a new template
func (*GormTemplateRepository) Delete ¶
func (r *GormTemplateRepository) Delete(ctx context.Context, id string) error
Delete deletes a template by ID
func (*GormTemplateRepository) Get ¶
func (r *GormTemplateRepository) Get(ctx context.Context, id string) (*types.RuleTemplate, error)
Get retrieves a template by ID
func (*GormTemplateRepository) GetByName ¶
func (r *GormTemplateRepository) GetByName(ctx context.Context, name string) (*types.RuleTemplate, error)
GetByName retrieves a template by name
func (*GormTemplateRepository) List ¶
func (r *GormTemplateRepository) List(ctx context.Context, filter TemplateFilter) ([]*types.RuleTemplate, error)
List returns templates matching the filter
func (*GormTemplateRepository) Update ¶
func (r *GormTemplateRepository) Update(ctx context.Context, tmpl *types.RuleTemplate) error
Update updates an existing template
type InMemoryNonceStore ¶
type InMemoryNonceStore struct {
// contains filtered or unexported fields
}
InMemoryNonceStore implements NonceStore with in-memory storage. Suitable for single-instance deployments. For multi-instance deployments, use Redis-based implementation.
func NewInMemoryNonceStore ¶
func NewInMemoryNonceStore(cleanupInterval time.Duration) (*InMemoryNonceStore, error)
NewInMemoryNonceStore creates a new in-memory nonce store. cleanupInterval specifies how often to run cleanup of expired nonces.
func (*InMemoryNonceStore) CheckAndStore ¶
func (s *InMemoryNonceStore) CheckAndStore(ctx context.Context, apiKeyID, nonce string, ttl time.Duration) (bool, error)
CheckAndStore checks if a nonce exists and stores it if not. Returns true if the nonce was stored (new), false if it already exists (replay).
func (*InMemoryNonceStore) Close ¶
func (s *InMemoryNonceStore) Close() error
Close stops the cleanup goroutine
type MemoryRuleRepository ¶ added in v0.1.0
type MemoryRuleRepository struct {
// contains filtered or unexported fields
}
MemoryRuleRepository is an in-memory RuleRepository for validation and tests. All methods are safe for concurrent use.
func NewMemoryRuleRepository ¶ added in v0.1.0
func NewMemoryRuleRepository() *MemoryRuleRepository
NewMemoryRuleRepository creates an empty in-memory rule repository.
func (*MemoryRuleRepository) Count ¶ added in v0.1.0
func (r *MemoryRuleRepository) Count(ctx context.Context, filter RuleFilter) (int, error)
Count returns the number of rules matching the filter.
func (*MemoryRuleRepository) Create ¶ added in v0.1.0
Create stores a new rule. Fails if ID already exists.
func (*MemoryRuleRepository) IncrementMatchCount ¶ added in v0.1.0
IncrementMatchCount is a no-op for in-memory repo.
func (*MemoryRuleRepository) List ¶ added in v0.1.0
func (r *MemoryRuleRepository) List(ctx context.Context, filter RuleFilter) ([]*types.Rule, error)
List returns rules matching the filter. Scope fields (ChainType, ChainID, APIKeyID, SignerAddress) use same semantics as GORM: rule field nil = applies to all; include when rule field is nil OR equals filter.
func (*MemoryRuleRepository) ListByChainType ¶ added in v0.1.0
func (r *MemoryRuleRepository) ListByChainType(ctx context.Context, chainType types.ChainType) ([]*types.Rule, error)
ListByChainType returns enabled rules for the given chain type.
func (*MemoryRuleRepository) RunInTransaction ¶ added in v0.1.0
func (r *MemoryRuleRepository) RunInTransaction(_ context.Context, fn func(txRepo RuleRepository) error) error
RunInTransaction runs fn directly (in-memory repo is single-process, already atomic).
type NonceStore ¶
type NonceStore interface {
// CheckAndStore checks if a nonce exists and stores it if not.
// Returns true if the nonce was stored (new), false if it already exists (replay).
CheckAndStore(ctx context.Context, apiKeyID, nonce string, ttl time.Duration) (bool, error)
}
NonceStore provides storage for request nonces to prevent replay attacks. Nonces are stored with TTL and automatically cleaned up.
type RequestFilter ¶
type RequestFilter struct {
APIKeyID *string
SignerAddress *string
ChainType *types.ChainType
ChainID *string
Status []types.SignRequestStatus
// Cursor-based pagination (preferred over Offset)
// Cursor is the created_at timestamp of the last item from previous page
Cursor *time.Time
// CursorID is the ID of the last item (for tie-breaking when timestamps are equal)
CursorID *types.SignRequestID
Limit int
}
RequestFilter for querying requests
type RequestRepository ¶
type RequestRepository interface {
Create(ctx context.Context, req *types.SignRequest) error
Get(ctx context.Context, id types.SignRequestID) (*types.SignRequest, error)
Update(ctx context.Context, req *types.SignRequest) error
// CompareAndUpdate atomically updates a request only if its current status
// matches expectedStatus. Returns ErrStateConflict if the status has changed.
CompareAndUpdate(ctx context.Context, req *types.SignRequest, expectedStatus types.SignRequestStatus) error
List(ctx context.Context, filter RequestFilter) ([]*types.SignRequest, error)
Count(ctx context.Context, filter RequestFilter) (int, error)
UpdateStatus(ctx context.Context, id types.SignRequestID, status types.SignRequestStatus) error
}
RequestRepository defines the interface for sign request persistence
type RuleFilter ¶
type RuleFilter struct {
ChainType *types.ChainType
ChainID *string
APIKeyID *string
SignerAddress *string
Type *types.RuleType
Source *types.RuleSource
EnabledOnly bool
Offset int
Limit int
}
RuleFilter for querying rules
type RuleRepository ¶
type RuleRepository interface {
Create(ctx context.Context, rule *types.Rule) error
Get(ctx context.Context, id types.RuleID) (*types.Rule, error)
Update(ctx context.Context, rule *types.Rule) error
Delete(ctx context.Context, id types.RuleID) error
List(ctx context.Context, filter RuleFilter) ([]*types.Rule, error)
Count(ctx context.Context, filter RuleFilter) (int, error)
ListByChainType(ctx context.Context, chainType types.ChainType) ([]*types.Rule, error)
IncrementMatchCount(ctx context.Context, id types.RuleID) error
}
RuleRepository defines the interface for rule persistence
type TemplateFilter ¶
type TemplateFilter struct {
Type *types.RuleType
Source *types.RuleSource
EnabledOnly bool
Offset int
Limit int
}
TemplateFilter for querying templates
type TemplateRepository ¶
type TemplateRepository interface {
Create(ctx context.Context, tmpl *types.RuleTemplate) error
Get(ctx context.Context, id string) (*types.RuleTemplate, error)
GetByName(ctx context.Context, name string) (*types.RuleTemplate, error)
Update(ctx context.Context, tmpl *types.RuleTemplate) error
Delete(ctx context.Context, id string) error
List(ctx context.Context, filter TemplateFilter) ([]*types.RuleTemplate, error)
Count(ctx context.Context, filter TemplateFilter) (int, error)
}
TemplateRepository defines the interface for template persistence
type Transactional ¶ added in v0.1.0
type Transactional interface {
RunInTransaction(ctx context.Context, fn func(txRepo RuleRepository) error) error
}
Transactional is implemented by repositories that support atomic operations. This is optional — callers should type-assert before use.