thread-master/internal/model/outreach_draft/usecase/usecase.go

112 lines
3.0 KiB
Go
Raw Normal View History

2026-06-26 08:37:04 +00:00
package usecase
import (
"context"
"strings"
"haixun-backend/internal/library/clock"
libmongo "haixun-backend/internal/library/mongo"
"haixun-backend/internal/model/outreach_draft/domain/entity"
domrepo "haixun-backend/internal/model/outreach_draft/domain/repository"
domusecase "haixun-backend/internal/model/outreach_draft/domain/usecase"
"github.com/google/uuid"
)
type outreachDraftUseCase struct {
repo domrepo.Repository
}
func NewUseCase(repo domrepo.Repository) domusecase.UseCase {
return &outreachDraftUseCase{repo: repo}
}
func (u *outreachDraftUseCase) Create(ctx context.Context, req domusecase.CreateRequest) (*domusecase.DraftSummary, error) {
if err := requireActor(req.TenantID, req.OwnerUID, req.BrandID); err != nil {
return nil, err
}
scanPostID := strings.TrimSpace(req.ScanPostID)
if scanPostID == "" {
return nil, errMissingScanPost()
}
now := clock.NowUnixNano()
drafts := make([]entity.DraftItem, 0, len(req.Drafts))
for _, item := range req.Drafts {
drafts = append(drafts, entity.DraftItem{
Text: item.Text,
Angle: item.Angle,
Rationale: item.Rationale,
})
}
record := &entity.OutreachDraft{
ID: uuid.NewString(),
TenantID: req.TenantID,
OwnerUID: req.OwnerUID,
BrandID: req.BrandID,
TopicID: strings.TrimSpace(req.TopicID),
ScanPostID: scanPostID,
Relevance: req.Relevance,
Reason: req.Reason,
Drafts: drafts,
CreateAt: now,
}
if err := u.repo.Create(ctx, record); err != nil {
return nil, err
}
return toSummary(record), nil
}
func (u *outreachDraftUseCase) GetLatestByScanPost(
ctx context.Context,
tenantID, ownerUID, brandID, topicID, scanPostID string,
) (*domusecase.DraftSummary, error) {
if err := requireActor(tenantID, ownerUID, brandID); err != nil {
return nil, err
}
scanPostID = strings.TrimSpace(scanPostID)
if scanPostID == "" {
return nil, errMissingScanPost()
}
record, err := u.repo.GetLatestByScanPost(ctx, tenantID, ownerUID, brandID, topicID, scanPostID)
if err != nil {
return nil, err
}
if record == nil {
return nil, nil
}
return toSummary(record), nil
}
func requireActor(tenantID, ownerUID, brandID string) error {
if strings.TrimSpace(tenantID) == "" || strings.TrimSpace(ownerUID) == "" {
return errMissingActor()
}
if strings.TrimSpace(brandID) == "" {
return errMissingBrand()
}
return nil
}
func toSummary(record *entity.OutreachDraft) *domusecase.DraftSummary {
if record == nil {
return nil
}
drafts := make([]domusecase.DraftItem, 0, len(record.Drafts))
for _, item := range record.Drafts {
drafts = append(drafts, domusecase.DraftItem{
Text: item.Text,
Angle: item.Angle,
Rationale: item.Rationale,
})
}
return &domusecase.DraftSummary{
ID: record.ID,
BrandID: libmongo.ResolveBrandID(record.BrandID, record.LegacyPersonaID),
ScanPostID: record.ScanPostID,
Relevance: record.Relevance,
Reason: record.Reason,
Drafts: drafts,
CreateAt: record.CreateAt,
}
}