thread-master/old/backend/internal/model/publish_analytics/usecase/usecase.go

112 lines
3.5 KiB
Go
Raw Normal View History

2026-06-27 16:03:28 +00:00
package usecase
import (
"context"
"strings"
"haixun-backend/internal/library/clock"
app "haixun-backend/internal/library/errors"
"haixun-backend/internal/library/errors/code"
jobdom "haixun-backend/internal/model/job/domain/usecase"
2026-06-27 16:03:28 +00:00
"haixun-backend/internal/model/publish_analytics/domain/entity"
domrepo "haixun-backend/internal/model/publish_analytics/domain/repository"
domusecase "haixun-backend/internal/model/publish_analytics/domain/usecase"
"github.com/google/uuid"
)
type publishAnalyticsUseCase struct {
repo domrepo.Repository
jobs jobdom.UseCase
2026-06-27 16:03:28 +00:00
}
func NewUseCase(repo domrepo.Repository, jobs jobdom.UseCase) domusecase.UseCase {
return &publishAnalyticsUseCase{repo: repo, jobs: jobs}
2026-06-27 16:03:28 +00:00
}
func (u *publishAnalyticsUseCase) RecordCheckpoint(ctx context.Context, tenantID, ownerUID string, summary domusecase.PublishAnalyticsSummary) (*domusecase.PublishAnalyticsSummary, error) {
tenantID = strings.TrimSpace(tenantID)
ownerUID = strings.TrimSpace(ownerUID)
if tenantID == "" || ownerUID == "" {
return nil, app.For(code.AI).AuthUnauthorized("missing actor")
}
mediaID := strings.TrimSpace(summary.MediaID)
if mediaID == "" {
return nil, app.For(code.AI).InputMissingRequired("media_id is required")
}
checkpoint := strings.TrimSpace(summary.Checkpoint)
if checkpoint == "" {
return nil, app.For(code.AI).InputMissingRequired("checkpoint is required")
}
now := clock.NowUnixNano()
analytics := &entity.PublishAnalytics{
ID: uuid.NewString(),
TenantID: tenantID,
OwnerUID: ownerUID,
MediaID: mediaID,
Permalink: strings.TrimSpace(summary.Permalink),
PublishedAt: summary.PublishedAt,
Checkpoint: checkpoint,
LikeCount: summary.LikeCount,
ReplyCount: summary.ReplyCount,
RepostCount: summary.RepostCount,
QuoteCount: summary.QuoteCount,
ViewCount: summary.ViewCount,
ShareCount: summary.ShareCount,
2026-06-27 16:03:28 +00:00
ImpressionCount: summary.ImpressionCount,
ReachCount: summary.ReachCount,
CheckedAt: now,
CreateAt: now,
}
created, err := u.repo.Upsert(ctx, analytics)
if err != nil {
return nil, err
}
out := toSummary(*created)
return &out, nil
}
func (u *publishAnalyticsUseCase) ListByMedia(ctx context.Context, tenantID, ownerUID, mediaID string) ([]domusecase.PublishAnalyticsSummary, error) {
tenantID = strings.TrimSpace(tenantID)
ownerUID = strings.TrimSpace(ownerUID)
mediaID = strings.TrimSpace(mediaID)
if tenantID == "" || ownerUID == "" {
return nil, app.For(code.AI).AuthUnauthorized("missing actor")
}
if mediaID == "" {
return nil, app.For(code.AI).InputMissingRequired("media_id is required")
}
items, err := u.repo.ListByMedia(ctx, tenantID, ownerUID, mediaID)
if err != nil {
return nil, err
}
out := make([]domusecase.PublishAnalyticsSummary, 0, len(items))
for _, item := range items {
out = append(out, toSummary(item))
}
return out, nil
}
func toSummary(item entity.PublishAnalytics) domusecase.PublishAnalyticsSummary {
return domusecase.PublishAnalyticsSummary{
ID: item.ID,
MediaID: item.MediaID,
Permalink: item.Permalink,
PublishedAt: item.PublishedAt,
Checkpoint: item.Checkpoint,
LikeCount: item.LikeCount,
ReplyCount: item.ReplyCount,
RepostCount: item.RepostCount,
QuoteCount: item.QuoteCount,
ViewCount: item.ViewCount,
ShareCount: item.ShareCount,
2026-06-27 16:03:28 +00:00
ImpressionCount: item.ImpressionCount,
ReachCount: item.ReachCount,
CheckedAt: item.CheckedAt,
CreateAt: item.CreateAt,
}
}