Commit graph

3897 commits

Author SHA1 Message Date
Till JS
5dc0494bb7 i18n(food): translate /food/[id] +page.svelte via $_() — meal detail page
- <title> with {description} interpolation, untitled fallback
- Back link, "Mahlzeit nicht gefunden." empty-state
- Lightbox aria-labels (vergrößern/schließen)
- Nutrient grid labels (Kalorien/Protein/Kohlenhydrate/Fett) via food.nutrition.* + Ballaststoffe/Zucker via food.detail.fiber_with_value/sugar_with_value
- Action buttons: Bearbeiten, "🔄 Erneut analysieren" + Analysiere…, Löschen + Sicher? + Abbrechen + delete-confirm Löschen
- Edit form: Mahlzeittyp/Beschreibung labels, Nährwerte heading, 6 nutrient input labels, Abbrechen/Speichere…/Speichern
- Foods section heading "Erkannte Bestandteile"
- Date formatter `toLocaleString('de-DE', …)` → `toLocaleString(get(locale) ?? 'de', …)`
- All 4 catch-block error fallbacks routed via $_()

Baselines: hardcoded 1140 → 1130 (10 cleared); missing-keys baseline unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 13:57:38 +02:00
Till JS
99e5621468 i18n(food): extend with detail sub-namespace for /food/[id] page
Adds detail: page-title (with {description}), back link, not-found
copy, lightbox aria-labels, edit-form labels (Mahlzeittyp/Beschreibung
+ 6 nutrient labels), Nährwerte section, error messages, action labels
(Erneut analysieren/Analysiere…/Speichere…/Sicher?), foods section
heading, fiber/sugar inline labels with {n}g.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 13:54:53 +02:00
Till JS
165a3e0d12 i18n(context): translate +page.svelte via $_() — overview page
Header (title + subtitle), 4 stat cards (Spaces/Dokumente/Wörter/Split-
label), 2 quick-action buttons, pinned-spaces section heading, recent-
docs section + "Alle anzeigen" link, "Angeheftet" badge, pin/unpin title
toggle, empty-state title+hint+action, "Dokument wirklich löschen?" confirm.

Baselines: hardcoded 1150 → 1140 (10 cleared); missing-keys baseline unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 13:53:14 +02:00
Till JS
3e7f70e096 i18n(context): extend with home sub-namespace for /context overview page
Adds home: page-title, subtitle, 4 stats (Spaces/Dokumente/Wörter/Split),
2 quick actions, 2 section headings, "Alle anzeigen" link, "Angeheftet"
badge, empty-state title+hint+action, delete-doc confirm.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 13:51:44 +02:00
Till JS
f29bb3034c i18n(finance): translate +page.svelte via $_() — header, summary cards, breakdown, add form, history
- <title> tag, page H1
- Summary cards (Einnahmen/Ausgaben/Bilanz) — labels via $_(); values stay numeric
- Section headings (Ausgaben nach Kategorie / Transaktionen)
- Add toggle button: cancel + "+ Transaktion hinzufügen" labels
- Add form: type-toggle (Ausgabe/Einnahme), amount placeholder ("0,00"), description placeholder, submit button
- Loading state ("Laden...")

Baselines: hardcoded 1160 → 1150 (10 cleared); missing-keys baseline unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 13:48:35 +02:00
Till JS
24fc3c610f i18n(finance): add namespace JSONs (de/en/es/fr/it)
Adds page sub-namespace covering page title, summary cards (Einnahmen/
Ausgaben/Bilanz), category breakdown + transactions sections, and add
form (type toggle, amount/description placeholders, submit/cancel).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 13:46:43 +02:00
Till JS
390da4c641 i18n(news): translate +page.svelte via $_() — onboarding wizard + feed cards
- Onboarding 3-step wizard: hero (welcome/intro), step labels (1.Themen/2.Sprache/3.Quellen), all section titles + hints, language pills (Deutsch/English via news.languages.*), back/next buttons, finish + finishLoading state
- Feed: title, "{n} Artikel" meta, "Fehler beim Laden" error, refresh/saved/settings tooltip titles, loading/empty states with hint, "Artikel öffnen" aria-label, reading-time pill ({n} min), saved-badge title + text
- Reaction buttons: interested/saved labels and their titles ("Schon gespeichert..." vs "In Leseliste speichern..."), notInterested + title, blockSource title

Baselines: hardcoded 1170 → 1160 (10 cleared); missing-keys baseline unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 13:45:33 +02:00
Till JS
ab57a62b06 i18n(news): extend feed/reactions/onboarding sub-namespaces with badge + state keys
Adds openArticleAria, savedBadgeTitle/Text, readingTimeMin to feed;
interestedSaved + interestedSavedTitle to reactions; finishLoading to
onboarding. Mirrors all 5 locales.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 13:44:13 +02:00
Till JS
e0e80dc5fa i18n(timeline): translate analytics +page.svelte via $_() — header, summary cards, sections
- Header: page title (Zeitanalyse), period selector (7T/14T/30T) interpolated via {n}
- 4 summary stat labels (Gesamt/Tage Streak/Plan-Treue/Einträge)
- 4 card titles (Zeitverteilung/Tagesverteilung/Habit-Aktivität (90 Tage)/Plan vs Realität)
- Empty-state copy + heatmap cell title with {date}/{count} interpolation
- 4 adherence labels (Geplant/Erledigt/Treue/Ø Abweichung)
- Dead `dayLabels` constant removed (was unused — date-fns formatter renders weekday names directly)

Baselines: hardcoded 1181 → 1170 (11 cleared); missing-keys baseline unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 13:37:11 +02:00
Till JS
582c1a2da8 i18n(timeline): add namespace JSONs (de/en/es/fr/it)
Adds analytics sub-namespace covering page title, period selector,
4 summary stats (total/streak/adherence/entries), 4 sections
(breakdown/daily/heatmap/plan-vs-reality), and 4 adherence labels.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 13:35:57 +02:00
Till JS
99244c68ef i18n(broadcast): translate ComposeView via $_() — 4-step wizard end to end
- Header: name input placeholder + aria, "Gespeichert um {time}" timestamp, Schließen/Speichern actions, Speichert… loading state
- Stepper: 4 step labels (Empfänger/Inhalt/Check/Senden)
- Step 2 content form: Betreff/Preheader/Absender-Name/Absender-E-Mail labels + placeholders, Editor placeholder
- Step 3 preflight: heading, 4 check rows (subject set/missing, recipients count, sender, legal address) with conditional warnings, "Lade Einstellungen…"
- Step 4 send states (idle/confirming/sending/done) with strong-tag interpolation via {@html}; counts injected via {n}, subject via {subject}, fromName via {from}
- Default name and error fallbacks routed through $_(); default-name uses untrack() since $state initialiser runs before template

Baselines: hardcoded 1192 → 1181 (11 cleared); missing-keys baseline unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 13:11:16 +02:00
Till JS
69bdd18490 i18n(broadcast): add namespace JSONs (de/en/es/fr/it)
Adds compose_view sub-namespace covering 4-step wizard: name input,
header actions, stepper labels, content-step form, preflight checks,
send-step states (idle/confirming/sending/done) with interpolated
recipient counts and HTML-formatted strong tags for emphasis.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 13:09:24 +02:00
Till JS
753230c2e6 i18n(todo/settings): translate +page.svelte via $_() — all 6 sections + reset
- Page <title>, header h1, back-link aria
- Task Behavior: section heading, default-priority label + 4 options (priorityLow/Medium/High/Urgent), default-due-time label, auto-archive label + description
- View & Display: section heading, default-view label + 4 options (Inbox/Heute/Anstehend/Kanban), 4 toggle labels (Kompaktmodus/Aufgabenzahl/Teilaufgaben-Fortschritt/Nach Projekt gruppieren) with descriptions; converted 'as size' to 'as const as size' to silence Svelte 5 narrowing
- Kanban Board: section heading, Kartengröße label + 3 size labels (Kompakt/Normal/Groß), Labels-on-cards label, WIP-limit label + description
- Smart Duration: section heading, smartDurationEnabled label + description, defaultTaskDuration label
- Notifications: section heading, defaultReminder label + 6 options (Keine/5/15/30/1h/1d), 2 toggle labels (Tägliche Zusammenfassung/Überfällig)
- Productivity: section heading, 4 toggle labels with descriptions (Fokus-Modus/Pomodoro/Streak/Immersiver Modus), Tagesziel label
- Reset button + 'Alle Todo-Einstellungen zurücksetzen?' confirm

Baselines: hardcoded 1205 → 1192 (13 cleared); missing-keys baseline unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 12:49:46 +02:00
Till JS
fbc06132f2 i18n(todo/settings): extend settings sub-namespace with descriptions and option labels
Adds pageTitle/backAria, view options (Inbox/Today/Upcoming/Kanban),
toggle descriptions (autoArchive/compactMode/showTaskCounts/
showSubtaskProgress/groupByProject/wipLimit/smartDuration/focusMode/
pomodoro/showStreak/immersiveMode), reminder options (None/5/15/30/1h/
1d), and confirmReset prompt. Refines existing labels to match the
page wording.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 12:47:40 +02:00
Till JS
84bc904775 i18n(quiz): translate EditView via $_() — header, meta inputs, question list, new-question form
- Header: back-button aria + "Quiz" label, Spielen play button
- Empty: "Quiz nicht gefunden."
- Meta-section: Titel/Beschreibung/Kategorie/Tags placeholders, Sichtbarkeit row label, untitled fallback
- Question list: "Fragen ({n})" heading, empty state, type-pill, edit/delete title+aria, "Frage löschen?" confirm
- Question types routed through $_('quiz.question_types.' + q.type); QUESTION_TYPE_LABELS constant kept in types.ts for non-Svelte callers
- New-question section: edit/new heading, cancel button, type select (4 options), question/correct-answer/expected-input fields, options-label (multi/single variant), correct-toggle title+aria, "Antwort {n}" placeholder, remove aria, "Antwort hinzufügen", explanation field, save/add submit button
- truefalse default options ("Wahr"/"Falsch") now i18n'd

Baselines: hardcoded 1218 → 1205 (13 cleared); missing-keys baseline +1 (quiz.question_types.* dynamic key).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 12:42:11 +02:00
Till JS
0fbef25565 i18n(quiz): add namespace JSONs (de/en/es/fr/it)
Adds question_types + edit_view sub-namespaces covering meta-section
inputs, question-list controls, new-question form (type/answers/options/
explanation), and confirm/empty messages.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 12:40:43 +02:00
Till JS
2790244683 i18n(spiral): translate ListView via $_() — visualization, stats, apps, palette, actions, info-box
- Section titles (Visualisierung/Statistiken/Apps/Farbpalette/Aktionen)
- Viz controls: Zoom + Grid labels, empty-state copy
- Stats grid: Bildgröße/Events/Pixel belegt/Kompression/Aktueller Ring/Apps aktiv labels, Ring {n} value, "Zuletzt gesammelt: …" line
- App cards: empty-state, "{n} Events" trailing text
- Action buttons: Sammle…/Daten sammeln, PNG herunterladen, PNG importieren, Zurücksetzen
- Info-box heading + 4-line body
- Toast/confirm: "Import fehlgeschlagen: {error}" alert + "Alle Spiral-Daten löschen?" confirm

Baselines: hardcoded 1230 → 1218 (12 cleared); missing-keys baseline unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 02:16:47 +02:00
Till JS
c1e5aa9341 i18n(spiral): add namespace JSONs (de/en/es/fr/it)
Adds list_view sub-namespace covering visualization controls, stats grid,
app breakdown, color palette, action buttons, info-box copy, and import/
clear toast messages.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 02:15:28 +02:00
Till JS
1894e65495 i18n(automations): translate ListView via $_() — suggestions, create form, flow visualization, empty state
- Section labels (Vorschläge/Aktive Regeln), suggestion CTAs (Aktivieren/Nein), '+ Neu' button
- Create form: name placeholder, WENN/FILTER/DANN step badges, source/action/habit/value selectors and placeholders, source-op options (erstellt wird / geändert wird), 'Kein Filter' option, Abbrechen/Erstellen footer
- Toggle title (Deaktivieren/Aktivieren), delete title (Löschen)
- Flow-chip 'wenn' marker, sourceDetail() helper now i18n's the 'erstellt'/'geändert' particle
- Empty state: title, hint, action

Baselines: hardcoded 1242 → 1230 (12 cleared); missing-keys baseline unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 02:14:40 +02:00
Till JS
1b295f3d01 i18n(automations): add namespace JSONs (de/en/es/fr/it)
Adds list_view sub-namespace covering suggestions, active rules section,
create form (WHEN/FILTER/THEN steps), toggle, flow-chip helpers, and
empty-state copy.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 02:13:22 +02:00
Till JS
779752e907 i18n(dreams): translate ListView via $_() — view tabs, insights, filters, editor, transcription badges
- View tabs (Träume/Symbole), insights ribbon, filter chips (Alle/Klarträume/Albträume/Wiederkehrend), search placeholder
- Inline editor: title placeholder, transcription status (transcribing/failed/done), content/symbols placeholders, sleep-row labels (Nacht/Ins Bett/Aufgewacht), sleep quality + star aria-label, Klartraum/Wiederkehrend toggles, Löschen/Fertig actions
- Dream-row: untitled fallback, transcribing/failed badge titles, STT-chip title
- FloatingInputBar placeholder + voice reason
- Mood labels routed through $_('dreams.moods.' + mood); MOOD_LABELS constant kept in types.ts for non-Svelte callers (SymbolDetailView)
- Context menu: edit/pin/unpin/delete via $_()

Baselines: hardcoded 1254 → 1242 (12 cleared); missing-keys baseline +1 (dreams.moods.* dynamic key).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 02:12:00 +02:00
Till JS
3e41b14a31 i18n(dreams): add namespace JSONs (de/en/es/fr/it)
Adds moods + list_view sub-namespaces for the dreams ListView translation
pass — view tabs, insights, filter chips, search, context menu, inline
editor, transcription badges, FloatingInputBar, voice reason.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 02:10:03 +02:00
Till JS
5c3c7ed3bc i18n(recipes): translate ListView via $_() — search, filters, ctx menu, detail panel, create form
- DIFFICULTY_LABELS map dropped from imports; routed through $_('recipes.difficulties.' + d) instead
- Context menu items, search placeholder, fav chip, add card, empty states, create-form labels all i18n'd
- Detail panel headings (Sichtbarkeit/Zutaten/Zubereitung) translated; servings suffix uses {n} interpolation
- Baselines ratcheted: hardcoded 1268 → 1254 (14 cleared); missing-keys baseline +1 (recipes.difficulties.* dynamic key, same pattern as firsts)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 02:08:40 +02:00
Till JS
65da520392 i18n(recipes): add namespace JSONs (de/en/es/fr/it)
Adds difficulties, list_view, detail_panel, create_form sub-namespaces
for the recipes ListView translation pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 02:06:39 +02:00
Till JS
897a55bc65 i18n(api-keys): wire +page to namespace — 14 strings cleared
Patches header, action button, error banner, active/revoked sections
with pluralized counts, empty state, key list rows (rate badge,
created/last-used metadata, revoke button), how-to section,
create/success modal incl. all form labels and rate-limit hint.
Locale-aware Date via get(locale).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 02:03:47 +02:00
Till JS
c9221b9d3d i18n(api-keys): add namespace JSONs for de/en/es/fr/it
Locale-only — page patches in follow-up commit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 02:01:47 +02:00
Till JS
fa5dbb2cfc i18n(firsts): wire ListView to namespace — 15 strings cleared
Patches tabs, quick-add, category filter, search, stats, dream/lived
edit forms, repeat picker, expectation-vs-reality labels, context menu,
all empty states, people-view "Alleine" fallback. CATEGORY_LABELS +
PRIORITY_LABELS routed through firsts.categories.* / firsts.priorities.*
keys; constants kept in milestones/categories.ts for non-Svelte
callers. Locale-aware Date via get(locale).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 01:59:09 +02:00
Till JS
d5d2b6fcf8 docs(sync): document F1 + F3 commit-log corrections (Punkt 9 + 11)
Two commit artifacts from the multi-terminal sprint phase that can't be
fixed without destructive rebase + force-push of 28+ already-pushed
commits on origin/main:

- Punkt 9: F1 commit (7766ea502) shipped under the misleading title
  'docs(plans): mark llm-fallback-aliases SHIPPED' due to a parallel
  terminal session. The real F1 implementation (27 files: shared-ai/
  field-meta.ts, database.ts hooks, sync.ts wire format, mana-sync Go
  schema reset, mana-ai projections, MCP sync-db.ts) is intact in that
  commit despite the title.

- Punkt 11: F3 commit (6bb9d77be) accidentally bundled a one-line
  DragType addition (`| 'last'` in packages/shared-ui/src/dnd/types.ts)
  that belongs to the Lasts module, not to F3's updatedAt sweep. The
  regex codemod ran across the same files and pulled the change in.
  Functionally harmless (DragType union is additive) but semantically
  two unrelated changes share one commit.

Both commits are now annotated via local Git tags
(`sync-field-meta-overhaul-F1`, `sync-field-meta-overhaul-F3`) so a
future reader can find them by name regardless of the commit titles.
Tags are local — `git push --tags` makes them visible upstream.

Plan: docs/plans/sync-field-meta-overhaul.md "Commit-Log Corrections"
section.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 01:56:38 +02:00
Till JS
275130f8a6 test(sync): cross-cutting integration tests for field-meta overhaul (Punkt 12)
Six new tests in sync.test.ts under the "field-meta overhaul (F1-F4-fu)"
block, verifying the architectural promises of the 2026-04-26 sync
field-meta overhaul end-to-end:

- deriveUpdatedAt returns max(__fieldMeta[*].at)
- deriveUpdatedAt gracefully handles legacy / null records
- Dexie creating-hook stamps __fieldMeta + _updatedAtIndex on every
  local write
- Dexie updating-hook bumps __fieldMeta only for changed fields and
  syncs _updatedAtIndex with the latest at
- SYSTEM_BOOTSTRAP-stamped local insert produces origin='system' (the
  fallback path in userContextStore + kontextStore)
- Bootstrap-twin race scenario: local SYSTEM_BOOTSTRAP row + later
  server insert collapses via field-LWW with no conflict surface

Also re-exports SYSTEM_BOOTSTRAP from $lib/data/events/actor for
parity with the other SYSTEM_* sentinels.

35/35 sync.test.ts pass (29 prior + 6 new).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 01:54:35 +02:00
Till JS
220afc092a i18n(firsts): add namespace JSONs for de/en/es/fr/it
Locale-only — ListView patches in follow-up commit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 01:49:24 +02:00
Till JS
b06d950c4f i18n(goals): wire GoalEditor to namespace — 15 strings cleared
Patches form labels, event type options (now reactive via $derived),
source/comparison/period selectors, action buttons. Locale JSONs
landed in the previous commit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 01:48:01 +02:00
Till JS
421a49a2a8 docs(sync): close Punkt 5 audit — backend updated_at columns are not sync orphans
Survey of all 17 backend Drizzle schemas (mana-mail/-media/-auth/
-analytics/-research/-events/-subscriptions/-credits + apps/api/
{unlisted,website,traces,presi,todo}):

- 3 columns are actively read by service code:
  - research.providerConfigs.updatedAt — explicit write + DTO field
  - unlisted.snapshots.updatedAt — read in public response
  - website.customDomains.updatedAt — read in DNS-status response
- 14 columns are AUTO-ONLY: Drizzle stamps them via defaultNow() /
  $onUpdate(), no service code reads them.

But the AUTO-ONLY columns are NOT sync-orphans — they're standard
Drizzle audit-timestamp convention, useful for Postgres-level forensics
(`ORDER BY updated_at DESC` to find recently-modified rows during
debugging). F3's plan note ("pure server-internal columns, not touched")
correctly identified them. No cleanup is needed.

Closing the audit item with rationale documented in
docs/plans/sync-field-meta-overhaul.md and DATA_LAYER_AUDIT.md.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 01:47:41 +02:00
Till JS
81f1056b4a i18n(goals): add namespace JSONs for de/en/es/fr/it
Locale-only — GoalEditor patches in follow-up commit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 01:47:02 +02:00
Till JS
9a712dde9f i18n(gifts): wire +page to namespace — 15 strings cleared
Patches all toast/error messages, page header, action buttons, tabs,
received/created sections, create form, info card. Locale-aware
Date/number formatting via get(locale). Locale JSONs landed in the
previous commit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 01:46:03 +02:00
Till JS
ae6a14fb76 feat(shared-ai): SYSTEM_BOOTSTRAP system source — fallback inserts now stamp origin='system'
The race-window `getOrCreateLocalDoc()` fallback in userContextStore +
kontextStore stays (without it, a write that lands between "endpoint
provisioned the singleton in mana_sync" and "first pull landed it in
IndexedDB" would hit `update(missing-id, diff)` — a Dexie no-op that
silently swallows the user's edit). But it was semantically lying: the
insert stamped `origin='user'` even though the row is logically a
client-side replica of the server-side bootstrap.

This commit adds `SYSTEM_BOOTSTRAP = 'system:bootstrap'` to
`@mana/shared-ai` and wraps the two fallback inserts in
`runAsAsync(makeSystemActor(SYSTEM_BOOTSTRAP), ...)`. The Dexie hook
now stamps `origin: 'system'` on the empty-row insert — structurally
identical to the row mana-auth's bootstrap-singletons.ts writes. When
the server's pull arrives later both sides carry the same origin and
the conflict-gate stays quiet. The user's subsequent writes still
stamp `origin: 'user'` on the changed fields.

Plan: docs/plans/sync-field-meta-overhaul.md (F4-fu Fallback-Origin row).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 01:44:30 +02:00
Till JS
01681b58ff i18n(gifts): add namespace JSONs for de/en/es/fr/it
Locale-only — page patches in follow-up commit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 01:43:01 +02:00
Till JS
36d832a3db i18n(library): wire DetailView to namespace — 16 strings cleared
Patches all action labels, kind/status/format pills (routed through
dynamic library.kinds.*, library.statuses.*, library.book_formats.*),
detail dt/dd pairs, restart label, times badge, review section.
constants.ts kept with literal {de,en} maps for non-Svelte callers.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 01:39:25 +02:00
Till JS
099cac4a01 feat(auth): explicit bootstrap-singletons endpoint + idempotent functions (F4 robust)
The F4 server-side singleton bootstrap was fire-and-forget at signup
time — a transient mana_sync outage during registration would leave the
user with no singleton and only the in-store `getOrCreateLocalDoc()`
fallback to race on the first write. The signup-hook is still the
happy-path zero-latency bootstrap; this commit adds a deliberate
reconciliation path that converges on every boot.

- Idempotent `bootstrapUserSingletons` / `bootstrapSpaceSingletons`:
  both functions now existence-check sync_changes before INSERT and
  return boolean (true=inserted, false=skipped).
- New endpoint `POST /api/v1/me/bootstrap-singletons` — JWT-gated under
  the existing `/api/v1/me/*` prefix. Provisions the caller's
  userContext and the kontextDoc for every Space they're a member of.
  Returns `{ ok, bootstrapped: { userContext, spaces: { id: bool } } }`.
- Webapp `(app)/+layout.svelte` calls the endpoint once per
  authenticated boot, after `restoreClientIdFromDexie()` and before
  `createUnifiedSync.startAll()`. Best-effort; failures swallow into a
  console warning and the in-store fallback still covers the rare
  race window.

Plan: docs/plans/sync-field-meta-overhaul.md (F4-robust row).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 01:38:14 +02:00
Till JS
98d334045a i18n(library): add namespace JSONs for de/en/es/fr/it
Locale-only — DetailView patches in follow-up commit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 01:38:03 +02:00
Till JS
4731bc80fd i18n(ai-missions): wire ListView to namespace — 22 strings cleared
Patches list/create/detail panes incl. PHASE_LABELS, describeCadence,
describeState, formatRelative, grant box, iteration phase block, error
details, feedback form. Locale JSONs landed in the previous commit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 01:36:12 +02:00
Till JS
da15f8de47 i18n(ai-missions): add namespace JSONs for de/en/es/fr/it
Locale-only — component patches in follow-up commit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 01:33:47 +02:00
Till JS
b064e8e51e fix(community): import queries via .svelte path; type DetailView reaction filter
- Views import '../queries.svelte' (not '../queries') so module
  resolution finds the renamed file.
- DetailView's filter callbacks need an explicit string param-type
  under the stricter implicit-any check — myReactions is string[].

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 01:30:47 +02:00
Till JS
4081ce6346 fix(community): queries.ts → queries.svelte.ts for runes ('$state is not defined')
Svelte 5 runes only work in .svelte / .svelte.ts files; the .ts
extension caused a server-side ReferenceError on /community SSR
because the runtime ships no $state symbol there.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 01:27:21 +02:00
Till JS
0a03e9e882 i18n(ai-agents): wire ListView to namespace — 23 strings cleared
Patches list/create/detail panes incl. POLICY_LABEL, TEMPLATES,
mission state labels, natural-language policy summary. Locale JSONs
landed in the previous commit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 01:26:30 +02:00
Till JS
53fecbf4a7 chore(dexie): v55 — sweep orphan updatedAt field from existing rows (F3 cleanup)
After F3 of the sync field-meta overhaul, every read of "last modified"
goes through `deriveUpdatedAt(record)` over `__fieldMeta`. The legacy
`updatedAt` field on existing IndexedDB rows was deliberately left in
place by v53 (its comment explicitly defers the row-rewrite to a later
cleanup) so the cut-over could proceed without a full DB rewrite.

This v55 upgrade walks every sync-relevant table (`Object.keys(TABLE_TO_APP)`)
and `delete row.updatedAt`. Idempotent (rows without the field are a
no-op), best-effort (try/catch per table guards against a registry
entry that doesn't yet have a Dexie store row).

Local-only tables (_pendingChanges, _activity, _clientIdentity,
_aiDebugLog) never carried `updatedAt`, so they stay out of the sweep.

Plan: docs/plans/sync-field-meta-overhaul.md (F3-fu row in Shipping Log).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 01:26:21 +02:00
Till JS
da50da8964 i18n(ai-agents): add namespace JSONs for de/en/es/fr/it
Locale-only — component patches in follow-up commit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 01:23:57 +02:00
Till JS
3df7391905 feat(auth): bootstrap per-Space kontextDoc on Space-creation (F4 follow-up)
Symmetrically extends the F4 server-side singleton bootstrap to the
per-Space `kontextDoc`. Every Space-creation — Personal at signup and
brand/club/family/team/practice via the org plugin — now writes an empty
kontextDoc row straight into mana_sync.sync_changes with origin='system',
client_id='system:bootstrap'. Fresh clients pull the row instead of
racing on a local insert that the next pull would clobber.

- New `bootstrapSpaceSingletons(spaceId, ownerUserId, syncSql)` in
  services/mana-auth/src/services/bootstrap-singletons.ts; shared
  `buildFieldMeta` helper extracted.
- `createBetterAuth(databaseUrl, syncDatabaseUrl, webauthn)` now takes
  the sync-DB URL and lazy-creates a module-scoped postgres pool for
  the bootstrap inserts.
- Hook into `databaseHooks.user.create.after` (only on `created: true`
  from createPersonalSpaceFor) and `organizationHooks.afterCreateOrganization`.
- Webapp `kontextStore.ensureDoc()` made private as `getOrCreateLocalDoc()` —
  same fallback role as userContextStore's after F5. Public API is now just
  setContent + appendContent.

Plan: docs/plans/sync-field-meta-overhaul.md (F4-fu row in Shipping Log).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 01:21:31 +02:00
Till JS
bcf150ea16 i18n(credits): wire ListView to namespace — 25 strings cleared
Patches all toast/error messages, balance labels, tabs, subscription
status/details, billing interval toggle, plan rows, invoices,
transaction table, package cards, costs filters/info-banner.
Locale-aware Date/number formatting via get(locale) ?? 'de'.
APP_LABELS + getCategoryLabel routed through namespace keys.
Locale JSONs landed in da330f0c7.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 01:20:34 +02:00
Till JS
da330f0c7a i18n(credits): extend namespace JSONs with list_view sub-namespace
Locale-only — component patches in follow-up commit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 01:17:36 +02:00
Till JS
6d1546975f i18n(website): wire components + views to namespace — 68 strings cleared
Patches ListView, EditorView, SubmissionsView, BlockInspector,
ImageInspector, GalleryInspector, InsertPalette, PageList,
PublishBar, RollbackDialog, SiteSettingsDialog, DomainsSection,
TemplatePicker. Locale JSONs landed in 9e9f5ce64.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 01:14:16 +02:00