Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -5,6 +5,7 @@ import (
|
|||||||
"bssapp-backend/models"
|
"bssapp-backend/models"
|
||||||
"context"
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@@ -16,176 +17,24 @@ func GetProductPricingList(ctx context.Context, limit int, afterProductCode stri
|
|||||||
}
|
}
|
||||||
afterProductCode = strings.TrimSpace(afterProductCode)
|
afterProductCode = strings.TrimSpace(afterProductCode)
|
||||||
|
|
||||||
cursorFilter := ""
|
// Stage 1: fetch only paged products first (fast path).
|
||||||
args := make([]any, 0, 1)
|
productQuery := `
|
||||||
if afterProductCode != "" {
|
SELECT TOP (` + strconv.Itoa(limit) + `)
|
||||||
cursorFilter = "WHERE bp.ProductCode > @p1"
|
LTRIM(RTRIM(ProductCode)) AS ProductCode,
|
||||||
args = append(args, afterProductCode)
|
COALESCE(LTRIM(RTRIM(ProductAtt45Desc)), '') AS AskiliYan,
|
||||||
}
|
COALESCE(LTRIM(RTRIM(ProductAtt44Desc)), '') AS Kategori,
|
||||||
|
COALESCE(LTRIM(RTRIM(ProductAtt42Desc)), '') AS UrunIlkGrubu,
|
||||||
query := `
|
COALESCE(LTRIM(RTRIM(ProductAtt01Desc)), '') AS UrunAnaGrubu,
|
||||||
WITH base_products AS (
|
COALESCE(LTRIM(RTRIM(ProductAtt02Desc)), '') AS UrunAltGrubu,
|
||||||
SELECT
|
COALESCE(LTRIM(RTRIM(ProductAtt41Desc)), '') AS Icerik,
|
||||||
LTRIM(RTRIM(ProductCode)) AS ProductCode,
|
COALESCE(LTRIM(RTRIM(ProductAtt29Desc)), '') AS Karisim,
|
||||||
COALESCE(LTRIM(RTRIM(ProductAtt45Desc)), '') AS AskiliYan,
|
COALESCE(LTRIM(RTRIM(ProductAtt10Desc)), '') AS Marka
|
||||||
COALESCE(LTRIM(RTRIM(ProductAtt44Desc)), '') AS Kategori,
|
FROM ProductFilterWithDescription('TR')
|
||||||
COALESCE(LTRIM(RTRIM(ProductAtt42Desc)), '') AS UrunIlkGrubu,
|
WHERE ProductAtt42 IN ('SERI', 'AKSESUAR')
|
||||||
COALESCE(LTRIM(RTRIM(ProductAtt01Desc)), '') AS UrunAnaGrubu,
|
AND IsBlocked = 0
|
||||||
COALESCE(LTRIM(RTRIM(ProductAtt02Desc)), '') AS UrunAltGrubu,
|
AND LEN(LTRIM(RTRIM(ProductCode))) = 13
|
||||||
COALESCE(LTRIM(RTRIM(ProductAtt41Desc)), '') AS Icerik,
|
AND (@p1 = '' OR LTRIM(RTRIM(ProductCode)) > @p1)
|
||||||
COALESCE(LTRIM(RTRIM(ProductAtt29Desc)), '') AS Karisim,
|
ORDER BY LTRIM(RTRIM(ProductCode));
|
||||||
COALESCE(LTRIM(RTRIM(ProductAtt10Desc)), '') AS Marka
|
|
||||||
FROM ProductFilterWithDescription('TR')
|
|
||||||
WHERE ProductAtt42 IN ('SERI', 'AKSESUAR')
|
|
||||||
AND IsBlocked = 0
|
|
||||||
AND LEN(LTRIM(RTRIM(ProductCode))) = 13
|
|
||||||
),
|
|
||||||
paged_products AS (
|
|
||||||
SELECT TOP (` + strconv.Itoa(limit) + `)
|
|
||||||
bp.ProductCode
|
|
||||||
FROM base_products bp
|
|
||||||
` + cursorFilter + `
|
|
||||||
ORDER BY bp.ProductCode
|
|
||||||
),
|
|
||||||
latest_base_price AS (
|
|
||||||
SELECT
|
|
||||||
LTRIM(RTRIM(b.ItemCode)) AS ItemCode,
|
|
||||||
CAST(b.Price AS DECIMAL(18, 2)) AS CostPrice,
|
|
||||||
CONVERT(VARCHAR(10), b.PriceDate, 23) AS LastPricingDate,
|
|
||||||
ROW_NUMBER() OVER (
|
|
||||||
PARTITION BY LTRIM(RTRIM(b.ItemCode))
|
|
||||||
ORDER BY b.PriceDate DESC, b.LastUpdatedDate DESC
|
|
||||||
) AS rn
|
|
||||||
FROM prItemBasePrice b
|
|
||||||
WHERE b.ItemTypeCode = 1
|
|
||||||
AND b.BasePriceCode = 1
|
|
||||||
AND LTRIM(RTRIM(b.CurrencyCode)) = 'USD'
|
|
||||||
AND EXISTS (
|
|
||||||
SELECT 1
|
|
||||||
FROM paged_products pp
|
|
||||||
WHERE pp.ProductCode = LTRIM(RTRIM(b.ItemCode))
|
|
||||||
)
|
|
||||||
),
|
|
||||||
stock_entry_dates AS (
|
|
||||||
SELECT
|
|
||||||
LTRIM(RTRIM(s.ItemCode)) AS ItemCode,
|
|
||||||
CONVERT(VARCHAR(10), MAX(s.OperationDate), 23) AS StockEntryDate
|
|
||||||
FROM trStock s WITH(NOLOCK)
|
|
||||||
WHERE s.ItemTypeCode = 1
|
|
||||||
AND LEN(LTRIM(RTRIM(s.ItemCode))) = 13
|
|
||||||
AND s.In_Qty1 > 0
|
|
||||||
AND LTRIM(RTRIM(s.WarehouseCode)) IN (
|
|
||||||
'1-0-14','1-0-10','1-0-8','1-2-5','1-2-4','1-0-12','100','1-0-28',
|
|
||||||
'1-0-24','1-2-6','1-1-14','1-0-2','1-0-52','1-1-2','1-0-21','1-1-3',
|
|
||||||
'1-0-33','101','1-014','1-0-49','1-0-36'
|
|
||||||
)
|
|
||||||
AND EXISTS (
|
|
||||||
SELECT 1
|
|
||||||
FROM paged_products pp
|
|
||||||
WHERE pp.ProductCode = LTRIM(RTRIM(s.ItemCode))
|
|
||||||
)
|
|
||||||
GROUP BY LTRIM(RTRIM(s.ItemCode))
|
|
||||||
),
|
|
||||||
stock_base AS (
|
|
||||||
SELECT
|
|
||||||
LTRIM(RTRIM(s.ItemCode)) AS ItemCode,
|
|
||||||
SUM(s.In_Qty1 - s.Out_Qty1) AS InventoryQty1
|
|
||||||
FROM trStock s WITH(NOLOCK)
|
|
||||||
WHERE s.ItemTypeCode = 1
|
|
||||||
AND LEN(LTRIM(RTRIM(s.ItemCode))) = 13
|
|
||||||
AND EXISTS (
|
|
||||||
SELECT 1
|
|
||||||
FROM paged_products pp
|
|
||||||
WHERE pp.ProductCode = LTRIM(RTRIM(s.ItemCode))
|
|
||||||
)
|
|
||||||
GROUP BY LTRIM(RTRIM(s.ItemCode))
|
|
||||||
),
|
|
||||||
pick_base AS (
|
|
||||||
SELECT
|
|
||||||
LTRIM(RTRIM(p.ItemCode)) AS ItemCode,
|
|
||||||
SUM(p.Qty1) AS PickingQty1
|
|
||||||
FROM PickingStates p
|
|
||||||
WHERE p.ItemTypeCode = 1
|
|
||||||
AND LEN(LTRIM(RTRIM(p.ItemCode))) = 13
|
|
||||||
AND EXISTS (
|
|
||||||
SELECT 1
|
|
||||||
FROM paged_products pp
|
|
||||||
WHERE pp.ProductCode = LTRIM(RTRIM(p.ItemCode))
|
|
||||||
)
|
|
||||||
GROUP BY LTRIM(RTRIM(p.ItemCode))
|
|
||||||
),
|
|
||||||
reserve_base AS (
|
|
||||||
SELECT
|
|
||||||
LTRIM(RTRIM(r.ItemCode)) AS ItemCode,
|
|
||||||
SUM(r.Qty1) AS ReserveQty1
|
|
||||||
FROM ReserveStates r
|
|
||||||
WHERE r.ItemTypeCode = 1
|
|
||||||
AND LEN(LTRIM(RTRIM(r.ItemCode))) = 13
|
|
||||||
AND EXISTS (
|
|
||||||
SELECT 1
|
|
||||||
FROM paged_products pp
|
|
||||||
WHERE pp.ProductCode = LTRIM(RTRIM(r.ItemCode))
|
|
||||||
)
|
|
||||||
GROUP BY LTRIM(RTRIM(r.ItemCode))
|
|
||||||
),
|
|
||||||
disp_base AS (
|
|
||||||
SELECT
|
|
||||||
LTRIM(RTRIM(d.ItemCode)) AS ItemCode,
|
|
||||||
SUM(d.Qty1) AS DispOrderQty1
|
|
||||||
FROM DispOrderStates d
|
|
||||||
WHERE d.ItemTypeCode = 1
|
|
||||||
AND LEN(LTRIM(RTRIM(d.ItemCode))) = 13
|
|
||||||
AND EXISTS (
|
|
||||||
SELECT 1
|
|
||||||
FROM paged_products pp
|
|
||||||
WHERE pp.ProductCode = LTRIM(RTRIM(d.ItemCode))
|
|
||||||
)
|
|
||||||
GROUP BY LTRIM(RTRIM(d.ItemCode))
|
|
||||||
),
|
|
||||||
stock_totals AS (
|
|
||||||
SELECT
|
|
||||||
pp.ProductCode AS ItemCode,
|
|
||||||
CAST(ROUND(
|
|
||||||
ISNULL(sb.InventoryQty1, 0)
|
|
||||||
- ISNULL(pb.PickingQty1, 0)
|
|
||||||
- ISNULL(rb.ReserveQty1, 0)
|
|
||||||
- ISNULL(db.DispOrderQty1, 0)
|
|
||||||
, 2) AS DECIMAL(18, 2)) AS StockQty
|
|
||||||
FROM paged_products pp
|
|
||||||
LEFT JOIN stock_base sb
|
|
||||||
ON sb.ItemCode = pp.ProductCode
|
|
||||||
LEFT JOIN pick_base pb
|
|
||||||
ON pb.ItemCode = pp.ProductCode
|
|
||||||
LEFT JOIN reserve_base rb
|
|
||||||
ON rb.ItemCode = pp.ProductCode
|
|
||||||
LEFT JOIN disp_base db
|
|
||||||
ON db.ItemCode = pp.ProductCode
|
|
||||||
)
|
|
||||||
SELECT
|
|
||||||
bp.ProductCode AS ProductCode,
|
|
||||||
COALESCE(lp.CostPrice, 0) AS CostPrice,
|
|
||||||
COALESCE(st.StockQty, 0) AS StockQty,
|
|
||||||
COALESCE(se.StockEntryDate, '') AS StockEntryDate,
|
|
||||||
COALESCE(lp.LastPricingDate, '') AS LastPricingDate,
|
|
||||||
bp.AskiliYan,
|
|
||||||
bp.Kategori,
|
|
||||||
bp.UrunIlkGrubu,
|
|
||||||
bp.UrunAnaGrubu,
|
|
||||||
bp.UrunAltGrubu,
|
|
||||||
bp.Icerik,
|
|
||||||
bp.Karisim,
|
|
||||||
bp.Marka
|
|
||||||
FROM paged_products pp
|
|
||||||
INNER JOIN base_products bp
|
|
||||||
ON bp.ProductCode = pp.ProductCode
|
|
||||||
LEFT JOIN latest_base_price lp
|
|
||||||
ON lp.ItemCode = bp.ProductCode
|
|
||||||
AND lp.rn = 1
|
|
||||||
LEFT JOIN stock_entry_dates se
|
|
||||||
ON se.ItemCode = bp.ProductCode
|
|
||||||
LEFT JOIN stock_totals st
|
|
||||||
ON st.ItemCode = bp.ProductCode
|
|
||||||
ORDER BY bp.ProductCode;
|
|
||||||
`
|
`
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -194,7 +43,7 @@ func GetProductPricingList(ctx context.Context, limit int, afterProductCode stri
|
|||||||
)
|
)
|
||||||
for attempt := 1; attempt <= 3; attempt++ {
|
for attempt := 1; attempt <= 3; attempt++ {
|
||||||
var err error
|
var err error
|
||||||
rows, err = db.MssqlDB.QueryContext(ctx, query, args...)
|
rows, err = db.MssqlDB.QueryContext(ctx, productQuery, afterProductCode)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
rowsErr = nil
|
rowsErr = nil
|
||||||
break
|
break
|
||||||
@@ -215,15 +64,11 @@ func GetProductPricingList(ctx context.Context, limit int, afterProductCode stri
|
|||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
|
|
||||||
var out []models.ProductPricing
|
out := make([]models.ProductPricing, 0, limit)
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var item models.ProductPricing
|
var item models.ProductPricing
|
||||||
if err := rows.Scan(
|
if err := rows.Scan(
|
||||||
&item.ProductCode,
|
&item.ProductCode,
|
||||||
&item.CostPrice,
|
|
||||||
&item.StockQty,
|
|
||||||
&item.StockEntryDate,
|
|
||||||
&item.LastPricingDate,
|
|
||||||
&item.AskiliYan,
|
&item.AskiliYan,
|
||||||
&item.Kategori,
|
&item.Kategori,
|
||||||
&item.UrunIlkGrubu,
|
&item.UrunIlkGrubu,
|
||||||
@@ -237,6 +82,171 @@ func GetProductPricingList(ctx context.Context, limit int, afterProductCode stri
|
|||||||
}
|
}
|
||||||
out = append(out, item)
|
out = append(out, item)
|
||||||
}
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(out) == 0 {
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stage 2: fetch metrics only for paged product codes.
|
||||||
|
codes := make([]string, 0, len(out))
|
||||||
|
for _, item := range out {
|
||||||
|
codes = append(codes, strings.TrimSpace(item.ProductCode))
|
||||||
|
}
|
||||||
|
codesCSV := strings.Join(codes, ",")
|
||||||
|
|
||||||
|
metricsQuery := `
|
||||||
|
WITH req_codes AS (
|
||||||
|
SELECT DISTINCT LTRIM(RTRIM(value)) AS ProductCode
|
||||||
|
FROM STRING_SPLIT(@p1, ',')
|
||||||
|
WHERE LEN(LTRIM(RTRIM(value))) > 0
|
||||||
|
),
|
||||||
|
latest_base_price AS (
|
||||||
|
SELECT
|
||||||
|
LTRIM(RTRIM(b.ItemCode)) AS ItemCode,
|
||||||
|
CAST(b.Price AS DECIMAL(18, 2)) AS CostPrice,
|
||||||
|
CONVERT(VARCHAR(10), b.PriceDate, 23) AS LastPricingDate,
|
||||||
|
ROW_NUMBER() OVER (
|
||||||
|
PARTITION BY LTRIM(RTRIM(b.ItemCode))
|
||||||
|
ORDER BY b.PriceDate DESC, b.LastUpdatedDate DESC
|
||||||
|
) AS rn
|
||||||
|
FROM prItemBasePrice b
|
||||||
|
INNER JOIN req_codes rc
|
||||||
|
ON rc.ProductCode = LTRIM(RTRIM(b.ItemCode))
|
||||||
|
WHERE b.ItemTypeCode = 1
|
||||||
|
AND b.BasePriceCode = 1
|
||||||
|
AND LTRIM(RTRIM(b.CurrencyCode)) = 'USD'
|
||||||
|
),
|
||||||
|
stock_entry_dates AS (
|
||||||
|
SELECT
|
||||||
|
LTRIM(RTRIM(s.ItemCode)) AS ItemCode,
|
||||||
|
CONVERT(VARCHAR(10), MAX(s.OperationDate), 23) AS StockEntryDate
|
||||||
|
FROM trStock s WITH(NOLOCK)
|
||||||
|
INNER JOIN req_codes rc
|
||||||
|
ON rc.ProductCode = LTRIM(RTRIM(s.ItemCode))
|
||||||
|
WHERE s.ItemTypeCode = 1
|
||||||
|
AND LEN(LTRIM(RTRIM(s.ItemCode))) = 13
|
||||||
|
AND s.In_Qty1 > 0
|
||||||
|
AND LTRIM(RTRIM(s.WarehouseCode)) IN (
|
||||||
|
'1-0-14','1-0-10','1-0-8','1-2-5','1-2-4','1-0-12','100','1-0-28',
|
||||||
|
'1-0-24','1-2-6','1-1-14','1-0-2','1-0-52','1-1-2','1-0-21','1-1-3',
|
||||||
|
'1-0-33','101','1-014','1-0-49','1-0-36'
|
||||||
|
)
|
||||||
|
GROUP BY LTRIM(RTRIM(s.ItemCode))
|
||||||
|
),
|
||||||
|
stock_base AS (
|
||||||
|
SELECT
|
||||||
|
LTRIM(RTRIM(s.ItemCode)) AS ItemCode,
|
||||||
|
SUM(s.In_Qty1 - s.Out_Qty1) AS InventoryQty1
|
||||||
|
FROM trStock s WITH(NOLOCK)
|
||||||
|
INNER JOIN req_codes rc
|
||||||
|
ON rc.ProductCode = LTRIM(RTRIM(s.ItemCode))
|
||||||
|
WHERE s.ItemTypeCode = 1
|
||||||
|
AND LEN(LTRIM(RTRIM(s.ItemCode))) = 13
|
||||||
|
GROUP BY LTRIM(RTRIM(s.ItemCode))
|
||||||
|
),
|
||||||
|
pick_base AS (
|
||||||
|
SELECT
|
||||||
|
LTRIM(RTRIM(p.ItemCode)) AS ItemCode,
|
||||||
|
SUM(p.Qty1) AS PickingQty1
|
||||||
|
FROM PickingStates p
|
||||||
|
INNER JOIN req_codes rc
|
||||||
|
ON rc.ProductCode = LTRIM(RTRIM(p.ItemCode))
|
||||||
|
WHERE p.ItemTypeCode = 1
|
||||||
|
AND LEN(LTRIM(RTRIM(p.ItemCode))) = 13
|
||||||
|
GROUP BY LTRIM(RTRIM(p.ItemCode))
|
||||||
|
),
|
||||||
|
reserve_base AS (
|
||||||
|
SELECT
|
||||||
|
LTRIM(RTRIM(r.ItemCode)) AS ItemCode,
|
||||||
|
SUM(r.Qty1) AS ReserveQty1
|
||||||
|
FROM ReserveStates r
|
||||||
|
INNER JOIN req_codes rc
|
||||||
|
ON rc.ProductCode = LTRIM(RTRIM(r.ItemCode))
|
||||||
|
WHERE r.ItemTypeCode = 1
|
||||||
|
AND LEN(LTRIM(RTRIM(r.ItemCode))) = 13
|
||||||
|
GROUP BY LTRIM(RTRIM(r.ItemCode))
|
||||||
|
),
|
||||||
|
disp_base AS (
|
||||||
|
SELECT
|
||||||
|
LTRIM(RTRIM(d.ItemCode)) AS ItemCode,
|
||||||
|
SUM(d.Qty1) AS DispOrderQty1
|
||||||
|
FROM DispOrderStates d
|
||||||
|
INNER JOIN req_codes rc
|
||||||
|
ON rc.ProductCode = LTRIM(RTRIM(d.ItemCode))
|
||||||
|
WHERE d.ItemTypeCode = 1
|
||||||
|
AND LEN(LTRIM(RTRIM(d.ItemCode))) = 13
|
||||||
|
GROUP BY LTRIM(RTRIM(d.ItemCode))
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
rc.ProductCode,
|
||||||
|
COALESCE(lp.CostPrice, 0) AS CostPrice,
|
||||||
|
CAST(ROUND(
|
||||||
|
ISNULL(sb.InventoryQty1, 0)
|
||||||
|
- ISNULL(pb.PickingQty1, 0)
|
||||||
|
- ISNULL(rb.ReserveQty1, 0)
|
||||||
|
- ISNULL(db.DispOrderQty1, 0)
|
||||||
|
, 2) AS DECIMAL(18, 2)) AS StockQty,
|
||||||
|
COALESCE(se.StockEntryDate, '') AS StockEntryDate,
|
||||||
|
COALESCE(lp.LastPricingDate, '') AS LastPricingDate
|
||||||
|
FROM req_codes rc
|
||||||
|
LEFT JOIN latest_base_price lp
|
||||||
|
ON lp.ItemCode = rc.ProductCode
|
||||||
|
AND lp.rn = 1
|
||||||
|
LEFT JOIN stock_entry_dates se
|
||||||
|
ON se.ItemCode = rc.ProductCode
|
||||||
|
LEFT JOIN stock_base sb
|
||||||
|
ON sb.ItemCode = rc.ProductCode
|
||||||
|
LEFT JOIN pick_base pb
|
||||||
|
ON pb.ItemCode = rc.ProductCode
|
||||||
|
LEFT JOIN reserve_base rb
|
||||||
|
ON rb.ItemCode = rc.ProductCode
|
||||||
|
LEFT JOIN disp_base db
|
||||||
|
ON db.ItemCode = rc.ProductCode;
|
||||||
|
`
|
||||||
|
|
||||||
|
metricsRows, err := db.MssqlDB.QueryContext(ctx, metricsQuery, codesCSV)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("metrics query failed: %w", err)
|
||||||
|
}
|
||||||
|
defer metricsRows.Close()
|
||||||
|
|
||||||
|
type metrics struct {
|
||||||
|
CostPrice float64
|
||||||
|
StockQty float64
|
||||||
|
StockEntryDate string
|
||||||
|
LastPricingDate string
|
||||||
|
}
|
||||||
|
metricsByCode := make(map[string]metrics, len(out))
|
||||||
|
for metricsRows.Next() {
|
||||||
|
var (
|
||||||
|
code string
|
||||||
|
m metrics
|
||||||
|
)
|
||||||
|
if err := metricsRows.Scan(
|
||||||
|
&code,
|
||||||
|
&m.CostPrice,
|
||||||
|
&m.StockQty,
|
||||||
|
&m.StockEntryDate,
|
||||||
|
&m.LastPricingDate,
|
||||||
|
); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
metricsByCode[strings.TrimSpace(code)] = m
|
||||||
|
}
|
||||||
|
if err := metricsRows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range out {
|
||||||
|
if m, ok := metricsByCode[strings.TrimSpace(out[i].ProductCode)]; ok {
|
||||||
|
out[i].CostPrice = m.CostPrice
|
||||||
|
out[i].StockQty = m.StockQty
|
||||||
|
out[i].StockEntryDate = m.StockEntryDate
|
||||||
|
out[i].LastPricingDate = m.LastPricingDate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,8 @@ func GetProductPricingListHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
log.Printf("[ProductPricing] trace=%s start user=%s id=%d", traceID, claims.Username, claims.ID)
|
log.Printf("[ProductPricing] trace=%s start user=%s id=%d", traceID, claims.Username, claims.ID)
|
||||||
|
|
||||||
ctx, cancel := context.WithTimeout(r.Context(), 180*time.Second)
|
// Cloudflare upstream timeout is lower than 180s; fail fast and return API 504 instead of CDN 524.
|
||||||
|
ctx, cancel := context.WithTimeout(r.Context(), 110*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
limit := 500
|
limit := 500
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ var (
|
|||||||
reScriptLabelProp = regexp.MustCompile(`\blabel\s*:\s*['"]([^'"]{2,180})['"]`)
|
reScriptLabelProp = regexp.MustCompile(`\blabel\s*:\s*['"]([^'"]{2,180})['"]`)
|
||||||
reScriptUIProp = regexp.MustCompile(`\b(?:label|message|title|placeholder|hint)\s*:\s*['"]([^'"]{2,180})['"]`)
|
reScriptUIProp = regexp.MustCompile(`\b(?:label|message|title|placeholder|hint)\s*:\s*['"]([^'"]{2,180})['"]`)
|
||||||
reTemplateDynamic = regexp.MustCompile(`[{][{]|[}][}]`)
|
reTemplateDynamic = regexp.MustCompile(`[{][{]|[}][}]`)
|
||||||
|
reCodeLikeText = regexp.MustCompile(`(?i)(\bconst\b|\blet\b|\bvar\b|\breturn\b|\bfunction\b|=>|\|\||&&|\?\?|//|/\*|\*/|\.trim\(|\.replace\(|\.map\(|\.filter\()`)
|
||||||
)
|
)
|
||||||
|
|
||||||
var translationNoiseTokens = map[string]struct{}{
|
var translationNoiseTokens = map[string]struct{}{
|
||||||
@@ -1800,9 +1801,22 @@ func isCandidateText(s string) bool {
|
|||||||
if strings.Contains(s, "/api/") {
|
if strings.Contains(s, "/api/") {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if reCodeLikeText.MatchString(s) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
if strings.ContainsAny(s, "{}[];`") {
|
if strings.ContainsAny(s, "{}[];`") {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
symbolCount := 0
|
||||||
|
for _, r := range s {
|
||||||
|
switch r {
|
||||||
|
case '(', ')', '=', ':', '/', '\\', '|', '&', '*', '<', '>', '_':
|
||||||
|
symbolCount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if symbolCount >= 4 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -894,9 +894,16 @@ async function reloadData () {
|
|||||||
console.info('[product-pricing][ui] reload:start', {
|
console.info('[product-pricing][ui] reload:start', {
|
||||||
at: new Date(startedAt).toISOString()
|
at: new Date(startedAt).toISOString()
|
||||||
})
|
})
|
||||||
nextCursor.value = ''
|
try {
|
||||||
await fetchChunk({ reset: true })
|
nextCursor.value = ''
|
||||||
await ensureEnoughVisibleRows(120, 6)
|
await fetchChunk({ reset: true })
|
||||||
|
await ensureEnoughVisibleRows(120, 6)
|
||||||
|
} catch (err) {
|
||||||
|
console.error('[product-pricing][ui] reload:error', {
|
||||||
|
duration_ms: Date.now() - startedAt,
|
||||||
|
message: String(err?.message || err || 'reload failed')
|
||||||
|
})
|
||||||
|
}
|
||||||
console.info('[product-pricing][ui] reload:done', {
|
console.info('[product-pricing][ui] reload:done', {
|
||||||
duration_ms: Date.now() - startedAt,
|
duration_ms: Date.now() - startedAt,
|
||||||
row_count: Array.isArray(store.rows) ? store.rows.length : 0,
|
row_count: Array.isArray(store.rows) ? store.rows.length : 0,
|
||||||
|
|||||||
Reference in New Issue
Block a user