package job import ( "strings" "haixun-backend/internal/library/clock" app "haixun-backend/internal/library/errors" "haixun-backend/internal/library/errors/code" "haixun-backend/internal/model/ai/domain/enum" jobentity "haixun-backend/internal/model/job/domain/entity" jobenum "haixun-backend/internal/model/job/domain/enum" "haixun-backend/internal/types" ) func mapWorkerAIProvider(provider string) (enum.ProviderID, error) { switch strings.TrimSpace(provider) { case string(enum.ProviderOpenCode): return enum.ProviderOpenCode, nil case string(enum.ProviderXAI): return enum.ProviderXAI, nil default: return "", app.For(code.AI).InputInvalidFormat("worker 8D 分析目前僅支援 opencode-go 與 xai,請在 AI 設定調整 research provider") } } func markWorkerStep(steps []jobentity.StepProgress, stepID string, status jobenum.StepStatus, message string) []jobentity.StepProgress { now := clock.NowUnixNano() found := false for i := range steps { if steps[i].ID != stepID { continue } found = true steps[i].Status = status steps[i].Message = message if status == jobenum.StepStatusRunning && steps[i].StartedAt == nil { steps[i].StartedAt = &now } if status == jobenum.StepStatusSucceeded || status == jobenum.StepStatusFailed { steps[i].EndedAt = &now } } if !found { item := jobentity.StepProgress{ID: stepID, Status: status, Message: message} if status == jobenum.StepStatusRunning { item.StartedAt = &now } if status == jobenum.StepStatusSucceeded || status == jobenum.StepStatusFailed { item.EndedAt = &now } steps = append(steps, item) } return steps } func toEntitySteps(steps []types.JobStepProgressData) []jobentity.StepProgress { out := make([]jobentity.StepProgress, 0, len(steps)) for _, step := range steps { out = append(out, jobentity.StepProgress{ ID: step.ID, Status: jobenum.StepStatus(step.Status), StartedAt: step.StartedAt, EndedAt: step.EndedAt, Message: step.Message, }) } return out }