2024-01-04 10:44:36 +00:00
|
|
|
package app
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"gitea.dwysokinski.me/twhelp/corev3/internal/domain"
|
|
|
|
)
|
|
|
|
|
|
|
|
type EnnoblementRepository interface {
|
|
|
|
Create(ctx context.Context, params ...domain.CreateEnnoblementParams) error
|
|
|
|
List(ctx context.Context, params domain.ListEnnoblementsParams) (domain.Ennoblements, error)
|
|
|
|
}
|
|
|
|
|
|
|
|
type EnnoblementService struct {
|
|
|
|
repo EnnoblementRepository
|
|
|
|
twSvc TWService
|
|
|
|
pub EnnoblementPublisher
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewEnnoblementService(repo EnnoblementRepository, twSvc TWService, pub EnnoblementPublisher) *EnnoblementService {
|
|
|
|
return &EnnoblementService{repo: repo, twSvc: twSvc, pub: pub}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (svc *EnnoblementService) Sync(
|
|
|
|
ctx context.Context,
|
|
|
|
syncEnnoblementsCmdPayload domain.SyncEnnoblementsCmdPayload,
|
|
|
|
) error {
|
|
|
|
serverURL := syncEnnoblementsCmdPayload.ServerURL()
|
|
|
|
serverKey := syncEnnoblementsCmdPayload.ServerKey()
|
|
|
|
|
2024-01-11 06:13:28 +00:00
|
|
|
latestEnnoblement, err := svc.getLatest(ctx, serverKey)
|
2024-01-04 10:44:36 +00:00
|
|
|
if err != nil && !errors.Is(err, errEnnoblementNotFound) {
|
|
|
|
return fmt.Errorf("%s: %w", serverKey, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
var since time.Time
|
|
|
|
if err == nil {
|
|
|
|
since = latestEnnoblement.CreatedAt()
|
|
|
|
}
|
|
|
|
|
|
|
|
ennoblements, err := svc.twSvc.GetEnnoblements(ctx, serverURL, since)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("%s: couldn't get ennoblements: %w", serverKey, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err = svc.create(ctx, serverKey, ennoblements); err != nil {
|
|
|
|
return fmt.Errorf("%s: couldn't create ennoblements: %w", serverKey, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
payload, err := domain.NewEnnoblementsSyncedEventPayload(
|
|
|
|
serverKey,
|
|
|
|
serverURL,
|
|
|
|
syncEnnoblementsCmdPayload.VersionCode(),
|
|
|
|
)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("%s: couldn't construct domain.EnnoblementsSyncedEventPayload %w", serverKey, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err = svc.pub.EventSynced(ctx, payload); err != nil {
|
|
|
|
return fmt.Errorf("%s: %w", serverKey, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
var errEnnoblementNotFound = errors.New("ennoblement not found")
|
|
|
|
|
2024-01-11 06:13:28 +00:00
|
|
|
func (svc *EnnoblementService) getLatest(ctx context.Context, serverKey string) (domain.Ennoblement, error) {
|
2024-01-04 10:44:36 +00:00
|
|
|
params := domain.NewListEnnoblementsParams()
|
|
|
|
if err := params.SetLimit(1); err != nil {
|
|
|
|
return domain.Ennoblement{}, err
|
|
|
|
}
|
|
|
|
if err := params.SetServerKeys([]string{serverKey}); err != nil {
|
|
|
|
return domain.Ennoblement{}, err
|
|
|
|
}
|
|
|
|
if err := params.SetSort([]domain.EnnoblementSort{domain.EnnoblementSortCreatedAtDESC}); err != nil {
|
|
|
|
return domain.Ennoblement{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
ennoblements, err := svc.repo.List(ctx, params)
|
|
|
|
if err != nil {
|
|
|
|
return domain.Ennoblement{}, err
|
|
|
|
}
|
|
|
|
if len(ennoblements) == 0 {
|
|
|
|
return domain.Ennoblement{}, errEnnoblementNotFound
|
|
|
|
}
|
|
|
|
|
|
|
|
return ennoblements[0], nil
|
|
|
|
}
|
|
|
|
|
|
|
|
const ennoblementCreateChunkSize = 500
|
|
|
|
|
|
|
|
func (svc *EnnoblementService) create(
|
|
|
|
ctx context.Context,
|
|
|
|
serverKey string,
|
|
|
|
ennoblements domain.BaseEnnoblements,
|
|
|
|
) error {
|
|
|
|
for i := 0; i < len(ennoblements); i += ennoblementCreateChunkSize {
|
|
|
|
end := i + ennoblementCreateChunkSize
|
|
|
|
if end > len(ennoblements) {
|
|
|
|
end = len(ennoblements)
|
|
|
|
}
|
|
|
|
|
|
|
|
createParams, err := domain.NewCreateEnnoblementParams(serverKey, ennoblements[i:end])
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if err = svc.repo.Create(ctx, createParams...); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|