package app import ( trafficprofilespkg "selective-vpn-api/app/trafficprofiles" "strings" ) func listTrafficAppProfiles() []TrafficAppProfile { raw := trafficAppProfilesStore.List() if len(raw) == 0 { return nil } out := make([]TrafficAppProfile, 0, len(raw)) for _, p := range raw { out = append(out, fromTrafficProfilesPackage(p)) } return out } func upsertTrafficAppProfile(req TrafficAppProfileUpsertRequest) (TrafficAppProfile, error) { p, err := trafficAppProfilesStore.Upsert(toTrafficProfilesPackageReq(req)) if err != nil { return TrafficAppProfile{}, err } return fromTrafficProfilesPackage(p), nil } func deleteTrafficAppProfile(id string) (bool, string) { return trafficAppProfilesStore.Delete(id) } func dedupeTrafficAppProfiles(in []TrafficAppProfile) ([]TrafficAppProfile, bool) { if len(in) == 0 { return in, false } raw := make([]trafficprofilespkg.Profile, 0, len(in)) for _, p := range in { raw = append(raw, toTrafficProfilesPackage(p)) } deduped, changed := trafficprofilespkg.Dedupe(raw, canonicalizeAppKey) if len(deduped) == 0 { return []TrafficAppProfile{}, changed } out := make([]TrafficAppProfile, 0, len(deduped)) for _, p := range deduped { out = append(out, fromTrafficProfilesPackage(p)) } return out, changed } func toTrafficProfilesPackageReq(in TrafficAppProfileUpsertRequest) trafficprofilespkg.UpsertRequest { return trafficprofilespkg.UpsertRequest{ ID: in.ID, Name: in.Name, AppKey: in.AppKey, Command: in.Command, Target: in.Target, TTLSec: in.TTLSec, VPNProfile: in.VPNProfile, } } func toTrafficProfilesPackage(in TrafficAppProfile) trafficprofilespkg.Profile { return trafficprofilespkg.Profile{ ID: in.ID, Name: in.Name, AppKey: in.AppKey, Command: in.Command, Target: in.Target, TTLSec: in.TTLSec, VPNProfile: in.VPNProfile, CreatedAt: in.CreatedAt, UpdatedAt: in.UpdatedAt, } } func fromTrafficProfilesPackage(in trafficprofilespkg.Profile) TrafficAppProfile { return TrafficAppProfile{ ID: in.ID, Name: in.Name, AppKey: in.AppKey, Command: in.Command, Target: in.Target, TTLSec: in.TTLSec, VPNProfile: in.VPNProfile, CreatedAt: in.CreatedAt, UpdatedAt: in.UpdatedAt, } } func sanitizeID(s string) string { in := strings.ToLower(strings.TrimSpace(s)) var b strings.Builder b.Grow(len(in)) lastDash := false for i := 0; i < len(in); i++ { ch := in[i] isAZ := ch >= 'a' && ch <= 'z' is09 := ch >= '0' && ch <= '9' if isAZ || is09 { b.WriteByte(ch) lastDash = false continue } if !lastDash { b.WriteByte('-') lastDash = true } } return strings.Trim(b.String(), "-") } func canonicalizeAppKey(appKey string, command string) string { return trafficprofilespkg.CanonicalizeAppKey(appKey, command) } func splitCommandTokens(raw string) []string { return trafficprofilespkg.SplitCommandTokens(raw) }