package job import ( "context" "fmt" libpersonacopy "haixun-backend/internal/library/personacopy" aiusecase "haixun-backend/internal/model/ai/usecase" contentopsdomain "haixun-backend/internal/model/content_ops/domain/usecase" copydraftdomain "haixun-backend/internal/model/copy_draft/domain/usecase" jobdom "haixun-backend/internal/model/job/domain/usecase" personadomain "haixun-backend/internal/model/persona/domain/usecase" placementusecase "haixun-backend/internal/model/placement/usecase" threadsaccountdomain "haixun-backend/internal/model/threads_account/domain/usecase" ) type GenerateTopicMatrixDeps struct { Jobs jobdom.UseCase Persona personadomain.UseCase CopyDraft copydraftdomain.UseCase ContentOps contentopsdomain.UseCase ThreadsAccount threadsaccountdomain.UseCase Placement placementusecase.UseCase AI aiusecase.UseCase } func RegisterGenerateTopicMatrixHandler(runner *Runner, deps GenerateTopicMatrixDeps) { if runner == nil { return } runner.RegisterStepHandler("topic_matrix_generate", func(ctx context.Context, step StepContext) error { return runGenerateTopicMatrix(ctx, step, deps) }) } func runGenerateTopicMatrix(ctx context.Context, step StepContext, deps GenerateTopicMatrixDeps) error { payload := step.Run.Payload tenantID, ownerUID := runActorFromPayload(payload, step.Run) personaID := stringField(payload, "persona_id") topic := stringField(payload, "topic") if tenantID == "" || ownerUID == "" || personaID == "" || topic == "" { return fmt.Errorf("generate-topic-matrix payload missing tenant_id, owner_uid, persona_id, or topic") } updateProgress := func(summary string, percentage int) { _ = step.Heartbeat(ctx) _, _ = deps.Jobs.UpdateProgress(ctx, jobdom.UpdateProgressRequest{ JobID: step.JobID, WorkerID: step.WorkerID, Phase: "topic_matrix_generate", Summary: summary, Percentage: percentage, }) } created, err := libpersonacopy.RunTopicMatrix(ctx, libpersonacopy.TopicMatrixDeps{ Persona: deps.Persona, CopyDraft: deps.CopyDraft, ContentOps: deps.ContentOps, ThreadsAccount: deps.ThreadsAccount, Placement: deps.Placement, AI: deps.AI, }, libpersonacopy.TopicMatrixInput{ TenantID: tenantID, OwnerUID: ownerUID, PersonaID: personaID, ContentPlanID: stringField(payload, "content_plan_id"), Topic: topic, Brief: stringField(payload, "brief"), UseWebSearch: boolField(payload, "use_web_search"), DraftCount: intField(payload, "draft_count"), }, updateProgress) if err != nil { return err } _ = created return nil }