managarten/scripts
Till JS fbbadc91f0 feat(calendar): M8.3 — calendar pilot for unlisted-share end-to-end
Wires Calendar through the M8.1+M8.2 backbone: flipping an event to
'unlisted' now publishes a server-side snapshot, the visible link in
the DetailView/EventDetailModal opens a real /share/[token] page, and
recipients can download an .ics file for their own calendar.

Changes:
- lib/data/unlisted/resolvers.ts (new):
    buildUnlistedBlob(collection, recordId) dispatcher.
    buildEventBlob: load LocalEvent + linked TimeBlock, decrypt
    client-side, return { title, location, startTime, endTime,
    isAllDay, timezone }. Description, reminders, tagIds, calendarId,
    color stay out of the blob — sensitive context the user didn't
    consent to share by flipping a single flag.
- modules/calendar/types: CalendarEvent gains `unlistedToken: string`
  (empty string when no active token). timeBlockToCalendarEvent
  forwards from LocalEvent. Draft-event scaffold initializes empty.
- modules/calendar/stores/events:
    setVisibility now coordinates with mana-api. Flip-to-unlisted:
      build blob -> publishUnlistedSnapshot -> store server-issued
      token in patch.unlistedToken -> commit local update. If the
      server call fails, no local change happens (no drift).
    Flip-from-unlisted: revoke server snapshot first, then clear
      local token + commit visibility change.
    deleteEvent: revoke active unlisted snapshot before tombstoning,
      so the share-link dies in lock-step with the local delete.
    updateEvent + updateSingleInstance fire-and-forget
      refreshUnlistedSnapshot(id) so the published blob tracks any
      whitelist-field edits. Failures log; the next successful
      refresh heals.
    New regenerateUnlistedToken(id): revoke + republish in one call,
      returns the fresh token. Powers the "Neu erzeugen" UI.
- routes/share/[token]/+layout.svelte: minimal anonymous chrome —
  no app nav, no auth, no Dexie. Light/dark via prefers-color-scheme.
  Footer carries "Geteilt via Mana" + signup CTA.
- routes/share/[token]/+page.server.ts: SSR loader. Fetches
  /api/v1/unlisted/public/:token, dispatches 404/410 cleanly,
  sets Cache-Control: private, max-age=60 + X-Robots-Tag: noindex.
- routes/share/[token]/+page.svelte: dispatcher; renders
  SharedEventView for collection='events', stub message otherwise.
- modules/calendar/SharedEventView.svelte: standalone public render —
  big date, location, "Zum eigenen Kalender hinzufügen" .ics link,
  optional expiry note. OG/Twitter meta tags for WhatsApp/Slack
  preview embedding. Uses $derived everywhere so prop updates
  propagate through reactive recompute.
- routes/share/[token]/ical/+server.ts: RFC 5545 builder. No npm
  library — small enough to inline. Escapes per spec, CRLF endings,
  DTSTART/DTEND swap between VALUE=DATE and UTC depending on isAllDay.
  Wrong-collection requests get 400.
- modules/calendar/views/DetailView (Workbench) + components/
  EventDetailModal (/calendar route): SharedLinkControls dropped in
  below the visibility row when event.visibility === 'unlisted'
  AND event.unlistedToken AND shareUrl computed. The URL is built
  client-side via buildShareUrl(window.location.origin, token) so it
  stays in sync with whichever host the editor is open on.

Verified:
- pnpm check (web): 7541 files, 0 errors, 0 warnings
- pnpm test calendar + website: 26/26
- typecheck of new resolver, store hooks, SSR loader, iCal builder

Manual test path:
1. Open /calendar event in Detail view, flip Sichtbarkeit -> "Per Link"
2. Server publishes snapshot, Dexie record gets the server token
3. SharedLinkControls appear with copy + regenerate + revoke buttons
4. Open the URL in incognito → SSR fetches snapshot, renders
   SharedEventView with date / location / .ics download
5. Edit the event title back in the main app → snapshot auto-refreshes
   (refreshUnlistedSnapshot fires after updateEvent succeeds)
6. Flip back to "Bereich" → snapshot revoked server-side; subsequent
   incognito reloads return 410 Gone

Next: M8.4 — same wiring for Library + Places. Uses the same
infra (resolvers dispatcher, share dispatcher) — just adds two new
buildXBlob functions, two SharedXView components, and the store
hooks.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 11:40:53 +02:00
..
dev chore(dev): seed real credit balance in setup-dev-user.sh 2026-04-15 18:51:39 +02:00
mac-mini chore(infra): unify prod deploy on .env.macmini + document missing keys 2026-04-23 13:01:29 +02:00
personas feat(personas): M2.a-c — persona schemas + admin endpoints + seed pipeline 2026-04-23 13:55:14 +02:00
test-data feat: rename ManaCore to Mana across entire codebase 2026-04-05 20:00:13 +02:00
test-reporting chore: complete ManaCore → Mana rename (docs, go modules, plists, images) 2026-04-07 12:26:10 +02:00
audit-bundle.mjs chore(bundle): add bundle-size audit + snapshot inventory 2026-04-22 17:52:08 +02:00
audit-complexity.mjs chore(audit): module complexity reports + workbench map 2026-04-14 19:47:42 +02:00
audit-crypto-registry.mjs feat(crypto): Phase C — build-time registry ↔ Dexie audit 2026-04-20 14:36:32 +02:00
audit-encrypted-tools.ts fix(personas): exact tool_use_id pairing + CI drift audit 2026-04-23 15:34:52 +02:00
audit-i18n-coverage.mjs chore(i18n): add coverage audit + migration inventory 2026-04-22 17:16:55 +02:00
audit-icon-usage.mjs perf(invoices): lazy-load pdf-lib + swissqrbill, -516 KB on route 2026-04-22 18:03:53 +02:00
audit-module-coupling.mjs chore(audit): module complexity reports + workbench map 2026-04-14 19:47:42 +02:00
audit-modules.mjs chore(audit): module complexity reports + workbench map 2026-04-14 19:47:42 +02:00
audit-port-drift.mjs chore(services): add port-drift audit 2026-04-22 17:22:37 +02:00
audit-test-coverage.mjs chore(test + audit): add test-coverage audit + wire audit:all 2026-04-22 17:38:12 +02:00
audit-workspace-deps.mjs refactor: rename zitare -> quotes (Zitate) 2026-04-14 20:59:16 +02:00
backup-monitoring.sh feat: rename ManaCore to Mana across entire codebase 2026-04-05 20:00:13 +02:00
build-complexity-map.mjs chore(audit): module complexity reports + workbench map 2026-04-14 19:47:42 +02:00
check-status.sh feat: rename ManaCore to Mana across entire codebase 2026-04-05 20:00:13 +02:00
create-gift-codes.mjs feat: rename ManaCore to Mana across entire codebase 2026-04-05 20:00:13 +02:00
deploy-metrics.sh fix(deploy): fix image size measurement in deploy metrics 2026-03-20 21:13:03 +01:00
ecosystem-audit.mjs feat: rename ManaCore to Mana across entire codebase 2026-04-05 20:00:13 +02:00
fix-mixed-imports.mjs Fix wrong type 2025-12-04 23:25:25 +01:00
generate-dockerfiles.mjs feat(infra): extend Dockerfile validator to backends and services 2026-03-25 08:57:10 +01:00
generate-env.mjs feat(wardrobe,picture): Google Nano Banana as a Try-On option 2026-04-24 16:04:21 +02:00
generate-status-page.sh feat(mana-ai): Prometheus /metrics endpoint + status.mana.how integration 2026-04-15 01:41:40 +02:00
i18n-hardcoded-baseline.json feat(scripts): validate:i18n-hardcoded — ratcheting baseline check 2026-04-25 11:33:24 +02:00
i18n-missing-baseline.json feat(calendar): M8.3 — calendar pilot for unlisted-share end-to-end 2026-04-25 11:40:53 +02:00
lighthouse-audit.sh refactor: rename zitare -> quotes (Zitate) 2026-04-14 20:59:16 +02:00
migrate-theme-tokens.mjs refactor(theming): migrate remaining 738 token violations across routes + components 2026-04-22 15:42:55 +02:00
migrate-transition-all.mjs refactor(theming): replace transition-all with specific transitions 2026-04-22 15:57:49 +02:00
run-integration-tests.sh fix(mana-auth): account lockout was structurally dead + add failure-path tests 2026-04-08 18:29:00 +02:00
run-tests-with-coverage.sh feat: rename ManaCore to Mana across entire codebase 2026-04-05 20:00:13 +02:00
setup-databases.sh chore(setup:db): surface drizzle-kit errors instead of catch-all 2026-04-23 15:36:18 +02:00
setup-secrets.mjs feat(env): persistent dev secrets via .env.secrets override 2026-04-08 17:50:37 +02:00
test-chat-auth.sh chore: tidy root files + reorganize a few stale docs 2026-04-08 12:15:27 +02:00
validate-cloudflared-config.mjs chore(infra): pre-commit validator for cloudflared-config.yml 2026-04-09 18:02:51 +02:00
validate-dockerfiles.mjs refactor: rename zitare -> quotes (Zitate) 2026-04-14 20:59:16 +02:00
validate-i18n-keys.mjs feat(calendar): M8.3 — calendar pilot for unlisted-share end-to-end 2026-04-25 11:40:53 +02:00
validate-i18n-parity.mjs feat(scripts): validate:i18n-parity — lock locale key-sets in CI 2026-04-24 16:30:35 +02:00
validate-monorepo.mjs refactor: rename zitare -> quotes (Zitate) 2026-04-14 20:59:16 +02:00
validate-no-hardcoded-strings.mjs feat(scripts): validate:i18n-hardcoded — ratcheting baseline check 2026-04-25 11:33:24 +02:00
validate-no-recursive-turbo.mjs chore(turbo): lint against recursive \turbo run\ calls in child packages 2026-04-20 14:39:32 +02:00
validate-pg-schema-isolation.mjs chore(db): enforce pgSchema isolation with a lint script 2026-04-20 14:45:59 +02:00
validate-theme-parity.mjs refactor(theming): migrate who semantic colours to theme tokens 2026-04-22 17:19:53 +02:00
validate-theme-utilities.mjs refactor(theming): migrate who semantic colours to theme tokens 2026-04-22 17:19:53 +02:00
validate-theme-variables.mjs refactor(theming): re-apply theme validator suite after parallel rebase 2026-04-22 17:07:48 +02:00