101 lines
3.0 KiB
Go
101 lines
3.0 KiB
Go
|
|
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,
|
||
|
|
}
|
||
|
|
}
|