diff --git a/internal/handler/address_handler.go b/internal/handler/address_handler.go index 7dad668..dc0cc8b 100644 --- a/internal/handler/address_handler.go +++ b/internal/handler/address_handler.go @@ -33,3 +33,25 @@ func (h *AddressHandler) CreateAddress(c *fiber.Ctx) error { return utils.CreateResponse(c, addressResponse, "user address created successfully") } + +func (h *AddressHandler) GetAddressByUserID(c *fiber.Ctx) error { + userID := c.Locals("userID").(string) + + addresses, err := h.AddressService.GetAddressByUserID(userID) + if err != nil { + return utils.GenericErrorResponse(c, fiber.StatusNotFound, err.Error()) + } + + return utils.SuccessResponse(c, addresses, "User addresses fetched successfully") +} + +func (h *AddressHandler) GetAddressByID(c *fiber.Ctx) error { + addressID := c.Params("address_id") + + address, err := h.AddressService.GetAddressByID(addressID) + if err != nil { + return utils.GenericErrorResponse(c, fiber.StatusNotFound, err.Error()) + } + + return utils.SuccessResponse(c, address, "Address fetched successfully") +} diff --git a/internal/repositories/address_repo.go b/internal/repositories/address_repo.go index 74a1e5c..cac0fd3 100644 --- a/internal/repositories/address_repo.go +++ b/internal/repositories/address_repo.go @@ -7,6 +7,8 @@ import ( type AddressRepository interface { CreateAddress(address *model.Address) error + FindAddressByUserID(userID string) ([]model.Address, error) + FindAddressByID(id string) (*model.Address, error) } type addressRepository struct { @@ -20,3 +22,22 @@ func NewAddressRepository(db *gorm.DB) AddressRepository { func (r *addressRepository) CreateAddress(address *model.Address) error { return r.DB.Create(address).Error } + + +func (r *addressRepository) FindAddressByUserID(userID string) ([]model.Address, error) { + var addresses []model.Address + err := r.DB.Where("user_id = ?", userID).Find(&addresses).Error + if err != nil { + return nil, err + } + return addresses, nil +} + +func (r *addressRepository) FindAddressByID(id string) (*model.Address, error) { + var address model.Address + err := r.DB.Where("id = ?", id).First(&address).Error + if err != nil { + return nil, err + } + return &address, nil +} \ No newline at end of file diff --git a/internal/services/address_service.go b/internal/services/address_service.go index 1ece7be..cd6088a 100644 --- a/internal/services/address_service.go +++ b/internal/services/address_service.go @@ -2,6 +2,7 @@ package services import ( "fmt" + "time" "github.com/pahmiudahgede/senggoldong/dto" "github.com/pahmiudahgede/senggoldong/internal/repositories" @@ -11,6 +12,8 @@ import ( type AddressService interface { CreateAddress(userID string, request dto.CreateAddressDTO) (*dto.AddressResponseDTO, error) + GetAddressByUserID(userID string) ([]dto.AddressResponseDTO, error) + GetAddressByID(id string) (*dto.AddressResponseDTO, error) } type addressService struct { @@ -86,3 +89,125 @@ func (s *addressService) CreateAddress(userID string, request dto.CreateAddressD return addressResponse, nil } + +func (s *addressService) GetAddressByUserID(userID string) ([]dto.AddressResponseDTO, error) { + + cacheKey := fmt.Sprintf("user:%s:addresses", userID) + cachedData, err := utils.GetJSONData(cacheKey) + if err == nil && cachedData != nil { + var addresses []dto.AddressResponseDTO + if data, ok := cachedData["data"].([]interface{}); ok { + for _, item := range data { + addressData, ok := item.(map[string]interface{}) + if ok { + addresses = append(addresses, dto.AddressResponseDTO{ + UserID: addressData["user_id"].(string), + ID: addressData["address_id"].(string), + Province: addressData["province"].(string), + Regency: addressData["regency"].(string), + District: addressData["district"].(string), + Village: addressData["village"].(string), + PostalCode: addressData["postalCode"].(string), + Detail: addressData["detail"].(string), + Geography: addressData["geography"].(string), + CreatedAt: addressData["createdAt"].(string), + UpdatedAt: addressData["updatedAt"].(string), + }) + } + } + return addresses, nil + } + } + + addresses, err := s.AddressRepo.FindAddressByUserID(userID) + if err != nil { + return nil, fmt.Errorf("failed to fetch addresses: %v", err) + } + + var addressDTOs []dto.AddressResponseDTO + for _, address := range addresses { + createdAt, _ := utils.FormatDateToIndonesianFormat(address.CreatedAt) + updatedAt, _ := utils.FormatDateToIndonesianFormat(address.UpdatedAt) + + addressDTOs = append(addressDTOs, dto.AddressResponseDTO{ + UserID: address.UserID, + ID: address.ID, + Province: address.Province, + Regency: address.Regency, + District: address.District, + Village: address.Village, + PostalCode: address.PostalCode, + Detail: address.Detail, + Geography: address.Geography, + CreatedAt: createdAt, + UpdatedAt: updatedAt, + }) + } + + cacheData := map[string]interface{}{ + "data": addressDTOs, + } + err = utils.SetJSONData(cacheKey, cacheData, time.Hour*24) + if err != nil { + fmt.Printf("Error caching addresses to Redis: %v\n", err) + } + + return addressDTOs, nil +} + +func (s *addressService) GetAddressByID(id string) (*dto.AddressResponseDTO, error) { + + cacheKey := fmt.Sprintf("address:%s", id) + cachedData, err := utils.GetJSONData(cacheKey) + if err == nil && cachedData != nil { + addressData, ok := cachedData["data"].(map[string]interface{}) + if ok { + address := dto.AddressResponseDTO{ + UserID: addressData["user_id"].(string), + ID: addressData["address_id"].(string), + Province: addressData["province"].(string), + Regency: addressData["regency"].(string), + District: addressData["district"].(string), + Village: addressData["village"].(string), + PostalCode: addressData["postalCode"].(string), + Detail: addressData["detail"].(string), + Geography: addressData["geography"].(string), + CreatedAt: addressData["createdAt"].(string), + UpdatedAt: addressData["updatedAt"].(string), + } + return &address, nil + } + } + + address, err := s.AddressRepo.FindAddressByID(id) + if err != nil { + return nil, fmt.Errorf("failed to fetch address: %v", err) + } + + createdAt, _ := utils.FormatDateToIndonesianFormat(address.CreatedAt) + updatedAt, _ := utils.FormatDateToIndonesianFormat(address.UpdatedAt) + + addressDTO := &dto.AddressResponseDTO{ + UserID: address.UserID, + ID: address.ID, + Province: address.Province, + Regency: address.Regency, + District: address.District, + Village: address.Village, + PostalCode: address.PostalCode, + Detail: address.Detail, + Geography: address.Geography, + CreatedAt: createdAt, + UpdatedAt: updatedAt, + } + + cacheData := map[string]interface{}{ + "data": addressDTO, + } + err = utils.SetJSONData(cacheKey, cacheData, time.Hour*24) + if err != nil { + fmt.Printf("Error caching address to Redis: %v\n", err) + } + + return addressDTO, nil +} diff --git a/presentation/address_route.go b/presentation/address_route.go index 7f06767..500d83e 100644 --- a/presentation/address_route.go +++ b/presentation/address_route.go @@ -18,4 +18,6 @@ func AddressRouter(api fiber.Router) { adddressAPI := api.Group("/user/address") adddressAPI.Post("/create-address", middleware.AuthMiddleware, addressHandler.CreateAddress) + adddressAPI.Get("/get-address", middleware.AuthMiddleware, addressHandler.GetAddressByUserID) + adddressAPI.Get("/get-address/:address_id", middleware.AuthMiddleware, addressHandler.GetAddressByID) }