This commit is contained in:
2026-08-23 19:30:05 +02:00
parent f61fe05e7a
commit 3b678ca857
4 changed files with 194 additions and 24 deletions
+35 -23
View File
@@ -413,14 +413,11 @@ func (e *Engine) RunSteps(ctx context.Context, companyID string, in ProductInput
}
langMetas = append(langMetas, meta)
if lang == primary {
// Enriched fields only — keep out.Name / out.Description as the
// supplier/normalized Original so Review can show a real diff
// (Matched when we stamp both sides is a false "no change").
out.ProcessedName = name
out.ProcessedDescription = desc
if name != "" {
out.Name = name
}
if desc != "" {
out.Description = desc
}
if lf := localized[lang]; lf.MetaTitle != "" {
out.MetaTitle = lf.MetaTitle
}
@@ -458,9 +455,7 @@ func (e *Engine) RunSteps(ctx context.Context, companyID string, in ProductInput
if out.ProcessedName != "" && descriptionNeedsEnhanceRepair(out.ProcessedDescription, failDescTpl, out.ProcessedName, out.Name) {
if synth := synthesizeProductDescription(out.ProcessedName, displayCat, primary, enhanceAttrs, failDescTpl); synth != "" {
out.ProcessedDescription = synth
if out.Description == "" || descriptionNeedsEnhanceRepair(out.Description, failDescTpl, out.Name, out.ProcessedName) {
out.Description = synth
}
// Never stamp invent fallback onto Original description.
if lf, ok := localized[primary]; ok {
lf.ProcessedDescription = synth
if lf.ProcessedName == "" {
@@ -562,18 +557,9 @@ func (e *Engine) RunSteps(ctx context.Context, companyID string, in ProductInput
finalRepaired = true
}
}
if descriptionNeedsEnhanceRepair(out.Description, finalDescTpl, out.Name, out.ProcessedName) {
if out.ProcessedDescription != "" && !descriptionNeedsEnhanceRepair(out.ProcessedDescription, finalDescTpl, out.Name, out.ProcessedName) {
out.Description = out.ProcessedDescription
finalRepaired = true
} else if synth := synthesizeProductDescription(out.Name, displayCat, in.Language, out.Attributes, finalDescTpl); synth != "" {
out.Description = synth
finalRepaired = true
if descriptionNeedsEnhanceRepair(out.ProcessedDescription, finalDescTpl, out.ProcessedName, out.Name) {
out.ProcessedDescription = synth
}
}
}
// Original description stays supplier/normalized feed copy. Formula HTML belongs
// only on processed_description — copying synth onto description made Review
// always Matched with invent "Ključne lastnosti" instead of a real enrich diff.
if finalRepaired {
delete(out.FieldSources, FieldEnhanceInputHash)
primary := strings.TrimSpace(in.Language)
@@ -794,10 +780,16 @@ func normalizeTitleCompare(s string) string {
}
func titleNeedsRewriteRetry(in ProductInput, name string) bool {
if !aiprompts.CategoryTitlePromptRequiresRewrite(in.CategoryEnhancePrompt) {
if !titlesAreEquivalent(name, in.Name) {
return false
}
return titlesAreEquivalent(name, in.Name)
if aiprompts.CategoryTitlePromptRequiresRewrite(in.CategoryEnhancePrompt) {
return true
}
if FormatTitleFormulaConstraint(in.TitleTemplate) != "" {
return true
}
return FormatTitleSectionConstraint(in.CategoryEnhancePrompt) != ""
}
// enhanceHashForceReason returns why a matching prior enhance_input_hash must not
@@ -815,9 +807,29 @@ func enhanceHashForceReason(in ProductInput) string {
if titleNeedsRewriteRetry(in, in.PriorProcessedName) {
return "title-copy-paste"
}
// Prior enrich left description identical to supplier — never hash-skip that.
if descriptionsAreEquivalent(in.PriorProcessedDescription, in.Description) {
return "desc-copy-paste"
}
return ""
}
// descriptionsAreEquivalent compares supplier vs enriched description ignoring
// trivial whitespace / case so copy-paste enhance cannot hash-skip forever.
func descriptionsAreEquivalent(a, b string) bool {
na := normalizeDescCompare(a)
nb := normalizeDescCompare(b)
if na == "" || nb == "" {
return false
}
return na == nb
}
func normalizeDescCompare(s string) string {
s = stripHTMLTags(s)
return strings.Join(strings.Fields(strings.ToLower(strings.TrimSpace(s))), " ")
}
func (e *Engine) enhance(ctx context.Context, in ProductInput, category string, attrs map[string]any) (string, string, int, any, error) {
// Prompt Description HTML overlays count as the formula when description_template
// is empty — otherwise enhance accepts supplier-like prose and skips formula retry.