From 600d42d529d4938f8bf13c3c98010dedc4611f02 Mon Sep 17 00:00:00 2001 From: "aditya.siregar" Date: Sat, 3 Aug 2024 20:01:25 +0700 Subject: [PATCH] Add Customer Discovery --- config/configs.go | 1 + config/discovery.go | 17 +++ infra/furtuna.development.yaml | 24 +++- internal/entity/discovery.go | 39 ++++++ internal/entity/sites.go | 35 +++++ internal/handlers/http/discovery/discover.go | 134 +++++++++++++++++++ internal/handlers/request/discovery.go | 33 +++++ internal/handlers/response/discovery.go | 49 +++++++ internal/repository/repository.go | 2 + internal/repository/sites/sites.go | 116 ++++++++++++++++ internal/routes/customer_routes.go | 25 ++++ internal/services/discovery/discovery.go | 121 +++++++++++++++++ internal/services/service.go | 42 +++--- main.go | 1 + 14 files changed, 620 insertions(+), 19 deletions(-) create mode 100644 config/discovery.go create mode 100644 internal/entity/discovery.go create mode 100644 internal/handlers/http/discovery/discover.go create mode 100644 internal/handlers/request/discovery.go create mode 100644 internal/handlers/response/discovery.go create mode 100644 internal/routes/customer_routes.go create mode 100644 internal/services/discovery/discovery.go diff --git a/config/configs.go b/config/configs.go index f1c30db..62f5c21 100644 --- a/config/configs.go +++ b/config/configs.go @@ -32,6 +32,7 @@ type Config struct { Brevo Brevo `mapstructure:"brevo"` Email Email `mapstructure:"email"` Withdraw Withdraw `mapstructure:"withdrawal"` + Discovery Discovery `mapstructure:"discovery"` } var ( diff --git a/config/discovery.go b/config/discovery.go new file mode 100644 index 0000000..da479df --- /dev/null +++ b/config/discovery.go @@ -0,0 +1,17 @@ +package config + +type Discovery struct { + ExploreDestinations []ExploreDestination `mapstructure:"explore_destinations"` + ExploreRegions []ExploreRegion `mapstructure:"explore_regions"` +} + +type ExploreDestinations []ExploreDestination + +type ExploreDestination struct { + Name string `mapstructure:"name"` + ImageURL string `mapstructure:"image_url"` +} + +type ExploreRegion struct { + Name string `mapstructure:"name"` +} diff --git a/infra/furtuna.development.yaml b/infra/furtuna.development.yaml index 9a78cb4..499a766 100644 --- a/infra/furtuna.development.yaml +++ b/infra/furtuna.development.yaml @@ -25,7 +25,7 @@ postgresql: max-idle-connections-in-second: 600 max-open-connections-in-second: 600 connection-max-life-time-in-second: 600 - debug: true + debug: false oss: access_key_id: e50b31e5eddf63c0ZKB2 @@ -53,4 +53,24 @@ email: closing_word: "Silakan login kembali menggunakan email dan password anda diatas, sistem akan secara otomatis meminta anda untuk membuat password baru setelah berhasil login. Mohon maaf atas kendala yang dialami." withdrawal: - platform_fee: 5000 \ No newline at end of file + platform_fee: 5000 + +discovery: + explore_destinations: + - name: "Jakarta" + image_url: "https://obs.eranyacloud.com/furtuna-dev/file/03c0b046-43ab-4d35-a743-6a173bc66b90-1722680749.png" + - name: "Banten" + image_url: "https://obs.eranyacloud.com/furtuna-dev/file/c8e7dd8a-17be-449f-afdc-0c07eda438ce-1722680809.png" + - name: "Yogyakarta" + image_url: "https://obs.eranyacloud.com/furtuna-dev/file/83b78c19-4c97-48c9-bc97-a7403e1c4eed-1722680828.png" + - name: "Jawa Barat" + image_url: "https://obs.eranyacloud.com/furtuna-dev/file/07c35ab1-3e20-4858-8d7d-b29517239dc3-1722680848.png" + - name: "Jawa Tengah" + image_url: "https://obs.eranyacloud.com/furtuna-dev/file/a1915a98-c2aa-4997-8e75-bd4e43789b0c-1722680874.png" + - name: "Jawa Timur" + image_url: "https://obs.eranyacloud.com/furtuna-dev/file/7b5d2b86-e8a8-4703-a153-c186021cf088-1722680894.png" + explore_regions: + - name: "Jawa" + - name: "Sumatera" + - name: "Kalimantan" + - name: "Sulawesi" \ No newline at end of file diff --git a/internal/entity/discovery.go b/internal/entity/discovery.go new file mode 100644 index 0000000..3986c77 --- /dev/null +++ b/internal/entity/discovery.go @@ -0,0 +1,39 @@ +package entity + +type DiscoverySearch struct { + Lat float64 + Long float64 + Name string + Region string + Discover string + Offset int + Limit int + Radius int +} + +type DiscoverySearchResp struct { + ExploreRegions []ExploreRegion `json:"exploreRegions"` + ExploreDestinations []ExploreDestination `json:"exploreDestinations"` + MustVisit []MustVisit `json:"mustVisit"` +} + +type ExploreRegion struct { + Name string `json:"name"` +} + +type ExploreDestination struct { + Name string `json:"name"` + ImageURL string `json:"image_url"` +} + +type MustVisit struct { + SiteID int64 `json:"site_id"` + Name string `json:"name"` + Location string `json:"location"` + Rating float64 `json:"rating"` + ReviewCount int `json:"reviewCount"` + Price float64 `json:"price"` + ImageURL string `json:"imageUrl"` + Region string `json:"region"` + Regency string `json:"regency"` +} diff --git a/internal/entity/sites.go b/internal/entity/sites.go index ac4fe78..2fd3c8b 100644 --- a/internal/entity/sites.go +++ b/internal/entity/sites.go @@ -25,6 +25,10 @@ type Site struct { CreatedBy int64 `gorm:"type:int;column:created_by"` UpdatedBy int64 `gorm:"type:int;column:updated_by"` Products []Product `gorm:"foreignKey:SiteID;constraint:OnDelete:CASCADE;"` + Latitude *float64 `json:"latitude"` + Longitude *float64 `json:"longitude"` + Region string `json:"region"` + Distance float64 `json:"distance"` } type SiteSearch struct { @@ -166,3 +170,34 @@ func (e *SiteCountDB) ToSiteCount() *SiteCount { Count: e.Count, } } + +type SiteProductInfo struct { + SiteID int64 `json:"site_id"` + SiteName string `json:"site_name"` + PartnerID int64 `json:"partner_id"` + Image string `json:"image"` + Address string `json:"address"` + LocationLink string `json:"location_link"` + Description string `json:"description"` + Highlight string `json:"highlight"` + ContactPerson string `json:"contact_person"` + TnC string `json:"tnc"` + AdditionalInfo string `json:"additional_info"` + Status string `json:"status"` + IsSeasonTicket bool `json:"is_season_ticket"` + IsDiscountActive bool `json:"is_discount_active"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + Latitude float64 `json:"latitude"` + Longitude float64 `json:"longitude"` + Distance float64 `json:"distance"` // Calculated field + ProductID int64 `json:"product_id"` + ProductName string `json:"product_name"` + ProductType string `json:"product_type"` + ProductPrice float64 `json:"product_price"` + IsWeekendTicket bool `json:"is_weekend_ticket"` + ProductStatus string `json:"product_status"` + ProductDescription string `json:"product_description"` + Region string `json:"region"` + Regency string `json:"regency"` +} diff --git a/internal/handlers/http/discovery/discover.go b/internal/handlers/http/discovery/discover.go new file mode 100644 index 0000000..cee541e --- /dev/null +++ b/internal/handlers/http/discovery/discover.go @@ -0,0 +1,134 @@ +package discovery + +import ( + "furtuna-be/internal/entity" + "github.com/gin-gonic/gin" + "net/http" + + "furtuna-be/internal/common/errors" + "furtuna-be/internal/handlers/request" + "furtuna-be/internal/handlers/response" + "furtuna-be/internal/services" +) + +type Handler struct { + service services.DiscoverService +} + +func (h *Handler) Route(group *gin.RouterGroup, jwt gin.HandlerFunc) { + route := group.Group("/discovery") + + route.GET("/home", h.DisoveryHome) + route.GET("/search", h.DisoverySearch) + +} + +func NewHandler(service services.DiscoverService) *Handler { + return &Handler{ + service: service, + } +} + +func (h *Handler) DisoveryHome(c *gin.Context) { + var req request.DiscoveryHomeParam + if err := c.ShouldBindQuery(&req); err != nil { + response.ErrorWrapper(c, errors.ErrorBadRequest) + return + } + + res, err := h.service.Home(c.Request.Context(), req.ToEntity()) + + if err != nil { + response.ErrorWrapper(c, err) + return + } + + c.JSON(http.StatusOK, response.BaseResponse{ + Success: true, + Status: http.StatusOK, + Data: ConvertEntityToResponse(res), + }) +} + +func (h *Handler) DisoverySearch(c *gin.Context) { + var req request.DiscoveryHomeParam + if err := c.ShouldBindQuery(&req); err != nil { + response.ErrorWrapper(c, errors.ErrorBadRequest) + return + } + + res, total, err := h.service.Search(c.Request.Context(), req.ToEntity()) + + if err != nil { + response.ErrorWrapper(c, err) + return + } + + c.JSON(http.StatusOK, response.BaseResponse{ + Success: true, + Status: http.StatusOK, + Data: ConvertEntityToSearchResponse(res, total, req), + }) +} + +func ConvertEntityToResponse(entityResp *entity.DiscoverySearchResp) *response.ExploreResponse { + // Convert ExploreRegions + exploreRegions := make([]response.Region, len(entityResp.ExploreRegions)) + for i, region := range entityResp.ExploreRegions { + exploreRegions[i] = response.Region{ + Name: region.Name, + } + } + + // Convert ExploreDestinations + exploreDestinations := make([]response.Destination, len(entityResp.ExploreDestinations)) + for i, destination := range entityResp.ExploreDestinations { + exploreDestinations[i] = response.Destination{ + Name: destination.Name, + ImageURL: destination.ImageURL, + } + } + + mustVisit := make([]response.MustVisit, len(entityResp.MustVisit)) + for i, mv := range entityResp.MustVisit { + mustVisit[i] = response.MustVisit{ + Name: mv.Name, + Region: mv.Region, + Rating: mv.Rating, + ReviewCount: mv.ReviewCount, + Price: mv.Price, + ImageURL: mv.ImageURL, + SiteID: mv.SiteID, + Regency: mv.Regency, + } + } + + return &response.ExploreResponse{ + ExploreRegions: exploreRegions, + ExploreDestinations: exploreDestinations, + MustVisit: mustVisit, + } +} + +func ConvertEntityToSearchResponse(entityResp *entity.DiscoverySearchResp, total int64, req request.DiscoveryHomeParam) *response.SearchResponse { + data := make([]response.SiteSeach, len(entityResp.MustVisit)) + for i, mv := range entityResp.MustVisit { + data[i] = response.SiteSeach{ + Name: mv.Name, + Region: mv.Region, + Rating: mv.Rating, + ReviewCount: mv.ReviewCount, + Price: mv.Price, + ImageURL: mv.ImageURL, + SiteID: mv.SiteID, + Regency: mv.Regency, + } + } + + return &response.SearchResponse{ + Data: data, + Total: int(total), + Limit: req.Limit, + Offset: req.Offset, + } +} diff --git a/internal/handlers/request/discovery.go b/internal/handlers/request/discovery.go new file mode 100644 index 0000000..0f5c0dc --- /dev/null +++ b/internal/handlers/request/discovery.go @@ -0,0 +1,33 @@ +package request + +import ( + "furtuna-be/internal/entity" +) + +type DiscoveryHomeParam struct { + Lat float64 `form:"lat" json:"lat" example:"10"` + Long float64 `form:"long" json:"long" example:"0"` + Name string `form:"name" json:"name" example:"0"` + Region string `form:"region" json:"region" example:"0"` + Radius int `form:"radius" json:"radius" example:"0"` + Limit int `form:"limit" json:"limit" example:"0"` + Offset int `form:"offset" json:"offset" example:"0"` + Discover string `form:"discover" json:"discover" example:"0"` +} + +func (d *DiscoveryHomeParam) ToEntity() *entity.DiscoverySearch { + if d.Limit == 0 { + d.Limit = 10 + } + + return &entity.DiscoverySearch{ + Lat: d.Lat, + Long: d.Long, + Name: d.Name, + Region: d.Region, + Radius: d.Radius, + Limit: d.Limit, + Offset: d.Offset, + Discover: d.Discover, + } +} diff --git a/internal/handlers/response/discovery.go b/internal/handlers/response/discovery.go new file mode 100644 index 0000000..940e412 --- /dev/null +++ b/internal/handlers/response/discovery.go @@ -0,0 +1,49 @@ +package response + +type ExploreResponse struct { + ExploreRegions []Region `json:"exploreRegions"` + ExploreDestinations []Destination `json:"exploreDestinations"` + MustVisit []MustVisit `json:"mustVisit"` +} + +type CurrentLocation struct { + City string `json:"city"` +} + +type Region struct { + Name string `json:"name"` +} + +type Destination struct { + Name string `json:"name"` + ImageURL string `json:"image_url"` +} + +type MustVisit struct { + SiteID int64 `json:"site_id"` + Name string `json:"name"` + Region string `json:"region"` + Rating float64 `json:"rating"` + ReviewCount int `json:"reviewCount"` + Price float64 `json:"price"` + ImageURL string `json:"imageUrl"` + Regency string `json:"regency"` +} + +type SearchResponse struct { + Offset int `json:"offset"` + Total int `json:"total"` + Limit int `json:"limit"` + Data []SiteSeach `json:"data"` +} + +type SiteSeach struct { + SiteID int64 `json:"site_id"` + Name string `json:"name"` + Region string `json:"region"` + Rating float64 `json:"rating"` + ReviewCount int `json:"reviewCount"` + Price float64 `json:"price"` + ImageURL string `json:"imageUrl"` + Regency string `json:"regency"` +} diff --git a/internal/repository/repository.go b/internal/repository/repository.go index 37729d8..a8a8be7 100644 --- a/internal/repository/repository.go +++ b/internal/repository/repository.go @@ -172,6 +172,8 @@ type SiteRepository interface { GetAll(ctx context.Context, req entity.SiteSearch) (entity.SiteList, int, error) Delete(ctx context.Context, id int64) error Count(ctx mycontext.Context, req entity.SiteSearch) (*entity.SiteCountDB, error) + GetNearestSites(ctx context.Context, latitude, longitude, radius float64) ([]entity.SiteProductInfo, error) + SearchSites(ctx context.Context, search *entity.DiscoverySearch) ([]entity.SiteProductInfo, int64, error) } type TransactionManager interface { diff --git a/internal/repository/sites/sites.go b/internal/repository/sites/sites.go index 124cc10..22d6bc8 100644 --- a/internal/repository/sites/sites.go +++ b/internal/repository/sites/sites.go @@ -156,3 +156,119 @@ func (r *SiteRepository) Count(ctx mycontext.Context, req entity.SiteSearch) (*e return count, nil } + +func (r *SiteRepository) GetNearestSites(ctx context.Context, latitude, longitude, radius float64) ([]entity.SiteProductInfo, error) { + const limit = 5 + var siteProducts []entity.SiteProductInfo + + distanceQuery := ` + (6371 * acos(cos(radians(?)) * cos(radians(latitude)) * cos(radians(longitude) - radians(?)) + sin(radians(?)) * sin(radians(latitude)))) + ` + + // Primary query for sites within the radius + err := r.db.WithContext(ctx).Raw(` + SELECT s.id AS site_id, s.name AS site_name, s.region, s.regency, s.partner_id, s.image, s.address, s.location_link, s.description, + s.highlight, s.contact_person, s.tnc, s.additional_info, s.status, s.is_season_ticket, s.is_discount_active, + s.latitude, s.longitude, s.created_at, s.updated_at, + `+distanceQuery+` AS distance, + p.id AS product_id, p.name AS product_name, p.type AS product_type, p.price AS product_price, + p.is_weekend_ticket, p.is_season_ticket, p.status AS product_status, p.description AS product_description + FROM sites s + LEFT JOIN ( + SELECT *, ROW_NUMBER() OVER (PARTITION BY site_id ORDER BY price ASC) AS rn + FROM products + ) p ON s.id = p.site_id AND p.rn = 1 + WHERE `+distanceQuery+` < ? + ORDER BY distance + LIMIT ?`, + latitude, longitude, latitude, latitude, longitude, latitude, radius, limit).Scan(&siteProducts).Error + + if err != nil { + return nil, err + } + + // If fewer than 5 sites found, fetch additional ones regardless of distance + if len(siteProducts) < limit { + additionalLimit := limit - len(siteProducts) + err = r.db.WithContext(ctx).Raw(` + SELECT s.id AS site_id, s.name AS site_name, s.region, s.regency, s.partner_id, s.image, s.address, s.location_link, s.description, + s.highlight, s.contact_person, s.tnc, s.additional_info, s.status, s.is_season_ticket, s.is_discount_active, + s.latitude, s.longitude, s.created_at, s.updated_at, + `+distanceQuery+` AS distance, + p.id AS product_id, p.name AS product_name, p.type AS product_type, p.price AS product_price, + p.is_weekend_ticket, p.is_season_ticket, p.status AS product_status, p.description AS product_description + FROM sites s + LEFT JOIN ( + SELECT *, ROW_NUMBER() OVER (PARTITION BY site_id ORDER BY price ASC) AS rn + FROM products + ) p ON s.id = p.site_id AND p.rn = 1 + ORDER BY distance + LIMIT ?`, + latitude, longitude, latitude, additionalLimit).Scan(&siteProducts).Error + + if err != nil { + return nil, err + } + } + + return siteProducts, nil +} + +func (r *SiteRepository) SearchSites(ctx context.Context, search *entity.DiscoverySearch) ([]entity.SiteProductInfo, int64, error) { + var siteProducts []entity.SiteProductInfo + var total int64 + + // Adding wildcard for partial matching + searchName := "%" + search.Name + "%" + + // Base conditions and parameters + conditions := "s.name ILIKE ?" + params := []interface{}{searchName} + + // Add region filtering if region is provided + if search.Region != "" { + conditions += " AND s.region = ?" + params = append(params, search.Region) + } + + if search.Discover != "" { + conditions += " AND s.address ILIKE ?" + params = append(params, "%"+search.Discover+"%") + } + + // Count query to get the total number of matching records + countQuery := ` + SELECT COUNT(*) + FROM sites s + WHERE ` + conditions + err := r.db.WithContext(ctx).Raw(countQuery, params...).Scan(&total).Error + if err != nil { + return nil, 0, err + } + + // Add limit and offset for the data query + dataParams := append(params, search.Limit, search.Offset) + + // Primary query for sites matching name and region, with pagination + dataQuery := ` + SELECT s.id AS site_id, s.name AS site_name, s.region, s.regency, s.partner_id, s.image, s.address, s.location_link, s.description, + s.highlight, s.contact_person, s.tnc, s.additional_info, s.status, s.is_season_ticket, s.is_discount_active, + s.latitude, s.longitude, s.created_at, s.updated_at, + p.id AS product_id, p.name AS product_name, p.type AS product_type, p.price AS product_price, + p.is_weekend_ticket, p.is_season_ticket, p.status AS product_status, p.description AS product_description + FROM sites s + LEFT JOIN ( + SELECT *, ROW_NUMBER() OVER (PARTITION BY site_id ORDER BY price ASC) AS rn + FROM products + ) p ON s.id = p.site_id AND p.rn = 1 + WHERE ` + conditions + ` + ORDER BY s.name + LIMIT ? OFFSET ? + ` + err = r.db.WithContext(ctx).Raw(dataQuery, dataParams...).Scan(&siteProducts).Error + if err != nil { + return nil, 0, err + } + + return siteProducts, total, nil +} diff --git a/internal/routes/customer_routes.go b/internal/routes/customer_routes.go new file mode 100644 index 0000000..e9d35cf --- /dev/null +++ b/internal/routes/customer_routes.go @@ -0,0 +1,25 @@ +package routes + +import ( + "furtuna-be/internal/handlers/http/discovery" + "furtuna-be/internal/middlewares" + + "furtuna-be/internal/app" + "furtuna-be/internal/repository" + "furtuna-be/internal/services" +) + +func RegisterCustomerRoutes(app *app.Server, serviceManager *services.ServiceManagerImpl, + repoManager *repository.RepoManagerImpl) { + approute := app.Group("/api/v1/customer") + + authMiddleware := middlewares.AuthorizationMiddleware(repoManager.Crypto) + + serverRoutes := []HTTPHandlerRoutes{ + discovery.NewHandler(serviceManager.DiscoverService), + } + + for _, handler := range serverRoutes { + handler.Route(approute, authMiddleware) + } +} diff --git a/internal/services/discovery/discovery.go b/internal/services/discovery/discovery.go new file mode 100644 index 0000000..755b0c1 --- /dev/null +++ b/internal/services/discovery/discovery.go @@ -0,0 +1,121 @@ +package discovery + +import ( + "context" + "furtuna-be/config" + + "furtuna-be/internal/entity" + "furtuna-be/internal/repository" +) + +const ( + defaultLatitude = -6.2088 + defaultLongitude = 106.8456 + radius = 10000 +) + +type DiscoveryService struct { + repo repository.SiteRepository + cfg config.Discovery +} + +func NewDiscoveryService(repo repository.SiteRepository, cfg config.Discovery) *DiscoveryService { + return &DiscoveryService{ + repo: repo, + cfg: cfg, + } +} + +func (s *DiscoveryService) Home(ctx context.Context, search *entity.DiscoverySearch) (*entity.DiscoverySearchResp, error) { + if search.Lat == 0 || search.Long == 0 { + search.Lat = defaultLatitude + search.Long = defaultLongitude + } + + siteProducts, err := s.repo.GetNearestSites(ctx, search.Lat, search.Long, radius) + if err != nil { + return nil, err + } + exploreDestinations := []entity.ExploreDestination{} + for _, exploreDestination := range s.cfg.ExploreDestinations { + exploreDestinations = append(exploreDestinations, entity.ExploreDestination{ + Name: exploreDestination.Name, + ImageURL: exploreDestination.ImageURL, + }) + } + + exploreRegions := []entity.ExploreRegion{} + for _, exploreRegion := range s.cfg.ExploreRegions { + exploreRegions = append(exploreRegions, entity.ExploreRegion{ + Name: exploreRegion.Name, + }) + } + + mustVisits := []entity.MustVisit{} + + for _, siteProduct := range siteProducts { + mustVisits = append(mustVisits, entity.MustVisit{ + Name: siteProduct.SiteName, + Price: siteProduct.ProductPrice, + Region: siteProduct.Region, + SiteID: siteProduct.SiteID, + ImageURL: siteProduct.Image, + }) + } + + response := &entity.DiscoverySearchResp{ + ExploreRegions: exploreRegions, + ExploreDestinations: exploreDestinations, + MustVisit: mustVisits, + } + + return response, nil +} + +func (s *DiscoveryService) Search(ctx context.Context, search *entity.DiscoverySearch) (*entity.DiscoverySearchResp, int64, error) { + if search.Lat == 0 || search.Long == 0 { + search.Lat = defaultLatitude + search.Long = defaultLongitude + search.Radius = radius + } + + siteProducts, total, err := s.repo.SearchSites(ctx, search) + if err != nil { + return nil, 0, err + } + exploreDestinations := []entity.ExploreDestination{} + for _, exploreDestination := range s.cfg.ExploreDestinations { + exploreDestinations = append(exploreDestinations, entity.ExploreDestination{ + Name: exploreDestination.Name, + ImageURL: exploreDestination.ImageURL, + }) + } + + exploreRegions := []entity.ExploreRegion{} + for _, exploreRegion := range s.cfg.ExploreRegions { + exploreRegions = append(exploreRegions, entity.ExploreRegion{ + Name: exploreRegion.Name, + }) + } + + mustVisits := []entity.MustVisit{} + + for _, siteProduct := range siteProducts { + mustVisits = append(mustVisits, entity.MustVisit{ + Name: siteProduct.SiteName, + Price: siteProduct.ProductPrice, + Region: siteProduct.Region, + SiteID: siteProduct.SiteID, + ImageURL: siteProduct.Image, + Regency: siteProduct.Regency, + }) + } + + response := &entity.DiscoverySearchResp{ + ExploreRegions: exploreRegions, + ExploreDestinations: exploreDestinations, + MustVisit: mustVisits, + } + + return response, total, nil +} diff --git a/internal/services/service.go b/internal/services/service.go index dea4fff..cde2232 100644 --- a/internal/services/service.go +++ b/internal/services/service.go @@ -5,6 +5,7 @@ import ( "furtuna-be/internal/common/mycontext" "furtuna-be/internal/services/balance" "furtuna-be/internal/services/branch" + "furtuna-be/internal/services/discovery" service "furtuna-be/internal/services/license" "furtuna-be/internal/services/order" "furtuna-be/internal/services/oss" @@ -25,19 +26,20 @@ import ( ) type ServiceManagerImpl struct { - AuthSvc Auth - EventSvc Event - UserSvc User - BranchSvc Branch - StudioSvc Studio - ProductSvc Product - OrderSvc Order - OSSSvc OSSService - PartnerSvc Partner - SiteSvc Site - LicenseSvc License - Transaction Transaction - Balance Balance + AuthSvc Auth + EventSvc Event + UserSvc User + BranchSvc Branch + StudioSvc Studio + ProductSvc Product + OrderSvc Order + OSSSvc OSSService + PartnerSvc Partner + SiteSvc Site + LicenseSvc License + Transaction Transaction + Balance Balance + DiscoverService DiscoverService } func NewServiceManagerImpl(cfg *config.Config, repo *repository.RepoManagerImpl) *ServiceManagerImpl { @@ -52,10 +54,11 @@ func NewServiceManagerImpl(cfg *config.Config, repo *repository.RepoManagerImpl) OSSSvc: oss.NewOSSService(repo.OSS), PartnerSvc: partner.NewPartnerService( repo.Partner, users.NewUserService(repo.User, repo.Branch), repo.Trx, repo.Wallet), - SiteSvc: site.NewSiteService(repo.Site), - LicenseSvc: service.NewLicenseService(repo.License), - Transaction: transaction.New(repo.Transaction, repo.Wallet, repo.Trx), - Balance: balance.NewBalanceService(repo.Wallet, repo.Trx, repo.Crypto, &cfg.Withdraw, repo.Transaction), + SiteSvc: site.NewSiteService(repo.Site), + LicenseSvc: service.NewLicenseService(repo.License), + Transaction: transaction.New(repo.Transaction, repo.Wallet, repo.Trx), + Balance: balance.NewBalanceService(repo.Wallet, repo.Trx, repo.Crypto, &cfg.Withdraw, repo.Transaction), + DiscoverService: discovery.NewDiscoveryService(repo.Site, cfg.Discovery), } } @@ -156,3 +159,8 @@ type Balance interface { WithdrawInquiry(ctx context.Context, req *entity.BalanceWithdrawInquiry) (*entity.BalanceWithdrawInquiryResponse, error) WithdrawExecute(ctx mycontext.Context, req *entity.WalletWithdrawRequest) (*entity.WalletWithdrawResponse, error) } + +type DiscoverService interface { + Home(ctx context.Context, search *entity.DiscoverySearch) (*entity.DiscoverySearchResp, error) + Search(ctx context.Context, search *entity.DiscoverySearch) (*entity.DiscoverySearchResp, int64, error) +} diff --git a/main.go b/main.go index 0a835d7..22cd59a 100644 --- a/main.go +++ b/main.go @@ -32,6 +32,7 @@ func main() { routes.RegisterPublicRoutes(server, service, repo) routes.RegisterPrivateRoutes(server, service, repo) + routes.RegisterCustomerRoutes(server, service, repo) server.StartScheduler()