package job import ( "context" "fmt" "strings" libthreads "haixun-backend/internal/library/threadsapi" jobdom "haixun-backend/internal/model/job/domain/usecase" publishanalyticsdomain "haixun-backend/internal/model/publish_analytics/domain/usecase" threadsaccountdomain "haixun-backend/internal/model/threads_account/domain/usecase" ) type PublishAnalyticsDeps struct { Jobs jobdom.UseCase ThreadsAccount threadsaccountdomain.UseCase PublishAnalytics publishanalyticsdomain.UseCase } func RegisterPublishAnalyticsHandler(runner *Runner, deps PublishAnalyticsDeps) { if runner == nil { return } runner.RegisterStepHandler("check", func(ctx context.Context, step StepContext) error { return runPublishAnalyticsCheck(ctx, step, deps) }) } func runPublishAnalyticsCheck(ctx context.Context, step StepContext, deps PublishAnalyticsDeps) error { payload := step.Run.Payload tenantID, ownerUID := runActorFromPayload(payload, step.Run) mediaID := strings.TrimSpace(stringField(payload, "media_id")) checkpoint := strings.TrimSpace(stringField(payload, "checkpoint")) permalink := strings.TrimSpace(stringField(payload, "permalink")) publishedAt := int64Field(payload, "published_at") if mediaID == "" || checkpoint == "" { return fmt.Errorf("publish-analytics payload missing media_id or checkpoint") } cred, err := deps.ThreadsAccount.ResolveMemberThreadsPublishCredential(ctx, tenantID, ownerUID) if err != nil { return fmt.Errorf("resolve publish credential: %w", err) } if cred == nil || cred.AccessToken == "" { return fmt.Errorf("no access token found") } stats, err := libthreads.GetMediaStats(ctx, cred.AccessToken, mediaID) if err != nil { return fmt.Errorf("get media stats: %w", err) } saved, err := deps.PublishAnalytics.RecordCheckpoint(ctx, tenantID, ownerUID, publishanalyticsdomain.PublishAnalyticsSummary{ MediaID: mediaID, Permalink: permalink, PublishedAt: publishedAt, Checkpoint: checkpoint, LikeCount: stats.LikeCount, ReplyCount: stats.ReplyCount, RepostCount: stats.RepostCount, QuoteCount: stats.QuoteCount, }) if err != nil { return fmt.Errorf("record checkpoint: %w", err) } _, err = deps.Jobs.CompleteRun(ctx, jobdom.CompleteRunRequest{ JobID: step.JobID, WorkerID: step.WorkerID, Result: map[string]any{ "media_id": mediaID, "checkpoint": checkpoint, "like_count": saved.LikeCount, "reply_count": saved.ReplyCount, "repost_count": saved.RepostCount, "quote_count": saved.QuoteCount, "analytics_id": saved.ID, }, }) return err }