From 701004d005451a319606643c5c5e83c22812e4a9 Mon Sep 17 00:00:00 2001 From: Wiktor Date: Fri, 3 Apr 2026 09:22:58 +0200 Subject: [PATCH] chore: add bruno endpoints --- app/delivery/web/api/restricted/currency.go | 29 ------- app/delivery/web/api/restricted/product.go | 1 - app/repos/productsRepo/productsRepo.go | 26 ++++-- app/service/productService/productService.go | 4 +- bruno/api_v1/Change Locales.yml | 2 +- bruno/api_v1/Create Search Index.yml | 2 +- bruno/api_v1/Delete Index - MeiliSearch.yml | 2 +- bruno/api_v1/Search Index Settings.yml | 2 +- bruno/api_v1/Search Items.yml | 2 +- bruno/api_v1/auth/Login.yml | 29 +++++++ bruno/api_v1/auth/folder.yml | 7 ++ bruno/api_v1/currency/currency-rate.yml | 15 ++++ bruno/api_v1/currency/currency.yml | 20 +++++ bruno/api_v1/currency/folder.yml | 7 ++ bruno/api_v1/customer/Customer (me).yml | 19 +++++ bruno/api_v1/customer/Customer (other).yml | 19 +++++ bruno/api_v1/customer/folder.yml | 7 ++ bruno/api_v1/product/Get Product.yml | 15 ++++ bruno/api_v1/{ => product}/Products List.yml | 0 bruno/api_v1/product/folder.yml | 7 ++ .../20260302163122_create_tables.sql | 81 ++++--------------- .../20260302163123_create_tables_data.sql | 9 ++- 22 files changed, 194 insertions(+), 111 deletions(-) create mode 100644 bruno/api_v1/auth/Login.yml create mode 100644 bruno/api_v1/auth/folder.yml create mode 100644 bruno/api_v1/currency/currency-rate.yml create mode 100644 bruno/api_v1/currency/currency.yml create mode 100644 bruno/api_v1/currency/folder.yml create mode 100644 bruno/api_v1/customer/Customer (me).yml create mode 100644 bruno/api_v1/customer/Customer (other).yml create mode 100644 bruno/api_v1/customer/folder.yml create mode 100644 bruno/api_v1/product/Get Product.yml rename bruno/api_v1/{ => product}/Products List.yml (100%) create mode 100644 bruno/api_v1/product/folder.yml diff --git a/app/delivery/web/api/restricted/currency.go b/app/delivery/web/api/restricted/currency.go index 3ffa226..52dee21 100644 --- a/app/delivery/web/api/restricted/currency.go +++ b/app/delivery/web/api/restricted/currency.go @@ -32,7 +32,6 @@ func CurrencyHandlerRoutes(r fiber.Router) fiber.Router { r.Post("/currency-rate", handler.PostCurrencyRate) r.Get("/currency-rate/:id", handler.GetCurrencyRate) - // r.Get("/currencies", handler.GetCurrencyRates) return r } @@ -65,33 +64,5 @@ func (h *CurrencyHandler) GetCurrencyRate(c fiber.Ctx) error { return c.Status(responseErrors.GetErrorStatus(err)).JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) } - // err = h.CurrencyService.GetCurrencyRate(userID, uint(productID), uint(productShopID), uint(productLangID), updates) - // if err != nil { - // return c.Status(responseErrors.GetErrorStatus(err)). - // JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) - // } - - return c.JSON(response.Make(currency, 0, i18n.T_(c, response.Message_OK))) -} - -func (h *CurrencyHandler) GetCurrencyRates(c fiber.Ctx) error { - idStr := c.Params("id") - id, err := strconv.Atoi(idStr) - if err != nil { - return c.Status(responseErrors.GetErrorStatus(err)).JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) - - } - - currency, err := h.CurrencyService.GetCurrency(uint(id)) - if err != nil { - return c.Status(responseErrors.GetErrorStatus(err)).JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) - } - - // err = h.CurrencyService.GetCurrencyRate(userID, uint(productID), uint(productShopID), uint(productLangID), updates) - // if err != nil { - // return c.Status(responseErrors.GetErrorStatus(err)). - // JSON(response.Make(nullable.GetNil(""), 0, responseErrors.GetErrorCode(c, err))) - // } - return c.JSON(response.Make(currency, 0, i18n.T_(c, response.Message_OK))) } diff --git a/app/delivery/web/api/restricted/product.go b/app/delivery/web/api/restricted/product.go index 8670c1a..eaade19 100644 --- a/app/delivery/web/api/restricted/product.go +++ b/app/delivery/web/api/restricted/product.go @@ -31,7 +31,6 @@ func NewProductsHandler() *ProductsHandler { func ProductsHandlerRoutes(r fiber.Router) fiber.Router { handler := NewProductsHandler() - //TODO: WIP doesn't work yet r.Get("/:id/:country_id/:quantity", handler.GetProductJson) return r diff --git a/app/repos/productsRepo/productsRepo.go b/app/repos/productsRepo/productsRepo.go index af68a63..7c6c08f 100644 --- a/app/repos/productsRepo/productsRepo.go +++ b/app/repos/productsRepo/productsRepo.go @@ -1,11 +1,14 @@ package productsRepo import ( + "encoding/json" + "fmt" + "git.ma-al.com/goc_daniel/b2b/app/db" ) type UIProductsRepo interface { - GetJSON(p_id_product, p_id_shop, p_id_lang, p_id_customer, b2b_id_country, p_quantity int) (*string, error) + GetJSON(p_id_product, p_id_shop, p_id_lang, p_id_customer, b2b_id_country, p_quantity int) (*json.RawMessage, error) } type ProductsRepo struct{} @@ -14,12 +17,23 @@ func New() UIProductsRepo { return &ProductsRepo{} } -func (repo *ProductsRepo) GetJSON(p_id_product, p_id_shop, p_id_lang, p_id_customer, b2b_id_country, p_quantity int) (*string, error) { - var product string +func (repo *ProductsRepo) GetJSON(p_id_product, p_id_shop, p_id_lang, p_id_customer, b2b_id_country, p_quantity int) (*json.RawMessage, error) { + var productStr string // ← Scan as string first - err := db.DB.Raw(`CALL get_full_product(?,?,?,?,?,?)`, p_id_product, p_id_shop, p_id_lang, p_id_customer, b2b_id_country, p_quantity). - Scan(&product). + err := db.DB.Raw(`CALL get_full_product(?,?,?,?,?,?)`, + p_id_product, p_id_shop, p_id_lang, p_id_customer, b2b_id_country, p_quantity). + Scan(&productStr). Error - return &product, err + if err != nil { + return nil, err + } + + // Optional: validate it's valid JSON + if !json.Valid([]byte(productStr)) { + return nil, fmt.Errorf("invalid json returned from stored procedure") + } + + raw := json.RawMessage(productStr) + return &raw, nil } diff --git a/app/service/productService/productService.go b/app/service/productService/productService.go index 364079d..66245f1 100644 --- a/app/service/productService/productService.go +++ b/app/service/productService/productService.go @@ -1,6 +1,8 @@ package productService import ( + "encoding/json" + "git.ma-al.com/goc_daniel/b2b/app/repos/productsRepo" constdata "git.ma-al.com/goc_daniel/b2b/app/utils/const_data" ) @@ -15,7 +17,7 @@ func New() *ProductService { } } -func (s *ProductService) GetJSON(p_id_product, p_id_lang, p_id_customer, b2b_id_country, p_quantity int) (*string, error) { +func (s *ProductService) GetJSON(p_id_product, p_id_lang, p_id_customer, b2b_id_country, p_quantity int) (*json.RawMessage, error) { products, err := s.productsRepo.GetJSON(p_id_product, constdata.SHOP_ID, p_id_lang, p_id_customer, b2b_id_country, p_quantity) if err != nil { return products, err diff --git a/bruno/api_v1/Change Locales.yml b/bruno/api_v1/Change Locales.yml index cff1b71..4e2388e 100644 --- a/bruno/api_v1/Change Locales.yml +++ b/bruno/api_v1/Change Locales.yml @@ -1,7 +1,7 @@ info: name: Change Locales type: http - seq: 4 + seq: 3 http: method: POST diff --git a/bruno/api_v1/Create Search Index.yml b/bruno/api_v1/Create Search Index.yml index 74040b6..a5dfd07 100644 --- a/bruno/api_v1/Create Search Index.yml +++ b/bruno/api_v1/Create Search Index.yml @@ -1,7 +1,7 @@ info: name: Create Search Index type: http - seq: 2 + seq: 1 http: method: GET diff --git a/bruno/api_v1/Delete Index - MeiliSearch.yml b/bruno/api_v1/Delete Index - MeiliSearch.yml index e5e011e..b18e531 100644 --- a/bruno/api_v1/Delete Index - MeiliSearch.yml +++ b/bruno/api_v1/Delete Index - MeiliSearch.yml @@ -1,7 +1,7 @@ info: name: Delete Index - MeiliSearch type: http - seq: 7 + seq: 5 http: method: DELETE diff --git a/bruno/api_v1/Search Index Settings.yml b/bruno/api_v1/Search Index Settings.yml index 8c3c4cb..b11cd07 100644 --- a/bruno/api_v1/Search Index Settings.yml +++ b/bruno/api_v1/Search Index Settings.yml @@ -1,7 +1,7 @@ info: name: Search Index Settings type: http - seq: 5 + seq: 4 http: method: POST diff --git a/bruno/api_v1/Search Items.yml b/bruno/api_v1/Search Items.yml index 112fb94..135daab 100644 --- a/bruno/api_v1/Search Items.yml +++ b/bruno/api_v1/Search Items.yml @@ -1,7 +1,7 @@ info: name: Search Items type: http - seq: 3 + seq: 2 http: method: POST diff --git a/bruno/api_v1/auth/Login.yml b/bruno/api_v1/auth/Login.yml new file mode 100644 index 0000000..d605774 --- /dev/null +++ b/bruno/api_v1/auth/Login.yml @@ -0,0 +1,29 @@ +info: + name: Login + type: http + seq: 1 + +http: + method: POST + url: "{{bas_url}}/public/auth/login" + body: + type: json + data: |- + { + "email":"{{email}}", + "password":"{{password}}" + } + auth: inherit + +runtime: + variables: + - name: email + value: admin@ma-al.com + - name: password + value: Maal12345678 + +settings: + encodeUrl: true + timeout: 0 + followRedirects: true + maxRedirects: 5 diff --git a/bruno/api_v1/auth/folder.yml b/bruno/api_v1/auth/folder.yml new file mode 100644 index 0000000..4d04d32 --- /dev/null +++ b/bruno/api_v1/auth/folder.yml @@ -0,0 +1,7 @@ +info: + name: auth + type: folder + seq: 6 + +request: + auth: inherit diff --git a/bruno/api_v1/currency/currency-rate.yml b/bruno/api_v1/currency/currency-rate.yml new file mode 100644 index 0000000..d5e5bac --- /dev/null +++ b/bruno/api_v1/currency/currency-rate.yml @@ -0,0 +1,15 @@ +info: + name: currency-rate + type: http + seq: 2 + +http: + method: POST + url: "{{bas_url}}/restricted/currency-rate" + auth: inherit + +settings: + encodeUrl: true + timeout: 0 + followRedirects: true + maxRedirects: 5 diff --git a/bruno/api_v1/currency/currency.yml b/bruno/api_v1/currency/currency.yml new file mode 100644 index 0000000..b3de3e9 --- /dev/null +++ b/bruno/api_v1/currency/currency.yml @@ -0,0 +1,20 @@ +info: + name: currency + type: http + seq: 1 + +http: + method: GET + url: "{{bas_url}}/restricted/currency-rate/{{id}}" + auth: inherit + +runtime: + variables: + - name: id + value: "1" + +settings: + encodeUrl: true + timeout: 0 + followRedirects: true + maxRedirects: 5 diff --git a/bruno/api_v1/currency/folder.yml b/bruno/api_v1/currency/folder.yml new file mode 100644 index 0000000..e409d83 --- /dev/null +++ b/bruno/api_v1/currency/folder.yml @@ -0,0 +1,7 @@ +info: + name: currency + type: folder + seq: 8 + +request: + auth: inherit diff --git a/bruno/api_v1/customer/Customer (me).yml b/bruno/api_v1/customer/Customer (me).yml new file mode 100644 index 0000000..253bead --- /dev/null +++ b/bruno/api_v1/customer/Customer (me).yml @@ -0,0 +1,19 @@ +info: + name: Customer (me) + type: http + seq: 2 + +http: + method: GET + url: "{{bas_url}}/restricted/customer?id=1" + params: + - name: id + value: "1" + type: query + auth: inherit + +settings: + encodeUrl: true + timeout: 0 + followRedirects: true + maxRedirects: 5 diff --git a/bruno/api_v1/customer/Customer (other).yml b/bruno/api_v1/customer/Customer (other).yml new file mode 100644 index 0000000..161094d --- /dev/null +++ b/bruno/api_v1/customer/Customer (other).yml @@ -0,0 +1,19 @@ +info: + name: Customer (other) + type: http + seq: 9 + +http: + method: GET + url: "{{bas_url}}/restricted/customer?id=1" + params: + - name: id + value: "1" + type: query + auth: inherit + +settings: + encodeUrl: true + timeout: 0 + followRedirects: true + maxRedirects: 5 diff --git a/bruno/api_v1/customer/folder.yml b/bruno/api_v1/customer/folder.yml new file mode 100644 index 0000000..cdd2d6f --- /dev/null +++ b/bruno/api_v1/customer/folder.yml @@ -0,0 +1,7 @@ +info: + name: customer + type: folder + seq: 9 + +request: + auth: inherit diff --git a/bruno/api_v1/product/Get Product.yml b/bruno/api_v1/product/Get Product.yml new file mode 100644 index 0000000..b9b182e --- /dev/null +++ b/bruno/api_v1/product/Get Product.yml @@ -0,0 +1,15 @@ +info: + name: Get Product + type: http + seq: 1 + +http: + method: GET + url: "{{bas_url}}/restricted/product/200/1/5" + auth: inherit + +settings: + encodeUrl: true + timeout: 0 + followRedirects: true + maxRedirects: 5 diff --git a/bruno/api_v1/Products List.yml b/bruno/api_v1/product/Products List.yml similarity index 100% rename from bruno/api_v1/Products List.yml rename to bruno/api_v1/product/Products List.yml diff --git a/bruno/api_v1/product/folder.yml b/bruno/api_v1/product/folder.yml new file mode 100644 index 0000000..cd2ad8b --- /dev/null +++ b/bruno/api_v1/product/folder.yml @@ -0,0 +1,7 @@ +info: + name: product + type: folder + seq: 7 + +request: + auth: inherit diff --git a/i18n/migrations/20260302163122_create_tables.sql b/i18n/migrations/20260302163122_create_tables.sql index 71b1344..b88f14e 100644 --- a/i18n/migrations/20260302163122_create_tables.sql +++ b/i18n/migrations/20260302163122_create_tables.sql @@ -45,12 +45,7 @@ CREATE TABLE IF NOT EXISTS b2b_translations ( CREATE TABLE `b2b_roles` ( `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, - `name` VARCHAR(63) NULL, - PRIMARY KEY (`id`) -); -CREATE UNIQUE INDEX `IX_b2b_roles_id` -ON `b2b_roles` ( - `id` ASC + `name` VARCHAR(63) NULL ); CREATE TABLE b2b_permissions ( @@ -76,8 +71,20 @@ CREATE TABLE b2b_role_permissions ( ); CREATE TABLE `b2b_top_menu_roles` ( - `top_menu_id` BIGINT UNSIGNED NOT NULL, - `role_id` BIGINT UNSIGNED NOT NULL + `top_menu_id` INT NOT NULL, + `role_id` BIGINT UNSIGNED NOT NULL, + + PRIMARY KEY (`top_menu_id`, `role_id`), + + CONSTRAINT fk_top_menu_roles_menu + FOREIGN KEY (`top_menu_id`) + REFERENCES `b2b_top_menu`(`menu_id`) + ON DELETE CASCADE, + + CONSTRAINT fk_top_menu_roles_role + FOREIGN KEY (`role_id`) + REFERENCES `b2b_roles`(`id`) + ON DELETE CASCADE ); -- customers @@ -216,15 +223,11 @@ CREATE TABLE b2b_specific_price ( is_active BOOLEAN DEFAULT TRUE ) ENGINE = InnoDB; CREATE INDEX idx_b2b_scope ON b2b_specific_price(scope); -CREATE INDEX idx_b2b_customer ON b2b_specific_price(b2b_id_customer); -CREATE INDEX idx_b2b_country ON b2b_specific_price(b2b_id_country); CREATE INDEX idx_b2b_active_dates ON b2b_specific_price(is_active, valid_from, valid_till); CREATE INDEX idx_b2b_lookup ON b2b_specific_price ( scope, is_active, - b2b_id_customer, - b2b_id_country, from_quantity ); @@ -373,60 +376,6 @@ END$$ DELIMITER ; -CREATE TABLE b2b_specific_price_product ( - b2b_specific_price_id BIGINT UNSIGNED, - id_product INT UNSIGNED, - PRIMARY KEY (b2b_specific_price_id, id_product), - FOREIGN KEY (b2b_specific_price_id) REFERENCES b2b_specific_price(id) ON DELETE CASCADE, - FOREIGN KEY (id_product) REFERENCES ps_product(id_product) ON DELETE CASCADE -); - -CREATE TABLE b2b_specific_price_category ( - b2b_specific_price_id BIGINT UNSIGNED, - id_category INT UNSIGNED, - PRIMARY KEY (b2b_specific_price_id, id_category), - FOREIGN KEY (b2b_specific_price_id) REFERENCES b2b_specific_price(id) ON DELETE CASCADE, - FOREIGN KEY (id_category) REFERENCES ps_category(id_category) ON DELETE CASCADE -); - -CREATE TABLE b2b_specific_price_product_attribute ( - b2b_specific_price_id BIGINT UNSIGNED, - id_product_attribute INT UNSIGNED, - PRIMARY KEY (b2b_specific_price_id, id_product_attribute), - FOREIGN KEY (b2b_specific_price_id) REFERENCES b2b_specific_price(id) ON DELETE CASCADE, - FOREIGN KEY (id_product_attribute) REFERENCES ps_product_attribute(id_product_attribute) ON DELETE CASCADE -); - -CREATE TABLE b2b_specific_price_customer ( - b2b_specific_price_id BIGINT UNSIGNED, - b2b_id_customer BIGINT UNSIGNED, - PRIMARY KEY (b2b_specific_price_id, b2b_id_customer), - FOREIGN KEY (b2b_specific_price_id) REFERENCES b2b_specific_price(id) ON DELETE CASCADE, - FOREIGN KEY (b2b_id_customer) REFERENCES b2b_customers(id) ON DELETE CASCADE -); - -CREATE TABLE b2b_specific_price_country ( - b2b_specific_price_id BIGINT UNSIGNED, - b2b_id_country BIGINT UNSIGNED, - PRIMARY KEY (b2b_specific_price_id, b2b_id_country), - FOREIGN KEY (b2b_specific_price_id) REFERENCES b2b_specific_price(id) ON DELETE CASCADE, - FOREIGN KEY (b2b_id_country) REFERENCES b2b_countries(id) ON DELETE CASCADE -); - -CREATE INDEX idx_b2b_product_rel -ON b2b_specific_price_product (id_product); - -CREATE INDEX idx_b2b_category_rel -ON b2b_specific_price_category (id_category); - -CREATE INDEX idx_b2b_product_attribute_rel -ON b2b_specific_price_product_attribute (id_product_attribute); - -CREATE INDEX idx_bsp_customer -ON b2b_specific_price_customer (b2b_specific_price_id, b2b_id_customer); - -CREATE INDEX idx_bsp_country -ON b2b_specific_price_country (b2b_specific_price_id, b2b_id_country); -- +goose Down DROP TABLE IF EXISTS b2b_countries; diff --git a/i18n/migrations/20260302163123_create_tables_data.sql b/i18n/migrations/20260302163123_create_tables_data.sql index 7bae811..88875c5 100644 --- a/i18n/migrations/20260302163123_create_tables_data.sql +++ b/i18n/migrations/20260302163123_create_tables_data.sql @@ -7,12 +7,15 @@ VALUES (2, '2022-09-16 17:10:02.852', '2026-03-02 21:24:36.779730', NULL, 'English', 'en', 'en', '__-__-____', '__-__', 0, 1, 1, '🇬🇧'), (3, '2022-09-16 17:10:02.852', '2026-03-02 21:24:36.779730', NULL, 'Deutsch', 'de', 'de', '__-__-____', '__-__', 0, 0, 1, '🇩🇪'); +INSERT INTO `b2b_roles` (`name`, `id`) VALUES ('user','1'); +INSERT INTO `b2b_roles` (`name`, `id`) VALUES ('admin','2'); +INSERT INTO `b2b_roles` (`name`, `id`) VALUES ('super_admin','3'); + -- insert sample admin user admin@ma-al.com/Maal12345678 - -INSERT IGNORE INTO b2b_customers (id, email, password, first_name, last_name, role, provider, provider_id, avatar_url, is_active, email_verified, email_verification_token, email_verification_expires, password_reset_token, password_reset_expires, last_password_reset_request, last_login_at, lang_id, country_id, created_at, updated_at, deleted_at) +INSERT IGNORE INTO b2b_customers (id, email, password, first_name, last_name, role_id, provider, provider_id, avatar_url, is_active, email_verified, email_verification_token, email_verification_expires, password_reset_token, password_reset_expires, last_password_reset_request, last_login_at, lang_id, country_id, created_at, updated_at, deleted_at) VALUES - (1, 'admin@ma-al.com', '$2a$10$Owy9DjrS0l3Fz4XoOvh5pulgmOMqdwXmb7hYE9BovnSuWS2plGr82', 'Super', 'Admin', 'admin', 'local', '', '', 1, 1, NULL, NULL, '', NULL, NULL, NULL, 1, 1, '2026-03-02 16:55:10.252740', '2026-03-02 16:55:10.252740', NULL); + (1, 'admin@ma-al.com', '$2a$10$Owy9DjrS0l3Fz4XoOvh5pulgmOMqdwXmb7hYE9BovnSuWS2plGr82', 'Super', 'Admin', 2, 'local', '', '', 1, 1, NULL, NULL, '', NULL, NULL, NULL, 1, 1, '2026-03-02 16:55:10.252740', '2026-03-02 16:55:10.252740', NULL); ALTER TABLE b2b_customers AUTO_INCREMENT = 1; INSERT INTO `b2b_currencies` (`ps_id_currency`, `is_default`, `is_active`) VALUES