package redisstate import ( "context" "errors" "fmt" "time" "galaxy/notification/internal/service/malformedintent" "github.com/redis/go-redis/v9" ) // MalformedIntentStore provides the Redis-backed storage used for // operator-visible malformed-intent records. type MalformedIntentStore struct { client *redis.Client keys Keyspace ttl time.Duration } // NewMalformedIntentStore constructs one Redis-backed malformed-intent store. func NewMalformedIntentStore(client *redis.Client, ttl time.Duration) (*MalformedIntentStore, error) { if client == nil { return nil, errors.New("new malformed intent store: nil redis client") } if ttl <= 0 { return nil, errors.New("new malformed intent store: non-positive ttl") } return &MalformedIntentStore{ client: client, keys: Keyspace{}, ttl: ttl, }, nil } // Record stores entry idempotently by its Redis Stream entry identifier. func (store *MalformedIntentStore) Record(ctx context.Context, entry malformedintent.Entry) error { if store == nil || store.client == nil { return errors.New("record malformed intent: nil store") } if ctx == nil { return errors.New("record malformed intent: nil context") } if err := entry.Validate(); err != nil { return fmt.Errorf("record malformed intent: %w", err) } payload, err := MarshalMalformedIntent(entry) if err != nil { return fmt.Errorf("record malformed intent: %w", err) } if err := store.client.Set(ctx, store.keys.MalformedIntent(entry.StreamEntryID), payload, store.ttl).Err(); err != nil { return fmt.Errorf("record malformed intent: %w", err) } return nil }