package runners import ( "context" "log/slog" "time" ) // MCPTokensPurgeRepo is the minimal repo surface this runner needs. // internal/mcp.Repository satisfies it via an adapter in app.go. type MCPTokensPurgeRepo interface { PurgeExpired(ctx context.Context, before time.Time) (int64, error) } // MCPTokensPurge deletes mcp_tokens older than retention. Periodic; idempotent. type MCPTokensPurge struct { repo MCPTokensPurgeRepo retention time.Duration log *slog.Logger } // NewMCPTokensPurge builds the purger. func NewMCPTokensPurge(repo MCPTokensPurgeRepo, retention time.Duration, log *slog.Logger) *MCPTokensPurge { if log == nil { log = slog.Default() } return &MCPTokensPurge{repo: repo, retention: retention, log: log} } // Run purges once. func (r *MCPTokensPurge) Run(ctx context.Context) { cutoff := time.Now().Add(-r.retention) rows, err := r.repo.PurgeExpired(ctx, cutoff) if err != nil { r.log.Error("mcp_tokens.purge", "err", err.Error()) return } if rows > 0 { r.log.Info("mcp_tokens.purged", "count", rows, "before", cutoff.UTC().Format(time.RFC3339)) } }