Merge remote-tracking branch 'origin' into front-styles

This commit is contained in:
2026-03-31 09:14:22 +02:00
44 changed files with 713 additions and 345 deletions

2
.env
View File

@@ -58,3 +58,5 @@ FILE_MAAL_PL_PASSWORD=1FnwqcEgIUjQHjt1
IMAGE_PREFIX=https://www.naluconcept.com # remove prefix to serv them from same host as presta
CORS_ORGIN=https://www.naluconcept.com
DSN=root:Maal12345678@tcp(localhost:3306)/nalu

View File

@@ -2,13 +2,17 @@ package public
import (
"log"
"strconv"
"time"
"git.ma-al.com/goc_daniel/b2b/app/config"
"git.ma-al.com/goc_daniel/b2b/app/delivery/middleware"
"git.ma-al.com/goc_daniel/b2b/app/model"
"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/nullable"
"git.ma-al.com/goc_daniel/b2b/app/utils/response"
"git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors"
"github.com/gofiber/fiber/v3"
@@ -345,9 +349,58 @@ func (h *AuthHandler) CompleteRegistration(c fiber.Ctx) error {
return c.Status(fiber.StatusCreated).JSON(response)
}
// Updates JWT Tokens
// Updates JWT Tokens. Requires authentication and updates access token only
func (h *AuthHandler) UpdateJWTToken(c fiber.Ctx) error {
return h.authService.UpdateJWTToken(c)
userLocals, ok := c.Locals(constdata.USER_LOCALES_NAME).(*model.UserSession)
if !ok {
return c.Status(fiber.StatusUnauthorized).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrNotAuthenticated)))
}
user := model.Customer{
ID: userLocals.UserID,
Email: userLocals.Email,
Role: userLocals.Role,
LangID: userLocals.LangID,
CountryID: userLocals.CountryID,
IsActive: userLocals.IsActive,
}
// Parse language and country_id from query params
langIDStr := c.Query("lang_id")
if langIDStr != "" {
parsedID, err := strconv.ParseUint(langIDStr, 10, 32)
if err != nil {
return c.Status(fiber.StatusBadRequest).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadLangID)))
}
user.LangID = uint(parsedID)
}
countryIDStr := c.Query("country_id")
if countryIDStr != "" {
parsedID, err := strconv.ParseUint(countryIDStr, 10, 32)
if err != nil {
return c.Status(fiber.StatusBadRequest).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadCountryID)))
}
user.CountryID = uint(parsedID)
}
newAccessToken, err := h.authService.UpdateJWTToken(&user)
if err != nil {
return c.Status(responseErrors.GetErrorStatus(err)).JSON(fiber.Map{
"error": responseErrors.GetErrorCode(c, err),
})
}
// does not reset refresh token
h.setAuthCookies(c, newAccessToken, "")
return c.JSON(response.Make(&fiber.Map{"token": newAccessToken}, 0, i18n.T_(c, response.Message_OK)))
}
// GoogleLogin redirects the user to Google's OAuth2 consent page
@@ -414,12 +467,12 @@ func (h *AuthHandler) GoogleCallback(c fiber.Ctx) error {
// Redirect to the locale-prefixed charts page after successful Google login.
// The user's preferred language is stored in the auth response; fall back to "en".
lang, err := h.authService.GetLangISOCode(response.User.LangID)
lang_iso_code, err := h.authService.GetLangISOCode(response.User.LangID)
if err != nil {
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadLangID)).JSON(fiber.Map{
"error": responseErrors.GetErrorCode(c, responseErrors.ErrBadLangID),
return c.Status(responseErrors.GetErrorStatus(err)).JSON(fiber.Map{
"error": responseErrors.GetErrorCode(c, err),
})
}
return c.Redirect().To(h.config.App.BaseURL + "/" + lang)
return c.Redirect().To(h.config.App.BaseURL + "/" + lang_iso_code)
}

View File

@@ -0,0 +1,98 @@
package restricted
import (
"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/service/listService"
"git.ma-al.com/goc_daniel/b2b/app/utils/i18n"
"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"
"git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors"
"github.com/gofiber/fiber/v3"
)
// ListHandler handles endpoints that list various things (e.g. products or users)
type ListHandler struct {
listService *listService.ListService
config *config.Config
}
// NewListHandler creates a new ListHandler instance
func NewListHandler() *ListHandler {
listService := listService.New()
return &ListHandler{
listService: listService,
config: config.Get(),
}
}
func ListHandlerRoutes(r fiber.Router) fiber.Router {
handler := NewListHandler()
r.Get("/list-products", handler.ListProducts)
r.Get("/list-users", handler.ListUsers)
return r
}
func (h *ListHandler) ListProducts(c fiber.Ctx) error {
paging, filters, err := query_params.ParseFilters[model.Product](c, columnMappingListProducts)
if err != nil {
return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
}
id_lang, ok := c.Locals("langID").(uint)
if !ok {
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute)))
}
listing, err := h.listService.ListProducts(id_lang, paging, filters)
if err != nil {
return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
}
return c.JSON(response.Make(&listing.Items, int(listing.Count), i18n.T_(c, response.Message_OK)))
}
var columnMappingListProducts map[string]string = map[string]string{
"product_id": "ps.id_product",
"name": "pl.name",
"reference": "p.reference",
"category_name": "cl.name",
"category_id": "cp.id_category",
"quantity": "sa.quantity",
}
func (h *ListHandler) ListUsers(c fiber.Ctx) error {
paging, filters, err := query_params.ParseFilters[model.Customer](c, columnMappingListUsers)
if err != nil {
return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
}
id_lang, ok := c.Locals("langID").(uint)
if !ok {
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute)))
}
listing, err := h.listService.ListUsers(id_lang, paging, filters)
if err != nil {
return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
}
return c.JSON(response.Make(&listing.Items, int(listing.Count), i18n.T_(c, response.Message_OK)))
}
var columnMappingListUsers map[string]string = map[string]string{
"user_id": "users.id",
"email": "users.email",
"first_name": "users.first_name",
"second_name": "users.second_name",
"role": "users.role",
}

View File

@@ -1,67 +0,0 @@
package restricted
import (
"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/service/listProductsService"
"git.ma-al.com/goc_daniel/b2b/app/utils/i18n"
"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"
"git.ma-al.com/goc_daniel/b2b/app/utils/responseErrors"
"github.com/gofiber/fiber/v3"
)
// ListProductsHandler handles endpoints that receive, save and translate product descriptions.
type ListProductsHandler struct {
listProductsService *listProductsService.ListProductsService
config *config.Config
}
// NewListProductsHandler creates a new ListProductsHandler instance
func NewListProductsHandler() *ListProductsHandler {
listProductsService := listProductsService.New()
return &ListProductsHandler{
listProductsService: listProductsService,
config: config.Get(),
}
}
func ListProductsHandlerRoutes(r fiber.Router) fiber.Router {
handler := NewListProductsHandler()
r.Get("/get-listing", handler.GetListing)
return r
}
func (h *ListProductsHandler) GetListing(c fiber.Ctx) error {
paging, filters, err := query_params.ParseFilters[model.Product](c, columnMappingGetListing)
if err != nil {
return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
}
id_lang, ok := c.Locals("langID").(uint)
if !ok {
return c.Status(responseErrors.GetErrorStatus(responseErrors.ErrBadAttribute)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadAttribute)))
}
listing, err := h.listProductsService.GetListing(id_lang, paging, filters)
if err != nil {
return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
}
return c.JSON(response.Make(&listing.Items, int(listing.Count), i18n.T_(c, response.Message_OK)))
}
var columnMappingGetListing map[string]string = map[string]string{
"product_id": "ps.id_product",
"name": "pl.name",
"reference": "p.reference",
"category_name": "cl.name",
"category_id": "cp.id_category",
"quantity": "sa.quantity",
}

View File

@@ -94,9 +94,9 @@ func (s *Server) Setup() error {
productTranslation := s.restricted.Group("/product-translation")
restricted.ProductTranslationHandlerRoutes(productTranslation)
// listing products routes (restricted)
listProducts := s.restricted.Group("/list-products")
restricted.ListProductsHandlerRoutes(listProducts)
// lists of things routes (restricted)
list := s.restricted.Group("/list")
restricted.ListHandlerRoutes(list)
// locale selector (restricted)
// this is basically for changing user's selected language and country

View File

@@ -1,31 +1,17 @@
package model
import "git.ma-al.com/goc_daniel/b2b/app/model/dbmodel"
// Represents a country together with its associated currency
type Country struct {
ID uint `gorm:"primaryKey;column:id" json:"id"`
Name string `gorm:"column:name" json:"name"`
Flag string `gorm:"size:16;not null;column:flag" json:"flag"`
CurrencyID uint `gorm:"column:id_currency" json:"currency_id"`
CurrencyISOCode string `gorm:"column:iso_code" json:"currency_iso_code"`
CurrencyName string `gorm:"column:name" json:"currency_name"`
// PSCountryID int `gorm:"column:id_country" json:"ps_country_id"`
// PSCountry *PSCountry `gorm:"foreignKey:PSCountryID;references:ID" json:"ps_country"`
PSCurrencyID uint `gorm:"column:currency" json:"currency"`
PSCurrency *PSCurrency `gorm:"foreignKey:PSCurrencyID;references:currency_id" json:"ps_currency"`
ID uint `gorm:"primaryKey;column:id" json:"id"`
Name string `gorm:"column:name" json:"name"`
Flag string `gorm:"size:16;not null;column:flag" json:"flag"`
PSCurrencyID uint `gorm:"column:currency_id" json:"currency_id"`
PSCurrency *dbmodel.PsCurrency `gorm:"foreignKey:PSCurrencyID;references:IDCurrency" json:"ps_currency"`
}
func (Country) TableName() string {
return "b2b_countries"
}
type PSCountry struct {
CurrencyID uint `gorm:"column:id_currency" json:"currency_id"`
}
func (PSCountry) TableName() string {
return "ps_country"
}
type PSCurrency struct {
Currency int `gorm:"column:currency" json:"currency"`
}

View File

@@ -144,3 +144,11 @@ type RefreshToken struct {
func (RefreshToken) TableName() string {
return "b2b_refresh_tokens"
}
type UserInList struct {
UserID uint `gorm:"primaryKey;column:id" json:"user_id"`
Email string `gorm:"column:email" json:"email"`
FirstName string `gorm:"column:first_name" json:"first_name"`
LastName string `gorm:"column:last_name" json:"last_name"`
Role string `gorm:"column:role" json:"role"`
}

View File

@@ -21,12 +21,12 @@ func (*PsGroupReduction) TableName() string {
var PsGroupReductionCols = struct {
IDGroupReduction gormcol.Field
IDGroup gormcol.Field
IDCategory gormcol.Field
Reduction gormcol.Field
IDGroup gormcol.Field
IDCategory gormcol.Field
Reduction gormcol.Field
}{
IDGroupReduction: gormcol.Field{}.Set((&PsGroupReduction{}).TableName(), "id_group_reduction"),
IDGroup: gormcol.Field{}.Set((&PsGroupReduction{}).TableName(), "id_group"),
IDCategory: gormcol.Field{}.Set((&PsGroupReduction{}).TableName(), "id_category"),
Reduction: gormcol.Field{}.Set((&PsGroupReduction{}).TableName(), "reduction"),
IDGroup: gormcol.Field{}.Set((&PsGroupReduction{}).TableName(), "id_group"),
IDCategory: gormcol.Field{}.Set((&PsGroupReduction{}).TableName(), "id_category"),
Reduction: gormcol.Field{}.Set((&PsGroupReduction{}).TableName(), "reduction"),
}

View File

@@ -18,9 +18,9 @@ func (*PsProductAttributeCombination) TableName() string {
}
var PsProductAttributeCombinationCols = struct {
IDAttribute gormcol.Field
IDAttribute gormcol.Field
IDProductAttribute gormcol.Field
}{
IDAttribute: gormcol.Field{}.Set((&PsProductAttributeCombination{}).TableName(), "id_attribute"),
IDAttribute: gormcol.Field{}.Set((&PsProductAttributeCombination{}).TableName(), "id_attribute"),
IDProductAttribute: gormcol.Field{}.Set((&PsProductAttributeCombination{}).TableName(), "id_product_attribute"),
}

View File

@@ -20,10 +20,10 @@ func (*PsProductGroupReductionCache) TableName() string {
var PsProductGroupReductionCacheCols = struct {
IDProduct gormcol.Field
IDGroup gormcol.Field
IDGroup gormcol.Field
Reduction gormcol.Field
}{
IDProduct: gormcol.Field{}.Set((&PsProductGroupReductionCache{}).TableName(), "id_product"),
IDGroup: gormcol.Field{}.Set((&PsProductGroupReductionCache{}).TableName(), "id_group"),
IDGroup: gormcol.Field{}.Set((&PsProductGroupReductionCache{}).TableName(), "id_group"),
Reduction: gormcol.Field{}.Set((&PsProductGroupReductionCache{}).TableName(), "reduction"),
}

View File

@@ -19,11 +19,11 @@ func (*PsPshowPshowproducttabsHook) TableName() string {
}
var PsPshowPshowproducttabsHookCols = struct {
IDHook gormcol.Field
HookName gormcol.Field
IDHook gormcol.Field
HookName gormcol.Field
PrestaIDHook gormcol.Field
}{
IDHook: gormcol.Field{}.Set((&PsPshowPshowproducttabsHook{}).TableName(), "id_hook"),
HookName: gormcol.Field{}.Set((&PsPshowPshowproducttabsHook{}).TableName(), "hook_name"),
IDHook: gormcol.Field{}.Set((&PsPshowPshowproducttabsHook{}).TableName(), "id_hook"),
HookName: gormcol.Field{}.Set((&PsPshowPshowproducttabsHook{}).TableName(), "hook_name"),
PrestaIDHook: gormcol.Field{}.Set((&PsPshowPshowproducttabsHook{}).TableName(), "presta_id_hook"),
}

View File

@@ -1,4 +1,4 @@
package listProductsRepo
package listRepo
import (
"git.ma-al.com/goc_daniel/b2b/app/config"
@@ -7,25 +7,27 @@ import (
"git.ma-al.com/goc_daniel/b2b/app/model/dbmodel"
"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_marek/gormcol"
"github.com/WinterYukky/gorm-extra-clause-plugin/exclause"
)
type UIListProductsRepo interface {
GetListing(id_lang uint, p find.Paging, filt *filters.FiltersList) (find.Found[model.ProductInList], error)
type UIListRepo interface {
ListProducts(id_lang uint, p find.Paging, filt *filters.FiltersList) (find.Found[model.ProductInList], error)
ListUsers(id_lang uint, p find.Paging, filt *filters.FiltersList) (find.Found[model.UserInList], error)
}
type ListProductsRepo struct{}
type ListRepo struct{}
func New() UIListProductsRepo {
return &ListProductsRepo{}
func New() UIListRepo {
return &ListRepo{}
}
func (repo *ListProductsRepo) GetListing(id_lang uint, p find.Paging, filt *filters.FiltersList) (find.Found[model.ProductInList], error) {
var listing []model.ProductInList
func (repo *ListRepo) ListProducts(id_lang uint, p find.Paging, filt *filters.FiltersList) (find.Found[model.ProductInList], error) {
var list []model.ProductInList
var total int64
query := db.Get().
Table("ps_product_shop ps").
Table(gormcol.Field.Tab(dbmodel.PsProductShopCols.Active)+" AS ps").
Select(`
ps.id_product AS product_id,
pl.name AS name,
@@ -67,13 +69,53 @@ func (repo *ListProductsRepo) GetListing(id_lang uint, p find.Paging, filt *filt
Order("ps.id_product DESC").
Limit(p.Limit()).
Offset(p.Offset()).
Find(&listing).Error
Find(&list).Error
if err != nil {
return find.Found[model.ProductInList]{}, err
}
return find.Found[model.ProductInList]{
Items: listing,
Items: list,
Count: uint(total),
}, nil
}
func (repo *ListRepo) ListUsers(id_lang uint, p find.Paging, filt *filters.FiltersList) (find.Found[model.UserInList], error) {
var list []model.UserInList
var total int64
query := db.Get().
Table("b2b_customers AS users").
Select(`
users.id AS id,
users.email AS email,
users.first_name AS first_name,
users.last_name AS last_name,
users.role AS role
`)
// Apply all filters
if filt != nil {
filt.ApplyAll(query)
}
// run counter first as query is without limit and offset
err := query.Count(&total).Error
if err != nil {
return find.Found[model.UserInList]{}, err
}
err = query.
Order("users.id DESC").
Limit(p.Limit()).
Offset(p.Offset()).
Find(&list).Error
if err != nil {
return find.Found[model.UserInList]{}, err
}
return find.Found[model.UserInList]{
Items: list,
Count: uint(total),
}, nil
}

View File

@@ -6,7 +6,6 @@ import (
"encoding/hex"
"errors"
"fmt"
"strconv"
"time"
"git.ma-al.com/goc_daniel/b2b/app/config"
@@ -14,13 +13,9 @@ import (
"git.ma-al.com/goc_daniel/b2b/app/model"
"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/i18n"
"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"
"github.com/dlclark/regexp2"
"github.com/gofiber/fiber/v3"
"github.com/golang-jwt/jwt/v5"
"golang.org/x/crypto/bcrypt"
"gorm.io/gorm"
@@ -167,7 +162,7 @@ func (s *AuthService) Register(req *model.RegisterRequest) error {
baseURL := config.Get().App.BaseURL
lang, err := s.GetLangISOCode(req.LangID)
if err != nil {
return responseErrors.ErrBadLangID
return err
}
if err := s.email.SendVerificationEmail(user.Email, user.EmailVerificationToken, baseURL, lang); err != nil {
@@ -276,7 +271,7 @@ func (s *AuthService) RequestPasswordReset(emailAddr string) error {
baseURL := config.Get().App.BaseURL
lang, err := s.GetLangISOCode(user.LangID)
if err != nil {
return responseErrors.ErrBadLangID
return err
}
if err := s.email.SendPasswordResetEmail(user.Email, user.PasswordResetToken, baseURL, lang); err != nil {
@@ -482,7 +477,7 @@ func hashToken(raw string) string {
func (s *AuthService) generateAccessToken(user *model.Customer) (string, error) {
_, err := s.GetLangISOCode(user.LangID)
if err != nil {
return "", responseErrors.ErrBadLangID
return "", err
}
err = s.CheckIfCountryExists(user.CountryID)
@@ -508,97 +503,19 @@ func (s *AuthService) generateAccessToken(user *model.Customer) (string, error)
return token.SignedString([]byte(s.config.JWTSecret))
}
func (s *AuthService) UpdateJWTToken(c fiber.Ctx) error {
// Get user ID from JWT claims in context (set by auth middleware)
// claims, ok := c.Locals("jwt_claims").(*JWTClaims)
// if !ok || claims == nil {
// return c.Status(fiber.StatusUnauthorized).
// JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrNotAuthenticated)))
// }
// fmt.Printf("claims: %v\n", claims)
// var user model.Customer
// // Find user by ID
// if err := s.db.First(&user, claims.UserID).Error; err != nil {
// return err
// }
userLocals, ok := c.Locals(constdata.USER_LOCALES_NAME).(*model.UserSession)
if !ok {
return c.Status(fiber.StatusUnauthorized).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrNotAuthenticated)))
}
user := model.Customer{
ID: userLocals.UserID,
Email: userLocals.Email,
Role: userLocals.Role,
LangID: userLocals.LangID,
CountryID: userLocals.CountryID,
IsActive: userLocals.IsActive,
}
// Parse language and country_id from query params
langIDStr := c.Query("lang_id")
var langID uint
if langIDStr != "" {
parsedID, err := strconv.ParseUint(langIDStr, 10, 32)
if err != nil {
return c.Status(fiber.StatusBadRequest).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadLangID)))
}
langID = uint(parsedID)
_, err = s.GetLangISOCode(langID)
if err != nil {
return responseErrors.ErrBadLangID
} else {
user.LangID = langID
}
}
countryIDStr := c.Query("country_id")
var countryID uint
if countryIDStr != "" {
parsedID, err := strconv.ParseUint(countryIDStr, 10, 32)
if err != nil {
return c.Status(fiber.StatusBadRequest).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, responseErrors.ErrBadCountryID)))
}
countryID = uint(parsedID)
err = s.CheckIfCountryExists(countryID)
if err != nil {
return responseErrors.ErrBadCountryID
} else {
user.CountryID = countryID
}
}
// Update choice and get new token using AuthService
newToken, err := s.generateAccessToken(&user)
func (s *AuthService) UpdateJWTToken(user *model.Customer) (string, error) {
// Update choice and get new access token using AuthService
new_access_token, err := s.generateAccessToken(user)
if err != nil {
return c.Status(responseErrors.GetErrorStatus(err)).
JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err)))
return "", err
}
// Save the updated user
if err := s.db.Save(&user).Error; err != nil {
return fmt.Errorf("database error: %w", err)
if err := s.db.Save(user).Error; err != nil {
return "", fmt.Errorf("database error: %w", err)
}
// Set the new JWT cookie
cookie := new(fiber.Cookie)
cookie.Name = "jwt_token"
cookie.Value = newToken
cookie.HTTPOnly = true
cookie.Secure = true
cookie.SameSite = fiber.CookieSameSiteLaxMode
c.Cookie(cookie)
return c.JSON(response.Make(&fiber.Map{"token": newToken}, 0, i18n.T_(c, response.Message_OK)))
return new_access_token, nil
}
// generateVerificationToken generates a random verification token
@@ -623,14 +540,20 @@ func validatePassword(password string) error {
func (s *AuthService) GetLangISOCode(langID uint) (string, error) {
var lang string
var err error
if langID == 0 { // retrieve the default lang
err := db.DB.Table("b2b_language").Where("is_default = ?", 1).Select("iso_code").Scan(&lang).Error
return lang, err
err = db.DB.Table("b2b_language").Where("is_default = ?", 1).Select("iso_code").Scan(&lang).Error
} else {
err := db.DB.Table("b2b_language").Where("id = ?", langID).Where("active = ?", 1).Select("iso_code").Scan(&lang).Error
return lang, err
err = db.DB.Table("b2b_language").Where("id = ?", langID).Where("active = ?", 1).Select("iso_code").Scan(&lang).Error
}
if err != nil {
return lang, err
} else if lang == "" {
return lang, responseErrors.ErrBadLangID
}
return lang, nil
}
func (s *AuthService) CheckIfCountryExists(countryID uint) error {

View File

@@ -153,7 +153,8 @@ func (s *AuthService) findOrCreateGoogleUser(info *view.GoogleUserInfo) (*model.
Role: model.RoleUser,
IsActive: true,
EmailVerified: true,
LangID: 2,
LangID: 2, // default is english
CountryID: 2, // default is England
}
if err := s.db.Create(&newUser).Error; err != nil {

View File

@@ -1,29 +0,0 @@
package listProductsService
import (
"git.ma-al.com/goc_daniel/b2b/app/model"
"git.ma-al.com/goc_daniel/b2b/app/repos/listProductsRepo"
"git.ma-al.com/goc_daniel/b2b/app/utils/query/filters"
"git.ma-al.com/goc_daniel/b2b/app/utils/query/find"
)
type ListProductsService struct {
listProductsRepo listProductsRepo.UIListProductsRepo
}
func New() *ListProductsService {
return &ListProductsService{
listProductsRepo: listProductsRepo.New(),
}
}
func (s *ListProductsService) GetListing(id_lang uint, p find.Paging, filters *filters.FiltersList) (find.Found[model.ProductInList], error) {
var products find.Found[model.ProductInList]
products, err := s.listProductsRepo.GetListing(id_lang, p, filters)
if err != nil {
return products, err
}
return products, nil
}

View File

@@ -0,0 +1,26 @@
package listService
import (
"git.ma-al.com/goc_daniel/b2b/app/model"
"git.ma-al.com/goc_daniel/b2b/app/repos/listRepo"
"git.ma-al.com/goc_daniel/b2b/app/utils/query/filters"
"git.ma-al.com/goc_daniel/b2b/app/utils/query/find"
)
type ListService struct {
listRepo listRepo.UIListRepo
}
func New() *ListService {
return &ListService{
listRepo: listRepo.New(),
}
}
func (s *ListService) ListProducts(id_lang uint, p find.Paging, filters *filters.FiltersList) (find.Found[model.ProductInList], error) {
return s.listRepo.ListProducts(id_lang, p, filters)
}
func (s *ListService) ListUsers(id_lang uint, p find.Paging, filters *filters.FiltersList) (find.Found[model.UserInList], error) {
return s.listRepo.ListUsers(id_lang, p, filters)
}

1
bo/.gitignore vendored
View File

@@ -13,6 +13,7 @@ dist
dist-ssr
coverage
*.local
bo/components.d.ts
# Editor directories and files
.vscode/*

12
bo/components.d.ts vendored
View File

@@ -11,27 +11,19 @@ export {}
/* prettier-ignore */
declare module 'vue' {
export interface GlobalComponents {
Cart1: typeof import('./src/components/customer/Cart1.vue')['default']
CartDetails: typeof import('./src/components/customer/CartDetails.vue')['default']
CategoryMenu: typeof import('./src/components/inner/categoryMenu.vue')['default']
CategoryMenuListing: typeof import('./src/components/inner/categoryMenuListing.vue')['default']
copy: typeof import('./src/components/customer/PageOrders copy.vue')['default']
Cs_PrivacyPolicyView: typeof import('./src/components/terms/cs_PrivacyPolicyView.vue')['default']
Cs_TermsAndConditionsView: typeof import('./src/components/terms/cs_TermsAndConditionsView.vue')['default']
En_PrivacyPolicyView: typeof import('./src/components/terms/en_PrivacyPolicyView.vue')['default']
En_TermsAndConditionsView: typeof import('./src/components/terms/en_TermsAndConditionsView.vue')['default']
LangSwitch: typeof import('./src/components/inner/langSwitch.vue')['default']
Page: typeof import('./src/components/customer/Page.vue')['default']
PageAddresses: typeof import('./src/components/customer/PageAddresses.vue')['default']
PageCart: typeof import('./src/components/customer/PageCart.vue')['default']
PageCarts: typeof import('./src/components/customer/PageCarts.vue')['default']
PageCreateAccount: typeof import('./src/components/customer/PageCreateAccount.vue')['default']
PageCustomerData: typeof import('./src/components/customer/PageCustomerData.vue')['default']
PageOrders: typeof import('./src/components/customer/PageOrders.vue')['default']
PageProduct: typeof import('./src/components/customer/PageProduct.vue')['default']
PageProductCardFull: typeof import('./src/components/customer/PageProductCardFull.vue')['default']
PageProducts: typeof import('./src/components/admin/PageProducts.vue')['default']
PageProductsList: typeof import('./src/components/admin/PageProductsList.vue')['default']
PageProfileDetails: typeof import('./src/components/customer/PageProfileDetails.vue')['default']
PageProfileDetailsAddInfo: typeof import('./src/components/customer/PageProfileDetailsAddInfo.vue')['default']
PageStatistic: typeof import('./src/components/customer/PageStatistic.vue')['default']
@@ -39,7 +31,6 @@ declare module 'vue' {
Pl_TermsAndConditionsView: typeof import('./src/components/terms/pl_TermsAndConditionsView.vue')['default']
ProductCustomization: typeof import('./src/components/customer/components/ProductCustomization.vue')['default']
ProductDetailView: typeof import('./src/components/admin/ProductDetailView.vue')['default']
ProductsView: typeof import('./src/components/admin/ProductsView.vue')['default']
ProductVariants: typeof import('./src/components/customer/components/ProductVariants.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
@@ -51,17 +42,14 @@ declare module 'vue' {
UCard: typeof import('./node_modules/@nuxt/ui/dist/runtime/components/Card.vue')['default']
UCheckbox: typeof import('./node_modules/@nuxt/ui/dist/runtime/components/Checkbox.vue')['default']
UDrawer: typeof import('./node_modules/@nuxt/ui/dist/runtime/components/Drawer.vue')['default']
UDropdownMenu: typeof import('./node_modules/@nuxt/ui/dist/runtime/components/DropdownMenu.vue')['default']
UForm: typeof import('./node_modules/@nuxt/ui/dist/runtime/components/Form.vue')['default']
UFormField: typeof import('./node_modules/@nuxt/ui/dist/runtime/components/FormField.vue')['default']
UIcon: typeof import('./node_modules/@nuxt/ui/dist/runtime/vue/components/Icon.vue')['default']
UInput: typeof import('./node_modules/@nuxt/ui/dist/runtime/components/Input.vue')['default']
UInputNumber: typeof import('./node_modules/@nuxt/ui/dist/runtime/components/InputNumber.vue')['default']
ULink: typeof import('./node_modules/@nuxt/ui/dist/runtime/vue/overrides/vue-router/Link.vue')['default']
UModal: typeof import('./node_modules/@nuxt/ui/dist/runtime/components/Modal.vue')['default']
UNavigationMenu: typeof import('./node_modules/@nuxt/ui/dist/runtime/components/NavigationMenu.vue')['default']
UPagination: typeof import('./node_modules/@nuxt/ui/dist/runtime/components/Pagination.vue')['default']
USelect: typeof import('./node_modules/@nuxt/ui/dist/runtime/components/Select.vue')['default']
USelectMenu: typeof import('./node_modules/@nuxt/ui/dist/runtime/components/SelectMenu.vue')['default']
UTable: typeof import('./node_modules/@nuxt/ui/dist/runtime/components/Table.vue')['default']
}

View File

@@ -1,63 +1,63 @@
// import type { NuxtUIOptions } from '@nuxt/ui/unplugin'
import type { NuxtUIOptions } from '@nuxt/ui/unplugin'
// export const uiOptions: NuxtUIOptions = {
// ui: {
// pagination: {
// slots: {
// root: '',
// }
// },
// button: {
// slots: {
// base: 'border! border-(--border-light)! dark:border-(--border-dark)! outline-0! ring-0!',
// },
// },
// input: {
// slots: {
// base: 'text-(--black) dark:text-white border! border-(--border-light)! dark:border-(--border-dark)! outline-0! ring-0!',
// error: 'text-red-600!'
// },
// },
// inputNumber: {
// slots: {
// base: 'text-(--black) dark:text-white border! border-(--border-light)! dark:border-(--border-dark)! outline-0! ring-0! pt-2 px-1! w-auto!',
// increment: 'border-0! pe-0! ps-0!',
// decrement: 'border-0! pe-0! ps-0!'
// },
// },
// select: {
// slots: {
// base: 'w-full! cursor-pointer border! border-(--border-light)! dark:border-(--border-dark)! outline-0! ring-0!',
// itemLabel: 'text-black! dark:text-white!',
// itemTrailingIcon: 'text-black! dark:text-white!'
// },
// },
// formField: {
// slots: {
// error: 'mt-1! text-[14px] text-error text-red-600! dark:text-red-400!',
// label: 'text-[16px]'
// },
// },
// selectMenu: {
// slots: {
// base: 'border! border-(--border-light)! dark:border-(--border-dark)! outline-0! ring-0!',
// content: 'border! border-(--border-light)! dark:border-(--border-dark)! outline-0! ring-0! z-80 text-(--black)! dark:text-white!',
// itemLeadingIcon: 'text-(--black)! dark:text-white!'
// }
export const uiOptions: NuxtUIOptions = {
ui: {
pagination: {
slots: {
root: '',
}
},
button: {
slots: {
base: 'border! border-(--border-light)! dark:border-(--border-dark)! outline-0! ring-0!',
},
},
input: {
slots: {
base: 'text-(--black) dark:text-white border! border-(--border-light)! dark:border-(--border-dark)! outline-0! ring-0!',
error: 'text-red-600!'
},
},
inputNumber: {
slots: {
base: 'text-(--black) dark:text-white border! border-(--border-light)! dark:border-(--border-dark)! outline-0! ring-0! pt-2 px-1! w-auto!',
increment: 'border-0! pe-0! ps-0!',
decrement: 'border-0! pe-0! ps-0!'
},
},
select: {
slots: {
base: 'w-full! cursor-pointer border! border-(--border-light)! dark:border-(--border-dark)! outline-0! ring-0!',
itemLabel: 'text-black! dark:text-white!',
itemTrailingIcon: 'text-black! dark:text-white!'
},
},
formField: {
slots: {
error: 'mt-1! text-[14px] text-error text-red-600! dark:text-red-400!',
label: 'text-[16px]'
},
},
selectMenu: {
slots: {
base: 'border! border-(--border-light)! dark:border-(--border-dark)! outline-0! ring-0!',
content: 'border! border-(--border-light)! dark:border-(--border-dark)! outline-0! ring-0! z-80 text-(--black)! dark:text-white!',
itemLeadingIcon: 'text-(--black)! dark:text-white!'
}
// },
// table: {
// slots: {
// base: 'border! border-(--border-light)! dark:border-(--border-dark)! outline-0! ring-0! bg-(--second-light) dark:bg-(--main-dark)',
// tr: 'border-b! border-(--border-light)! dark:border-(--border-dark)! outline-0! ring-0! text-(--black)! dark:text-white!',
// }
},
table: {
slots: {
base: 'border! border-(--border-light)! dark:border-(--border-dark)! outline-0! ring-0! bg-(--second-light) dark:bg-(--main-dark)',
tr: 'border-b! border-(--border-light)! dark:border-(--border-dark)! outline-0! ring-0! text-(--black)! dark:text-white!',
}
// },
// modal: {
// slots: {
// content: 'border! border-(--border-light)! dark:border-(--border-dark)! outline-0! ring-0! bg-(--second-light) dark:bg-(--main-dark)',
// }
},
modal: {
slots: {
content: 'border! border-(--border-light)! dark:border-(--border-dark)! outline-0! ring-0! bg-(--second-light) dark:bg-(--main-dark)',
}
// }
// }
// }
}
}
}

View File

@@ -62,14 +62,6 @@ async function changeLang() {
method: 'POST'
})
if (items?.token) {
cookie.setCookie('Aurrie', items.token, {
days: 60,
secure: true,
sameSite: 'Lax'
})
}
} catch (error) {
console.log(error)
}

View File

@@ -5,7 +5,7 @@ info:
http:
method: GET
url: "{{bas_url}}/restricted/list-products/get-listing?p=1&elems=30&sort=product_id,asc&category_id_in=243&reference=~62"
url: "{{bas_url}}/restricted/list/list-products?p=1&elems=30&sort=product_id,asc&category_id_in=243&reference=~62"
params:
- name: p
value: "1"

View File

@@ -10,12 +10,11 @@ http:
type: json
data: |-
{
"q": "kinder",
"q": "mat",
"limit": 50,
"offset": 0,
// "filter": "'attr.10'= 71",
// "facets":["category_ids", "price", "attr"],
"attributesToRetrieve" : ["product_id"]
"filter": "'category_ids'= 10",
// "facets":["category_ids", "price"]
"facets": ["category_ids", "attr", "feat", "price"]
}
auth:

9
bruno/b2b-daniel/.gitignore vendored Normal file
View File

@@ -0,0 +1,9 @@
# Secrets
.env*
# Dependencies
node_modules
# OS files
.DS_Store
Thumbs.db

View File

@@ -0,0 +1,15 @@
info:
name: add-new-cart
type: http
seq: 11
http:
method: GET
url: http://localhost:3000/api/v1/restricted/carts/add-new-cart
auth: inherit
settings:
encodeUrl: true
timeout: 0
followRedirects: true
maxRedirects: 5

View File

@@ -0,0 +1,25 @@
info:
name: add-product-to-cart (1)
type: http
seq: 16
http:
method: GET
url: http://localhost:3000/api/v1/restricted/carts/add-product-to-cart?cart_id=1&product_id=51&amount=1
params:
- name: cart_id
value: "1"
type: query
- name: product_id
value: "51"
type: query
- name: amount
value: "1"
type: query
auth: inherit
settings:
encodeUrl: true
timeout: 0
followRedirects: true
maxRedirects: 5

View File

@@ -0,0 +1,28 @@
info:
name: add-product-to-cart
type: http
seq: 15
http:
method: GET
url: http://localhost:3000/api/v1/restricted/carts/add-product-to-cart?cart_id=1&product_id=51&product_attribute_id=1115&amount=1
params:
- name: cart_id
value: "1"
type: query
- name: product_id
value: "51"
type: query
- name: product_attribute_id
value: "1115"
type: query
- name: amount
value: "1"
type: query
auth: inherit
settings:
encodeUrl: true
timeout: 0
followRedirects: true
maxRedirects: 5

View File

@@ -0,0 +1,22 @@
info:
name: change-cart-name
type: http
seq: 12
http:
method: GET
url: http://localhost:3000/api/v1/restricted/carts/change-cart-name?cart_id=1&new_name=test
params:
- name: cart_id
value: "1"
type: query
- name: new_name
value: test
type: query
auth: inherit
settings:
encodeUrl: true
timeout: 0
followRedirects: true
maxRedirects: 5

View File

@@ -0,0 +1,15 @@
info:
name: create-index
type: http
seq: 7
http:
method: GET
url: http://localhost:3000/api/v1/restricted/meili-search/create-index
auth: inherit
settings:
encodeUrl: true
timeout: 0
followRedirects: true
maxRedirects: 5

View File

@@ -0,0 +1,17 @@
info:
name: get-indexes
type: http
seq: 9
http:
method: GET
url: http://localhost:7700/indexes
auth:
type: bearer
token: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
settings:
encodeUrl: true
timeout: 0
followRedirects: true
maxRedirects: 5

View File

@@ -0,0 +1,19 @@
info:
name: get-menu
type: http
seq: 5
http:
method: GET
url: http://localhost:3000/api/v1/restricted/menu/get-menu?lang_id=1
params:
- name: lang_id
value: "1"
type: query
auth: inherit
settings:
encodeUrl: true
timeout: 0
followRedirects: true
maxRedirects: 5

View File

@@ -0,0 +1,15 @@
info:
name: get_countries
type: http
seq: 4
http:
method: GET
url: http://localhost:3000/api/v1/restricted/langs-and-countries/get-countries
auth: inherit
settings:
encodeUrl: true
timeout: 0
followRedirects: true
maxRedirects: 5

View File

@@ -0,0 +1,21 @@
info:
name: list-products
type: http
seq: 1
http:
method: GET
url: http://localhost:3000/api/v1/restricted/list/list-products?p=1&elems=10
params:
- name: p
value: "1"
type: query
- name: elems
value: "10"
type: query
settings:
encodeUrl: true
timeout: 0
followRedirects: true
maxRedirects: 5

View File

@@ -0,0 +1,21 @@
info:
name: list-users
type: http
seq: 2
http:
method: GET
url: http://localhost:3000/api/v1/restricted/list/list-users?p=1&elems=10
params:
- name: p
value: "1"
type: query
- name: elems
value: "10"
type: query
settings:
encodeUrl: true
timeout: 0
followRedirects: true
maxRedirects: 5

View File

@@ -0,0 +1,21 @@
opencollection: 1.0.0
info:
name: b2b-daniel
config:
proxy:
inherit: true
config:
protocol: http
hostname: ""
port: ""
auth:
username: ""
password: ""
bypassProxy: ""
bundled: false
extensions:
bruno:
ignore:
- node_modules
- .git

View File

@@ -0,0 +1,17 @@
info:
name: remove-index
type: http
seq: 8
http:
method: DELETE
url: http://localhost:7700/indexes/meili_products_shop1_lang1
auth:
type: bearer
token: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
settings:
encodeUrl: true
timeout: 0
followRedirects: true
maxRedirects: 5

View File

@@ -0,0 +1,19 @@
info:
name: retrieve-cart
type: http
seq: 14
http:
method: GET
url: http://localhost:3000/api/v1/restricted/carts/retrieve-cart?cart_id=3
params:
- name: cart_id
value: "3"
type: query
auth: inherit
settings:
encodeUrl: true
timeout: 0
followRedirects: true
maxRedirects: 5

View File

@@ -0,0 +1,15 @@
info:
name: retrieve-carts-info
type: http
seq: 13
http:
method: GET
url: http://localhost:3000/api/v1/restricted/carts/retrieve-carts-info
auth: inherit
settings:
encodeUrl: true
timeout: 0
followRedirects: true
maxRedirects: 5

View File

@@ -0,0 +1,31 @@
info:
name: search
type: http
seq: 10
http:
method: GET
url: http://localhost:3000/api/v1/restricted/meili-search/search?query=w&limit=4&id_category=0&price_lower_bound=60.0&price_upper_bound=70.0
params:
- name: query
value: w
type: query
- name: limit
value: "4"
type: query
- name: id_category
value: "0"
type: query
- name: price_lower_bound
value: "60.0"
type: query
- name: price_upper_bound
value: "70.0"
type: query
auth: inherit
settings:
encodeUrl: true
timeout: 0
followRedirects: true
maxRedirects: 5

15
bruno/b2b-daniel/test.yml Normal file
View File

@@ -0,0 +1,15 @@
info:
name: test
type: http
seq: 6
http:
method: GET
url: http://localhost:3000/api/v1/restricted/meili-search/test
auth: inherit
settings:
encodeUrl: true
timeout: 0
followRedirects: true
maxRedirects: 5

View File

@@ -0,0 +1,22 @@
info:
name: update-choice
type: http
seq: 3
http:
method: POST
url: http://localhost:3000/api/v1/public/auth/update-choice?lang_id=0&country_id=1
params:
- name: lang_id
value: "0"
type: query
- name: country_id
value: "1"
type: query
auth: inherit
settings:
encodeUrl: true
timeout: 0
followRedirects: true
maxRedirects: 5

4
bruno/folder.yml Normal file
View File

@@ -0,0 +1,4 @@
info:
name: bruno
type: folder
seq: 18

2
go.mod
View File

@@ -5,6 +5,7 @@ go 1.26.0
require (
cloud.google.com/go/auth v0.16.4
cloud.google.com/go/translate v1.12.7
git.ma-al.com/goc_marek/gormcol v1.0.3
github.com/WinterYukky/gorm-extra-clause-plugin v0.4.0
github.com/a-h/templ v0.3.1001
github.com/alecthomas/chroma v0.10.0
@@ -28,7 +29,6 @@ require (
cloud.google.com/go v0.121.6 // indirect
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
cloud.google.com/go/longrunning v0.6.7 // indirect
git.ma-al.com/goc_marek/gormcol v1.0.3 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect

11
go.sum
View File

@@ -217,17 +217,11 @@ go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts=
golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos=
golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4=
golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA=
golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8=
golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w=
golang.org/x/mod v0.34.0 h1:xIHgNUUnW6sYkcM5Jleh05DvLOtwc6RitGHbDk4akRI=
golang.org/x/mod v0.34.0/go.mod h1:ykgH52iCZe79kzLLMhyCUzhMci+nQj+0XkbXpNYtVjY=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo=
golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y=
golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0=
golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw=
golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=
@@ -244,17 +238,14 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo=
golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.40.0 h1:36e4zGLqU4yhjlmxEaagx2KuYbJq3EwY8K943ZsHcvg=
golang.org/x/term v0.40.0/go.mod h1:w2P8uVp06p2iyKKuvXIm7N/y0UCRt3UfJTfZ7oOpglM=
golang.org/x/term v0.41.0 h1:QCgPso/Q3RTJx2Th4bDLqML4W6iJiaXFq2/ftQF13YU=
golang.org/x/term v0.41.0/go.mod h1:3pfBgksrReYfZ5lvYM0kSO0LIkAl4Yl2bXOkKP7Ec2A=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8=
golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA=
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k=
golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0=
golang.org/x/tools v0.43.0 h1:12BdW9CeB3Z+J/I/wj34VMl8X+fEXBxVR90JeMX5E7s=
golang.org/x/tools v0.43.0/go.mod h1:uHkMso649BX2cZK6+RpuIPXS3ho2hZo4FVwfoy1vIk0=
google.golang.org/api v0.247.0 h1:tSd/e0QrUlLsrwMKmkbQhYVa109qIintOls2Wh6bngc=

View File

@@ -24,6 +24,7 @@ vue:
- "**/dist/**"
- "**/.nuxt/**"
- "**/.output/**"
tablename_prefix: "b2b_"
# Vue scope and components
scope_id: 3
language_ids:
@@ -53,6 +54,7 @@ go:
- "**/vendor/**"
- "**/.git/**"
- "**/node_modules/**"
tablename_prefix: "b2b_"
# Go scope and components
scope_id: 1
scope_name: "Backend"
@@ -73,6 +75,7 @@ go:
# Legacy configuration (for backward compatibility)
# Used when vue/go sections are not present
save:
tablename_prefix: "b2b_"
scope_id: 1
scope_name: "Default"
language_ids: