diff --git a/internal/input/retool.go b/internal/input/retool.go index f54978c3..9a632e0f 100644 --- a/internal/input/retool.go +++ b/internal/input/retool.go @@ -15,28 +15,7 @@ const ( apiKey = "test-api-key" ) -// RetoolEntityDataTransformInput is a representation of the input for the TransformRetoolEntityData function -type RetoolEntityDataTransformInput struct { - ID int `json:"id"` - Name string `json:"name"` - Status string `json:"status"` - CreatedAt int64 `json:"created_at"` - UpdatedAt *int64 `json:"updated_at"` - Custodial bool `json:"custodial"` - NonCustodial bool `json:"non_custodial"` - HomeDomainsID int `json:"home_domains_id"` - Description string `json:"description"` - WebsiteURL string `json:"website_url"` - SdpEnabled bool `json:"sdp_enabled"` - SorobanEnabled bool `json:"soroban_enabled"` - Notes string `json:"notes"` - Verified bool `json:"verified"` - FeeSponsor bool `json:"fee_sponsor"` - AccountSponsor bool `json:"account_sponsor"` - Live bool `json:"live"` -} - -func GetRetoolData(client *apiclient.APIClient) ([]RetoolEntityDataTransformInput, error) { +func GetRetoolData(client *apiclient.APIClient) ([]utils.RetoolEntityDataTransformInput, error) { if client == nil { client = &apiclient.APIClient{ BaseURL: baseUrl, @@ -60,11 +39,11 @@ func GetRetoolData(client *apiclient.APIClient) ([]RetoolEntityDataTransformInpu if !ok { return nil, fmt.Errorf("Result is not a slice of interface") } - retoolDataSlice := []RetoolEntityDataTransformInput{} + retoolDataSlice := []utils.RetoolEntityDataTransformInput{} for i, item := range resultSlice { if itemMap, ok := item.(map[string]interface{}); ok { - var resp RetoolEntityDataTransformInput + var resp utils.RetoolEntityDataTransformInput err := utils.MapToStruct(itemMap, &resp) if err != nil { log.Printf("Error converting map to struct: %v", err) diff --git a/internal/input/retool_test.go b/internal/input/retool_test.go index dc249e2c..2347285a 100644 --- a/internal/input/retool_test.go +++ b/internal/input/retool_test.go @@ -7,6 +7,7 @@ import ( "github.com/stellar/go/support/http/httptest" "github.com/stellar/go/utils/apiclient" + "github.com/stellar/stellar-etl/internal/utils" "github.com/stretchr/testify/assert" ) @@ -34,7 +35,53 @@ func TestGetRetoolData(t *testing.T) { "fee_sponsor": false, "account_sponsor": false, "live": true, - "status": "live" + "status": "live", + "_home_domain": { + "id": 240, + "created_at": 1706749903897, + "home_domain": "eldorado.io", + "updated_at": 1706749903897 + }, + "_app_geographies_details": [ + { + "id": 39, + "apps_id": 16, + "created_at": 1707887845605, + "geographies_id": [ + { + "id": 176, + "created_at": 1691020699576, + "updated_at": 1706650713745, + "name": "Argentina", + "official_name": "The Argentine Republic" + }, + { + "id": 273, + "created_at": 1691020699834, + "updated_at": 1706650708355, + "name": "Brazil", + "official_name": "The Federative Republic of Brazil" + } + ], + "retail": false, + "enterprise": false + } + ], + "_app_to_ramps_integrations": [ + { + "id": 18, + "created_at": 1707617027154, + "anchors_id": 28, + "apps_id": 16, + "_anchor": { + "id": 28, + "created_at": 1705423531705, + "name": "MoneyGram", + "updated_at": 1706596979487, + "home_domains_id": 203 + } + } + ] } ]`, Header: nil, @@ -54,7 +101,7 @@ func TestGetRetoolData(t *testing.T) { t.Fatalf("Error calling GetRetoolData: %v", err) } - expected := []RetoolEntityDataTransformInput{ + expected := []utils.RetoolEntityDataTransformInput{ { ID: 16, Name: "El Dorado", @@ -73,6 +120,51 @@ func TestGetRetoolData(t *testing.T) { FeeSponsor: false, AccountSponsor: false, Live: true, + HomeDomain: utils.HomeDomain{ + ID: 240, + CreatedAt: 1706749903897, + UpdatedAt: 1706749903897, + HomeDomain: "eldorado.io", + }, + AppGeographiesDetails: []utils.AppGeographyDetail{ + { + ID: 39, + AppsID: 16, + CreatedAt: 1707887845605, + GeographiesID: []utils.Geography{ + { + ID: 176, + CreatedAt: 1691020699576, + UpdatedAt: 1706650713745, + Name: "Argentina", + OfficialName: "The Argentine Republic", + }, + { + ID: 273, + CreatedAt: 1691020699834, + UpdatedAt: 1706650708355, + Name: "Brazil", + OfficialName: "The Federative Republic of Brazil", + }, + }, + Retail: false, + Enterprise: false, + }, + }, + AppToRampsIntegrations: []utils.AppToRampIntegration{ + { + ID: 18, + CreatedAt: 1707617027154, + AnchorsID: 28, + AppsID: 16, + Anchor: utils.Anchor{ + ID: 28, + CreatedAt: 1705423531705, + UpdatedAt: 1706596979487, + Name: "MoneyGram", + }, + }, + }, }, } diff --git a/internal/transform/retool.go b/internal/transform/retool.go new file mode 100644 index 00000000..d964b4a6 --- /dev/null +++ b/internal/transform/retool.go @@ -0,0 +1,50 @@ +package transform + +import ( + "github.com/stellar/stellar-etl/internal/utils" +) + +func TransformRetoolEntityData(entityData utils.RetoolEntityDataTransformInput) (EntityDataTransformOutput, error) { + transformedRetoolEntityData := EntityDataTransformOutput{ + ID: entityData.ID, + Name: entityData.Name, + HomeDomain: entityData.HomeDomain.HomeDomain, + Status: entityData.Status, + CreatedAt: entityData.CreatedAt, + UpdatedAt: entityData.UpdatedAt, + Custodial: entityData.Custodial, + NonCustodial: entityData.NonCustodial, + HomeDomainsID: entityData.HomeDomainsID, + Description: entityData.Description, + WebsiteURL: entityData.WebsiteURL, + SdpEnabled: entityData.SdpEnabled, + SorobanEnabled: entityData.SorobanEnabled, + Notes: entityData.Notes, + Verified: entityData.Verified, + FeeSponsor: entityData.FeeSponsor, + AccountSponsor: entityData.AccountSponsor, + Live: entityData.Live, + AppGeographies: mapGeographies(entityData.AppGeographiesDetails), + Ramps: mapRamps(entityData.AppToRampsIntegrations), + } + + return transformedRetoolEntityData, nil +} + +func mapGeographies(appGeographies []utils.AppGeographyDetail) []string { + var geographies []string + for _, geoDetail := range appGeographies { + for _, geo := range geoDetail.GeographiesID { + geographies = append(geographies, geo.Name) + } + } + return geographies +} + +func mapRamps(appRamps []utils.AppToRampIntegration) []string { + var ramps []string + for _, ramp := range appRamps { + ramps = append(ramps, ramp.Anchor.Name) + } + return ramps +} diff --git a/internal/transform/retool_test.go b/internal/transform/retool_test.go new file mode 100644 index 00000000..13630e31 --- /dev/null +++ b/internal/transform/retool_test.go @@ -0,0 +1,99 @@ +package transform + +import ( + "testing" + + "github.com/stellar/stellar-etl/internal/utils" + "github.com/stretchr/testify/assert" +) + +func TestTransformRetoolEntityData(t *testing.T) { + output, _ := TransformRetoolEntityData(utils.RetoolEntityDataTransformInput{ + ID: 16, + Name: "El Dorado", + Status: "live", + CreatedAt: 1706749912776, + UpdatedAt: nil, + Custodial: true, + NonCustodial: true, + HomeDomainsID: 240, + Description: "", + WebsiteURL: "", + SdpEnabled: false, + SorobanEnabled: false, + Notes: "", + Verified: false, + FeeSponsor: false, + AccountSponsor: false, + Live: true, + HomeDomain: utils.HomeDomain{ + ID: 240, + CreatedAt: 1706749903897, + UpdatedAt: 1706749903897, + HomeDomain: "eldorado.io", + }, + AppGeographiesDetails: []utils.AppGeographyDetail{ + { + ID: 39, + AppsID: 16, + CreatedAt: 1707887845605, + GeographiesID: []utils.Geography{ + { + ID: 176, + CreatedAt: 1691020699576, + UpdatedAt: 1706650713745, + Name: "Argentina", + OfficialName: "The Argentine Republic", + }, + { + ID: 273, + CreatedAt: 1691020699834, + UpdatedAt: 1706650708355, + Name: "Brazil", + OfficialName: "The Federative Republic of Brazil", + }, + }, + Retail: false, + Enterprise: false, + }, + }, + AppToRampsIntegrations: []utils.AppToRampIntegration{ + { + ID: 18, + CreatedAt: 1707617027154, + AnchorsID: 28, + AppsID: 16, + Anchor: utils.Anchor{ + ID: 28, + CreatedAt: 1705423531705, + UpdatedAt: 1706596979487, + Name: "MoneyGram", + }, + }, + }, + }, + ) + expectedOutput := EntityDataTransformOutput{ + ID: 16, + Name: "El Dorado", + Status: "live", + CreatedAt: 1706749912776, + UpdatedAt: nil, + Custodial: true, + NonCustodial: true, + HomeDomainsID: 240, + Description: "", + WebsiteURL: "", + SdpEnabled: false, + SorobanEnabled: false, + Notes: "", + Verified: false, + FeeSponsor: false, + AccountSponsor: false, + Live: true, + HomeDomain: "eldorado.io", + AppGeographies: []string{"Argentina", "Brazil"}, + Ramps: []string{"MoneyGram"}, + } + assert.Equal(t, expectedOutput, output) +} diff --git a/internal/transform/schema.go b/internal/transform/schema.go index 1bcce561..cf990ba0 100644 --- a/internal/transform/schema.go +++ b/internal/transform/schema.go @@ -629,3 +629,26 @@ type ContractEventOutput struct { DataDecoded map[string]string `json:"data_decoded"` ContractEventXDR string `json:"contract_event_xdr"` } + +type EntityDataTransformOutput struct { + ID int `json:"id"` + Name string `json:"name"` + HomeDomain string `json:"home_domain"` + Status string `json:"status"` + CreatedAt int64 `json:"created_at"` + UpdatedAt *int64 `json:"updated_at"` + Custodial bool `json:"custodial"` + NonCustodial bool `json:"non_custodial"` + HomeDomainsID int `json:"home_domains_id"` + Description string `json:"description"` + WebsiteURL string `json:"website_url"` + SdpEnabled bool `json:"sdp_enabled"` + SorobanEnabled bool `json:"soroban_enabled"` + Notes string `json:"notes"` + Verified bool `json:"verified"` + FeeSponsor bool `json:"fee_sponsor"` + AccountSponsor bool `json:"account_sponsor"` + Live bool `json:"live"` + AppGeographies []string `json:"app_geographies"` + Ramps []string `json:"ramps"` +} diff --git a/internal/utils/retool.go b/internal/utils/retool.go new file mode 100644 index 00000000..20d65213 --- /dev/null +++ b/internal/utils/retool.go @@ -0,0 +1,64 @@ +package utils + +// RetoolEntityDataTransformInput is a representation of the input for the TransformRetoolEntityData function +type RetoolEntityDataTransformInput struct { + ID int `json:"id"` + Name string `json:"name"` + Status string `json:"status"` + CreatedAt int64 `json:"created_at"` + UpdatedAt *int64 `json:"updated_at"` + Custodial bool `json:"custodial"` + NonCustodial bool `json:"non_custodial"` + HomeDomainsID int `json:"home_domains_id"` + Description string `json:"description"` + WebsiteURL string `json:"website_url"` + SdpEnabled bool `json:"sdp_enabled"` + SorobanEnabled bool `json:"soroban_enabled"` + Notes string `json:"notes"` + Verified bool `json:"verified"` + FeeSponsor bool `json:"fee_sponsor"` + AccountSponsor bool `json:"account_sponsor"` + Live bool `json:"live"` + HomeDomain HomeDomain `json:"_home_domain"` + AppGeographiesDetails []AppGeographyDetail `json:"_app_geographies_details"` + AppToRampsIntegrations []AppToRampIntegration `json:"_app_to_ramps_integrations"` +} + +type HomeDomain struct { + ID int64 `json:"id"` + CreatedAt int64 `json:"created_at"` + UpdatedAt int64 `json:"updated_at"` + HomeDomain string `json:"home_domain"` +} + +type AppGeographyDetail struct { + ID int64 `json:"id"` + AppsID int64 `json:"apps_id"` + CreatedAt int64 `json:"created_at"` + GeographiesID []Geography `json:"geographies_id"` + Retail bool `json:"retail"` + Enterprise bool `json:"enterprise"` +} + +type Geography struct { + ID int64 `json:"id"` + CreatedAt int64 `json:"created_at"` + UpdatedAt int64 `json:"updated_at"` + Name string `json:"name"` + OfficialName string `json:"official_name"` +} + +type AppToRampIntegration struct { + ID int64 `json:"id"` + CreatedAt int64 `json:"created_at"` + AnchorsID int64 `json:"anchors_id"` + AppsID int64 `json:"apps_id"` + Anchor Anchor `json:"_anchor"` +} + +type Anchor struct { + ID int64 `json:"id"` + CreatedAt int64 `json:"created_at"` + UpdatedAt int64 `json:"updated_at"` + Name string `json:"name"` +}