fix
This commit is contained in:
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/descrybe/descrybe-v2/apps/api/internal/company"
|
||||
"github.com/descrybe/descrybe-v2/apps/api/internal/eprel"
|
||||
"github.com/google/uuid"
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
)
|
||||
|
||||
var v1PartialSteps = []string{"category", "title", "description", "attributes"}
|
||||
@@ -274,7 +275,7 @@ func (p *Pipeline) LoadV1ProcessJobItems(ctx context.Context, companyID, jobID u
|
||||
"error": "Product data not available",
|
||||
}
|
||||
if itemError != nil && *itemError != "" {
|
||||
item["error"] = *itemError
|
||||
item["error"] = PublicV1Error(*itemError)
|
||||
}
|
||||
full = append(full, item)
|
||||
continue
|
||||
@@ -309,6 +310,9 @@ func (p *Pipeline) LoadV1ProcessJobItems(ctx context.Context, companyID, jobID u
|
||||
if descTxt != nil {
|
||||
descOut = v1PreserveDescription(*descTxt)
|
||||
}
|
||||
if isPromptLeakageTitle(descOut) || isPromptLabelTitle(descOut) {
|
||||
descOut = ""
|
||||
}
|
||||
|
||||
eprelVal := extractEPRELFromAttrs(attrs)
|
||||
attrs = SanitizeV1ProcessAttributesAllowed(attrs, allowedAttrs)
|
||||
@@ -453,7 +457,7 @@ func (p *Pipeline) LoadV1ProcessJobItems(ctx context.Context, companyID, jobID u
|
||||
// Internal ids (id / processed_product_id / raw_product_id) are omitted from
|
||||
// the public V1 process item shape — use catalog APIs when a UUID is needed.
|
||||
if itemError != nil && *itemError != "" {
|
||||
item["error"] = *itemError
|
||||
item["error"] = PublicV1Error(*itemError)
|
||||
}
|
||||
if len(attrs) > 0 {
|
||||
item["attributes"] = attrs
|
||||
@@ -484,35 +488,72 @@ func nullIfEmptyPtr(s *string) any {
|
||||
return *s
|
||||
}
|
||||
|
||||
// companyOmitsSEOMeta is true when V1/process must omit meta_title / meta_description:
|
||||
// A1 cohort (legacy id), Platform Demo (A1-cloned prompts, no legacy id), or any
|
||||
// company whose categories store A1-style role-section enhance prompts.
|
||||
func companyOmitsSEOMeta(ctx context.Context, p *Pipeline, companyID uuid.UUID) bool {
|
||||
if p == nil || p.Pool == nil {
|
||||
// Known v2 companies.id values that omit SEO meta on V1 process payloads.
|
||||
// A1 Slovenija is also matched via billing.A1LegacyCompanyID (legacy_company_id / PK).
|
||||
const (
|
||||
a1V2CompanyID = "604f23a8-b66e-4b21-8b45-0d72b68f4790"
|
||||
platformDemoV2CompanyID = "2b3159b0-fc08-415b-b248-35ed02a6baab"
|
||||
)
|
||||
|
||||
// CompanyOmitsSEOMetaID is true for A1 Slovenija and Platform Demo by companies.id
|
||||
// (or the migrated MySQL company id). Does not grant Legacy plan privileges.
|
||||
func CompanyOmitsSEOMetaID(companyID uuid.UUID) bool {
|
||||
if companyID == uuid.Nil {
|
||||
return false
|
||||
}
|
||||
id := strings.ToLower(companyID.String())
|
||||
switch id {
|
||||
case a1V2CompanyID, platformDemoV2CompanyID, strings.ToLower(billing.A1LegacyCompanyID):
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// CompanyOmitsSEOMetaLookup is the shared A1/Demo SEO-omit decision used by V1 process
|
||||
// and catalog list/get/update. Matches hardcoded companies.id, A1 cohort (legacy id),
|
||||
// Platform Demo by name, or A1-style --- Title --- / --- Description --- / --- Meta ---
|
||||
// category prompts.
|
||||
func CompanyOmitsSEOMetaLookup(companyID uuid.UUID, legacyID, name string, hasA1SectionPrompts bool) bool {
|
||||
if CompanyOmitsSEOMetaID(companyID) {
|
||||
return true
|
||||
}
|
||||
if billing.IsA1CohortCompany(legacyID, "") {
|
||||
return true
|
||||
}
|
||||
if strings.EqualFold(strings.TrimSpace(name), "Platform Demo") {
|
||||
return true
|
||||
}
|
||||
return hasA1SectionPrompts
|
||||
}
|
||||
|
||||
// CompanyOmitsSEOMeta is true when catalog/V1 process must omit meta_title /
|
||||
// meta_description for this company (same rules as CompanyOmitsSEOMetaLookup).
|
||||
func CompanyOmitsSEOMeta(ctx context.Context, pool *pgxpool.Pool, companyID uuid.UUID) bool {
|
||||
if CompanyOmitsSEOMetaID(companyID) {
|
||||
return true
|
||||
}
|
||||
if pool == nil {
|
||||
return false
|
||||
}
|
||||
var legacy, name string
|
||||
err := p.Pool.QueryRow(ctx, `
|
||||
err := pool.QueryRow(ctx, `
|
||||
SELECT COALESCE(legacy_company_id, ''), COALESCE(name, '')
|
||||
FROM companies
|
||||
WHERE id = $1`, companyID).Scan(&legacy, &name)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
if billing.IsA1CohortCompany(legacy, "") {
|
||||
return true
|
||||
}
|
||||
if strings.EqualFold(strings.TrimSpace(name), "Platform Demo") {
|
||||
if CompanyOmitsSEOMetaLookup(companyID, legacy, name, false) {
|
||||
return true
|
||||
}
|
||||
var hasA1Prompts bool
|
||||
err = p.Pool.QueryRow(ctx, `
|
||||
err = pool.QueryRow(ctx, `
|
||||
SELECT EXISTS (
|
||||
SELECT 1 FROM categories
|
||||
WHERE company_id = $1
|
||||
AND prompt ILIKE '%--- Title ---%'
|
||||
AND prompt ILIKE '%--- Description ---%'
|
||||
AND prompt ILIKE '%--- Meta ---%'
|
||||
AND prompt ILIKE '%--- Title ---%'
|
||||
AND prompt ILIKE '%--- Description ---%'
|
||||
AND prompt ILIKE '%--- Meta ---%'
|
||||
LIMIT 1
|
||||
)`, companyID).Scan(&hasA1Prompts)
|
||||
if err != nil {
|
||||
@@ -521,6 +562,34 @@ func companyOmitsSEOMeta(ctx context.Context, p *Pipeline, companyID uuid.UUID)
|
||||
return hasA1Prompts
|
||||
}
|
||||
|
||||
// StripV1SEOMeta removes meta_title / meta_description keys (omit, not null).
|
||||
func StripV1SEOMeta(items []V1ProcessJobItem) []V1ProcessJobItem {
|
||||
for _, item := range items {
|
||||
if item == nil {
|
||||
continue
|
||||
}
|
||||
delete(item, "meta_title")
|
||||
delete(item, "meta_description")
|
||||
}
|
||||
return items
|
||||
}
|
||||
|
||||
// ApplyV1SEOMetaPolicy omits SEO meta on A1/Demo process items by companies.id.
|
||||
func ApplyV1SEOMetaPolicy(companyID uuid.UUID, items []V1ProcessJobItem) []V1ProcessJobItem {
|
||||
if !CompanyOmitsSEOMetaID(companyID) {
|
||||
return items
|
||||
}
|
||||
return StripV1SEOMeta(items)
|
||||
}
|
||||
|
||||
// companyOmitsSEOMeta is the pipeline wrapper around CompanyOmitsSEOMeta.
|
||||
func companyOmitsSEOMeta(ctx context.Context, p *Pipeline, companyID uuid.UUID) bool {
|
||||
if p == nil {
|
||||
return CompanyOmitsSEOMeta(ctx, nil, companyID)
|
||||
}
|
||||
return CompanyOmitsSEOMeta(ctx, p.Pool, companyID)
|
||||
}
|
||||
|
||||
func derefStringPtr(s *string) string {
|
||||
if s == nil {
|
||||
return ""
|
||||
|
||||
Reference in New Issue
Block a user