Surface Slovenian A1 content in prompt page; purge English defaults
Three bugs hid the split A1 data behind English junk:
1. /api/auth/me company was only {id, name} — me.company.language never
existed, so the prompt/formula pages ALWAYS fell back to English as
the primary content language and never showed the Slovenian ("sl")
prompt sections by default. handleMe now enriches the active company
with language + content_languages from the companies table.
2. The unified prompt page injected English default texts: meta title /
meta description fields were pre-filled via getDefaultMetaTitle/
Description (and silently SAVED on Save), new description sections
started with English instructions, and type changes overwrote user
text with English defaults. All removed — empty stays empty
(placeholders only), stored tenant content is shown exactly as-is,
meta-only templates now save (sections no longer required).
3. Sync A1 / repair left English formula artifacts on categories with no
seed content ("Audio video" etc.): earlier repairs backfilled
DefaultRetailTitleFormula and cats.json-style English description
sections onto every category. Repair now (a) never invents a default
title formula — formulas derive ONLY from legacy naming rules — and
(b) with the seed as source of truth clears title_template and
description_template on non-seed categories (new
title/description_template_cleared counters).
Locally verified end-to-end: corrupted Platform Demo Monitorji (legacy
combined blob) + Audio video (English junk), called the real admin
POST /companies/{id}/sync-a1 as the platform admin — Monitorji restored
to the exact split Slovenian Title/Description/Meta + formulas +
Slovenian meta title/description, Audio video fully cleared; repair
idempotent (0 on re-run); me.company.language returns sl for A1;
zero English-default templates remain in A1 + Platform Demo.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -37,6 +37,10 @@ type RepairCategoryEnhancePromptsResult struct {
|
||||
FallbackTemplate int `json:"fallback_template"`
|
||||
TitleTemplateBackfill int `json:"title_template_backfill"`
|
||||
DescTemplateBackfill int `json:"description_template_backfill"`
|
||||
// *_Cleared count non-seed categories whose leftover formula artifacts
|
||||
// (English defaults from earlier repairs / cats.json / migration) were removed.
|
||||
TitleTemplateCleared int `json:"title_template_cleared"`
|
||||
DescTemplateCleared int `json:"description_template_cleared"`
|
||||
ByCompany map[string]int `json:"by_company"`
|
||||
DryRun bool `json:"dry_run"`
|
||||
SeedPath string `json:"seed_path,omitempty"`
|
||||
@@ -524,7 +528,19 @@ func repairCompanyCategoryEnhancePrompts(
|
||||
if needDesc && strings.TrimSpace(legacyParts.DescriptionRules) == "" && strings.TrimSpace(legacyParts.MetaRules) == "" {
|
||||
needDesc = false
|
||||
}
|
||||
if !needPrompt && !needTitle && !needDesc {
|
||||
// Never invent a default title formula: formulas are derived ONLY from
|
||||
// legacy naming rules. (Earlier repairs backfilled DefaultRetailTitleFormula
|
||||
// with English labels onto every category — that junk gets cleared below.)
|
||||
if strings.TrimSpace(titleRules) == "" {
|
||||
needTitle = false
|
||||
}
|
||||
// Seed is the source of truth: categories with no seed/legacy content must
|
||||
// not keep formula artifacts (English default sections/formulas from
|
||||
// earlier repairs, cats.json seeding, or migration).
|
||||
noLegacyContent := seedLegacy == "" && !legacyParts.WasLegacy && strings.TrimSpace(titleRules) == ""
|
||||
clearTitleTpl := forceFromSeed && noLegacyContent && jsonbTemplatePresent(titleTpl)
|
||||
clearDescTpl := forceFromSeed && noLegacyContent && jsonbTemplatePresent(descTpl)
|
||||
if !needPrompt && !needTitle && !needDesc && !clearTitleTpl && !clearDescTpl {
|
||||
if company.HasAnyPrompt(m) {
|
||||
out.AlreadyOK++
|
||||
} else {
|
||||
@@ -564,6 +580,12 @@ func repairCompanyCategoryEnhancePrompts(
|
||||
if needDesc {
|
||||
out.DescTemplateBackfill++
|
||||
}
|
||||
if clearTitleTpl {
|
||||
out.TitleTemplateCleared++
|
||||
}
|
||||
if clearDescTpl {
|
||||
out.DescTemplateCleared++
|
||||
}
|
||||
updatedHere++
|
||||
continue
|
||||
}
|
||||
@@ -640,6 +662,26 @@ func repairCompanyCategoryEnhancePrompts(
|
||||
}
|
||||
}
|
||||
|
||||
if clearTitleTpl {
|
||||
if _, err := pool.Exec(ctx, `
|
||||
UPDATE categories
|
||||
SET title_template = NULL, updated_at = now()
|
||||
WHERE id = $1 AND company_id = $2`, id, companyID); err != nil {
|
||||
return updatedHere, fmt.Errorf("clear title_template category=%s: %w", id, err)
|
||||
}
|
||||
out.TitleTemplateCleared++
|
||||
}
|
||||
|
||||
if clearDescTpl {
|
||||
if _, err := pool.Exec(ctx, `
|
||||
UPDATE categories
|
||||
SET description_template = NULL, updated_at = now()
|
||||
WHERE id = $1 AND company_id = $2`, id, companyID); err != nil {
|
||||
return updatedHere, fmt.Errorf("clear description_template category=%s: %w", id, err)
|
||||
}
|
||||
out.DescTemplateCleared++
|
||||
}
|
||||
|
||||
out.Updated++
|
||||
updatedHere++
|
||||
}
|
||||
|
||||
@@ -340,6 +340,24 @@ func (s *Server) handleMe(w http.ResponseWriter, r *http.Request) {
|
||||
out["company"] = c
|
||||
}
|
||||
}
|
||||
// Enrich with content language settings: the dashboard (category prompt /
|
||||
// formula pages, language switchers) reads me.company.language as the
|
||||
// primary content language — auth.Company alone is only {id, name},
|
||||
// which silently fell back to English for every tenant.
|
||||
if c, ok := out["company"].(auth.Company); ok {
|
||||
var lang string
|
||||
var contentLangs []string
|
||||
if err := s.Pool.QueryRow(r.Context(), `
|
||||
SELECT COALESCE(language, 'en'), COALESCE(content_languages, '{}')
|
||||
FROM companies WHERE id = $1`, cid).Scan(&lang, &contentLangs); err == nil {
|
||||
out["company"] = map[string]any{
|
||||
"id": c.ID,
|
||||
"name": c.Name,
|
||||
"language": lang,
|
||||
"content_languages": contentLangs,
|
||||
}
|
||||
}
|
||||
}
|
||||
if credits, err := s.Billing.CreditsOverview(r.Context(), cid, s.Config.LowCreditsThreshold); err == nil {
|
||||
out["credits"] = credits
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user