Pulse/pkg/licensing/conversion_api_helpers.go
2026-03-18 16:06:30 +00:00

67 lines
1.7 KiB
Go

package licensing
import (
"fmt"
"strconv"
"strings"
"time"
)
func ConversionValidationReason(err error) string {
if err == nil {
return "unknown"
}
msg := strings.ToLower(err.Error())
switch {
case strings.Contains(msg, "type is required"):
return "missing_type"
case strings.Contains(msg, "is not supported"):
return "unsupported_type"
case strings.Contains(msg, "surface is required"):
return "missing_surface"
case strings.Contains(msg, "timestamp is required"):
return "missing_timestamp"
case strings.Contains(msg, "idempotency_key is required"):
return "missing_idempotency_key"
case strings.Contains(msg, "tenant_mode must be"):
return "invalid_tenant_mode"
case strings.Contains(msg, "capability is required"):
return "missing_capability"
case strings.Contains(msg, "limit_key is required"):
return "missing_limit_key"
default:
return "validation_error"
}
}
func ParseOptionalTimeParam(raw string, defaultValue time.Time) (time.Time, error) {
raw = strings.TrimSpace(raw)
if raw == "" {
return defaultValue.UTC(), nil
}
// RFC3339 / RFC3339Nano
if t, err := time.Parse(time.RFC3339Nano, raw); err == nil {
return t.UTC(), nil
}
if t, err := time.Parse(time.RFC3339, raw); err == nil {
return t.UTC(), nil
}
// Date-only (local midnight is ambiguous; use UTC midnight).
if t, err := time.ParseInLocation("2006-01-02", raw, time.UTC); err == nil {
return t.UTC(), nil
}
// Unix seconds or milliseconds.
if i, err := strconv.ParseInt(raw, 10, 64); err == nil {
// Heuristic: >= 10^12 is likely ms.
if i >= 1_000_000_000_000 {
return time.UnixMilli(i).UTC(), nil
}
return time.Unix(i, 0).UTC(), nil
}
return time.Time{}, fmt.Errorf("unsupported time format")
}