package usecase import ( "context" "strings" app "haixun-backend/internal/library/errors" "haixun-backend/internal/library/errors/code" "haixun-backend/internal/model/job/domain/entity" domusecase "haixun-backend/internal/model/job/domain/usecase" ) func (u *jobUseCase) UpsertTemplate(ctx context.Context, req domusecase.UpsertTemplateRequest) (*entity.Template, error) { templateType := strings.TrimSpace(req.Type) if templateType == "" { return nil, app.For(code.Job).InputMissingRequired("template type is required") } if strings.TrimSpace(req.Name) == "" { return nil, app.For(code.Job).InputMissingRequired("template name is required") } if len(req.Steps) == 0 { return nil, app.For(code.Job).InputMissingRequired("template steps are required") } version := req.Version if version <= 0 { version = 1 } timeout := req.TimeoutSeconds if timeout <= 0 { timeout = 600 } template := &entity.Template{ Type: templateType, Version: version, Name: req.Name, Description: req.Description, Enabled: req.Enabled, Repeatable: req.Repeatable, ConcurrencyPolicy: req.ConcurrencyPolicy, DedupeKeys: req.DedupeKeys, TimeoutSeconds: timeout, CancelPolicy: req.CancelPolicy, RetryPolicy: req.RetryPolicy, Steps: req.Steps, } if template.ConcurrencyPolicy == "" { template.ConcurrencyPolicy = "reject_same_scope" } if template.CancelPolicy.Mode == "" { template.CancelPolicy.Mode = "cooperative" } if template.CancelPolicy.GraceSeconds <= 0 { template.CancelPolicy.GraceSeconds = 30 } return u.templates.Upsert(ctx, template) } func (u *jobUseCase) ListJobEvents(ctx context.Context, jobID string, limit int64) ([]*entity.Event, error) { if strings.TrimSpace(jobID) == "" { return nil, app.For(code.Job).InputMissingRequired("job id is required") } if _, err := u.runs.FindByID(ctx, jobID); err != nil { return nil, err } return u.events.ListByJobID(ctx, jobID, limit) }