package app import ( "context" "fmt" "time" "gitea.dwysokinski.me/twhelp/corev3/internal/domain" ) type TribeSnapshotRepository interface { // Create persists tribe snapshots in a store (e.g. Postgres). // Duplicates are ignored. Create(ctx context.Context, params ...domain.CreateTribeSnapshotParams) error ListWithRelations( ctx context.Context, params domain.ListTribeSnapshotsParams, ) (domain.ListTribeSnapshotsWithRelationsResult, error) Delete(ctx context.Context, serverKey string, dateLTE time.Time) error } type TribeSnapshotService struct { repo TribeSnapshotRepository tribeSvc *TribeService pub SnapshotPublisher } func NewTribeSnapshotService( repo TribeSnapshotRepository, tribeSvc *TribeService, pub SnapshotPublisher, ) *TribeSnapshotService { return &TribeSnapshotService{repo: repo, tribeSvc: tribeSvc, pub: pub} } //nolint:gocyclo func (svc *TribeSnapshotService) Create( ctx context.Context, createSnapshotsCmdPayload domain.CreateSnapshotsCmdPayload, ) error { serverKey := createSnapshotsCmdPayload.ServerKey() date := createSnapshotsCmdPayload.Date() listTribesParams := domain.NewListTribesParams() if err := listTribesParams.SetServerKeys([]string{serverKey}); err != nil { return fmt.Errorf("%s: %w", serverKey, err) } if err := listTribesParams.SetDeleted(domain.NullBool{ V: false, Valid: true, }); err != nil { return fmt.Errorf("%s: %w", serverKey, err) } if err := listTribesParams.SetSort([]domain.TribeSort{domain.TribeSortIDASC}); err != nil { return fmt.Errorf("%s: %w", serverKey, err) } if err := listTribesParams.SetLimit(domain.TribeListMaxLimit); err != nil { return fmt.Errorf("%s: %w", serverKey, err) } for { res, err := svc.tribeSvc.List(ctx, listTribesParams) if err != nil { return fmt.Errorf("%s: %w", serverKey, err) } tribes := res.Tribes() if len(tribes) == 0 { break } params, err := domain.NewCreateTribeSnapshotParams(tribes, date) if err != nil { return fmt.Errorf("%s: %w", serverKey, err) } if err = svc.repo.Create(ctx, params...); err != nil { return fmt.Errorf("%s: %w", serverKey, err) } if res.Next().IsZero() { break } if err = listTribesParams.SetCursor(res.Next()); err != nil { return fmt.Errorf("%s: %w", serverKey, err) } } payload, err := domain.NewSnapshotsCreatedEventPayload(serverKey, createSnapshotsCmdPayload.VersionCode()) if err != nil { return fmt.Errorf("%s: couldn't construct domain.SnapshotsCreatedEventPayload: %w", serverKey, err) } if err = svc.pub.EventCreated(ctx, payload); err != nil { return fmt.Errorf("%s: %w", serverKey, err) } return nil } func (svc *TribeSnapshotService) ListWithRelations( ctx context.Context, params domain.ListTribeSnapshotsParams, ) (domain.ListTribeSnapshotsWithRelationsResult, error) { return svc.repo.ListWithRelations(ctx, params) } func (svc *TribeSnapshotService) CleanUp(ctx context.Context, payload domain.CleanUpDataCmdPayload) error { if !payload.CanCleanUpTribeSnapshots() { return nil } if err := svc.repo.Delete( ctx, payload.Server().Key(), time.Now().Add(-domain.TribeSnapshotRetentionForClosedServers), ); err != nil { return fmt.Errorf("%s: %w", payload.Server().Key(), err) } return nil }