package main import ( "errors" "strings" ) type publishingPolicy interface { defaultStatus() string isAllowedStatus(status string) bool invalidStatusMessage() string validate(payload Doc, existing Doc) error } func applyPublishingPolicy(payload Doc, partial bool, existing Doc, policy publishingPolicy) error { status, hasStatus, err := getOptionalString(payload, "status") if err != nil { return errors.New("status must be a string") } if !hasStatus && !partial { status = policy.defaultStatus() hasStatus = true } if hasStatus { normalizedStatus := strings.TrimSpace(strings.ToLower(status)) if !policy.isAllowedStatus(normalizedStatus) { return errors.New(policy.invalidStatusMessage()) } payload["status"] = normalizedStatus } return policy.validate(payload, existing) } func mergedPublishingValue(payload Doc, existing Doc, field string) (any, bool) { if value, ok := payload[field]; ok { return value, true } if existing == nil { return nil, false } value, ok := existing[field] return value, ok } func mergedPublishingString(payload Doc, existing Doc, field string) (string, bool) { value, ok := mergedPublishingValue(payload, existing, field) if !ok { return "", false } text, ok := value.(string) if !ok { return "", false } trimmed := strings.TrimSpace(text) if trimmed == "" { return "", false } return strings.ToLower(trimmed), true }