package usecase import ( "context" "strings" "haixun-backend/internal/library/clock" app "haixun-backend/internal/library/errors" "haixun-backend/internal/library/errors/code" "haixun-backend/internal/model/copy_draft/domain/entity" domrepo "haixun-backend/internal/model/copy_draft/domain/repository" domusecase "haixun-backend/internal/model/copy_draft/domain/usecase" "github.com/google/uuid" ) type copyDraftUseCase struct { repo domrepo.Repository } func NewUseCase(repo domrepo.Repository) domusecase.UseCase { return ©DraftUseCase{repo: repo} } func (u *copyDraftUseCase) Create(ctx context.Context, req domusecase.CreateRequest) (*domusecase.CopyDraftSummary, error) { if err := requireActor(req.TenantID, req.OwnerUID, req.PersonaID); err != nil { return nil, err } text := strings.TrimSpace(req.Text) if text == "" { return nil, app.For(code.Persona).InputMissingRequired("draft text is required") } draftType := strings.TrimSpace(req.DraftType) if draftType == "" { draftType = entity.DraftTypeViralReplica } item := &entity.CopyDraft{ ID: uuid.NewString(), TenantID: req.TenantID, OwnerUID: req.OwnerUID, PersonaID: req.PersonaID, ScanPostID: strings.TrimSpace(req.ScanPostID), DraftType: draftType, Text: text, Angle: strings.TrimSpace(req.Angle), Hook: strings.TrimSpace(req.Hook), Rationale: strings.TrimSpace(req.Rationale), ReferenceNotes: strings.TrimSpace(req.ReferenceNotes), Sources: req.Sources, Status: "pending", CreateAt: clock.NowUnixNano(), } if err := u.repo.Create(ctx, item); err != nil { return nil, err } summary := toSummary(*item) return &summary, nil } func (u *copyDraftUseCase) List(ctx context.Context, tenantID, ownerUID, personaID string, limit int) ([]domusecase.CopyDraftSummary, error) { if err := requireActor(tenantID, ownerUID, personaID); err != nil { return nil, err } items, err := u.repo.List(ctx, tenantID, ownerUID, personaID, limit) if err != nil { return nil, err } out := make([]domusecase.CopyDraftSummary, 0, len(items)) for _, item := range items { out = append(out, toSummary(item)) } return out, nil } func requireActor(tenantID, ownerUID, personaID string) error { if strings.TrimSpace(tenantID) == "" || strings.TrimSpace(ownerUID) == "" { return app.For(code.Auth).AuthUnauthorized("missing actor") } if strings.TrimSpace(personaID) == "" { return app.For(code.Persona).InputMissingRequired("persona_id is required") } return nil } func toSummary(item entity.CopyDraft) domusecase.CopyDraftSummary { return domusecase.CopyDraftSummary{ ID: item.ID, PersonaID: item.PersonaID, ScanPostID: item.ScanPostID, DraftType: item.DraftType, Text: item.Text, Angle: item.Angle, Hook: item.Hook, Rationale: item.Rationale, ReferenceNotes: item.ReferenceNotes, Sources: item.Sources, Status: item.Status, CreateAt: item.CreateAt, } }