Files
orbit/weave/signal/history.go

92 lines
5.0 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package signal
import (
"context"
"encoding/json"
"time"
"git.yuntuo.hk/k2safe/orbit/internal/fault"
core "git.yuntuo.hk/k2safe/orbit/model"
"git.yuntuo.hk/k2safe/orbit/platform/auth"
"git.yuntuo.hk/k2safe/orbit/pulse/service"
)
const AuditAction = "workflows:audit:read"
// Summary 不聚合信号正文、关联键或证据;单条Get用于读取完整原始信号。
type Summary struct {
ID core.ID `json:"id"` // ID 持久信号身份。
WorkflowID core.ID `json:"workflow_id"` // WorkflowID 所属实例。
Revision uint64 `json:"revision,string"` // Revision 该信号当前记录版本。
Name string `json:"name"` // Name 原信号类型名称。
PayloadVersion string `json:"payload_version"` // PayloadVersion 固定内容契约;未核验旧数据可能为空。
TargetStepKey string `json:"target_step_key"` // TargetStepKey 原目标步骤名称,不跟随当前步骤变更。
TargetActivationSequence uint32 `json:"target_activation_sequence"` // TargetActivationSequence 原指定代次,未核验旧数据可能为0。
State string `json:"state"` // State 当前PENDING、CONSUMED、EXPIRED或REJECTED。
Disposition string `json:"disposition,omitempty"` // Disposition 已记录的消费或拒绝原因。
AcceptedAt time.Time `json:"accepted_at"` // AcceptedAt 原受理时间,也是分页排序依据。
ExpiresAt time.Time `json:"expires_at"` // ExpiresAt 原固定截止,不因读取或重报延长。
}
type Page struct {
WorkflowID core.ID `json:"workflow_id"` // WorkflowID 已授权实例。
Revision uint64 `json:"revision,string"` // Revision 本页读取时的实例版本;跨页状态可变化。
Items []Summary `json:"items"` // Items 按受理时间及ID倒序的摘要,空页为[]。
NextCursor string `json:"next_cursor,omitempty"` // NextCursor 绑定命名空间及实例的后续位置。
}
type OperationSummary struct {
ID core.ID `json:"id"` // ID 不可改写的操作审计身份。
WorkflowID core.ID `json:"workflow_id"` // WorkflowID 经信号归属验证的实例。
SignalID core.ID `json:"signal_id"` // SignalID 本次操作对应的信号资源。
OperationID core.ID `json:"operation_id"` // OperationID 服务端操作身份,不是原始幂等键。
ActorID string `json:"actor_id"` // ActorID 已认证的实际操作主体。
Action string `json:"action"` // Action 操作种类,如workflow.signal。
CreatedAt time.Time `json:"created_at"` // CreatedAt 原操作创建时间。
}
type OperationView struct {
OperationSummary
Reason string `json:"reason"` // Reason 原操作原因。
EvidenceRef string `json:"evidence_ref,omitempty"` // EvidenceRef 原证据引用,不保存外部秘密。
Before json.RawMessage `json:"before"` // Before 操作前摘要,首次受理可为null。
After json.RawMessage `json:"after"` // After 原受理身份、摘要、时间和当时状态,不替代当前消费状态。
}
type OperationPage struct {
Items []OperationSummary `json:"items"` // Items 按创建时间和ID倒序的有界审计摘要。
NextCursor string `json:"next_cursor,omitempty"` // NextCursor 绑定实例、信号及查询类型的后续位置。
}
func historyPage(in service.HistoryPageInput) (service.HistoryPageInput, error) {
if in.Limit == 0 {
in.Limit = 20
}
if in.Limit < 1 || in.Limit > 100 || len(in.Cursor) > 1024 {
return in, fault.Invalid("invalid workflow signal history page")
}
return in, nil
}
func (s *Service) List(ctx context.Context, t auth.Token, workflow core.ID, in service.HistoryPageInput) (Page, error) {
if workflow.Validate() != nil {
return Page{}, fault.Invalid("invalid workflow id")
}
in, err := historyPage(in)
if err != nil {
return Page{}, err
}
return s.store.List(ctx, t, workflow, in)
}
func (s *Service) ListOperations(ctx context.Context, t auth.Token, workflow, id core.ID, in service.HistoryPageInput) (OperationPage, error) {
if workflow.Validate() != nil || id.Validate() != nil {
return OperationPage{}, fault.Invalid("invalid workflow signal identity")
}
in, err := historyPage(in)
if err != nil {
return OperationPage{}, err
}
return s.store.ListOperations(ctx, t, workflow, id, in)
}
func (s *Service) GetOperation(ctx context.Context, t auth.Token, workflow, id, operation core.ID) (OperationView, error) {
if workflow.Validate() != nil || id.Validate() != nil || operation.Validate() != nil {
return OperationView{}, fault.Invalid("invalid signal operation identity")
}
return s.store.GetOperation(ctx, t, workflow, id, operation)
}