fix
This commit is contained in:
@@ -8,7 +8,9 @@ import (
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/descrybe/descrybe-v2/apps/api/internal/billing"
|
||||
"github.com/descrybe/descrybe-v2/apps/api/internal/catalog"
|
||||
"github.com/descrybe/descrybe-v2/apps/api/internal/company"
|
||||
"github.com/descrybe/descrybe-v2/apps/api/internal/eprel"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
@@ -209,6 +211,11 @@ func (p *Pipeline) LoadV1ProcessJobItems(ctx context.Context, companyID, jobID u
|
||||
}
|
||||
allowedAttrs := loadCompanyAttributeKeySet(ctx, p, companyID)
|
||||
categoryNames := loadCompanyCategoryNameMap(ctx, p, companyID)
|
||||
omitSEOMeta := companyOmitsSEOMeta(ctx, p, companyID)
|
||||
language := ""
|
||||
if p != nil {
|
||||
language = company.LoadLanguage(ctx, p.Pool, companyID)
|
||||
}
|
||||
rows, err := p.Pool.Query(ctx, `
|
||||
SELECT
|
||||
COALESCE(r.gtin, p.product_id, '') AS ean,
|
||||
@@ -356,49 +363,53 @@ func (p *Pipeline) LoadV1ProcessJobItems(ctx context.Context, companyID, jobID u
|
||||
}
|
||||
}
|
||||
|
||||
metaTitleOut := nullIfEmptyPtr(metaTitle)
|
||||
metaDescOut := nullIfEmptyPtr(metaDesc)
|
||||
if s, ok := metaTitleOut.(string); ok && isPoisonedMetaTitle(s) {
|
||||
metaTitleOut = nil
|
||||
// Poisoned title refresh: also drop empty/weak/leakage stub meta_description.
|
||||
if ds, ok := metaDescOut.(string); ok && (ds == "" || isWeakPriorEnhanceDescription(ds, titleStr) || isPromptLeakageTitle(ds)) {
|
||||
titleStr = ensureReadableTitleSpacing(titleStr)
|
||||
|
||||
var metaTitleOut, metaDescOut any
|
||||
if !omitSEOMeta {
|
||||
metaTitleOut = nullIfEmptyPtr(metaTitle)
|
||||
metaDescOut = nullIfEmptyPtr(metaDesc)
|
||||
if s, ok := metaTitleOut.(string); ok && isPoisonedMetaTitle(s) {
|
||||
metaTitleOut = nil
|
||||
if ds, ok := metaDescOut.(string); ok && (ds == "" || isWeakPriorEnhanceDescription(ds, titleStr) || isPromptLeakageTitle(ds)) {
|
||||
metaDescOut = nil
|
||||
}
|
||||
}
|
||||
if ds, ok := metaDescOut.(string); ok && isPromptLeakageTitle(ds) {
|
||||
metaDescOut = nil
|
||||
}
|
||||
}
|
||||
if ds, ok := metaDescOut.(string); ok && isPromptLeakageTitle(ds) {
|
||||
metaDescOut = nil
|
||||
}
|
||||
catLabel := catNameStr
|
||||
if catLabel == "" {
|
||||
catLabel = catStr
|
||||
}
|
||||
if (metaTitleOut == nil || metaDescOut == nil) && (titleStr != "" || descOut != "" || catLabel != "") {
|
||||
synthTitle, synthDesc := fillMetaFromResult(StepResult{
|
||||
Name: titleStr,
|
||||
ProcessedName: titleStr,
|
||||
Category: catStr,
|
||||
CategoryName: catNameStr,
|
||||
Description: descOut,
|
||||
ProcessedDescription: descOut,
|
||||
Attributes: attrs,
|
||||
ProcessedAttributes: attrs,
|
||||
})
|
||||
if metaTitleOut == nil {
|
||||
if synthTitle != "" {
|
||||
metaTitleOut = synthTitle
|
||||
} else {
|
||||
metaTitleOut = nullIfEmptyPtr(title)
|
||||
}
|
||||
catLabel := catNameStr
|
||||
if catLabel == "" {
|
||||
catLabel = catStr
|
||||
}
|
||||
if metaDescOut == nil {
|
||||
if synthDesc != "" {
|
||||
metaDescOut = synthDesc
|
||||
} else if descOut != "" {
|
||||
metaDescOut = truncateMetaDescription(v1PlainDescription(descOut), v1MetaDescriptionMaxChars)
|
||||
if (metaTitleOut == nil || metaDescOut == nil) && (titleStr != "" || descOut != "" || catLabel != "") {
|
||||
synthTitle, synthDesc := fillMetaFromResult(StepResult{
|
||||
Name: titleStr,
|
||||
ProcessedName: titleStr,
|
||||
Category: catStr,
|
||||
CategoryName: catNameStr,
|
||||
Description: descOut,
|
||||
ProcessedDescription: descOut,
|
||||
Attributes: attrs,
|
||||
ProcessedAttributes: attrs,
|
||||
})
|
||||
if metaTitleOut == nil {
|
||||
if synthTitle != "" {
|
||||
metaTitleOut = synthTitle
|
||||
} else {
|
||||
metaTitleOut = nullIfEmptyPtr(title)
|
||||
}
|
||||
}
|
||||
if metaDescOut == nil {
|
||||
if synthDesc != "" {
|
||||
metaDescOut = synthDesc
|
||||
} else if descOut != "" {
|
||||
metaDescOut = truncateMetaDescription(v1PlainDescription(descOut), v1MetaDescriptionMaxChars)
|
||||
}
|
||||
}
|
||||
} else if metaTitleOut == nil {
|
||||
metaTitleOut = nullIfEmptyPtr(title)
|
||||
}
|
||||
} else if metaTitleOut == nil {
|
||||
metaTitleOut = nullIfEmptyPtr(title)
|
||||
}
|
||||
|
||||
var description any
|
||||
@@ -407,32 +418,37 @@ func (p *Pipeline) LoadV1ProcessJobItems(ctx context.Context, companyID, jobID u
|
||||
} else {
|
||||
description = nil
|
||||
}
|
||||
var catOut, catNameOut any
|
||||
if catStr != "" {
|
||||
catOut = catStr
|
||||
}
|
||||
// ASSUMPTION: V1 `category` is the display name; `category_id` is unique_id
|
||||
// (additive). `category_name` mirrors the display name for dual-mode clients.
|
||||
var catNameOut, catIDOut any
|
||||
if catNameStr != "" {
|
||||
catNameOut = catNameStr
|
||||
}
|
||||
if catStr != "" {
|
||||
catIDOut = catStr
|
||||
}
|
||||
|
||||
var titleOut any
|
||||
if titleStr != "" {
|
||||
titleOut = titleStr
|
||||
}
|
||||
item := V1ProcessJobItem{
|
||||
"ean": ean,
|
||||
"status": MapV1JobItemStatus(itemStatus, true),
|
||||
"category": catOut,
|
||||
"category_name": catNameOut,
|
||||
"title": titleOut,
|
||||
"name": titleOut,
|
||||
"meta_title": metaTitleOut,
|
||||
"meta_description": metaDescOut,
|
||||
"description": description,
|
||||
"attributes": nil,
|
||||
"main_image": nil,
|
||||
"more_images": nil,
|
||||
"eprel": eprelVal,
|
||||
"ean": ean,
|
||||
"status": MapV1JobItemStatus(itemStatus, true),
|
||||
"category": catNameOut,
|
||||
"category_id": catIDOut,
|
||||
"category_name": catNameOut,
|
||||
"title": titleOut,
|
||||
"name": titleOut,
|
||||
"description": description,
|
||||
"attributes": nil,
|
||||
"main_image": nil,
|
||||
"more_images": nil,
|
||||
"eprel": eprelVal,
|
||||
}
|
||||
if !omitSEOMeta {
|
||||
item["meta_title"] = metaTitleOut
|
||||
item["meta_description"] = metaDescOut
|
||||
}
|
||||
applyV1ProcessItemIDs(item, processedID, rawProductID)
|
||||
if itemError != nil && *itemError != "" {
|
||||
@@ -447,7 +463,11 @@ func (p *Pipeline) LoadV1ProcessJobItems(ctx context.Context, companyID, jobID u
|
||||
if len(more) > 0 {
|
||||
item["more_images"] = more
|
||||
}
|
||||
item = EnforceV1ProcessCompletedItem(item, "", allowedAttrs)
|
||||
item = EnforceV1ProcessCompletedItemOpts(item, EnforceV1Opts{
|
||||
Language: language,
|
||||
Allowed: allowedAttrs,
|
||||
OmitSEOMeta: omitSEOMeta,
|
||||
})
|
||||
full = append(full, item)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
@@ -463,6 +483,22 @@ func nullIfEmptyPtr(s *string) any {
|
||||
return *s
|
||||
}
|
||||
|
||||
// companyOmitsSEOMeta is true for the A1 cohort (no meta_title / meta_description).
|
||||
func companyOmitsSEOMeta(ctx context.Context, p *Pipeline, companyID uuid.UUID) bool {
|
||||
if p == nil || p.Pool == nil {
|
||||
return false
|
||||
}
|
||||
var legacy string
|
||||
err := p.Pool.QueryRow(ctx, `
|
||||
SELECT COALESCE(legacy_company_id, '')
|
||||
FROM companies
|
||||
WHERE id = $1`, companyID).Scan(&legacy)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return billing.IsA1CohortCompany(legacy, "")
|
||||
}
|
||||
|
||||
func derefStringPtr(s *string) string {
|
||||
if s == nil {
|
||||
return ""
|
||||
@@ -685,6 +721,7 @@ func ProjectV1ProcessJobItems(storedType string, items []V1ProcessJobItem) []V1P
|
||||
switch step {
|
||||
case "category":
|
||||
projected["category"] = item["category"]
|
||||
projected["category_id"] = item["category_id"]
|
||||
projected["category_name"] = item["category_name"]
|
||||
case "title":
|
||||
projected["title"] = item["title"]
|
||||
@@ -692,10 +729,14 @@ func ProjectV1ProcessJobItems(storedType string, items []V1ProcessJobItem) []V1P
|
||||
if projected["name"] == nil {
|
||||
projected["name"] = item["title"]
|
||||
}
|
||||
projected["meta_title"] = item["meta_title"]
|
||||
if _, ok := item["meta_title"]; ok {
|
||||
projected["meta_title"] = item["meta_title"]
|
||||
}
|
||||
case "description":
|
||||
projected["description"] = item["description"]
|
||||
projected["meta_description"] = item["meta_description"]
|
||||
if _, ok := item["meta_description"]; ok {
|
||||
projected["meta_description"] = item["meta_description"]
|
||||
}
|
||||
case "attributes":
|
||||
projected["attributes"] = item["attributes"]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user