package instance import ( "context" "strings" "time" "unicode/utf8" "git.yuntuo.hk/k2safe/orbit/internal/fault" core "git.yuntuo.hk/k2safe/orbit/model" "git.yuntuo.hk/k2safe/orbit/platform/auth" weave "git.yuntuo.hk/k2safe/orbit/weave/model" ) // ListInput 在认证命名空间内筛选实例;所有队列权限必须覆盖整个固定定义版本。 type ListInput struct { DefinitionID core.ID // DefinitionID 可选定义身份,未传入时跨已授权定义查询。 Version string // Version 可选固定发布版本名,仅在指定定义时使用。 State weave.InstanceState // State 可选执行状态,与暂停标志独立。 Paused *bool // Paused nil不筛选;false明确筛选未暂停实例。 BusinessKey string // BusinessKey 非空时精确匹配,包含尾部空格;空表示不筛选。 CreatedFrom *time.Time // CreatedFrom 可选创建时间下界,包含,UTC微秒精度。 CreatedBefore *time.Time // CreatedBefore 可选创建时间上界,不包含。 Limit int // Limit 默认20,上限100。 Cursor string // Cursor 服务端返回的位置,绑定命名空间、全部筛选及队列权限范围。 } // Summary 仅返回实例元数据,不聚合业务输入输出、定义或策略快照。 type Summary struct { ID core.ID `json:"id"` // ID 实例身份。 NamespaceID core.ID `json:"namespace_id"` // NamespaceID 授权及数据隔离范围。 DefinitionID core.ID `json:"definition_id"` // DefinitionID 稳定定义身份。 DefinitionVersionID core.ID `json:"definition_version_id"` // DefinitionVersionID 固定版本记录身份。 Version string `json:"version"` // Version 启动时固定的发布版本名。 State weave.InstanceState `json:"state"` // State 执行状态,受理不代表业务成功。 Revision uint64 `json:"revision,string"` // Revision 实例并发版本。 Paused bool `json:"paused"` // Paused 独立暂停标志,不表示在途工作已停止。 ControlRevision uint64 `json:"control_revision,string"` // ControlRevision 控制操作并发版本。 BusinessKey string `json:"business_key"` // BusinessKey 原始追踪键。 DeadlineAt time.Time `json:"deadline_at"` // DeadlineAt 数据库时间确定的固定总截止。 CancelRequestedAt *time.Time `json:"cancel_requested_at,omitempty"` // CancelRequestedAt 已保存的取消意图时间。 StopKind *string `json:"stop_kind,omitempty"` // StopKind 首次停止原因CANCEL或FAILURE;核查不会清除。 StopRequestedAt *time.Time `json:"stop_requested_at,omitempty"` // StopRequestedAt 首次停止意图时间,后续操作不会延长。 CompletedAt *time.Time `json:"completed_at,omitempty"` // CompletedAt 终结时间,非终态为空。 CreatedAt time.Time `json:"created_at"` // CreatedAt UTC受理时间。 UpdatedAt time.Time `json:"updated_at"` // UpdatedAt 最近状态更新时间。 } type Page struct { Items []Summary `json:"items"` // Items 按创建时间及ID倒序的授权摘要;空列表为[]。 NextCursor string `json:"next_cursor,omitempty"` // NextCursor 沿相同筛选与权限继续使用,空表示本次无下一页。 } func (s *Service) List(ctx context.Context, t auth.Token, in ListInput) (Page, error) { if in.Limit == 0 { in.Limit = 20 } if in.Limit < 1 || in.Limit > 100 || len(in.Cursor) > 1024 || in.DefinitionID != "" && in.DefinitionID.Validate() != nil || in.Version != "" && (in.DefinitionID == "" || !versionName(in.Version)) { return Page{}, fault.Invalid("invalid workflow query definition, version or page") } switch in.State { case "", "RUNNING", "WAITING", "CANCELLING", "NEEDS_REVIEW", "SUCCEEDED", "FAILED", "CANCELLED": default: return Page{}, fault.Invalid("invalid workflow state") } if !utf8.ValidString(in.BusinessKey) || utf8.RuneCountInString(in.BusinessKey) > 191 || strings.ContainsRune(in.BusinessKey, 0) { return Page{}, fault.Invalid("invalid workflow business key filter") } for _, f := range []**time.Time{&in.CreatedFrom, &in.CreatedBefore} { if *f == nil { continue } v := (*f).UTC() if v.Year() < 2000 || v.Year() > 9998 || v.Nanosecond()%1000 != 0 { return Page{}, fault.Invalid("invalid workflow creation time bound") } *f = &v } if in.CreatedFrom != nil && in.CreatedBefore != nil && !in.CreatedFrom.Before(*in.CreatedBefore) { return Page{}, fault.Invalid("created_from must be before created_before") } return s.store.List(ctx, t, in) }