56 Commits
Author SHA1 Message Date
greeneclipse 65e1fdd55b fix 2026-08-24 04:31:49 +02:00
greeneclipse 7bafd7a322 fix 2026-08-24 04:03:44 +02:00
greeneclipse 8a690a0464 fix 2026-08-24 03:41:06 +02:00
greeneclipse a246ed8fe5 fix 2026-08-23 23:14:57 +02:00
greeneclipse 296dc3c841 fix 2026-08-23 22:52:13 +02:00
greeneclipse 8983cfc8a1 update see calss 2026-08-23 22:03:57 +02:00
greeneclipse f3d4fb56ed fix 2026-08-23 20:49:40 +02:00
greeneclipse 3b678ca857 fix 2026-08-23 19:30:05 +02:00
greeneclipse f61fe05e7a fix 2026-08-23 18:58:03 +02:00
greeneclipse a30b78c3b6 fix 2026-08-23 16:34:50 +02:00
greeneclipse 815e26d359 fix 2026-08-23 13:39:56 +02:00
greeneclipse 89ae7e5fa8 fix 2026-08-23 13:08:14 +02:00
greeneclipse ee1405cc1a fix 2026-08-23 12:56:19 +02:00
greeneclipse 5340158228 fix 2026-08-23 12:40:59 +02:00
greeneclipse bd762d1ccf fix 2026-08-22 19:23:15 +02:00
greeneclipse 0c154254c3 major fixes 2026-08-22 18:51:17 +02:00
greeneclipseandClaude Fable 5 0ff24b1534 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>
2026-08-18 01:49:44 +02:00
greeneclipseandClaude Fable 5 c9554f2f7c Fix DedupeSessionCookies panic with pgxstore (use FindCtx)
Production uses pgxstore, whose plain scs.Store.Find deliberately panics
("missing context arg") — only FindCtx works. DedupeSessionCookies called
Store.Find directly, so any request carrying duplicate session cookies
500'd (chi Recoverer caught the panic). Unit tests passed because the
in-memory store implements plain Find.

Mirror scs.doStoreFind: type-assert FindCtx(context.Context, string) and
use it with the request context, falling back to plain Find for simple
stores. Regression test adds a ctx-only store whose plain methods panic.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-18 01:33:05 +02:00
greeneclipseandClaude Fable 5 6facfbb0aa Self-heal duplicate session cookies from the Domain rollout
Browsers that logged in before the session cookie became Domain-scoped
still hold the old host-only descrybe_session for api.descrybe.io. They
then send BOTH cookies — older (stale) first — and Go reads the first
match, so the stale relic shadows the fresh Domain cookie and every
request 401s even immediately after a successful login. Clearing
browser cookies fixed it manually; users should never have to.

New DedupeSessionCookies middleware (mounted before scs LoadAndSave):
when duplicate session cookies arrive, pick the token that resolves in
the session store, rewrite the Cookie header to just that one, expire
the host-only relic (Set-Cookie without Domain only touches the
host-only variant), and re-issue the surviving token on the canonical
Domain cookie. One request converges the browser to a single cookie.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-18 01:19:46 +02:00
greeneclipseandClaude Fable 5 d03c2a5c57 Auto-derive session cookie domain; AI prompt page = formula builder hub
Session (no env needed):
- SESSION_COOKIE_DOMAIN env removed. Config.SessionCookieParentDomain()
  derives the cookie Domain from WEB_ORIGIN + PUBLIC_API_URL, which the
  API already requires: sibling hosts of one parent (descrybe.io +
  api.descrybe.io) share the parent domain so SvelteKit SSR (/admin
  gate, user switching) receives the session cookie; localhost, IPs,
  same-host, and unrelated hosts stay host-only. Deploying the new build
  is the whole fix — nothing to configure.

AI generation prompt page:
- Each section now embeds its formula editor next to the per-language
  prompt instructions: Title = full title formula builder (preview,
  elements, separator, variable selector, custom variables), Description
  = description formula sections editor (type + instructions + export
  id, drag reorder), Meta = meta title / meta description formula
  fields. One Save writes categories.prompt + title_template +
  description_template together; Assign copies all three to the
  selected categories.
- New $lib/categories/formula-variables.ts loads every usable field for
  the builder: custom variables (/api/variables), company attributes
  (/api/attributes — attribute_key, name, unit, example), and standard
  fields (/api/standard-fields). Used by both the prompt page and the
  title-formula page (which previously ignored attributes).

Verified locally: svelte-check clean for changed files, unit tests pass,
and the full save contract exercised over HTTP as the page does it
(login → load variables/attributes/standard-fields → PATCH prompt +
title-formula + description-formula → round-trip read), then the test
category restored via repair-category-prompts.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-18 01:12:23 +02:00
greeneclipseandClaude Fable 5 9a839d6d13 Store category prompts as EXACT split legacy text, no boilerplate
The per-category prompt editor showed English machine boilerplate
("Role: description. Build JSON …", schema intro, {{var}} context lines)
because seed/sync baked the render framing into categories.prompt. Now the
stored overlay is exactly the legacy wp_product_categories.sql content,
split into the three sections a user would type themselves:

  --- Title ---        Slovenian naming formula
  --- Description ---  legacy <H2>/<p>/<ul> body structure
  --- Meta ---         legacy metaDescription instruction

Schema, role framing, and Name/Description/Category/Attrs product context
stay render-time only (system template + ensureCategoryEnhanceUserContext),
where they already existed.

- SplitLegacyCombinedEnhancePrompt: non-legacy input now returns "" —
  categories without seed/legacy content get their override CLEARED
  (company default) instead of being stuffed with the canonical template
  (e.g. parent categories like "Bela tehnika" absent from the SQL).
- CategoryEnhancePromptNeedsRepair flags stored boilerplate ("parsed as
  JSON", "Build JSON", retired Attributes section) so Sync rewrites old
  data to the clean shape; repair supports clearing (prompt = '{}').
- seed-a1 apply-category-prompts skips instead of writing template text.
- Web editor compose stores only the user's section text: empty sections
  keep bare markers, default bodies and the default preamble are never
  persisted (DEFAULT_SECTION_BODIES removed).
- Verified locally: apply rewrote 238 A1+Demo categories (216 exact
  splits, 22 cleared), zero boilerplate matches in DB, idempotent re-run
  (would_update=0).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-18 00:53:26 +02:00
greeneclipseandClaude Fable 5 0eef202f56 Add SESSION_COOKIE_DOMAIN so /admin SSR sees the session cookie
Production splits web (descrybe.io) and API (api.descrybe.io). The session
cookie was host-only for api.descrybe.io, so the browser never sent it to
the web host. The /admin SvelteKit SSR gate (fetchMeStaff in
+layout.server.ts) forwards the incoming cookie header to /api/auth/me —
with no cookie to forward it always got 401 and bounced every successful
login back to /login?next=/admin (login POST 200, /me 200 from the
browser, /me 401 from the web server).

New SESSION_COOKIE_DOMAIN env (default empty = host-only, local dev
unchanged) sets the session cookie Domain attribute; set it to the parent
domain (descrybe.io) in production so both hosts receive the cookie.
Leading dot is normalized away. CSRF needs no change — it already seeds
cross-origin via the X-CSRF-Token response header.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-18 00:31:58 +02:00
greeneclipseandClaude Fable 5 b595398389 Split A1 category prompts canonically; retire attributes prompting
- Category enhance prompts (Sync A1 / seed-a1 / repair) now use the same
  three role sections as the rest of the platform: Title / Description /
  Meta. The retired "--- Attributes ---" role section is removed from the
  canonical template, the legacy-split overlay, and the web prompt editor;
  Category/Attrs stay as plain product-context lines (attribute extraction
  remains pipeline-level via AppendAttributeConstraints).
- Stored prompts still carrying an attributes section are detected by
  CategoryEnhancePromptNeedsRepair and rewritten on the next Sync.
- Legacy wp_product_categories.sql splits now also seed a default Slovenian
  metaTitle rule (dumps only carried <metaDescription>), so every A1
  category gets all four prompt areas: title formula, description
  sections, meta title, meta description.
- Role-sectioned prompts no longer imply the A1 SEO-omit cohort
  (CompanyOmitsSEOMeta): sectioned prompts are the canonical prompt-editor
  output for every tenant, and the sniff silently disabled SEO meta for
  any company that saved a category prompt.
- Verified locally: repair-category-prompts -apply updated 238 A1 +
  Platform Demo categories from scripts/seed/wp_product_categories.sql
  (216 legacy splits), idempotent on re-run, zero attributes sections
  left in DB.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-18 00:13:44 +02:00
greeneclipse 2a2b01bf59 fix 2026-08-17 23:06:07 +02:00
greeneclipse a7e53ca0a3 fix 2026-08-17 21:56:09 +02:00
greeneclipse 6fcdc74843 fix 2026-08-17 21:20:45 +02:00
greeneclipse 321f11e817 fix 2026-08-17 11:30:14 +02:00
greeneclipse fe94c2fb9c fix 2026-08-17 09:33:07 +02:00
greeneclipse 0dceb3a404 fix 2026-08-17 01:30:28 +02:00
greeneclipse c2429873b3 fix 2026-08-17 00:53:51 +02:00
greeneclipse 179a47494f fix 2026-08-17 00:40:46 +02:00
greeneclipse 93dc70123c fix 2026-08-17 00:39:25 +02:00
greeneclipse 92f046b542 fix 2026-08-16 23:42:00 +02:00
greeneclipse 6e77154228 fix 2026-08-16 23:07:32 +02:00
greeneclipse 389608ea56 fix 2026-08-16 21:35:48 +02:00
greeneclipse 106f602232 fix 2026-08-16 19:21:49 +02:00
greeneclipse d6fe7c38d5 fix 2026-08-16 18:59:29 +02:00
greeneclipse a94a5aaad7 fix 2026-08-16 18:36:56 +02:00
greeneclipse d981147ff2 fix 2026-08-16 18:18:39 +02:00
greeneclipse b19373e2a4 fix 2026-08-16 17:38:15 +02:00
greeneclipse d161b28a10 fix 2026-08-16 17:16:47 +02:00
greeneclipse 532d439c41 fixes 2026-08-16 16:57:36 +02:00
greeneclipse 96f8c1115c update 2026-08-16 12:47:06 +02:00
greeneclipse 1d3a9d5abd fix 2026-08-16 12:23:14 +02:00
greeneclipse 52fb129957 fix 2026-08-16 12:00:28 +02:00
greeneclipse 52f27e30fc fixes 2026-08-16 11:37:42 +02:00
greeneclipse dc9ea628c1 fix 2026-08-14 01:38:34 +02:00
greeneclipse a9395585f8 fix 2026-08-14 00:06:43 +02:00
greeneclipse 841a05572e fix 2026-08-13 23:43:53 +02:00
greeneclipse 322c70e5cf fix 2026-08-13 23:40:39 +02:00