v2.0: massive test data (104 products, 41 postings, 20 returns, 20 payouts, 25 txs, 3 companies)
Some checks failed
deploy / deploy (push) Failing after 2s
test / test (push) Failing after 1s

- Remove unused gin dependency from go.mod
- Remove credential logging from startup
- Remove dead parseOfferIDs function
- Add method check to GET /v1/product/list
- Complete all filter implementations (since, to, status, product_id, return_id, dir, analytics, page)
- CancelPosting now validates posting existence (404 for unknown)
- Implement MOCK_STOCKS_JSON file loading
- Add Phase 2 endpoints: v3/product/import, v1/product/info/description,
  v1/product/info/attributes, v2/category/tree, v3/category/attribute,
  v3/category/attribute/values
- Generate 104 products/stocks/prices across 3 companies:
  TechGiant (TG-0001..TG-0035), FashionLine (FL-0001..FL-0035), HomeStyle (HS-0001..HS-0034)
- 41 postings, 20 returns, 20 payouts, 25 transactions
- 31 tests (all PASS with race detector)
- Add Makefile
This commit is contained in:
Rinat
2026-07-17 14:38:53 +03:00
parent bb665d31bf
commit 50dc046369
9 changed files with 1644 additions and 374 deletions

View File

@ -0,0 +1,263 @@
package handlers
import (
"encoding/json"
"net/http"
)
type CategoryTreeRequest struct {
Language string `json:"language"`
}
type CategoryTreeNode struct {
CategoryID int64 `json:"category_id"`
Title string `json:"title"`
Children []CategoryTreeNode `json:"children"`
}
type CategoryTreeResponse struct {
Result []CategoryTreeNode `json:"result"`
}
func CategoryTree(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "method not allowed", 405)
return
}
var req CategoryTreeRequest
_ = json.NewDecoder(r.Body).Decode(&req)
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(CategoryTreeResponse{
Result: []CategoryTreeNode{
{
CategoryID: 17000000,
Title: "Электроника",
Children: []CategoryTreeNode{
{CategoryID: 17000001, Title: "Смартфоны и гаджеты", Children: []CategoryTreeNode{
{CategoryID: 17036136, Title: "Смартфоны"},
{CategoryID: 17036137, Title: "Планшеты"},
}},
{CategoryID: 17000002, Title: "Ноутбуки и компьютеры"},
},
},
{
CategoryID: 17010000,
Title: "Одежда",
Children: []CategoryTreeNode{
{CategoryID: 17010001, Title: "Мужская одежда"},
{CategoryID: 17010002, Title: "Женская одежда"},
},
},
{
CategoryID: 17020000,
Title: "Дом и сад",
Children: []CategoryTreeNode{
{CategoryID: 17020001, Title: "Мебель"},
{CategoryID: 17020002, Title: "Освещение"},
},
},
},
})
}
type CategoryAttributeRequest struct {
AttributeType string `json:"attribute_type"`
CategoryID []int64 `json:"category_id"`
Language string `json:"language"`
}
type CategoryAttribute struct {
ID int64 `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
Type string `json:"type"`
IsCollection bool `json:"is_collection"`
IsRequired bool `json:"is_required"`
GroupID int64 `json:"group_id"`
GroupName string `json:"group_name"`
DictionaryID int64 `json:"dictionary_id"`
}
type CategoryAttributesResponse struct {
Result []CategoryAttribute `json:"result"`
}
func CategoryAttributes(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "method not allowed", 405)
return
}
var req CategoryAttributeRequest
_ = json.NewDecoder(r.Body).Decode(&req)
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(CategoryAttributesResponse{
Result: []CategoryAttribute{
{
ID: 8229,
Name: "Название модели",
Description: "Название модели товара",
Type: "String",
IsCollection: false,
IsRequired: true,
GroupID: 1,
GroupName: "Основные характеристики",
DictionaryID: 0,
},
{
ID: 85,
Name: "Бренд",
Description: "Производитель товара",
Type: "String",
IsCollection: false,
IsRequired: true,
GroupID: 1,
GroupName: "Основные характеристики",
DictionaryID: 0,
},
{
ID: 9044,
Name: "Цвет товара",
Description: "Основной цвет",
Type: "String",
IsCollection: false,
IsRequired: false,
GroupID: 2,
GroupName: "Внешний вид",
DictionaryID: 0,
},
{
ID: 4416,
Name: "Гарантия",
Description: "Срок гарантии в месяцах",
Type: "Number",
IsCollection: false,
IsRequired: false,
GroupID: 3,
GroupName: "Гарантия и сервис",
DictionaryID: 0,
},
{
ID: 4074,
Name: "Комплектация",
Description: "Что входит в комплект поставки",
Type: "String",
IsCollection: true,
IsRequired: false,
GroupID: 4,
GroupName: "Комплектация",
DictionaryID: 0,
},
{
ID: 5076,
Name: "Вес с упаковкой",
Description: "Вес товара в упаковке, г",
Type: "Number",
IsCollection: false,
IsRequired: false,
GroupID: 5,
GroupName: "Упаковка и габариты",
DictionaryID: 0,
},
},
})
}
type CategoryAttributeValuesRequest struct {
AttributeID int64 `json:"attribute_id"`
CategoryID int64 `json:"category_id"`
Language string `json:"language"`
}
type CategoryAttributeValue struct {
ID int64 `json:"id"`
Value string `json:"value"`
Info string `json:"info,omitempty"`
}
type CategoryAttributeValuesResponse struct {
Result []CategoryAttributeValue `json:"result"`
}
func CategoryAttributeValues(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "method not allowed", 405)
return
}
var req CategoryAttributeValuesRequest
_ = json.NewDecoder(r.Body).Decode(&req)
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(CategoryAttributeValuesResponse{
Result: []CategoryAttributeValue{
{ID: 1, Value: "Apple", Info: "Apple Inc."},
{ID: 2, Value: "Samsung", Info: "Samsung Electronics"},
{ID: 3, Value: "Xiaomi", Info: "Xiaomi Corporation"},
{ID: 4, Value: "Huawei", Info: "Huawei Technologies"},
},
})
}
type ProductAttributesRequest struct {
Filter struct {
OfferIDs []string `json:"offer_id"`
ProductIDs []int64 `json:"product_id"`
} `json:"filter"`
}
type ProductAttributeValue struct {
AttributeID int64 `json:"attribute_id"`
Value string `json:"value"`
}
type ProductAttributesResult struct {
OfferID string `json:"offer_id"`
ProductID int64 `json:"product_id"`
Attributes []ProductAttributeValue `json:"attributes"`
}
type ProductAttributesResponse struct {
Result []ProductAttributesResult `json:"result"`
}
func ProductAttributes(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "method not allowed", 405)
return
}
var req ProductAttributesRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
writeError(w, 400, "invalid json")
return
}
allProducts := GetProductsFixtures()
results := make([]ProductAttributesResult, 0)
for _, oid := range req.Filter.OfferIDs {
for _, p := range allProducts {
if p.OfferID == oid {
results = append(results, ProductAttributesResult{
OfferID: p.OfferID,
ProductID: p.ProductID,
Attributes: []ProductAttributeValue{
{AttributeID: 8229, Value: p.Name},
{AttributeID: 85, Value: "Test Brand"},
{AttributeID: 9044, Value: "Черный"},
},
})
break
}
}
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(ProductAttributesResponse{
Result: results,
})
}