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:
@@ -10,9 +10,6 @@
|
||||
buildTemplateToSave,
|
||||
elementId,
|
||||
generatePreviewElements,
|
||||
getDefaultInstructions,
|
||||
getDefaultMetaDescription,
|
||||
getDefaultMetaTitle,
|
||||
parseDescriptionTemplate,
|
||||
parseTemplateToFormula
|
||||
} from "$lib/categories/formula";
|
||||
@@ -137,10 +134,13 @@
|
||||
let confirmOpen = $state(false);
|
||||
let itemToDelete = $state<{ type: string; id: string } | null>(null);
|
||||
|
||||
// Description formula (categories.description_template) — same editor as /description-formula.
|
||||
// Description formula (categories.description_template) — same editor as
|
||||
// /description-formula, but NEVER pre-filled with English default texts:
|
||||
// empty stays empty (placeholders only) so stored Slovenian/tenant content
|
||||
// is shown exactly as-is and defaults are never silently saved.
|
||||
let descSections = $state<DescriptionSection[]>([]);
|
||||
let metaTitle = $state(getDefaultMetaTitle());
|
||||
let metaDescription = $state(getDefaultMetaDescription());
|
||||
let metaTitle = $state("");
|
||||
let metaDescription = $state("");
|
||||
let dragIndex = $state<number | null>(null);
|
||||
|
||||
const langLabel = $derived(
|
||||
@@ -224,8 +224,14 @@
|
||||
titleFormula = parseTemplateToFormula(cat.title_template, customVariables);
|
||||
const parsedDesc = parseDescriptionTemplate(cat.description_template);
|
||||
descSections = parsedDesc.sections;
|
||||
metaTitle = parsedDesc.metaTitle;
|
||||
metaDescription = parsedDesc.metaDescription;
|
||||
// Raw stored values only — parseDescriptionTemplate injects English
|
||||
// defaults for missing meta fields, which must never be displayed or saved.
|
||||
const rawTpl = (cat.description_template ?? {}) as {
|
||||
metaTitle?: unknown;
|
||||
metaDescription?: unknown;
|
||||
};
|
||||
metaTitle = typeof rawTpl.metaTitle === "string" ? rawTpl.metaTitle : "";
|
||||
metaDescription = typeof rawTpl.metaDescription === "string" ? rawTpl.metaDescription : "";
|
||||
}
|
||||
|
||||
function onLangChange(code: string) {
|
||||
@@ -374,10 +380,9 @@
|
||||
|
||||
// ----- Description formula editing -----
|
||||
function addDescSection() {
|
||||
descSections = [
|
||||
...descSections,
|
||||
{ id: crypto.randomUUID(), type: "p", instructions: getDefaultInstructions("p") }
|
||||
];
|
||||
// New sections start EMPTY — placeholder text guides the user; no
|
||||
// English default instructions are ever inserted into stored content.
|
||||
descSections = [...descSections, { id: crypto.randomUUID(), type: "p", instructions: "" }];
|
||||
}
|
||||
|
||||
function removeDescSection(id: string) {
|
||||
@@ -385,14 +390,9 @@
|
||||
}
|
||||
|
||||
function updateDescSection(id: string, updates: Partial<DescriptionSection>) {
|
||||
descSections = descSections.map((section) => {
|
||||
if (section.id !== id) return section;
|
||||
const next = { ...section, ...updates };
|
||||
if (updates.type && updates.type !== section.type) {
|
||||
next.instructions = getDefaultInstructions(updates.type);
|
||||
}
|
||||
return next;
|
||||
});
|
||||
descSections = descSections.map((section) =>
|
||||
section.id === id ? { ...section, ...updates } : section
|
||||
);
|
||||
}
|
||||
|
||||
function reorderDescSections(from: number, to: number) {
|
||||
@@ -403,11 +403,14 @@
|
||||
}
|
||||
|
||||
function buildDescriptionTemplate() {
|
||||
if (descSections.length === 0) return null;
|
||||
const keep = descSections.filter((s) => s.instructions.trim() || s.exportId?.trim());
|
||||
const mt = metaTitle.trim();
|
||||
const md = metaDescription.trim();
|
||||
if (keep.length === 0 && !mt && !md) return null;
|
||||
return {
|
||||
sections: descSections,
|
||||
metaTitle: metaTitle.trim() || undefined,
|
||||
metaDescription: metaDescription.trim() || undefined
|
||||
sections: keep,
|
||||
metaTitle: mt || undefined,
|
||||
metaDescription: md || undefined
|
||||
};
|
||||
}
|
||||
|
||||
@@ -820,19 +823,9 @@
|
||||
rows="2"
|
||||
placeholder={i18n.t("categories.seoTitlePlaceholder")}
|
||||
></textarea>
|
||||
<div class="flex items-center justify-between">
|
||||
<p class="text-xs text-muted-foreground">
|
||||
{i18n.t("categories.metaTitleHint")}
|
||||
</p>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
class="text-xs"
|
||||
onclick={() => (metaTitle = getDefaultMetaTitle())}
|
||||
>
|
||||
{i18n.t("categories.resetToDefault")}
|
||||
</Button>
|
||||
</div>
|
||||
<p class="text-xs text-muted-foreground">
|
||||
{i18n.t("categories.metaTitleHint")}
|
||||
</p>
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
<Label for="metaDescription">{i18n.t("categories.metaDescriptionFormula")}</Label>
|
||||
@@ -843,19 +836,9 @@
|
||||
rows="3"
|
||||
placeholder={i18n.t("categories.seoDescriptionPlaceholder")}
|
||||
></textarea>
|
||||
<div class="flex items-center justify-between">
|
||||
<p class="text-xs text-muted-foreground">
|
||||
{i18n.t("categories.metaDescriptionHint")}
|
||||
</p>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
class="text-xs"
|
||||
onclick={() => (metaDescription = getDefaultMetaDescription())}
|
||||
>
|
||||
{i18n.t("categories.resetToDefault")}
|
||||
</Button>
|
||||
</div>
|
||||
<p class="text-xs text-muted-foreground">
|
||||
{i18n.t("categories.metaDescriptionHint")}
|
||||
</p>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
Reference in New Issue
Block a user