Refactor domain_log usecase: simplification

This commit is contained in:
nemunaire 2025-10-25 04:28:11 +07:00
commit 5cc3275fa5
13 changed files with 47 additions and 197 deletions

View file

@ -246,7 +246,7 @@ func (app *App) initInsights() {
func (app *App) initUsecases() {
sessionService := sessionUC.NewService(app.store)
authUserService := authuserUC.NewAuthUserUsecases(app.cfg, app.mailer, app.store, sessionService)
domainLogService := domainlogUC.NewDomainLogUsecases(app.store)
domainLogService := domainlogUC.NewService(app.store)
providerService := providerUC.NewRestrictedProviderUsecases(app.cfg, app.store)
serviceService := serviceUC.NewServiceUsecases()
zoneService := zoneUC.NewZoneUsecases(app.store, serviceService)
@ -259,7 +259,7 @@ func (app *App) initUsecases() {
app.usecases.zone = zoneService
app.usecases.domainLog = domainLogService
domainService := domainUC.NewDomainUsecases(app.store, providerService.GetProviderUC, zoneService.GetZoneUC, providerService.DomainExistenceUC, domainLogService.CreateDomainLogUC)
domainService := domainUC.NewDomainUsecases(app.store, providerService.GetProviderUC, zoneService.GetZoneUC, providerService.DomainExistenceUC, domainLogService)
app.usecases.domain = domainService
app.usecases.zoneService = zoneServiceUC.NewZoneServiceUsecases(domainService.UpdateDomainUC, zoneService.CreateZoneUC, serviceService.ValidateServiceUC, app.store)
@ -270,7 +270,7 @@ func (app *App) initUsecases() {
app.usecases.session = sessionService
app.usecases.orchestrator = orchestrator.NewOrchestrator(
domainLogService.CreateDomainLogUC,
domainLogService,
domainService.UpdateDomainUC,
providerService.GetProviderUC,
zoneService.ListRecordsUC,

View file

@ -31,12 +31,12 @@ import (
type CreateDomainUsecase struct {
domainExistence *providerUC.DomainExistenceUsecase
domainLogAppender *domainLogUC.CreateDomainLogUsecase
domainLogAppender domainLogUC.DomainLogAppender
getProvider *providerUC.GetProviderUsecase
store DomainStorage
}
func NewCreateDomainUsecase(store DomainStorage, getProvider *providerUC.GetProviderUsecase, domainExistence *providerUC.DomainExistenceUsecase, domainLogAppender *domainLogUC.CreateDomainLogUsecase) *CreateDomainUsecase {
func NewCreateDomainUsecase(store DomainStorage, getProvider *providerUC.GetProviderUsecase, domainExistence *providerUC.DomainExistenceUsecase, domainLogAppender domainLogUC.DomainLogAppender) *CreateDomainUsecase {
return &CreateDomainUsecase{
domainExistence: domainExistence,
domainLogAppender: domainLogAppender,
@ -69,7 +69,7 @@ func (uc *CreateDomainUsecase) Create(user *happydns.User, uz *happydns.Domain)
// Add a log entry
if uc.domainLogAppender != nil {
uc.domainLogAppender.Create(uz, happydns.NewDomainLog(user, happydns.LOG_INFO, fmt.Sprintf("Domain name %s added.", uz.DomainName)))
uc.domainLogAppender.AppendDomainLog(uz, happydns.NewDomainLog(user, happydns.LOG_INFO, fmt.Sprintf("Domain name %s added.", uz.DomainName)))
}
return nil

View file

@ -41,7 +41,7 @@ func NewDomainUsecases(
getProviderUC *providerUC.GetProviderUsecase,
getZoneUC *zoneUC.GetZoneUsecase,
domainExistenceUC *providerUC.DomainExistenceUsecase,
domainLogAppenderUC *domainLogUC.CreateDomainLogUsecase,
domainLogAppenderUC domainLogUC.DomainLogAppender,
) *Service {
getDomainUC := NewGetDomainUsecase(store, getZoneUC)

View file

@ -29,12 +29,12 @@ import (
)
type UpdateDomainUsecase struct {
domainLogAppender *domainLogUC.CreateDomainLogUsecase
domainLogAppender domainLogUC.DomainLogAppender
getDomain *GetDomainUsecase
store DomainStorage
}
func NewUpdateDomainUsecase(store DomainStorage, getDomain *GetDomainUsecase, domainLogAppender *domainLogUC.CreateDomainLogUsecase) *UpdateDomainUsecase {
func NewUpdateDomainUsecase(store DomainStorage, getDomain *GetDomainUsecase, domainLogAppender domainLogUC.DomainLogAppender) *UpdateDomainUsecase {
return &UpdateDomainUsecase{
domainLogAppender: domainLogAppender,
getDomain: getDomain,
@ -65,7 +65,7 @@ func (uc *UpdateDomainUsecase) Update(domainid happydns.Identifier, user *happyd
// Add a log entry
if uc.domainLogAppender != nil {
uc.domainLogAppender.Create(domain, happydns.NewDomainLog(user, happydns.LOG_INFO, fmt.Sprintf("Domain name %s properties changed.", domain.DomainName)))
uc.domainLogAppender.AppendDomainLog(domain, happydns.NewDomainLog(user, happydns.LOG_INFO, fmt.Sprintf("Domain name %s properties changed.", domain.DomainName)))
}
return nil

View file

@ -1,40 +0,0 @@
// This file is part of the happyDomain (R) project.
// Copyright (c) 2020-2025 happyDomain
// Authors: Pierre-Olivier Mercier, et al.
//
// This program is offered under a commercial and under the AGPL license.
// For commercial licensing, contact us at <contact@happydomain.org>.
//
// For AGPL licensing:
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package domainlog
import (
"git.happydns.org/happyDomain/model"
)
type CreateDomainLogUsecase struct {
store DomainLogStorage
}
func NewCreateDomainLogUsecase(store DomainLogStorage) *CreateDomainLogUsecase {
return &CreateDomainLogUsecase{
store: store,
}
}
func (uc *CreateDomainLogUsecase) Create(domain *happydns.Domain, log *happydns.DomainLog) error {
return uc.store.CreateDomainLog(domain, log)
}

View file

@ -1,40 +0,0 @@
// This file is part of the happyDomain (R) project.
// Copyright (c) 2020-2025 happyDomain
// Authors: Pierre-Olivier Mercier, et al.
//
// This program is offered under a commercial and under the AGPL license.
// For commercial licensing, contact us at <contact@happydomain.org>.
//
// For AGPL licensing:
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package domainlog
import (
"git.happydns.org/happyDomain/model"
)
type DeleteDomainLogUsecase struct {
store DomainLogStorage
}
func NewDeleteDomainLogUsecase(store DomainLogStorage) *DeleteDomainLogUsecase {
return &DeleteDomainLogUsecase{
store: store,
}
}
func (uc *DeleteDomainLogUsecase) Delete(domain *happydns.Domain, log *happydns.DomainLog) error {
return uc.store.DeleteDomainLog(domain, log)
}

View file

@ -28,18 +28,30 @@ import (
"git.happydns.org/happyDomain/model"
)
type ListDomainLogsUsecase struct {
// DomainLogAppender is a minimal interface for appending domain logs.
// Used by orchestrator to decouple from the full Service.
type DomainLogAppender interface {
AppendDomainLog(domain *happydns.Domain, entry *happydns.DomainLog) error
}
type Service struct {
store DomainLogStorage
}
func NewListDomainLogsUsecase(store DomainLogStorage) *ListDomainLogsUsecase {
return &ListDomainLogsUsecase{
func NewService(store DomainLogStorage) *Service {
return &Service{
store: store,
}
}
func (uc *ListDomainLogsUsecase) List(domain *happydns.Domain) ([]*happydns.DomainLog, error) {
logs, err := uc.store.ListDomainLogs(domain)
// AppendDomainLog creates a new domain log entry.
func (s *Service) AppendDomainLog(domain *happydns.Domain, entry *happydns.DomainLog) error {
return s.store.CreateDomainLog(domain, entry)
}
// ListDomainLogs retrieves all logs for a domain, sorted by date (newest first).
func (s *Service) ListDomainLogs(domain *happydns.Domain) ([]*happydns.DomainLog, error) {
logs, err := s.store.ListDomainLogs(domain)
if err != nil {
return nil, happydns.InternalError{
Err: fmt.Errorf("unable to retrieve logs for domain %q (did=%s): %w", domain.DomainName, domain.Id.String(), err),
@ -54,3 +66,13 @@ func (uc *ListDomainLogsUsecase) List(domain *happydns.Domain) ([]*happydns.Doma
return logs, nil
}
// UpdateDomainLog updates an existing domain log entry.
func (s *Service) UpdateDomainLog(domain *happydns.Domain, log *happydns.DomainLog) error {
return s.store.UpdateDomainLog(domain, log)
}
// DeleteDomainLog removes a domain log entry.
func (s *Service) DeleteDomainLog(domain *happydns.Domain, log *happydns.DomainLog) error {
return s.store.DeleteDomainLog(domain, log)
}

View file

@ -1,52 +0,0 @@
// This file is part of the happyDomain (R) project.
// Copyright (c) 2020-2025 happyDomain
// Authors: Pierre-Olivier Mercier, et al.
//
// This program is offered under a commercial and under the AGPL license.
// For commercial licensing, contact us at <contact@happydomain.org>.
//
// For AGPL licensing:
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package domainlog
import (
"git.happydns.org/happyDomain/model"
)
type Service struct {
CreateDomainLogUC *CreateDomainLogUsecase
DeleteDomainLogUC *DeleteDomainLogUsecase
ListDomainLogsUC *ListDomainLogsUsecase
UpdateDomainLogUC *UpdateDomainLogUsecase
}
func NewDomainLogUsecases(
store DomainLogStorage,
) *Service {
return &Service{
CreateDomainLogUC: NewCreateDomainLogUsecase(store),
DeleteDomainLogUC: NewDeleteDomainLogUsecase(store),
ListDomainLogsUC: NewListDomainLogsUsecase(store),
UpdateDomainLogUC: NewUpdateDomainLogUsecase(store),
}
}
func (s *Service) AppendDomainLog(domain *happydns.Domain, entry *happydns.DomainLog) error {
return s.CreateDomainLogUC.Create(domain, entry)
}
func (s *Service) ListDomainLogs(domain *happydns.Domain) ([]*happydns.DomainLog, error) {
return s.ListDomainLogsUC.List(domain)
}

View file

@ -1,40 +0,0 @@
// This file is part of the happyDomain (R) project.
// Copyright (c) 2020-2025 happyDomain
// Authors: Pierre-Olivier Mercier, et al.
//
// This program is offered under a commercial and under the AGPL license.
// For commercial licensing, contact us at <contact@happydomain.org>.
//
// For AGPL licensing:
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package domainlog
import (
"git.happydns.org/happyDomain/model"
)
type UpdateDomainLogUsecase struct {
store DomainLogStorage
}
func NewUpdateDomainLogUsecase(store DomainLogStorage) *UpdateDomainLogUsecase {
return &UpdateDomainLogUsecase{
store: store,
}
}
func (uc *UpdateDomainLogUsecase) Update(domain *happydns.Domain, log *happydns.DomainLog) error {
return uc.store.UpdateDomainLog(domain, log)
}

View file

@ -35,7 +35,7 @@ type Orchestrator struct {
}
func NewOrchestrator(
appendDomainLog *domainlogUC.CreateDomainLogUsecase,
appendDomainLog domainlogUC.DomainLogAppender,
domainUpdater *domainUC.UpdateDomainUsecase,
getProvider *providerUC.GetProviderUsecase,
listRecords *zoneUC.ListRecordsUsecase,

View file

@ -30,14 +30,14 @@ import (
)
type RemoteZoneImporterUsecase struct {
appendDomainLog *domainlogUC.CreateDomainLogUsecase
appendDomainLog domainlogUC.DomainLogAppender
getProvider *providerUC.GetProviderUsecase
zoneImporter *ZoneImporterUsecase
zoneRetriever *providerUC.ZoneRetrieverUsecase
}
func NewRemoteZoneImporterUsecase(
appendDomainLog *domainlogUC.CreateDomainLogUsecase,
appendDomainLog domainlogUC.DomainLogAppender,
getProvider *providerUC.GetProviderUsecase,
zoneImporter *ZoneImporterUsecase,
zoneRetriever *providerUC.ZoneRetrieverUsecase,
@ -68,7 +68,7 @@ func (uc *RemoteZoneImporterUsecase) Import(user *happydns.User, domain *happydn
}
if uc.appendDomainLog != nil {
uc.appendDomainLog.Create(domain, happydns.NewDomainLog(user, happydns.LOG_INFO, fmt.Sprintf("Zone imported from provider API: %s", myZone.Id.String())))
uc.appendDomainLog.AppendDomainLog(domain, happydns.NewDomainLog(user, happydns.LOG_INFO, fmt.Sprintf("Zone imported from provider API: %s", myZone.Id.String())))
}
return myZone, nil

View file

@ -35,7 +35,7 @@ import (
)
type ZoneCorrectionApplierUsecase struct {
appendDomainLog *domainlogUC.CreateDomainLogUsecase
appendDomainLog domainlogUC.DomainLogAppender
domainUpdater *domainUC.UpdateDomainUsecase
getProvider *providerUC.GetProviderUsecase
listRecords *zoneUC.ListRecordsUsecase
@ -45,7 +45,7 @@ type ZoneCorrectionApplierUsecase struct {
}
func NewZoneCorrectionApplierUsecase(
appendDomainLog *domainlogUC.CreateDomainLogUsecase,
appendDomainLog domainlogUC.DomainLogAppender,
domainUpdater *domainUC.UpdateDomainUsecase,
getProvider *providerUC.GetProviderUsecase,
listRecords *zoneUC.ListRecordsUsecase,
@ -95,7 +95,7 @@ corrections:
if err != nil {
log.Printf("%s: unable to apply correction: %s", domain.DomainName, err.Error())
uc.appendDomainLog.Create(domain, happydns.NewDomainLog(user, happydns.LOG_ERR, fmt.Sprintf("Failed record update (%s): %s", cr.Msg, err.Error())))
uc.appendDomainLog.AppendDomainLog(domain, happydns.NewDomainLog(user, happydns.LOG_ERR, fmt.Sprintf("Failed record update (%s): %s", cr.Msg, err.Error())))
errs = errors.Join(errs, fmt.Errorf("%s: %w", cr.Msg, err))
// Stop the zone update if we didn't change it yet
if i == 0 {
@ -110,14 +110,14 @@ corrections:
}
if errs != nil {
uc.appendDomainLog.Create(domain, happydns.NewDomainLog(user, happydns.LOG_ERR, fmt.Sprintf("Failed zone publishing (%s): %d corrections were not applied due to errors.", zone.Id.String(), nbcorrections)))
uc.appendDomainLog.AppendDomainLog(domain, happydns.NewDomainLog(user, happydns.LOG_ERR, fmt.Sprintf("Failed zone publishing (%s): %d corrections were not applied due to errors.", zone.Id.String(), nbcorrections)))
return nil, happydns.ValidationError{Msg: fmt.Sprintf("unable to update the zone: %s", errs.Error())}
} else if len(form.WantedCorrections) > 0 {
uc.appendDomainLog.Create(domain, happydns.NewDomainLog(user, happydns.LOG_ERR, fmt.Sprintf("Failed zone publishing (%s): %d corrections were not applied.", zone.Id.String(), nbcorrections)))
uc.appendDomainLog.AppendDomainLog(domain, happydns.NewDomainLog(user, happydns.LOG_ERR, fmt.Sprintf("Failed zone publishing (%s): %d corrections were not applied.", zone.Id.String(), nbcorrections)))
return nil, happydns.ValidationError{Msg: fmt.Sprintf("unable to perform the following changes: %s", form.WantedCorrections)}
}
uc.appendDomainLog.Create(domain, happydns.NewDomainLog(user, happydns.LOG_ACK, fmt.Sprintf("Zone published (%s), %d corrections applied with success", zone.Id.String(), nbcorrections)))
uc.appendDomainLog.AppendDomainLog(domain, happydns.NewDomainLog(user, happydns.LOG_ACK, fmt.Sprintf("Zone published (%s), %d corrections applied with success", zone.Id.String(), nbcorrections)))
// Create a new zone in history for futher updates
newZone := zone.DerivateNew()