feat: implement logger #74
3
.env
3
.env
@@ -64,3 +64,6 @@ IMAGE_PREFIX=https://www.naluconcept.com # remove prefix to serv them from same
|
||||
CORS_ORGIN=https://www.naluconcept.com
|
||||
|
||||
DSN=root:Maal12345678@tcp(localhost:3306)/nalu
|
||||
|
||||
LOG_LEVEL=warn
|
||||
LOG_COLORIZE=true
|
||||
@@ -4,8 +4,11 @@ import (
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"git.ma-al.com/goc_daniel/b2b/app/config"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/delivery/web"
|
||||
|
||||
"git.ma-al.com/goc_daniel/b2b/app/service/langsService"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/logger"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/version"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
@@ -21,6 +24,8 @@ var (
|
||||
return
|
||||
}
|
||||
|
||||
logger.Init("b2b", nil, config.Get().Log.LogLevel, config.Get().Log.LogColorize)
|
||||
|
||||
// Create and setup the server
|
||||
server := web.New()
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ type Config struct {
|
||||
Cors CorsConfig
|
||||
MeiliSearch MeiliSearchConfig
|
||||
Storage StorageConfig
|
||||
Log LogConfig
|
||||
}
|
||||
|
||||
type I18n struct {
|
||||
@@ -87,6 +88,11 @@ type AppConfig struct {
|
||||
BaseURL string `env:"APP_BASE_URL,http://localhost:5173"`
|
||||
}
|
||||
|
||||
type LogConfig struct {
|
||||
LogLevel string `env:"LOG_LEVEL,warn"`
|
||||
LogColorize bool `env:"LOG_COLORIZE,true"`
|
||||
}
|
||||
|
||||
type EmailConfig struct {
|
||||
SMTPHost string `env:"EMAIL_SMTP_HOST,localhost"`
|
||||
SMTPPort int `env:"EMAIL_SMTP_PORT,587"`
|
||||
@@ -209,6 +215,11 @@ func load() *Config {
|
||||
if err != nil {
|
||||
slog.Error("not possible to load env variables for storage : ", err.Error(), "")
|
||||
}
|
||||
|
||||
err = loadEnv(&cfg.Log)
|
||||
if err != nil {
|
||||
slog.Error("not possible to load env variables for logger : ", err.Error(), "")
|
||||
}
|
||||
cfg.Storage.RootFolder = ResolveRelativePath(cfg.Storage.RootFolder)
|
||||
|
||||
return cfg
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package public
|
||||
|
||||
import (
|
||||
"log"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
@@ -11,6 +10,7 @@ import (
|
||||
"git.ma-al.com/goc_daniel/b2b/app/service/authService"
|
||||
constdata "git.ma-al.com/goc_daniel/b2b/app/utils/const_data"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/i18n"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/logger"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/nullable"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/response"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors"
|
||||
@@ -178,7 +178,13 @@ func (h *AuthHandler) ForgotPassword(c fiber.Ctx) error {
|
||||
// Request password reset - always return success to prevent email enumeration
|
||||
err := h.authService.RequestPasswordReset(req.Email)
|
||||
if err != nil {
|
||||
log.Printf("Password reset request error: %v", err)
|
||||
|
||||
logger.Warn("password reset request failed",
|
||||
"handler", "AuthHandler.ForgotPassword",
|
||||
|
||||
"email", req.Email,
|
||||
"error", err.Error(),
|
||||
)
|
||||
}
|
||||
|
||||
return c.JSON(fiber.Map{
|
||||
@@ -307,7 +313,6 @@ func (h *AuthHandler) Register(c fiber.Ctx) error {
|
||||
// Attempt registration
|
||||
err := h.authService.Register(&req)
|
||||
if err != nil {
|
||||
log.Printf("Register error: %v", err)
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).JSON(fiber.Map{
|
||||
"error": responseErrors.GetErrorCode(c, err),
|
||||
})
|
||||
@@ -447,7 +452,6 @@ func (h *AuthHandler) GoogleCallback(c fiber.Ctx) error {
|
||||
|
||||
response, rawRefreshToken, err := h.authService.HandleGoogleCallback(code)
|
||||
if err != nil {
|
||||
log.Printf("Google OAuth callback error: %v", err)
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).JSON(fiber.Map{
|
||||
"error": responseErrors.GetErrorCode(c, err),
|
||||
})
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"git.ma-al.com/goc_daniel/b2b/app/service/addressesService"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/i18n"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/localeExtractor"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/logger"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/nullable"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/response"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors"
|
||||
@@ -45,6 +46,13 @@ func (h *AddressesHandler) GetTemplate(c fiber.Ctx) error {
|
||||
|
||||
template, err := h.addressesService.GetTemplate(uint(country_id))
|
||||
if err != nil {
|
||||
|
||||
logger.Error("failed to get address template",
|
||||
"handler", "AddressesHandler.GetTemplate",
|
||||
|
||||
"country_id", country_id,
|
||||
"error", err.Error(),
|
||||
)
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
@@ -74,6 +82,13 @@ func (h *AddressesHandler) AddNewAddress(c fiber.Ctx) error {
|
||||
|
||||
err = h.addressesService.AddNewAddress(userID, address_info, uint(country_id))
|
||||
if err != nil {
|
||||
|
||||
logger.Error("failed to add new address",
|
||||
"handler", "AddressesHandler.AddNewAddress",
|
||||
|
||||
"user_id", userID,
|
||||
"error", err.Error(),
|
||||
)
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
@@ -110,6 +125,14 @@ func (h *AddressesHandler) ModifyAddress(c fiber.Ctx) error {
|
||||
|
||||
err = h.addressesService.ModifyAddress(userID, uint(address_id), address_info, uint(country_id))
|
||||
if err != nil {
|
||||
|
||||
logger.Error("failed to modify address",
|
||||
"handler", "AddressesHandler.ModifyAddress",
|
||||
|
||||
"user_id", userID,
|
||||
"address_id", address_id,
|
||||
"error", err.Error(),
|
||||
)
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
@@ -126,6 +149,13 @@ func (h *AddressesHandler) RetrieveAddressesInfo(c fiber.Ctx) error {
|
||||
|
||||
addresses, err := h.addressesService.RetrieveAddresses(userID)
|
||||
if err != nil {
|
||||
|
||||
logger.Error("failed to retrieve addresses",
|
||||
"handler", "AddressesHandler.RetrieveAddressesInfo",
|
||||
|
||||
"user_id", userID,
|
||||
"error", err.Error(),
|
||||
)
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
@@ -149,6 +179,14 @@ func (h *AddressesHandler) DeleteAddress(c fiber.Ctx) error {
|
||||
|
||||
err = h.addressesService.DeleteAddress(userID, uint(address_id))
|
||||
if err != nil {
|
||||
|
||||
logger.Error("failed to delete address",
|
||||
"handler", "AddressesHandler.DeleteAddress",
|
||||
|
||||
"user_id", userID,
|
||||
"address_id", address_id,
|
||||
"error", err.Error(),
|
||||
)
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"git.ma-al.com/goc_daniel/b2b/app/service/cartsService"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/i18n"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/localeExtractor"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/logger"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/nullable"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/response"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors"
|
||||
@@ -49,6 +50,13 @@ func (h *CartsHandler) AddNewCart(c fiber.Ctx) error {
|
||||
name := c.Query("name")
|
||||
new_cart, err := h.cartsService.CreateNewCart(userID, name)
|
||||
if err != nil {
|
||||
|
||||
logger.Error("failed to create cart",
|
||||
"handler", "CartsHandler.AddNewCart",
|
||||
|
||||
"user_id", userID,
|
||||
"error", err.Error(),
|
||||
)
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
@@ -72,6 +80,14 @@ func (h *CartsHandler) RemoveCart(c fiber.Ctx) error {
|
||||
|
||||
err = h.cartsService.RemoveCart(userID, uint(cart_id))
|
||||
if err != nil {
|
||||
|
||||
logger.Error("failed to remove cart",
|
||||
"handler", "CartsHandler.RemoveCart",
|
||||
|
||||
"user_id", userID,
|
||||
"cart_id", cart_id,
|
||||
"error", err.Error(),
|
||||
)
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
@@ -97,6 +113,14 @@ func (h *CartsHandler) ChangeCartName(c fiber.Ctx) error {
|
||||
|
||||
err = h.cartsService.UpdateCartName(userID, uint(cart_id), new_name)
|
||||
if err != nil {
|
||||
|
||||
logger.Error("failed to update cart name",
|
||||
"handler", "CartsHandler.ChangeCartName",
|
||||
|
||||
"user_id", userID,
|
||||
"cart_id", cart_id,
|
||||
"error", err.Error(),
|
||||
)
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
@@ -113,6 +137,13 @@ func (h *CartsHandler) RetrieveCartsInfo(c fiber.Ctx) error {
|
||||
|
||||
carts_info, err := h.cartsService.RetrieveCartsInfo(userID)
|
||||
if err != nil {
|
||||
|
||||
logger.Error("failed to retrieve carts info",
|
||||
"handler", "CartsHandler.RetrieveCartsInfo",
|
||||
|
||||
"user_id", userID,
|
||||
"error", err.Error(),
|
||||
)
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
@@ -136,6 +167,14 @@ func (h *CartsHandler) RetrieveCart(c fiber.Ctx) error {
|
||||
|
||||
cart, err := h.cartsService.RetrieveCart(userID, uint(cart_id))
|
||||
if err != nil {
|
||||
|
||||
logger.Error("failed to retrieve cart",
|
||||
"handler", "CartsHandler.RetrieveCart",
|
||||
|
||||
"user_id", userID,
|
||||
"cart_id", cart_id,
|
||||
"error", err.Error(),
|
||||
)
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
@@ -195,6 +234,15 @@ func (h *CartsHandler) AddProduct(c fiber.Ctx) error {
|
||||
|
||||
err = h.cartsService.AddProduct(userID, uint(cart_id), uint(product_id), product_attribute_id, amount, set_amount)
|
||||
if err != nil {
|
||||
|
||||
logger.Error("failed to add product to cart",
|
||||
"handler", "CartsHandler.AddProduct",
|
||||
|
||||
"user_id", userID,
|
||||
"cart_id", cart_id,
|
||||
"product_id", product_id,
|
||||
"error", err.Error(),
|
||||
)
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
@@ -240,6 +288,15 @@ func (h *CartsHandler) RemoveProduct(c fiber.Ctx) error {
|
||||
|
||||
err = h.cartsService.RemoveProduct(userID, uint(cart_id), uint(product_id), product_attribute_id)
|
||||
if err != nil {
|
||||
|
||||
logger.Error("failed to remove product from cart",
|
||||
"handler", "CartsHandler.RemoveProduct",
|
||||
|
||||
"user_id", userID,
|
||||
"cart_id", cart_id,
|
||||
"product_id", product_id,
|
||||
"error", err.Error(),
|
||||
)
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"git.ma-al.com/goc_daniel/b2b/app/model"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/service/currencyService"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/i18n"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/logger"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/nullable"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/response"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors"
|
||||
@@ -46,6 +47,12 @@ func (h *CurrencyHandler) PostCurrencyRate(c fiber.Ctx) error {
|
||||
|
||||
err := h.CurrencyService.CreateCurrencyRate(¤cyRate)
|
||||
if err != nil {
|
||||
|
||||
logger.Error("failed to create currency rate",
|
||||
"handler", "CurrencyHandler.PostCurrencyRate",
|
||||
|
||||
"error", err.Error(),
|
||||
)
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
@@ -63,6 +70,13 @@ func (h *CurrencyHandler) GetCurrencyRate(c fiber.Ctx) error {
|
||||
|
||||
currency, err := h.CurrencyService.GetCurrency(uint(id))
|
||||
if err != nil {
|
||||
|
||||
logger.Error("failed to get currency",
|
||||
"handler", "CurrencyHandler.GetCurrencyRate",
|
||||
|
||||
"currency_id", id,
|
||||
"error", err.Error(),
|
||||
)
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"git.ma-al.com/goc_daniel/b2b/app/service/customerService"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/i18n"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/localeExtractor"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/logger"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/nullable"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/query/query_params"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/response"
|
||||
@@ -64,6 +65,13 @@ func (h *customerHandler) customerData(fc fiber.Ctx) error {
|
||||
|
||||
customer, err := h.service.GetById(customerId)
|
||||
if err != nil {
|
||||
|
||||
logger.Error("failed to get customer",
|
||||
"handler", "customerHandler.customerData",
|
||||
|
||||
"customer_id", customerId,
|
||||
"error", err.Error(),
|
||||
)
|
||||
return fc.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(fc, err)))
|
||||
}
|
||||
@@ -88,6 +96,12 @@ func (h *customerHandler) listCustomers(fc fiber.Ctx) error {
|
||||
|
||||
customer, err := h.service.Find(user.LangID, p, filt, search)
|
||||
if err != nil {
|
||||
|
||||
logger.Error("failed to list customers",
|
||||
"handler", "customerHandler.listCustomers",
|
||||
|
||||
"error", err.Error(),
|
||||
)
|
||||
return fc.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(fc, err)))
|
||||
}
|
||||
@@ -120,6 +134,13 @@ func (h *customerHandler) setCustomerNoVatStatus(fc fiber.Ctx) error {
|
||||
}
|
||||
|
||||
if err := h.service.SetCustomerNoVatStatus(req.CustomerID, req.IsNoVat); err != nil {
|
||||
|
||||
logger.Error("failed to set customer no vat status",
|
||||
"handler", "customerHandler.setCustomerNoVatStatus",
|
||||
|
||||
"customer_id", req.CustomerID,
|
||||
"error", err.Error(),
|
||||
)
|
||||
return fc.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(fc, err)))
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package restricted
|
||||
import (
|
||||
"git.ma-al.com/goc_daniel/b2b/app/service/localeSelectorService"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/i18n"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/logger"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/nullable"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/response"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors"
|
||||
@@ -34,6 +35,12 @@ func LocaleSelectorHandlerRoutes(r fiber.Router) fiber.Router {
|
||||
func (h *LocaleSelectorHandler) GetLanguages(c fiber.Ctx) error {
|
||||
languages, err := h.localeSelectorService.GetLanguages()
|
||||
if err != nil {
|
||||
|
||||
logger.Error("failed to get languages",
|
||||
"handler", "LocaleSelectorHandler.GetLanguages",
|
||||
|
||||
"error", err.Error(),
|
||||
)
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
@@ -44,6 +51,12 @@ func (h *LocaleSelectorHandler) GetLanguages(c fiber.Ctx) error {
|
||||
func (h *LocaleSelectorHandler) GetCountries(c fiber.Ctx) error {
|
||||
countries, err := h.localeSelectorService.GetCountriesAndCurrencies()
|
||||
if err != nil {
|
||||
|
||||
logger.Error("failed to get countries",
|
||||
"handler", "LocaleSelectorHandler.GetCountries",
|
||||
|
||||
"error", err.Error(),
|
||||
)
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"git.ma-al.com/goc_daniel/b2b/app/service/menuService"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/i18n"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/localeExtractor"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/logger"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/nullable"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/response"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors"
|
||||
@@ -49,6 +50,12 @@ func (h *MenuHandler) GetCategoryTree(c fiber.Ctx) error {
|
||||
|
||||
category_tree, err := h.menuService.GetCategoryTree(uint(root_category_id), lang_id)
|
||||
if err != nil {
|
||||
|
||||
logger.Error("failed to get category tree",
|
||||
"handler", "MenuHandler.GetCategoryTree",
|
||||
|
||||
"error", err.Error(),
|
||||
)
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
@@ -79,6 +86,12 @@ func (h *MenuHandler) GetBreadcrumb(c fiber.Ctx) error {
|
||||
|
||||
breadcrumb, err := h.menuService.GetBreadcrumb(uint(root_category_id), uint(category_id), lang_id)
|
||||
if err != nil {
|
||||
|
||||
logger.Error("failed to get breadcrumb",
|
||||
"handler", "MenuHandler.GetBreadcrumb",
|
||||
|
||||
"error", err.Error(),
|
||||
)
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
@@ -94,6 +107,12 @@ func (h *MenuHandler) GetTopMenu(c fiber.Ctx) error {
|
||||
}
|
||||
menu, err := h.menuService.GetTopMenu(customer.LangID, customer.RoleID)
|
||||
if err != nil {
|
||||
|
||||
logger.Error("failed to get top menu",
|
||||
"handler", "MenuHandler.GetTopMenu",
|
||||
|
||||
"error", err.Error(),
|
||||
)
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"git.ma-al.com/goc_daniel/b2b/app/service/orderService"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/i18n"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/localeExtractor"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/logger"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/nullable"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/query/query_params"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/response"
|
||||
@@ -53,6 +54,12 @@ func (h *OrdersHandler) ListOrders(c fiber.Ctx) error {
|
||||
|
||||
list, err := h.ordersService.Find(user, paging, filters)
|
||||
if err != nil {
|
||||
|
||||
logger.Error("failed to list orders",
|
||||
"handler", "OrdersHandler.ListOrders",
|
||||
|
||||
"error", err.Error(),
|
||||
)
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
@@ -99,6 +106,13 @@ func (h *OrdersHandler) PlaceNewOrder(c fiber.Ctx) error {
|
||||
|
||||
err = h.ordersService.PlaceNewOrder(userID, uint(cart_id), name, uint(country_id), address_info)
|
||||
if err != nil {
|
||||
|
||||
logger.Error("failed to place order",
|
||||
"handler", "OrdersHandler.PlaceNewOrder",
|
||||
|
||||
"user_id", userID,
|
||||
"error", err.Error(),
|
||||
)
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
@@ -136,6 +150,13 @@ func (h *OrdersHandler) ChangeOrderAddress(c fiber.Ctx) error {
|
||||
|
||||
err = h.ordersService.ChangeOrderAddress(user, uint(order_id), uint(country_id), address_info)
|
||||
if err != nil {
|
||||
|
||||
logger.Error("failed to change order address",
|
||||
"handler", "OrdersHandler.ChangeOrderAddress",
|
||||
|
||||
"order_id", order_id,
|
||||
"error", err.Error(),
|
||||
)
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
@@ -163,6 +184,13 @@ func (h *OrdersHandler) ChangeOrderStatus(c fiber.Ctx) error {
|
||||
|
||||
err = h.ordersService.ChangeOrderStatus(user, uint(order_id), status)
|
||||
if err != nil {
|
||||
|
||||
logger.Error("failed to change order status",
|
||||
"handler", "OrdersHandler.ChangeOrderStatus",
|
||||
|
||||
"order_id", order_id,
|
||||
"error", err.Error(),
|
||||
)
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
constdata "git.ma-al.com/goc_daniel/b2b/app/utils/const_data"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/i18n"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/localeExtractor"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/logger"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/nullable"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/query/query_params"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/response"
|
||||
@@ -74,6 +75,15 @@ func (h *ProductsHandler) GetProductJson(c fiber.Ctx) error {
|
||||
}
|
||||
productJson, err := h.productService.Get(uint(p_id_product), customer.LangID, customer.ID, uint(b2b_id_country), uint(p_quantity))
|
||||
if err != nil {
|
||||
logger.Error("failed to get product",
|
||||
"handler", "ProductsHandler.GetProductJson",
|
||||
"product_id", p_id_product,
|
||||
"lang_id", customer.LangID,
|
||||
"customer_id", customer.ID,
|
||||
"b2b_id_country", b2b_id_country,
|
||||
"quantity", p_quantity,
|
||||
"error", err.Error(),
|
||||
)
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
@@ -96,6 +106,13 @@ func (h *ProductsHandler) ListProducts(c fiber.Ctx) error {
|
||||
|
||||
list, err := h.productService.Find(customer.LangID, customer.ID, paging, filters, customer, constdata.DEFAULT_PRODUCT_QUANTITY, constdata.SHOP_ID)
|
||||
if err != nil {
|
||||
|
||||
logger.Error("failed to list products",
|
||||
"handler", "ProductsHandler.ListProducts",
|
||||
"lang_id", customer.LangID,
|
||||
"customer_id", customer.ID,
|
||||
"error", err.Error(),
|
||||
)
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
@@ -132,6 +149,13 @@ func (h *ProductsHandler) AddToFavorites(c fiber.Ctx) error {
|
||||
|
||||
err = h.productService.AddToFavorites(userID, uint(productID))
|
||||
if err != nil {
|
||||
|
||||
logger.Error("failed to add to favorites",
|
||||
"handler", "ProductsHandler.AddToFavorites",
|
||||
"user_id", userID,
|
||||
"product_id", productID,
|
||||
"error", err.Error(),
|
||||
)
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
@@ -156,6 +180,12 @@ func (h *ProductsHandler) RemoveFromFavorites(c fiber.Ctx) error {
|
||||
|
||||
err = h.productService.RemoveFromFavorites(userID, uint(productID))
|
||||
if err != nil {
|
||||
logger.Error("failed to remove from favorites",
|
||||
"handler", "ProductsHandler.RemoveFromFavorites",
|
||||
"user_id", userID,
|
||||
"product_id", productID,
|
||||
"error", err.Error(),
|
||||
)
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
@@ -180,6 +210,15 @@ func (h *ProductsHandler) ListProductVariants(c fiber.Ctx) error {
|
||||
|
||||
list, err := h.productService.GetProductAttributes(customer.LangID, uint(productID), constdata.SHOP_ID, customer.ID, customer.CountryID, constdata.DEFAULT_PRODUCT_QUANTITY)
|
||||
if err != nil {
|
||||
|
||||
logger.Error("failed to list product variants",
|
||||
"handler", "ProductsHandler.ListProductVariants",
|
||||
"product_id", productID,
|
||||
"customer_id", customer.ID,
|
||||
"lang_id", customer.LangID,
|
||||
"country_id", customer.CountryID,
|
||||
"error", err.Error(),
|
||||
)
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"git.ma-al.com/goc_daniel/b2b/app/service/productTranslationService"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/i18n"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/localeExtractor"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/logger"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/nullable"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/response"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors"
|
||||
@@ -66,6 +67,13 @@ func (h *ProductTranslationHandler) GetProductDescription(c fiber.Ctx) error {
|
||||
|
||||
description, err := h.productTranslationService.GetProductDescription(userID, uint(productID), uint(productLangID))
|
||||
if err != nil {
|
||||
|
||||
logger.Error("failed to get product description",
|
||||
"handler", "ProductTranslationHandler.GetProductDescription",
|
||||
|
||||
"product_id", productID,
|
||||
"error", err.Error(),
|
||||
)
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
@@ -103,6 +111,13 @@ func (h *ProductTranslationHandler) SaveProductDescription(c fiber.Ctx) error {
|
||||
|
||||
err = h.productTranslationService.SaveProductDescription(userID, uint(productID), uint(productLangID), updates)
|
||||
if err != nil {
|
||||
|
||||
logger.Error("failed to save product description",
|
||||
"handler", "ProductTranslationHandler.SaveProductDescription",
|
||||
|
||||
"product_id", productID,
|
||||
"error", err.Error(),
|
||||
)
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
@@ -147,6 +162,13 @@ func (h *ProductTranslationHandler) TranslateProductDescription(c fiber.Ctx) err
|
||||
|
||||
description, err := h.productTranslationService.TranslateProductDescription(userID, uint(productID), uint(productFromLangID), uint(productToLangID), aiModel)
|
||||
if err != nil {
|
||||
|
||||
logger.Error("failed to translate product description",
|
||||
"handler", "ProductTranslationHandler.TranslateProductDescription",
|
||||
|
||||
"product_id", productID,
|
||||
"error", err.Error(),
|
||||
)
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package restricted
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"git.ma-al.com/goc_daniel/b2b/app/delivery/middleware"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/delivery/middleware/perms"
|
||||
@@ -10,6 +9,7 @@ import (
|
||||
searchservice "git.ma-al.com/goc_daniel/b2b/app/service/searchService"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/i18n"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/localeExtractor"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/logger"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/nullable"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/response"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors"
|
||||
@@ -47,7 +47,13 @@ func (h *MeiliSearchHandler) CreateIndex(c fiber.Ctx) error {
|
||||
|
||||
err := h.meiliService.CreateIndex(id_lang)
|
||||
if err != nil {
|
||||
fmt.Printf("CreateIndex error: %v\n", err)
|
||||
|
||||
logger.Error("failed to create search index",
|
||||
"handler", "MeiliSearchHandler.CreateIndex",
|
||||
|
||||
"lang_id", id_lang,
|
||||
"error", err.Error(),
|
||||
)
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
@@ -72,6 +78,13 @@ func (h *MeiliSearchHandler) Search(c fiber.Ctx) error {
|
||||
|
||||
result, err := h.searchService.Search(index, c.Body(), id_lang)
|
||||
if err != nil {
|
||||
|
||||
logger.Error("failed to search",
|
||||
"handler", "MeiliSearchHandler.Search",
|
||||
|
||||
"index", index,
|
||||
"error", err.Error(),
|
||||
)
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
@@ -80,6 +93,13 @@ func (h *MeiliSearchHandler) Search(c fiber.Ctx) error {
|
||||
if createErr := h.meiliService.CreateIndex(id_lang); createErr == nil {
|
||||
result, err = h.searchService.Search(index, c.Body(), id_lang)
|
||||
if err != nil {
|
||||
|
||||
logger.Error("failed to search after index creation",
|
||||
"handler", "MeiliSearchHandler.Search",
|
||||
|
||||
"index", index,
|
||||
"error", err.Error(),
|
||||
)
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
@@ -100,6 +120,13 @@ func (h *MeiliSearchHandler) GetSettings(c fiber.Ctx) error {
|
||||
|
||||
result, err := h.searchService.GetIndexSettings(index)
|
||||
if err != nil {
|
||||
|
||||
logger.Error("failed to get index settings",
|
||||
"handler", "MeiliSearchHandler.GetSettings",
|
||||
|
||||
"index", index,
|
||||
"error", err.Error(),
|
||||
)
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"git.ma-al.com/goc_daniel/b2b/app/model"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/service/specificPriceService"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/i18n"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/logger"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/nullable"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/response"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors"
|
||||
@@ -51,6 +52,12 @@ func (h *SpecificPriceHandler) Create(c fiber.Ctx) error {
|
||||
|
||||
result, err := h.SpecificPriceService.Create(c.Context(), &pr)
|
||||
if err != nil {
|
||||
|
||||
logger.Error("failed to create specific price",
|
||||
"handler", "SpecificPriceHandler.Create",
|
||||
|
||||
"error", err.Error(),
|
||||
)
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
@@ -74,6 +81,13 @@ func (h *SpecificPriceHandler) Update(c fiber.Ctx) error {
|
||||
|
||||
result, err := h.SpecificPriceService.Update(c.Context(), id, &pr)
|
||||
if err != nil {
|
||||
|
||||
logger.Error("failed to update specific price",
|
||||
"handler", "SpecificPriceHandler.Update",
|
||||
|
||||
"specific_price_id", id,
|
||||
"error", err.Error(),
|
||||
)
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
@@ -84,6 +98,12 @@ func (h *SpecificPriceHandler) Update(c fiber.Ctx) error {
|
||||
func (h *SpecificPriceHandler) List(c fiber.Ctx) error {
|
||||
result, err := h.SpecificPriceService.List(c.Context())
|
||||
if err != nil {
|
||||
|
||||
logger.Error("failed to list specific prices",
|
||||
"handler", "SpecificPriceHandler.List",
|
||||
|
||||
"error", err.Error(),
|
||||
)
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
@@ -101,6 +121,13 @@ func (h *SpecificPriceHandler) GetByID(c fiber.Ctx) error {
|
||||
|
||||
result, err := h.SpecificPriceService.GetByID(c.Context(), id)
|
||||
if err != nil {
|
||||
|
||||
logger.Error("failed to get specific price",
|
||||
"handler", "SpecificPriceHandler.GetByID",
|
||||
|
||||
"specific_price_id", id,
|
||||
"error", err.Error(),
|
||||
)
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
@@ -118,6 +145,13 @@ func (h *SpecificPriceHandler) Activate(c fiber.Ctx) error {
|
||||
|
||||
err = h.SpecificPriceService.SetActive(c.Context(), id, true)
|
||||
if err != nil {
|
||||
|
||||
logger.Error("failed to activate specific price",
|
||||
"handler", "SpecificPriceHandler.Activate",
|
||||
|
||||
"specific_price_id", id,
|
||||
"error", err.Error(),
|
||||
)
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
@@ -135,6 +169,13 @@ func (h *SpecificPriceHandler) Deactivate(c fiber.Ctx) error {
|
||||
|
||||
err = h.SpecificPriceService.SetActive(c.Context(), id, false)
|
||||
if err != nil {
|
||||
|
||||
logger.Error("failed to deactivate specific price",
|
||||
"handler", "SpecificPriceHandler.Deactivate",
|
||||
|
||||
"specific_price_id", id,
|
||||
"error", err.Error(),
|
||||
)
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
@@ -152,6 +193,13 @@ func (h *SpecificPriceHandler) Delete(c fiber.Ctx) error {
|
||||
|
||||
err = h.SpecificPriceService.Delete(c.Context(), id)
|
||||
if err != nil {
|
||||
|
||||
logger.Error("failed to delete specific price",
|
||||
"handler", "SpecificPriceHandler.Delete",
|
||||
|
||||
"specific_price_id", id,
|
||||
"error", err.Error(),
|
||||
)
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"git.ma-al.com/goc_daniel/b2b/app/service/storageService"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/i18n"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/localeExtractor"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/logger"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/nullable"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/response"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors"
|
||||
@@ -52,6 +53,12 @@ func (h *StorageHandler) ListContent(c fiber.Ctx) error {
|
||||
entries_in_list, err := h.storageService.ListContent(abs_path)
|
||||
|
||||
if err != nil {
|
||||
|
||||
logger.Error("failed to list storage content",
|
||||
"handler", "StorageHandler.ListContent",
|
||||
"path", abs_path,
|
||||
"error", err.Error(),
|
||||
)
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
@@ -68,6 +75,12 @@ func (h *StorageHandler) DownloadFile(c fiber.Ctx) error {
|
||||
|
||||
f, filename, filesize, err := h.storageService.DownloadFilePrep(abs_path)
|
||||
if err != nil {
|
||||
|
||||
logger.Error("failed to prepare file download",
|
||||
"handler", "StorageHandler.DownloadFile",
|
||||
"path", abs_path,
|
||||
"error", err.Error(),
|
||||
)
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
@@ -87,6 +100,12 @@ func (h *StorageHandler) CreateNewWebdavToken(c fiber.Ctx) error {
|
||||
|
||||
new_token, err := h.storageService.NewWebdavToken(userID)
|
||||
if err != nil {
|
||||
|
||||
logger.Error("failed to create webdav token",
|
||||
"handler", "StorageHandler.CreateNewWebdavToken",
|
||||
"user_id", userID,
|
||||
"error", err.Error(),
|
||||
)
|
||||
return c.Status(responseErrors.GetErrorStatus(err)).
|
||||
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
roleRepo "git.ma-al.com/goc_daniel/b2b/app/repos/rolesRepo"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/service/emailService"
|
||||
constdata "git.ma-al.com/goc_daniel/b2b/app/utils/const_data"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/logger"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors"
|
||||
|
||||
"github.com/dlclark/regexp2"
|
||||
@@ -68,22 +69,47 @@ func (s *AuthService) Login(req *model.LoginRequest) (*model.AuthResponse, strin
|
||||
// Find user by email
|
||||
if err := s.db.Preload("Role.Permissions").Where("email = ?", req.Email).First(&user).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
logger.Info("login failed - invalid credentials",
|
||||
"service", "AuthService.Login",
|
||||
"email", req.Email,
|
||||
"reason", "user not found",
|
||||
)
|
||||
return nil, "", responseErrors.ErrInvalidCredentials
|
||||
}
|
||||
logger.Error("login failed - database error",
|
||||
"service", "AuthService.Login",
|
||||
"email", req.Email,
|
||||
"error", err.Error(),
|
||||
)
|
||||
return nil, "", fmt.Errorf("database error: %w", err)
|
||||
}
|
||||
// Check if user is active
|
||||
if !user.IsActive {
|
||||
logger.Info("login failed - user inactive",
|
||||
"service", "AuthService.Login",
|
||||
"email", req.Email,
|
||||
"reason", "user account is inactive",
|
||||
)
|
||||
return nil, "", responseErrors.ErrUserInactive
|
||||
}
|
||||
|
||||
// Check if email is verified
|
||||
if !user.EmailVerified {
|
||||
logger.Info("login failed - email not verified",
|
||||
"service", "AuthService.Login",
|
||||
"email", req.Email,
|
||||
"reason", "email not verified",
|
||||
)
|
||||
return nil, "", responseErrors.ErrEmailNotVerified
|
||||
}
|
||||
|
||||
// Verify password
|
||||
if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(req.Password)); err != nil {
|
||||
logger.Info("login failed - invalid credentials",
|
||||
"service", "AuthService.Login",
|
||||
"email", req.Email,
|
||||
"reason", "wrong password",
|
||||
)
|
||||
return nil, "", responseErrors.ErrInvalidCredentials
|
||||
}
|
||||
|
||||
@@ -94,6 +120,11 @@ func (s *AuthService) Login(req *model.LoginRequest) (*model.AuthResponse, strin
|
||||
if req.LangID != nil {
|
||||
_, err := s.GetLangISOCode(*req.LangID)
|
||||
if err != nil {
|
||||
logger.Warn("login failed - invalid language ID",
|
||||
"service", "AuthService.Login",
|
||||
"email", req.Email,
|
||||
"reason", "invalid language ID",
|
||||
)
|
||||
return nil, "", responseErrors.ErrBadLangID
|
||||
}
|
||||
user.LangID = *req.LangID
|
||||
@@ -104,12 +135,22 @@ func (s *AuthService) Login(req *model.LoginRequest) (*model.AuthResponse, strin
|
||||
// Generate access token (JWT)
|
||||
accessToken, err := s.generateAccessToken(&user)
|
||||
if err != nil {
|
||||
logger.Error("login failed - token generation error",
|
||||
"service", "AuthService.Login",
|
||||
"email", req.Email,
|
||||
"error", err.Error(),
|
||||
)
|
||||
return nil, "", fmt.Errorf("failed to generate access token: %w", err)
|
||||
}
|
||||
|
||||
// Generate opaque refresh token and store in DB
|
||||
rawRefreshToken, err := s.createRefreshToken(user.ID)
|
||||
if err != nil {
|
||||
logger.Error("login failed - refresh token creation error",
|
||||
"service", "AuthService.Login",
|
||||
"email", req.Email,
|
||||
"error", err.Error(),
|
||||
)
|
||||
return nil, "", fmt.Errorf("failed to create refresh token: %w", err)
|
||||
}
|
||||
|
||||
@@ -170,6 +211,11 @@ func (s *AuthService) Register(req *model.RegisterRequest) error {
|
||||
}
|
||||
|
||||
if err := s.db.Create(&user).Error; err != nil {
|
||||
logger.Error("registration failed - database error",
|
||||
"service", "AuthService.Register",
|
||||
"email", req.Email,
|
||||
"error", err.Error(),
|
||||
)
|
||||
return fmt.Errorf("failed to create user: %w", err)
|
||||
}
|
||||
|
||||
@@ -181,8 +227,11 @@ func (s *AuthService) Register(req *model.RegisterRequest) error {
|
||||
}
|
||||
|
||||
if err := s.email.SendVerificationEmail(user.Email, user.EmailVerificationToken, baseURL, lang); err != nil {
|
||||
// Log error but don't fail registration - user can request resend
|
||||
_ = err
|
||||
logger.Warn("failed to send verification email",
|
||||
"service", "AuthService.Register",
|
||||
"email", req.Email,
|
||||
"error", err.Error(),
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -304,6 +353,10 @@ func (s *AuthService) ResetPassword(token, newPassword string) error {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return responseErrors.ErrInvalidResetToken
|
||||
}
|
||||
logger.Error("password reset failed - database error",
|
||||
"service", "AuthService.ResetPassword",
|
||||
"error", err.Error(),
|
||||
)
|
||||
return fmt.Errorf("database error: %w", err)
|
||||
}
|
||||
|
||||
@@ -329,6 +382,10 @@ func (s *AuthService) ResetPassword(token, newPassword string) error {
|
||||
user.PasswordResetExpires = nil
|
||||
|
||||
if err := s.db.Save(&user).Error; err != nil {
|
||||
logger.Error("password reset failed - database error",
|
||||
"service", "AuthService.ResetPassword",
|
||||
"error", err.Error(),
|
||||
)
|
||||
return fmt.Errorf("failed to update password: %w", err)
|
||||
}
|
||||
|
||||
|
||||
@@ -8,10 +8,12 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.ma-al.com/goc_daniel/b2b/app/config"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/model"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/logger"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/view"
|
||||
"golang.org/x/oauth2"
|
||||
@@ -77,6 +79,13 @@ func (s *AuthService) HandleGoogleCallback(code string) (*model.AuthResponse, st
|
||||
// Find or create user
|
||||
user, err := s.findOrCreateGoogleUser(userInfo)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "database") {
|
||||
logger.Error("google oauth callback failed - database error",
|
||||
"service", "AuthService.HandleGoogleCallback",
|
||||
"email", userInfo.Email,
|
||||
"error", err.Error(),
|
||||
)
|
||||
}
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"git.ma-al.com/goc_daniel/b2b/app/model"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/repos/cartsRepo"
|
||||
constdata "git.ma-al.com/goc_daniel/b2b/app/utils/const_data"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/logger"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors"
|
||||
)
|
||||
|
||||
@@ -34,6 +35,15 @@ func (s *CartsService) CreateNewCart(user_id uint, name string) (model.CustomerC
|
||||
|
||||
// create new cart for customer
|
||||
cart, err = s.repo.CreateNewCart(user_id, name)
|
||||
if err != nil {
|
||||
return cart, err
|
||||
}
|
||||
|
||||
logger.Info("cart created",
|
||||
"service", "cartsService",
|
||||
"user_id", user_id,
|
||||
"cart_id", cart.CartID,
|
||||
)
|
||||
|
||||
return cart, nil
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package orderService
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"git.ma-al.com/goc_daniel/b2b/app/delivery/middleware/perms"
|
||||
@@ -10,6 +9,7 @@ import (
|
||||
"git.ma-al.com/goc_daniel/b2b/app/repos/ordersRepo"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/service/addressesService"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/service/emailService"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/logger"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/query/filters"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/query/find"
|
||||
"git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors"
|
||||
@@ -45,9 +45,12 @@ func (s *OrderService) Find(user *model.Customer, p find.Paging, filt *filters.F
|
||||
|
||||
for i := 0; i < len(list.Items); i++ {
|
||||
address_unparsed, err := s.addressesService.ValidateAddressJson(list.Items[i].AddressString, list.Items[i].CountryID)
|
||||
// log such errors
|
||||
if err != nil {
|
||||
fmt.Printf("err: %v\n", err)
|
||||
logger.Warn("failed to validate address",
|
||||
"service", "orderService",
|
||||
"order_id", list.Items[i].OrderID,
|
||||
"error", err.Error(),
|
||||
)
|
||||
}
|
||||
|
||||
list.Items[i].AddressUnparsed = &address_unparsed
|
||||
@@ -92,16 +95,23 @@ func (s *OrderService) PlaceNewOrder(user_id uint, cart_id uint, name string, co
|
||||
// if no error is returned, remove the cart. This should be smooth
|
||||
err = s.cartsRepo.RemoveCart(user_id, cart_id)
|
||||
if err != nil {
|
||||
// Log error but don't fail placing order
|
||||
_ = err
|
||||
logger.Warn("failed to remove cart after order placement",
|
||||
"service", "orderService",
|
||||
"user_id", user_id,
|
||||
"cart_id", cart_id,
|
||||
"error", err.Error(),
|
||||
)
|
||||
}
|
||||
|
||||
// send email to admin
|
||||
go func(user_id uint) {
|
||||
err := s.emailService.SendNewOrderPlacedNotification(user_id)
|
||||
if err != nil {
|
||||
// Log error but don't fail placing order
|
||||
_ = err
|
||||
logger.Warn("failed to send new order notification",
|
||||
"service", "orderService",
|
||||
"user_id", user_id,
|
||||
"error", err.Error(),
|
||||
)
|
||||
}
|
||||
}(user_id)
|
||||
|
||||
|
||||
151
app/utils/logger/logger.go
Normal file
151
app/utils/logger/logger.go
Normal file
@@ -0,0 +1,151 @@
|
||||
package logger
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"log/slog"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var L *slog.Logger
|
||||
|
||||
const (
|
||||
reset = "\033[0m"
|
||||
red = "\033[31m"
|
||||
yellow = "\033[33m"
|
||||
green = "\033[32m"
|
||||
blue = "\033[36m"
|
||||
gray = "\033[90m"
|
||||
)
|
||||
|
||||
type consoleHandler struct {
|
||||
w io.Writer
|
||||
colorize bool
|
||||
}
|
||||
|
||||
func (h *consoleHandler) Enabled(ctx context.Context, level slog.Level) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (h *consoleHandler) Handle(ctx context.Context, r slog.Record) error {
|
||||
level := r.Level.String()
|
||||
color := reset
|
||||
|
||||
switch r.Level {
|
||||
case slog.LevelError:
|
||||
color = red
|
||||
case slog.LevelWarn:
|
||||
color = yellow
|
||||
case slog.LevelInfo:
|
||||
color = blue
|
||||
case slog.LevelDebug:
|
||||
color = gray
|
||||
}
|
||||
|
||||
var msg string
|
||||
if h.colorize {
|
||||
msg = fmt.Sprintf("%s%s%s %s%s%s %s%s%s",
|
||||
reset, r.Time.Format("15:04:05"), reset,
|
||||
color, level, reset,
|
||||
reset, r.Message, reset)
|
||||
} else {
|
||||
msg = fmt.Sprintf("%s %s %s", r.Time.Format("15:04:05"), level, r.Message)
|
||||
}
|
||||
|
||||
var pairs []string
|
||||
r.Attrs(func(attr slog.Attr) bool {
|
||||
if h.colorize {
|
||||
pairs = append(pairs, fmt.Sprintf("%s%s=%s%v%s", green, attr.Key, reset, attr.Value, reset))
|
||||
} else {
|
||||
pairs = append(pairs, fmt.Sprintf("%s=%v", attr.Key, attr.Value))
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
if len(pairs) > 0 {
|
||||
msg += " " + strings.Join(pairs, " ")
|
||||
}
|
||||
|
||||
fmt.Fprintln(h.w, msg)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *consoleHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
|
||||
return &consoleHandler{w: h.w, colorize: h.colorize}
|
||||
}
|
||||
|
||||
func (h *consoleHandler) WithGroup(name string) slog.Handler {
|
||||
return &consoleHandler{w: h.w, colorize: h.colorize}
|
||||
}
|
||||
|
||||
func Init(service string, output io.Writer, level string, colorize bool) {
|
||||
if output == nil {
|
||||
output = os.Stderr
|
||||
}
|
||||
|
||||
var lvl slog.Level
|
||||
switch level {
|
||||
case "debug":
|
||||
lvl = slog.LevelDebug
|
||||
case "warn":
|
||||
lvl = slog.LevelWarn
|
||||
case "error":
|
||||
lvl = slog.LevelError
|
||||
default:
|
||||
lvl = slog.LevelInfo
|
||||
}
|
||||
|
||||
if colorize {
|
||||
L = slog.New(&consoleHandler{w: output, colorize: true}).With("service", service, "level", lvl.String())
|
||||
} else {
|
||||
L = slog.New(slog.NewJSONHandler(output, &slog.HandlerOptions{
|
||||
Level: lvl,
|
||||
AddSource: false,
|
||||
ReplaceAttr: func(groups []string, a slog.Attr) slog.Attr {
|
||||
if a.Key == slog.TimeKey && groups == nil {
|
||||
a.Key = "timestamp"
|
||||
}
|
||||
if a.Key == slog.LevelKey {
|
||||
a.Key = "level"
|
||||
}
|
||||
if a.Key == slog.MessageKey {
|
||||
a.Key = "message"
|
||||
}
|
||||
return a
|
||||
},
|
||||
})).With("service", service)
|
||||
}
|
||||
}
|
||||
|
||||
func Info(msg string, args ...any) {
|
||||
if L != nil {
|
||||
L.Info(msg, args...)
|
||||
}
|
||||
}
|
||||
|
||||
func Warn(msg string, args ...any) {
|
||||
if L != nil {
|
||||
L.Warn(msg, args...)
|
||||
}
|
||||
}
|
||||
|
||||
func Error(msg string, args ...any) {
|
||||
if L != nil {
|
||||
L.Error(msg, args...)
|
||||
}
|
||||
}
|
||||
|
||||
func Debug(msg string, args ...any) {
|
||||
if L != nil {
|
||||
L.Debug(msg, args...)
|
||||
}
|
||||
}
|
||||
|
||||
func With(args ...any) *slog.Logger {
|
||||
if L == nil {
|
||||
return nil
|
||||
}
|
||||
return L.With(args...)
|
||||
}
|
||||
@@ -113,7 +113,7 @@ CREATE TABLE IF NOT EXISTS b2b_customers (
|
||||
created_at DATETIME(6) NULL,
|
||||
updated_at DATETIME(6) NULL,
|
||||
deleted_at DATETIME(6) NULL,
|
||||
is_no_vat TINYINT(1) NULL DEFAULT 0
|
||||
is_no_vat TINYINT(1) NOT NULL DEFAULT 0
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_customers_email
|
||||
|
||||
Reference in New Issue
Block a user