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, 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, 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, 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, } }