Files
Erupe/server/channelserver/svc_festa.go
Houmgaor 4d3ec8164c refactor(festa): extract festa logic into FestaService
The festa handler contained event lifecycle management (cleanup expired
events, create new ones) and the repo enforced a business rule (skip
zero-value soul submissions). Move these into a new FestaService to
keep repos as pure data access and consolidate business logic.
2026-02-24 16:12:40 +01:00

62 lines
1.7 KiB
Go

package channelserver
import (
"time"
"go.uber.org/zap"
)
// FestaService encapsulates festa business logic, sitting between handlers and repos.
type FestaService struct {
festaRepo FestaRepo
logger *zap.Logger
}
// NewFestaService creates a new FestaService.
func NewFestaService(fr FestaRepo, log *zap.Logger) *FestaService {
return &FestaService{
festaRepo: fr,
logger: log,
}
}
// EnsureActiveEvent checks whether the current festa event is still active.
// If it has expired or none exists, all festa state is cleaned up and a new
// event is created starting at the next midnight. Returns the (possibly new)
// start time.
func (svc *FestaService) EnsureActiveEvent(currentStart uint32, now time.Time, nextMidnight time.Time) (uint32, error) {
if currentStart != 0 && now.Unix() <= int64(currentStart)+festaEventLifespan {
return currentStart, nil
}
if err := svc.festaRepo.CleanupAll(); err != nil {
svc.logger.Error("Failed to cleanup festa", zap.Error(err))
return 0, err
}
newStart := uint32(nextMidnight.Unix())
if err := svc.festaRepo.InsertEvent(newStart); err != nil {
svc.logger.Error("Failed to insert festa event", zap.Error(err))
return 0, err
}
return newStart, nil
}
// SubmitSouls filters out zero-value soul entries and records the remaining
// submissions for the character. Returns nil if all entries are zero.
func (svc *FestaService) SubmitSouls(charID, guildID uint32, souls []uint16) error {
var filtered []uint16
hasNonZero := false
for _, s := range souls {
filtered = append(filtered, s)
if s != 0 {
hasNonZero = true
}
}
if !hasNonZero {
return nil
}
return svc.festaRepo.SubmitSouls(charID, guildID, souls)
}