Browse Source

add comments + reorganize

Alexander Belanger 4 years ago
parent
commit
853051ffa6
2 changed files with 302 additions and 223 deletions
  1. 167 0
      internal/analytics/track_scopes.go
  2. 135 223
      internal/analytics/tracks.go

+ 167 - 0
internal/analytics/track_scopes.go

@@ -0,0 +1,167 @@
+package analytics
+
+import (
+	"fmt"
+)
+
+// UserScopedTrack is a track that automatically adds a user id to the tracking
+type UserScopedTrack struct {
+	*defaultSegmentTrack
+
+	userID uint
+}
+
+// UserScopedTrackOpts are the options for created a new user-scoped track
+type UserScopedTrackOpts struct {
+	*defaultTrackOpts
+
+	UserID uint
+}
+
+// GetUserScopedTrackOpts is a helper method to getting the UserScopedTrackOpts
+func GetUserScopedTrackOpts(userID uint) *UserScopedTrackOpts {
+	return &UserScopedTrackOpts{
+		UserID: userID,
+	}
+}
+
+func (u *UserScopedTrack) getUserId() string {
+	return fmt.Sprintf("%d", u.userID)
+}
+
+func getSegmentUserTrack(opts *UserScopedTrackOpts, track *defaultSegmentTrack) *UserScopedTrack {
+	return &UserScopedTrack{
+		defaultSegmentTrack: track,
+		userID:              opts.UserID,
+	}
+}
+
+// ProjectScopedTrack is a track that automatically adds a project id to the track
+type ProjectScopedTrack struct {
+	*UserScopedTrack
+
+	projectID uint
+}
+
+// ProjectScopedTrackOpts are the options for created a new project-scoped track
+type ProjectScopedTrackOpts struct {
+	*UserScopedTrackOpts
+
+	ProjectID uint
+}
+
+// GetProjectScopedTrackOpts is a helper method to getting the ProjectScopedTrackOpts
+func GetProjectScopedTrackOpts(userID, projID uint) *ProjectScopedTrackOpts {
+	return &ProjectScopedTrackOpts{
+		UserScopedTrackOpts: GetUserScopedTrackOpts(userID),
+		ProjectID:           projID,
+	}
+}
+
+func getSegmentProjectTrack(opts *ProjectScopedTrackOpts, track *defaultSegmentTrack) *ProjectScopedTrack {
+	track.properties.addProjectProperties(opts)
+
+	return &ProjectScopedTrack{
+		UserScopedTrack: getSegmentUserTrack(opts.UserScopedTrackOpts, track),
+		projectID:       opts.ProjectID,
+	}
+}
+
+// RegistryScopedTrack is a track that automatically adds a registry id to the track
+type RegistryScopedTrack struct {
+	*ProjectScopedTrack
+
+	registryID uint
+}
+
+// RegistryScopedTrackOpts are the options for created a new registry-scoped track
+type RegistryScopedTrackOpts struct {
+	*ProjectScopedTrackOpts
+
+	RegistryID uint
+}
+
+// GetRegistryScopedTrackOpts is a helper method to getting the RegistryScopedTrackOpts
+func GetRegistryScopedTrackOpts(userID, projID, regID uint) *RegistryScopedTrackOpts {
+	return &RegistryScopedTrackOpts{
+		ProjectScopedTrackOpts: GetProjectScopedTrackOpts(userID, projID),
+		RegistryID:             regID,
+	}
+}
+
+func getSegmentRegistryTrack(opts *RegistryScopedTrackOpts, track *defaultSegmentTrack) *RegistryScopedTrack {
+	track.properties.addRegistryProperties(opts)
+
+	return &RegistryScopedTrack{
+		ProjectScopedTrack: getSegmentProjectTrack(opts.ProjectScopedTrackOpts, track),
+		registryID:         opts.RegistryID,
+	}
+}
+
+// ClusterScopedTrack is a track that automatically adds a cluster id to the track
+type ClusterScopedTrack struct {
+	*ProjectScopedTrack
+
+	clusterID uint
+}
+
+// ClusterScopedTrackOpts are the options for created a new cluster-scoped track
+type ClusterScopedTrackOpts struct {
+	*ProjectScopedTrackOpts
+
+	ClusterID uint
+}
+
+// GetClusterScopedTrackOpts is a helper method to getting the ClusterScopedTrackOpts
+func GetClusterScopedTrackOpts(userID, projID, clusterID uint) *ClusterScopedTrackOpts {
+	return &ClusterScopedTrackOpts{
+		ProjectScopedTrackOpts: GetProjectScopedTrackOpts(userID, projID),
+		ClusterID:              clusterID,
+	}
+}
+
+func getSegmentClusterTrack(opts *ClusterScopedTrackOpts, track *defaultSegmentTrack) *ClusterScopedTrack {
+	track.properties.addClusterProperties(opts)
+
+	return &ClusterScopedTrack{
+		ProjectScopedTrack: getSegmentProjectTrack(opts.ProjectScopedTrackOpts, track),
+		clusterID:          opts.ClusterID,
+	}
+}
+
+// ApplicationScopedTrack is a track that automatically adds an app name and namespace to the track
+type ApplicationScopedTrack struct {
+	*ClusterScopedTrack
+
+	name      string
+	namespace string
+}
+
+// ApplicationScopedTrackOpts are the options for created a new app-scoped track
+type ApplicationScopedTrackOpts struct {
+	*ClusterScopedTrackOpts
+
+	Name      string
+	Namespace string
+	ChartName string
+}
+
+// GetApplicationScopedTrackOpts is a helper method to getting the ApplicationScopedTrackOpts
+func GetApplicationScopedTrackOpts(userID, projID, clusterID uint, name, namespace, chartName string) *ApplicationScopedTrackOpts {
+	return &ApplicationScopedTrackOpts{
+		ClusterScopedTrackOpts: GetClusterScopedTrackOpts(userID, projID, clusterID),
+		Name:                   name,
+		Namespace:              namespace,
+		ChartName:              chartName,
+	}
+}
+
+func getSegmentApplicationTrack(opts *ApplicationScopedTrackOpts, track *defaultSegmentTrack) *ApplicationScopedTrack {
+	track.properties.addApplicationProperties(opts)
+
+	return &ApplicationScopedTrack{
+		ClusterScopedTrack: getSegmentClusterTrack(opts.ClusterScopedTrackOpts, track),
+		name:               opts.Name,
+		namespace:          opts.Namespace,
+	}
+}

+ 135 - 223
internal/analytics/tracks.go

@@ -1,17 +1,87 @@
 package analytics
 
 import (
-	"fmt"
-
 	"github.com/porter-dev/porter/internal/models"
 	segment "gopkg.in/segmentio/analytics-go.v3"
 )
 
-// TRACK FUNCTIONS
+type segmentTrack interface {
+	getUserId() string
+	getEvent() SegmentEvent
+	getProperties() segment.Properties
+}
+
+type defaultTrackOpts struct {
+	AdditionalProps map[string]interface{}
+}
+
+type defaultSegmentTrack struct {
+	event      SegmentEvent
+	properties segmentProperties
+}
+
+func getDefaultSegmentTrack(additionalProps map[string]interface{}, event SegmentEvent) *defaultSegmentTrack {
+	props := newSegmentProperties()
+	props.addAdditionalProperties(additionalProps)
+
+	return &defaultSegmentTrack{
+		event:      event,
+		properties: props,
+	}
+}
+
+func (t *defaultSegmentTrack) getEvent() SegmentEvent {
+	return t.event
+}
+
+func (t *defaultSegmentTrack) getProperties() segment.Properties {
+	props := segment.NewProperties()
+
+	for key, val := range t.properties {
+		props = props.Set(key, val)
+	}
+
+	return props
+}
+
+type segmentProperties map[string]interface{}
+
+func newSegmentProperties() segmentProperties {
+	props := make(map[string]interface{})
+
+	return props
+}
+
+func (p segmentProperties) addProjectProperties(opts *ProjectScopedTrackOpts) {
+	p["proj_id"] = opts.ProjectID
+}
+
+func (p segmentProperties) addClusterProperties(opts *ClusterScopedTrackOpts) {
+	p["cluster_id"] = opts.ClusterID
+}
+
+func (p segmentProperties) addRegistryProperties(opts *RegistryScopedTrackOpts) {
+	p["registry_id"] = opts.RegistryID
+}
+
+func (p segmentProperties) addApplicationProperties(opts *ApplicationScopedTrackOpts) {
+	p["app_name"] = opts.Name
+	p["app_namespace"] = opts.Namespace
+	p["chart_name"] = opts.ChartName
+}
+
+func (p segmentProperties) addAdditionalProperties(props map[string]interface{}) {
+	for key, val := range props {
+		p[key] = val
+	}
+}
+
+// UserCreateTrackOpts are the options for creating a track when a user is created
 type UserCreateTrackOpts struct {
 	*UserScopedTrackOpts
 }
 
+// UserCreateTrack returns a track for when a user is created
 func UserCreateTrack(opts *UserCreateTrackOpts) segmentTrack {
 	additionalProps := make(map[string]interface{})
 
@@ -21,10 +91,12 @@ func UserCreateTrack(opts *UserCreateTrackOpts) segmentTrack {
 	)
 }
 
+// ProjectCreateTrackOpts are the options for creating a track when a project is created
 type ProjectCreateTrackOpts struct {
 	*ProjectScopedTrackOpts
 }
 
+// ProjectCreateTrack returns a track for when a project is created
 func ProjectCreateTrack(opts *ProjectCreateTrackOpts) segmentTrack {
 	additionalProps := make(map[string]interface{})
 
@@ -34,6 +106,8 @@ func ProjectCreateTrack(opts *ProjectCreateTrackOpts) segmentTrack {
 	)
 }
 
+// ClusterProvisioningStartTrackOpts are the options for creating a track when a cluster
+// has started provisioning
 type ClusterProvisioningStartTrackOpts struct {
 	// note that this is a project-scoped track, since the cluster has not been created yet
 	*ProjectScopedTrackOpts
@@ -42,6 +116,8 @@ type ClusterProvisioningStartTrackOpts struct {
 	InfraID     uint
 }
 
+// ClusterProvisioningStartTrack returns a track for when a cluster
+// has started provisioning
 func ClusterProvisioningStartTrack(opts *ClusterProvisioningStartTrackOpts) segmentTrack {
 	additionalProps := make(map[string]interface{})
 	additionalProps["cluster_type"] = opts.ClusterType
@@ -53,6 +129,8 @@ func ClusterProvisioningStartTrack(opts *ClusterProvisioningStartTrackOpts) segm
 	)
 }
 
+// ClusterProvisioningErrorTrackOpts are the options for creating a track when a cluster
+// has experienced a provisioning error
 type ClusterProvisioningErrorTrackOpts struct {
 	// note that this is a project-scoped track, since the cluster has not been created yet
 	*ProjectScopedTrackOpts
@@ -61,6 +139,8 @@ type ClusterProvisioningErrorTrackOpts struct {
 	InfraID     uint
 }
 
+// ClusterProvisioningErrorTrack returns a track for when a cluster
+// has experienced a provisioning error
 func ClusterProvisioningErrorTrack(opts *ClusterProvisioningErrorTrackOpts) segmentTrack {
 	additionalProps := make(map[string]interface{})
 	additionalProps["cluster_type"] = opts.ClusterType
@@ -72,6 +152,8 @@ func ClusterProvisioningErrorTrack(opts *ClusterProvisioningErrorTrackOpts) segm
 	)
 }
 
+// ClusterProvisioningSuccessTrackOpts are the options for creating a track when a cluster
+// has successfully provisioned
 type ClusterProvisioningSuccessTrackOpts struct {
 	*ClusterScopedTrackOpts
 
@@ -79,6 +161,8 @@ type ClusterProvisioningSuccessTrackOpts struct {
 	InfraID     uint
 }
 
+// ClusterProvisioningSuccessTrack returns a new track for when a cluster
+// has successfully provisioned
 func ClusterProvisioningSuccessTrack(opts *ClusterProvisioningSuccessTrackOpts) segmentTrack {
 	additionalProps := make(map[string]interface{})
 	additionalProps["cluster_type"] = opts.ClusterType
@@ -90,6 +174,8 @@ func ClusterProvisioningSuccessTrack(opts *ClusterProvisioningSuccessTrackOpts)
 	)
 }
 
+// ClusterConnectionStartTrackOpts are the options for creating a track when a cluster
+// connection has started
 type ClusterConnectionStartTrackOpts struct {
 	// note that this is a project-scoped track, since the cluster has not been created yet
 	*ProjectScopedTrackOpts
@@ -97,6 +183,8 @@ type ClusterConnectionStartTrackOpts struct {
 	ClusterCandidateID uint
 }
 
+// ClusterConnectionStartTrack returns a new track for when a cluster
+// connection has started
 func ClusterConnectionStartTrack(opts *ClusterConnectionStartTrackOpts) segmentTrack {
 	additionalProps := make(map[string]interface{})
 	additionalProps["cc_id"] = opts.ClusterCandidateID
@@ -107,12 +195,16 @@ func ClusterConnectionStartTrack(opts *ClusterConnectionStartTrackOpts) segmentT
 	)
 }
 
+// ClusterConnectionSuccessTrackOpts are the options for creating a track when a cluster
+// connection has finished
 type ClusterConnectionSuccessTrackOpts struct {
 	*ClusterScopedTrackOpts
 
 	ClusterCandidateID uint
 }
 
+// ClusterConnectionSuccessTrack returns a new track for when a cluster
+// connection has finished
 func ClusterConnectionSuccessTrack(opts *ClusterConnectionSuccessTrackOpts) segmentTrack {
 	additionalProps := make(map[string]interface{})
 	additionalProps["cc_id"] = opts.ClusterCandidateID
@@ -123,6 +215,8 @@ func ClusterConnectionSuccessTrack(opts *ClusterConnectionSuccessTrackOpts) segm
 	)
 }
 
+// RegistryConnectionStartTrackOpts are the options for creating a track when a registry
+// connection has started
 type RegistryConnectionStartTrackOpts struct {
 	// note that this is a project-scoped track, since the cluster has not been created yet
 	*ProjectScopedTrackOpts
@@ -131,6 +225,8 @@ type RegistryConnectionStartTrackOpts struct {
 	FlowID string
 }
 
+// RegistryConnectionStartTrack returns a new track for when a registry
+// connection has started
 func RegistryConnectionStartTrack(opts *RegistryConnectionStartTrackOpts) segmentTrack {
 	additionalProps := make(map[string]interface{})
 	additionalProps["flow_id"] = opts.FlowID
@@ -141,6 +237,8 @@ func RegistryConnectionStartTrack(opts *RegistryConnectionStartTrackOpts) segmen
 	)
 }
 
+// RegistryConnectionSuccessTrackOpts are the options for creating a track when a registry
+// connection has completed
 type RegistryConnectionSuccessTrackOpts struct {
 	*RegistryScopedTrackOpts
 
@@ -148,6 +246,8 @@ type RegistryConnectionSuccessTrackOpts struct {
 	FlowID string
 }
 
+// RegistryConnectionSuccessTrack returns a new track for when a registry
+// connection has completed
 func RegistryConnectionSuccessTrack(opts *RegistryConnectionSuccessTrackOpts) segmentTrack {
 	additionalProps := make(map[string]interface{})
 	additionalProps["flow_id"] = opts.FlowID
@@ -158,11 +258,15 @@ func RegistryConnectionSuccessTrack(opts *RegistryConnectionSuccessTrackOpts) se
 	)
 }
 
+// GithubConnectionStartTrackOpts are the options for creating a track when a github account
+// connection has started
 type GithubConnectionStartTrackOpts struct {
 	// note that this is a user-scoped track, since github repos are tied to the user
 	*UserScopedTrackOpts
 }
 
+// GithubConnectionStartTrack returns a new track for when a github account
+// connection has started
 func GithubConnectionStartTrack(opts *GithubConnectionStartTrackOpts) segmentTrack {
 	additionalProps := make(map[string]interface{})
 
@@ -172,11 +276,15 @@ func GithubConnectionStartTrack(opts *GithubConnectionStartTrackOpts) segmentTra
 	)
 }
 
+// GithubConnectionSuccessTrackOpts are the options for creating a track when a github account
+// connection has completed
 type GithubConnectionSuccessTrackOpts struct {
 	// note that this is a user-scoped track, since github repos are tied to the user
 	*UserScopedTrackOpts
 }
 
+// GithubConnectionSuccessTrack returns a new track when a github account
+// connection has completed
 func GithubConnectionSuccessTrack(opts *GithubConnectionSuccessTrackOpts) segmentTrack {
 	additionalProps := make(map[string]interface{})
 
@@ -186,12 +294,16 @@ func GithubConnectionSuccessTrack(opts *GithubConnectionSuccessTrackOpts) segmen
 	)
 }
 
+// ApplicationLaunchStartTrackOpts are the options for creating a track when an application
+// launch has started
 type ApplicationLaunchStartTrackOpts struct {
 	*ClusterScopedTrackOpts
 
 	FlowID string
 }
 
+// ApplicationLaunchStartTrack returns a new track for when an application
+// launch has started
 func ApplicationLaunchStartTrack(opts *ApplicationLaunchStartTrackOpts) segmentTrack {
 	additionalProps := make(map[string]interface{})
 	additionalProps["flow_id"] = opts.FlowID
@@ -202,12 +314,16 @@ func ApplicationLaunchStartTrack(opts *ApplicationLaunchStartTrackOpts) segmentT
 	)
 }
 
+// ApplicationLaunchSuccessTrackOpts are the options for creating a track when an application
+// launch has completed
 type ApplicationLaunchSuccessTrackOpts struct {
 	*ApplicationScopedTrackOpts
 
 	FlowID string
 }
 
+// ApplicationLaunchSuccessTrack returns a new track for when an application
+// launch has completed
 func ApplicationLaunchSuccessTrack(opts *ApplicationLaunchSuccessTrackOpts) segmentTrack {
 	additionalProps := make(map[string]interface{})
 	additionalProps["flow_id"] = opts.FlowID
@@ -218,12 +334,16 @@ func ApplicationLaunchSuccessTrack(opts *ApplicationLaunchSuccessTrackOpts) segm
 	)
 }
 
+// ApplicationDeploymentWebhookTrackOpts are the options for creating a track when an application
+// launch has completed from a webhook
 type ApplicationDeploymentWebhookTrackOpts struct {
 	*ApplicationScopedTrackOpts
 
 	ImageURI string
 }
 
+// ApplicationDeploymentWebhookTrack returns a new track for when an application
+// launch has completed from a webhook
 func ApplicationDeploymentWebhookTrack(opts *ApplicationDeploymentWebhookTrackOpts) segmentTrack {
 	additionalProps := make(map[string]interface{})
 	additionalProps["image_uri"] = opts.ImageURI
@@ -234,6 +354,8 @@ func ApplicationDeploymentWebhookTrack(opts *ApplicationDeploymentWebhookTrackOp
 	)
 }
 
+// RegistryProvisioningStartTrackOpts are the options for creating a track when a registry
+// provisioning has started
 type RegistryProvisioningStartTrackOpts struct {
 	// note that this is a project-scoped track, since the registry has not been created yet
 	*ProjectScopedTrackOpts
@@ -242,6 +364,8 @@ type RegistryProvisioningStartTrackOpts struct {
 	InfraID      uint
 }
 
+// RegistryProvisioningStartTrack returns a new track for when a registry
+// provisioning has started
 func RegistryProvisioningStartTrack(opts *RegistryProvisioningStartTrackOpts) segmentTrack {
 	additionalProps := make(map[string]interface{})
 	additionalProps["registry_type"] = opts.RegistryType
@@ -253,6 +377,8 @@ func RegistryProvisioningStartTrack(opts *RegistryProvisioningStartTrackOpts) se
 	)
 }
 
+// RegistryProvisioningErrorTrackOpts are the options for creating a track when a registry
+// provisioning has failed
 type RegistryProvisioningErrorTrackOpts struct {
 	// note that this is a project-scoped track, since the registry has not been created yet
 	*ProjectScopedTrackOpts
@@ -261,6 +387,8 @@ type RegistryProvisioningErrorTrackOpts struct {
 	InfraID      uint
 }
 
+// RegistryProvisioningErrorTrack returns a new track for when a registry
+// provisioning has failed
 func RegistryProvisioningErrorTrack(opts *RegistryProvisioningErrorTrackOpts) segmentTrack {
 	additionalProps := make(map[string]interface{})
 	additionalProps["registry_type"] = opts.RegistryType
@@ -272,6 +400,8 @@ func RegistryProvisioningErrorTrack(opts *RegistryProvisioningErrorTrackOpts) se
 	)
 }
 
+// RegistryProvisioningSuccessTrackOpts are the options for creating a track when a registry
+// provisioning has completed
 type RegistryProvisioningSuccessTrackOpts struct {
 	*RegistryScopedTrackOpts
 
@@ -279,6 +409,8 @@ type RegistryProvisioningSuccessTrackOpts struct {
 	InfraID      uint
 }
 
+// RegistryProvisioningSuccessTrack returns a new track for when a registry
+// provisioning has completed
 func RegistryProvisioningSuccessTrack(opts *RegistryProvisioningSuccessTrackOpts) segmentTrack {
 	additionalProps := make(map[string]interface{})
 	additionalProps["registry_type"] = opts.RegistryType
@@ -289,223 +421,3 @@ func RegistryProvisioningSuccessTrack(opts *RegistryProvisioningSuccessTrackOpts
 		getDefaultSegmentTrack(additionalProps, RegistryProvisioningSuccess),
 	)
 }
-
-// HELPERS
-
-type segmentTrack interface {
-	getUserId() string
-	getEvent() SegmentEvent
-	getProperties() segment.Properties
-}
-
-type defaultTrackOpts struct {
-	AdditionalProps map[string]interface{}
-}
-
-type defaultSegmentTrack struct {
-	event      SegmentEvent
-	properties segmentProperties
-}
-
-func getDefaultSegmentTrack(additionalProps map[string]interface{}, event SegmentEvent) *defaultSegmentTrack {
-	props := newSegmentProperties()
-	props.addAdditionalProperties(additionalProps)
-
-	return &defaultSegmentTrack{
-		event:      event,
-		properties: props,
-	}
-}
-
-func (t *defaultSegmentTrack) getEvent() SegmentEvent {
-	return t.event
-}
-
-func (t *defaultSegmentTrack) getProperties() segment.Properties {
-	props := segment.NewProperties()
-
-	for key, val := range t.properties {
-		props = props.Set(key, val)
-	}
-
-	return props
-}
-
-type segmentProperties map[string]interface{}
-
-func newSegmentProperties() segmentProperties {
-	props := make(map[string]interface{})
-
-	return props
-}
-
-func (p segmentProperties) addProjectProperties(opts *ProjectScopedTrackOpts) {
-	p["proj_id"] = opts.ProjectID
-}
-
-func (p segmentProperties) addClusterProperties(opts *ClusterScopedTrackOpts) {
-	p["cluster_id"] = opts.ClusterID
-}
-
-func (p segmentProperties) addRegistryProperties(opts *RegistryScopedTrackOpts) {
-	p["registry_id"] = opts.RegistryID
-}
-
-func (p segmentProperties) addApplicationProperties(opts *ApplicationScopedTrackOpts) {
-	p["app_name"] = opts.Name
-	p["app_namespace"] = opts.Namespace
-	p["chart_name"] = opts.ChartName
-}
-
-func (p segmentProperties) addAdditionalProperties(props map[string]interface{}) {
-	for key, val := range props {
-		p[key] = val
-	}
-}
-
-type UserScopedTrack struct {
-	*defaultSegmentTrack
-
-	userID uint
-}
-
-type UserScopedTrackOpts struct {
-	*defaultTrackOpts
-
-	UserID uint
-}
-
-func GetUserScopedTrackOpts(userID uint) *UserScopedTrackOpts {
-	return &UserScopedTrackOpts{
-		UserID: userID,
-	}
-}
-
-func (u *UserScopedTrack) getUserId() string {
-	return fmt.Sprintf("%d", u.userID)
-}
-
-func getSegmentUserTrack(opts *UserScopedTrackOpts, track *defaultSegmentTrack) *UserScopedTrack {
-	return &UserScopedTrack{
-		defaultSegmentTrack: track,
-		userID:              opts.UserID,
-	}
-}
-
-type ProjectScopedTrack struct {
-	*UserScopedTrack
-
-	projectID uint
-}
-
-type ProjectScopedTrackOpts struct {
-	*UserScopedTrackOpts
-
-	ProjectID uint
-}
-
-func GetProjectScopedTrackOpts(userID, projID uint) *ProjectScopedTrackOpts {
-	return &ProjectScopedTrackOpts{
-		UserScopedTrackOpts: GetUserScopedTrackOpts(userID),
-		ProjectID:           projID,
-	}
-}
-
-func getSegmentProjectTrack(opts *ProjectScopedTrackOpts, track *defaultSegmentTrack) *ProjectScopedTrack {
-	track.properties.addProjectProperties(opts)
-
-	return &ProjectScopedTrack{
-		UserScopedTrack: getSegmentUserTrack(opts.UserScopedTrackOpts, track),
-		projectID:       opts.ProjectID,
-	}
-}
-
-type RegistryScopedTrack struct {
-	*ProjectScopedTrack
-
-	registryID uint
-}
-
-type RegistryScopedTrackOpts struct {
-	*ProjectScopedTrackOpts
-
-	RegistryID uint
-}
-
-func GetRegistryScopedTrackOpts(userID, projID, regID uint) *RegistryScopedTrackOpts {
-	return &RegistryScopedTrackOpts{
-		ProjectScopedTrackOpts: GetProjectScopedTrackOpts(userID, projID),
-		RegistryID:             regID,
-	}
-}
-
-func getSegmentRegistryTrack(opts *RegistryScopedTrackOpts, track *defaultSegmentTrack) *RegistryScopedTrack {
-	track.properties.addRegistryProperties(opts)
-
-	return &RegistryScopedTrack{
-		ProjectScopedTrack: getSegmentProjectTrack(opts.ProjectScopedTrackOpts, track),
-		registryID:         opts.RegistryID,
-	}
-}
-
-type ClusterScopedTrack struct {
-	*ProjectScopedTrack
-
-	clusterID uint
-}
-
-type ClusterScopedTrackOpts struct {
-	*ProjectScopedTrackOpts
-
-	ClusterID uint
-}
-
-func GetClusterScopedTrackOpts(userID, projID, clusterID uint) *ClusterScopedTrackOpts {
-	return &ClusterScopedTrackOpts{
-		ProjectScopedTrackOpts: GetProjectScopedTrackOpts(userID, projID),
-		ClusterID:              clusterID,
-	}
-}
-
-func getSegmentClusterTrack(opts *ClusterScopedTrackOpts, track *defaultSegmentTrack) *ClusterScopedTrack {
-	track.properties.addClusterProperties(opts)
-
-	return &ClusterScopedTrack{
-		ProjectScopedTrack: getSegmentProjectTrack(opts.ProjectScopedTrackOpts, track),
-		clusterID:          opts.ClusterID,
-	}
-}
-
-type ApplicationScopedTrack struct {
-	*ClusterScopedTrack
-
-	name      string
-	namespace string
-}
-
-type ApplicationScopedTrackOpts struct {
-	*ClusterScopedTrackOpts
-
-	Name      string
-	Namespace string
-	ChartName string
-}
-
-func GetApplicationScopedTrackOpts(userID, projID, clusterID uint, name, namespace, chartName string) *ApplicationScopedTrackOpts {
-	return &ApplicationScopedTrackOpts{
-		ClusterScopedTrackOpts: GetClusterScopedTrackOpts(userID, projID, clusterID),
-		Name:                   name,
-		Namespace:              namespace,
-		ChartName:              chartName,
-	}
-}
-
-func getSegmentApplicationTrack(opts *ApplicationScopedTrackOpts, track *defaultSegmentTrack) *ApplicationScopedTrack {
-	track.properties.addApplicationProperties(opts)
-
-	return &ApplicationScopedTrack{
-		ClusterScopedTrack: getSegmentClusterTrack(opts.ClusterScopedTrackOpts, track),
-		name:               opts.Name,
-		namespace:          opts.Namespace,
-	}
-}