Commit graph

3676 commits

Author SHA1 Message Date
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
Till JS
9e9f5ce641 i18n(website): add namespace JSONs for de/en/es/fr/it
Locale files only — component patches in follow-up commit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 01:07:05 +02:00
Till JS
98d07a8d48 docs(claude): document sync field-meta overhaul (F1-F7) in CLAUDE.md + DATA_LAYER_AUDIT
apps/mana/CLAUDE.md:
- Data-flow diagram updated: __fieldMeta + _updatedAtIndex + origin
  replace the older __fieldTimestamps / __fieldActors / __lastActor trio.
- New "Conflict-Detection" sub-section in §Data Layer summarizes the
  four moving parts (origin-gating, derived updatedAt, server-side
  singleton bootstrap, stable client_id) with a "use this" cheatsheet
  for the patterns you'll reach for when writing new module code.

DATA_LAYER_AUDIT.md:
- Eckdaten line points at v53/v54 instead of "v9 added updatedAt
  indexes". Conflict-Resolution bullet says "Origin-gated Field-Level
  LWW via __fieldMeta" (was: __fieldTimestamps).
- New "Sync Field-Meta Overhaul (2026-04-26, F1-F7 SHIPPED)" sub-section
  with one paragraph per phase + commit hash + the four bug-roots that
  were closed.
- Punkt 15 (Conflict-Visualisierung) flipped from "🟢 Backlog" to "
  Sprint 4+ Backlog C shipped, F2 origin-gated the trigger so only
  real user edits surface".

Future sessions reading the repo cold get the post-overhaul architecture
from these two files instead of having to chase the plan + commit log.

Closes Punkt 10 of the F1-F7 follow-up audit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 01:06:05 +02:00
Till JS
899fccd455 i18n(uload): wire components + routes to namespace — 67 strings cleared
Patches ListView, DetailView, /uload root page, /uload/links,
/uload/analytics/[id], /uload/settings, /uload/tags. Locale JSONs
landed in 812f3f7fa.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 01:03:00 +02:00
Till JS
c9a091e696 fix(docker): COPY packages/shared-privacy into sveltekit-base
mana-web depends on @mana/shared-privacy (visibility-system) but it was
missing from the base-image COPY list, causing pnpm install to fail
inside the build container with ERR_PNPM_WORKSPACE_PKG_NOT_FOUND.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 01:02:55 +02:00
Till JS
119cd2cf83 chore(boot): sweep orphan migration flags from localStorage
Two one-shot bootstraps left a per-user flag in localStorage so they
wouldn't run twice — and after F7 deleted the helpers themselves
(2a8e8ff98), the flags pointed at code that no longer existed:

  mana.profile.silentTwinRepair.<userId>
  mana.profile.avatarMigration.<userId>

New \`cleanupOrphanMigrationFlags()\` runs once per page load from the
(app) layout's onMount, right after \`restoreClientIdFromDexie()\`.
Cheap (single localStorage scan), idempotent (no-op once swept),
silent on private-mode / quota errors. The known-orphan prefix list
lives in the helper file with deletion-commit refs so it's clear
when each entry can be retired.

Future migration deletions: append the prefix to ORPHAN_KEY_PREFIXES
in the same commit that drops the helper, and the next page load
on every device cleans up.

Closes Punkt 8 of the F1-F7 follow-up audit.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 01:01:35 +02:00
Till JS
cabfd1004d feat(infra): community.mana.how (instead of analytics.*) for the public-feedback hub
analytics.mana.how DNS already existed as a non-CNAME record — picking
the user-facing 'community.mana.how' subdomain instead. Added the
tunnel ingress + matched the CORS origin + client-side env var.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 01:00:22 +02:00
Till JS
515de79c8b refactor(stores): replace Record<string,unknown> declarations with Partial<LocalX>
Final follow-up to drop the type-bypass patterns from F3's codemod.
Mit \`Partial<LocalX>\` als Deklaration akzeptiert Dexie's UpdateSpec
ohne weiteren Cast — die kombinierte \`as Record<string,unknown>\` +
\`as never\` Konstruktion wird durch eine einzige saubere
Typ-Annotation ersetzt.

Touched stores (12 Files):
  wardrobe/stores/{garments,outfits}, invoices/stores/invoices,
  sleep/stores/sleep, library/stores/entries,
  comic/stores/{characters,stories},
  profile/stores/me-images, recipes/stores/recipes,
  broadcast/stores/campaigns, writing/stores/{styles,drafts}

Plus inline literal-object patterns (\`{ lines, totals } as Record\`,
\`{ content } as Record\`, \`{ audience } as Record\`,
\`{ ...spread } as Record\` im comic appendPanel).

Verbleibende \`as Record<string, unknown>\` Vorkommen sind legitime
Reads von typed-data und nicht das F3-Pattern.

7670 svelte-check Files, 0 Errors, 0 Warnings.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 00:58:01 +02:00
Till JS
b4589a7249 feat(infra): route analytics.mana.how to mana-analytics:3064
Phase 2 feedback hub needs a public hostname so the browser-side
FeedbackHook + /community page can talk to mana-analytics. Internal
docker URL stays for SSR.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 00:57:05 +02:00
Till JS
812f3f7fa0 i18n(uload): extend namespace JSONs for routes/views
Adds list_view, detail_view, page, links_route, analytics_route,
settings_route, tags_route sub-namespaces across all 5 locales.
Component patches in follow-up commit (split to land safely with
parallel sessions in this repo committing).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 00:55:48 +02:00
Till JS
3673542f82 feat(mana-web): inject PUBLIC_MANA_ANALYTICS_URL for client-side feedback calls
mana-web SSR + browser need the analytics URL so the inline
FeedbackHook + /community page can talk to the new public-feedback
endpoints. SSR uses the internal docker hostname; browser uses the
public subdomain.

Note: analytics.mana.how DNS + Caddy reverse-proxy block must be
provisioned separately on the Mac Mini before browser-side calls
work — TODO in deploy-followup.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 00:55:40 +02:00
Till JS
1334bd3626 refactor(stores): drop remaining \as never\ + \as Record<string,unknown>\ casts
Follow-up to a68933bff. Multi-Terminal commits hatten meinen ersten
Cleanup teilweise verschluckt — dieser Commit räumt die übrig
gebliebenen 22 \`update(id, X as never)\` Casts in den 13 Stores
zusammen mit den letzten \`as Record<string, unknown>\` Argumenten
für \`encryptRecord\` weg. Public API der Stores unverändert,
\`Partial<LocalX>\` reicht für Dexie's UpdateSpec ohne Cast.

7670 svelte-check Files, 0 Errors, 0 Warnings.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 00:53:41 +02:00
Till JS
5387681936 fix(mana-analytics): copy shared-logger into installer (transitive workspace dep)
shared-hono depends on @mana/shared-logger; without it, the bun runtime
crashes on first import with ENOENT for the workspace symlink target.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 00:52:33 +02:00
Till JS
db01ddccc7 fix(mana-analytics): multi-stage Dockerfile that resolves workspace deps
Switches the build context to repo-root so the pnpm-workspace install
can pull in @mana/shared-hono. Mirrors the mana-auth/mana-ai pattern
(node+pnpm installer stage → bun runtime stage).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 00:50:25 +02:00
Till JS
722fe74ced i18n(stretch): wire components to namespace — 34 strings cleared
Patches ListView, AssessmentWizard, ReminderManager, RoutineCreator,
SessionHistory, SessionPlayer, plus the /stretch route page title.

Locale JSONs landed in 421663ba3.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 00:49:23 +02:00
Till JS
421663ba3d i18n(stretch): add namespace JSONs for de/en/es/fr/it
Locale files only — component patches land in a follow-up commit.
Splitting the work to land translations safely while parallel sessions
in this repo are committing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 00:30:17 +02:00
Till JS
a68933bff3 refactor(stores): drop \as never\ Dexie-update casts
Cleanup-Schuld aus F3 (sync-field-meta-overhaul). Der Codemod hatte
\`Record<string, unknown>\`-Deklarationen via \`as never\` durch
Dexie's strikten \`UpdateSpec<LocalX>\` durchgemogelt. Jetzt sauber:
jeder Store deklariert \`const wrapped: Partial<LocalX> = { ...patch }\`
und Dexie akzeptiert das ohne Cast.

Touched stores (13 Files, ~24 update-sites):
  comic/stores/{stories,characters}, comic/views/DetailView
  wardrobe/stores/{garments,outfits}
  invoices/stores/invoices
  sleep/stores/sleep
  library/stores/entries
  profile/stores/me-images
  recipes/stores/recipes
  broadcast/stores/campaigns
  writing/stores/{styles,drafts}

\`encryptRecord\` ist generic (\`<T extends object>\`) und akzeptiert
Partial<LocalX> direkt — der äußere \`as Record<string, unknown>\`
Cast ist auch weg.

Übrig bleibende \`as Record<string, unknown>\`-Vorkommen in
{invoices,broadcast}/stores/settings + profile/user-context sind
legitime Reads von nested-data, nicht das F3-Pattern.

7670 svelte-check Files, 0 Errors, 0 Warnings. 29/29 sync.test.ts.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 00:29:51 +02:00
Till JS
576fe79269 fix(community): clear svelte-check warnings for fail-on-warnings push gate
Reactive-state-locally + a11y-noninteractive-tabindex/element warnings.
No behavior changes — props stay reactive via destructure-from-$props
pattern, ignore-comments document intentional a11y exceptions.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 00:25:35 +02:00
Till JS
39ef7ca9d5 chore(compose): wire FEEDBACK_PSEUDONYM_SECRET into mana-analytics
Required by the public-community-hub stamping. Compose enforces the
var via :? syntax — startup fails fast if .env.macmini is missing it,
which beats silently using the dev default in production.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 00:18:16 +02:00
Till JS
5959f66387 i18n(wardrobe): translate all 5 locales — 36 strings
Adds wardrobe namespace (de/en/es/fr/it) covering ListView,
GridView, OutfitsView, DetailGarmentView, DetailOutfitView,
GarmentForm, OutfitComposer, GarmentTryOnButton, TryOnButton,
TryOnModelPicker, CategoryTabs, GarmentCard, OutfitCard, plus
the /wardrobe/compose route. Categories/occasions/seasons routed
through dynamic `wardrobe.categories.{key}` lookups so constants.ts
keeps the order-tuples without leaking DE labels into UI.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 00:12:18 +02:00
Till JS
8804a20a7f feat(community): public anon hub — module + inline + admin + onboarding
Macht @mana/feedback omnipräsent + öffentlich. Phase 2 vom
Public-Community-Hub-Plan (docs/plans/feedback-hub-public.md).

Inline-Touchpoints:
- FeedbackHook: Lightbulb-Button, opens FeedbackQuickModal vorausgefüllt
  mit module-context. Auto-injected in jeder ModuleShell-Header
  (window-actions row), opt-out via hideFeedback prop.
- GlobalFeedbackPill: Floating "Idee?"-Pill bottom-right, self-hides
  auf /onboarding, /feedback, /community, und für Gäste. Auto-detected
  module-context aus URL bzw. ?app=-Param.
- FeedbackQuickModal: 3-Klick-Submit mit Category-Dropdown, Public-
  Toggle, "Sichtbar als {Pseudonym}"-Confirm-State.

Community-Modul (eigenes Modul, in Workbench drop-bar):
- module.config.ts (server-only, keine Sync-Tabellen)
- queries.ts: useCommunityFeed + useCommunityItem mit auth-aware Switch
  zwischen public + auth-enriched Endpoints
- ListView/DetailView/RoadmapView mit ItemCard-Component
- App-Registry-Eintrag (Megaphone-Icon, #F59E0B)

Public-Mirror-Routes (kein AuthGate):
- /community            — Feed mit SSR-Pre-Render via Public-Endpoint
- /community/[id]       — Single item + replies, SSR
- /community/roadmap    — Kanban Submitted/Planned/InProgress/Completed
- /community/admin      — Founder-only Triage (Status, AdminResponse,
                         visibility-Toggle); Client-side role-gate
                         redirect → /community.
SEO: <svelte:head> mit title/description, <noscript>-Fallback,
Cache-Headers stale-while-revalidate.

API:
- web's lib/api/feedback.ts pointed an die echte mana-analytics-URL
  (3064 dev) statt mana-auth. Neuer publicFeedbackService für
  unauthenticated SSR.
- getManaAnalyticsUrl() in lib/api/config.ts.

Onboarding-Wish public-by-default:
- Disclosure-Text: "Erscheint in Community-Page als Tier-Pseudonym".
- Toggle "Öffentlich teilen" / "Nur für Admins" mit Default on.
- Submitted-Confirm zeigt das generierte Display-Name.

Plan-Doc-Updates:
- feedback-hub.md Phase 2 abgespeckt → Verweis auf feedback-hub-public.md
- feedback-hub-public.md komplett: Architektur-Optionen A-E, Phase 2.x,
  Phase 3 Roadmap (16 Future-Features), Risiken.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 00:02:25 +02:00
Till JS
c9b122076a feat(feedback): public feed types + ReactionBar + service split
@mana/feedback wird zur Pflege-SSOT für Public-Community-Hub.

- PublicFeedbackItem-Typ: anonymisiertes Item, das nur display_name +
  reactions + status führt — kein userId, displayHash, deviceInfo.
- ReactionEmoji ('👍' '❤️' '🚀' '🤔' '🎉') + REACTION_LABELS mit DE-Labels.
- CreateFeedbackInput erweitert um moduleContext + parentId. Reactions
  + score auf Feedback-Type optional gemacht.
- Service-Split:
  createFeedbackService    — auth-required Submit/React/Manage,
                            getPublicFeed (auth-enriched mit myReactions)
  createPublicFeedbackService — anonymous, SSR-only, getFeed/getItem.
  toggleReaction(emoji) statt vote/unvote (legacy-Shims bleiben für
  back-compat zu vote → '👍'-Toggle).
- ReactionBar.svelte: Slack-Style emoji-row mit Active-Highlighting für
  myReactions, ReadOnly-Mode für Public-SSR. Auto-disabled-Tooltip.
- index.ts re-exportiert die neuen Typen + ReactionBar; FeedbackVote
  rausgeschmissen (durch FeedbackReactions im Server-Schema ersetzt).

FeedbackCard + FeedbackPage minimal angepasst, damit svelte-check
clean bleibt — die Legacy-Komponenten bleiben funktional, werden aber
in Phase 3 zu @mana/feedback's neuen Modul-Views ausgemistet.

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