Files

93 lines
3.0 KiB
Go
Raw Permalink Normal View History

package workbench
import "fmt"
var legacyMetadataKeys = []string{"legacy_import", "legacy_history", "legacy_activation"}
type configurationSaveKey struct{}
type legacyImportProtection struct {
ReadOnly bool `json:"read_only"`
RequiresReview bool `json:"requires_review"`
NeedsConfiguration bool `json:"needs_configuration"`
MissingConfiguration []string `json:"missing_configuration"`
}
// Import provenance and historical output are migration-owned, opaque data.
// Typed map/task updates must retain them without treating them as executable state.
func resourceData(r *Resource, value any) JSON {
data := asJSON(value)
for _, key := range legacyMetadataKeys {
if original, exists := r.Data[key]; exists {
data[key] = original
}
}
return data
}
func validateLegacyMetadataUpdate(original, proposed JSON) error {
for _, key := range legacyMetadataKeys {
before, existed := original[key]
after, supplied := proposed[key]
if supplied && (!existed || compact(before) != compact(after)) {
return fmt.Errorf("%w: 历史迁移标记和原始记录不可修改", ErrInvalid)
}
}
return nil
}
func requireLegacyExecutable(r *Resource) error {
value, exists := r.Data["legacy_import"]
if !exists {
return nil
}
// Invalid protection metadata must fail closed rather than enable old jobs.
if value == nil {
return fmt.Errorf("%w: 历史迁移标记无效,请检查迁移结果", ErrInvalid)
}
decoded, err := decode[struct {
Flags *legacyImportProtection `json:"legacy_import"`
}](JSON{"legacy_import": value})
if err != nil || decoded.Flags == nil {
return fmt.Errorf("%w: 历史迁移标记无效,请检查迁移结果", ErrInvalid)
}
flags := decoded.Flags
if activation, ok := r.Data["legacy_activation"]; ok {
state, err := decode[struct {
Activation struct {
Status string `json:"status"`
} `json:"legacy_activation"`
}](JSON{"legacy_activation": activation})
if err == nil && state.Activation.Status == "active" {
return nil
}
}
if flags.ReadOnly {
return fmt.Errorf("%w: 此记录为只读历史资料,原正文、质检和成稿已保留;请编辑配置并保存后继续创作", ErrInvalid)
}
if flags.RequiresReview {
return fmt.Errorf("%w: 此历史资源尚未完成配置复核,请编辑配置并保存后执行", ErrInvalid)
}
if flags.NeedsConfiguration || len(flags.MissingConfiguration) > 0 {
return fmt.Errorf("%w: 此历史资源缺少可执行配置,请先完成迁移配置核对", ErrInvalid)
}
return nil
}
func requireExecutable(r *Resource) error {
if err := requireLegacyExecutable(r); err != nil {
return err
}
if r.Status == "needs_configuration" {
return fmt.Errorf("%w: 资源缺少可执行配置,请重新选择并保存可用的导图、日期、画布和 Agent;历史正文、质检和成稿仍保留", ErrInvalid)
}
return nil
}
func requireActionExecutable(r *Resource, action string) error {
if r.Kind == "content-tasks" && taskActionUsesOnlySavedContent(action) {
return requireLegacyExecutable(r)
}
return requireExecutable(r)
}