/* Volt Platform — License Management Core license types and validation logic */ package license import ( "fmt" "regexp" "time" ) // License represents a Volt platform license type License struct { Key string `yaml:"key"` Tier string `yaml:"tier"` // community, pro, enterprise NodeID string `yaml:"node_id"` Organization string `yaml:"organization"` ActivatedAt time.Time `yaml:"activated_at"` ExpiresAt time.Time `yaml:"expires_at"` Token string `yaml:"token"` // signed activation token from server Features []string `yaml:"features"` Fingerprint string `yaml:"fingerprint"` CouponCode string `yaml:"coupon_code,omitempty"` // Promotional code used TrialEndsAt time.Time `yaml:"trial_ends_at,omitempty"` // Trial expiration IsTrial bool `yaml:"is_trial,omitempty"` // Whether this is a trial license } // IsTrialExpired checks if a trial license has expired. // Returns false for non-trial licenses. func (l *License) IsTrialExpired() bool { if !l.IsTrial { return false } if l.TrialEndsAt.IsZero() { return false } return time.Now().After(l.TrialEndsAt) } // licenseKeyPattern validates VOLT-{TIER}-XXXX-XXXX-XXXX-XXXX-XXXX-XXXX format // Tier prefix: COM (Community), PRO (Professional), ENT (Enterprise) // Followed by 6 groups of 4 uppercase hex characters var licenseKeyPattern = regexp.MustCompile(`^VOLT-(COM|PRO|ENT)-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{4}-[A-F0-9]{4}$`) // ValidateKeyFormat checks if a license key matches the expected format func ValidateKeyFormat(key string) error { if !licenseKeyPattern.MatchString(key) { return fmt.Errorf("invalid license key format: expected VOLT-{COM|PRO|ENT}-XXXX-XXXX-XXXX-XXXX-XXXX-XXXX") } return nil } // TierName returns a human-readable tier name func TierName(tier string) string { switch tier { case TierCommunity: return "Community" case TierPro: return "Professional" case TierEnterprise: return "Enterprise" default: return "Unknown" } } // DetermineTier determines the tier from a license key prefix func DetermineTier(key string) string { if len(key) < 8 { return TierCommunity } switch key[5:8] { case "PRO": return TierPro case "ENT": return TierEnterprise default: return TierCommunity } }