93 lines
3.1 KiB
Go
93 lines
3.1 KiB
Go
package usecase
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
"time"
|
|
|
|
app "haixun-backend/internal/library/errors"
|
|
"haixun-backend/internal/library/errors/code"
|
|
"haixun-backend/internal/library/clock"
|
|
libownpost "haixun-backend/internal/library/ownpost"
|
|
"haixun-backend/internal/model/own_post_formula/domain/entity"
|
|
domrepo "haixun-backend/internal/model/own_post_formula/domain/repository"
|
|
)
|
|
|
|
const FormulaCacheTTL = 5 * time.Minute
|
|
|
|
type UseCase interface {
|
|
Get(ctx context.Context, tenantID, ownerUID, accountID, mediaID string) (*entity.Review, error)
|
|
SaveGenerated(ctx context.Context, tenantID, ownerUID, accountID, mediaID, personaID, postText string, review *libownpost.PostFormulaReview) (*entity.Review, error)
|
|
ListByAccount(ctx context.Context, tenantID, ownerUID, accountID string) ([]entity.Review, error)
|
|
IsFresh(review *entity.Review, now int64) bool
|
|
}
|
|
|
|
func (u *useCase) Get(ctx context.Context, tenantID, ownerUID, accountID, mediaID string) (*entity.Review, error) {
|
|
return u.repo.Get(ctx, tenantID, ownerUID, accountID, mediaID)
|
|
}
|
|
|
|
func (u *useCase) IsFresh(review *entity.Review, now int64) bool {
|
|
if review == nil || review.UpdateAt <= 0 {
|
|
return false
|
|
}
|
|
if now <= 0 {
|
|
now = clock.NowUnixNano()
|
|
}
|
|
return now-review.UpdateAt < int64(FormulaCacheTTL)
|
|
}
|
|
|
|
type useCase struct {
|
|
repo domrepo.Repository
|
|
}
|
|
|
|
func NewUseCase(repo domrepo.Repository) UseCase {
|
|
return &useCase{repo: repo}
|
|
}
|
|
|
|
func (u *useCase) SaveGenerated(
|
|
ctx context.Context,
|
|
tenantID, ownerUID, accountID, mediaID, personaID, postText string,
|
|
review *libownpost.PostFormulaReview,
|
|
) (*entity.Review, error) {
|
|
if review == nil {
|
|
return nil, app.For(code.ThreadsAccount).InputMissingRequired("review is required")
|
|
}
|
|
accountID = strings.TrimSpace(accountID)
|
|
mediaID = strings.TrimSpace(mediaID)
|
|
if accountID == "" || mediaID == "" {
|
|
return nil, app.For(code.ThreadsAccount).InputMissingRequired("account_id and media_id are required")
|
|
}
|
|
now := clock.NowUnixNano()
|
|
doc := &entity.Review{
|
|
ID: entity.ReviewDocID(accountID, mediaID),
|
|
TenantID: strings.TrimSpace(tenantID),
|
|
OwnerUID: strings.TrimSpace(ownerUID),
|
|
AccountID: accountID,
|
|
MediaID: mediaID,
|
|
PersonaID: strings.TrimSpace(personaID),
|
|
PostText: strings.TrimSpace(postText),
|
|
Summary: review.Summary,
|
|
Wins: review.Wins,
|
|
Improvements: review.Improvements,
|
|
Formula: review.Formula,
|
|
PostTemplate: review.PostTemplate,
|
|
HookPattern: review.HookPattern,
|
|
Structure: review.Structure,
|
|
ReplicationTips: review.ReplicationTips,
|
|
Avoid: review.Avoid,
|
|
CreateAt: now,
|
|
UpdateAt: now,
|
|
}
|
|
if existing, err := u.repo.Get(ctx, tenantID, ownerUID, accountID, mediaID); err == nil && existing != nil {
|
|
doc.CreateAt = existing.CreateAt
|
|
}
|
|
return u.repo.Upsert(ctx, doc)
|
|
}
|
|
|
|
func (u *useCase) ListByAccount(ctx context.Context, tenantID, ownerUID, accountID string) ([]entity.Review, error) {
|
|
accountID = strings.TrimSpace(accountID)
|
|
if accountID == "" {
|
|
return nil, app.For(code.ThreadsAccount).InputMissingRequired("account_id is required")
|
|
}
|
|
return u.repo.ListByAccount(ctx, tenantID, ownerUID, accountID)
|
|
} |