package store import ( "sort" "strings" "time" "github.com/google/uuid" ) func (m *Memory) AppendRuntimeLogCleanupAudit(tenantID, actor, filename, action string, sizeBefore int64, sizeAfter *int64, detail map[string]any) (string, error) { if strings.TrimSpace(tenantID) == "" { return "", ErrNotFound } if !ValidRuntimeLogCleanupAction(action) { return "", ErrInvalidInput } name := strings.TrimSpace(filename) if name == "" { return "", ErrInvalidInput } m.mu.Lock() defer m.mu.Unlock() id := uuid.NewString() row := &RuntimeLogCleanupAudit{ ID: id, TenantID: tenantID, ActorPrefix: strings.TrimSpace(actor), Filename: name, Action: action, SizeBefore: sizeBefore, SizeAfter: sizeAfter, Detail: detail, CreatedAt: time.Now().UTC(), } m.runtimeLogCleanupAudit = append(m.runtimeLogCleanupAudit, row) return id, nil } func (m *Memory) ListRuntimeLogCleanupAudit(tenantID, cursor string, limit int) ([]*RuntimeLogCleanupAudit, string, bool, error) { if limit <= 0 { limit = 50 } m.mu.RLock() defer m.mu.RUnlock() var filtered []*RuntimeLogCleanupAudit for _, row := range m.runtimeLogCleanupAudit { if row.TenantID == tenantID { filtered = append(filtered, row) } } sort.Slice(filtered, func(i, j int) bool { if filtered[i].CreatedAt.Equal(filtered[j].CreatedAt) { return filtered[i].ID > filtered[j].ID } return filtered[i].CreatedAt.After(filtered[j].CreatedAt) }) off := parseMaintCursor(cursor) end := off + limit next := "" hasMore := false if end > len(filtered) { end = len(filtered) } else if end < len(filtered) { hasMore = true next = formatMaintCursor(end) } if off >= len(filtered) { return nil, "", false, nil } out := make([]*RuntimeLogCleanupAudit, end-off) copy(out, filtered[off:end]) return out, next, hasMore, nil }