From 39fe22a01849f10e6c7bcc994f2bc081688a8653 Mon Sep 17 00:00:00 2001 From: Till JS Date: Sun, 17 May 2026 20:46:10 +0200 Subject: [PATCH] feat: Wordeck-Web-Branding + Manifest-Cutover MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cards-zu-Wordeck-Umbennung im Web-Layer komplett: - app-manifest.json: id, name, homepage, icon, base_url, deep_link_scheme, link_patterns alle auf wordeck. tools[].name auch (cards.create → wordeck.create — bei mana-mcp wird das beim re-upsert konsumiert). - 5 i18n-Files (de/en/fr/es/it): App-Beschreibung von Cardecky-zu-Wordeck- Wording, USP "text-first" wo es passt. - 11 Routes mit Page-: Cardecky → Wordeck. - CSP connect-src ergänzt um api.wordeck.com (cardecky-api bleibt während Übergang). - AASA exposed jetzt BEIDE Bundle-IDs (ev.mana.cardecky alt + ev.mana.wordeck neu) — die alte Native bleibt während der Ω-3 Bauphase funktional. - UI-Slug-Vorschau (PublishDeckModal, +page, me/published): wordeck.com. DNS für wordeck.com + api.wordeck.com + www.wordeck.com sind als Cloudflare-Tunnel-CNAMEs angelegt; cloudflared-Ingress auf mana-server patched + reloaded. wordeck.com antwortet HTTP 200 mit Cards-Container (Branding-Update hier macht das jetzt zu Wordeck). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --- app-manifest.json | 24 +++++++-------- apps/web/src/hooks.server.ts | 2 +- .../marketplace/PublishDeckModal.svelte | 2 +- apps/web/src/lib/i18n/de.ts | 2 +- apps/web/src/lib/i18n/en.ts | 2 +- apps/web/src/lib/i18n/es.ts | 2 +- apps/web/src/lib/i18n/fr.ts | 2 +- apps/web/src/lib/i18n/it.ts | 2 +- apps/web/src/routes/+page.svelte | 2 +- .../apple-app-site-association/+server.ts | 30 +++++++++++-------- apps/web/src/routes/auth/reset/+page.svelte | 4 +-- apps/web/src/routes/auth/verify/+page.svelte | 4 +-- apps/web/src/routes/d/[slug]/+page.svelte | 2 +- apps/web/src/routes/decks/+page.svelte | 2 +- .../src/routes/decks/[id]/print/+page.svelte | 2 +- apps/web/src/routes/explore/+page.svelte | 4 +-- apps/web/src/routes/help/+page.svelte | 10 +++---- apps/web/src/routes/me/forks/+page.svelte | 2 +- apps/web/src/routes/me/published/+page.svelte | 6 ++-- .../web/src/routes/me/subscribed/+page.svelte | 2 +- apps/web/src/routes/u/[slug]/+page.svelte | 2 +- 21 files changed, 58 insertions(+), 52 deletions(-) diff --git a/app-manifest.json b/app-manifest.json index 3b71fbb..e112037 100644 --- a/app-manifest.json +++ b/app-manifest.json @@ -1,31 +1,31 @@ { "$schema": "https://pkg.mana.how/@mana/shared-share-protocol/0.1/manifest.json", "schema_version": "0.1", - "id": "cards", - "name": "Cardecky", + "id": "wordeck", + "name": "Wordeck", "version": "1.0.0", - "homepage": "https://cardecky.mana.how", - "icon": "https://cardecky.mana.how/icon-512.png", - "description": "Spaced-repetition flashcards with FSRS scheduling.", - "description_de": "Lernkarten mit Spaced-Repetition (FSRS).", + "homepage": "https://wordeck.com", + "icon": "https://wordeck.com/icon-512.png", + "description": "Spaced-repetition flashcards with FSRS scheduling — text-first, no images, no audio.", + "description_de": "Spaced Repetition, text-first. Nur Worte, keine Bilder, kein Audio.", "ownership": { "kind": "verein" }, "tier_required": "beta", "endpoints": { - "base_url": "https://cardecky.mana.how", + "base_url": "https://wordeck.com", "health": "/healthz", "dsgvo_export": "/api/v1/dsgvo/export", "search": "/api/v1/search", "share_receive": "/api/v1/share/receive", "tool_invoke": "/api/v1/tools/:name", - "deep_link_scheme": "cards://", + "deep_link_scheme": "wordeck://", "link_patterns": [ { "pattern": "card/(?<id>[a-z0-9_-]+)", - "template": "https://cardecky.mana.how/c/{id}" + "template": "https://wordeck.com/c/{id}" }, { "pattern": "deck/(?<id>[a-z0-9_-]+)", - "template": "https://cardecky.mana.how/d/{id}" + "template": "https://wordeck.com/d/{id}" } ] }, @@ -37,14 +37,14 @@ ], "tools": [ { - "name": "cards.create", + "name": "wordeck.create", "description": "Erzeugt eine Lernkarte für den authentifizierten User.", "input_schema": { "$ref": "/payload-schemas/create-card-input.json" }, "output_schema": { "$ref": "/payload-schemas/card.json" }, "auth": "user_token" }, { - "name": "cards.search", + "name": "wordeck.search", "description": "Sucht in den Lernkarten des authentifizierten Users.", "input_schema": { "$ref": "/payload-schemas/search-input.json" }, "output_schema": { "$ref": "/payload-schemas/search-output.json" }, diff --git a/apps/web/src/hooks.server.ts b/apps/web/src/hooks.server.ts index 1212293..f7ba85c 100644 --- a/apps/web/src/hooks.server.ts +++ b/apps/web/src/hooks.server.ts @@ -22,7 +22,7 @@ const CSP_POLICY = [ "img-src 'self' data: blob:", "font-src 'self' data:", // XHR/fetch-Ziele: eigene API + Auth-Portal + LLM/Share/MCP-Plattform. - "connect-src 'self' https://cardecky-api.mana.how https://auth.mana.how https://share.mana.how https://mcp.mana.how", + "connect-src 'self' https://api.wordeck.com https://cardecky-api.mana.how https://auth.mana.how https://share.mana.how https://mcp.mana.how", "media-src 'self' blob:", "frame-ancestors 'none'", "base-uri 'self'", diff --git a/apps/web/src/lib/components/marketplace/PublishDeckModal.svelte b/apps/web/src/lib/components/marketplace/PublishDeckModal.svelte index a6fde26..6bb8707 100644 --- a/apps/web/src/lib/components/marketplace/PublishDeckModal.svelte +++ b/apps/web/src/lib/components/marketplace/PublishDeckModal.svelte @@ -193,7 +193,7 @@ <div class="field"> <label class="field-label" for="pub-slug">Marketplace-Slug</label> <div class="slug-row"> - <span class="slug-prefix">cardecky.mana.how/d/</span> + <span class="slug-prefix">wordeck.com/d/</span> <input id="pub-slug" type="text" diff --git a/apps/web/src/lib/i18n/de.ts b/apps/web/src/lib/i18n/de.ts index 65e4b5e..7dcb850 100644 --- a/apps/web/src/lib/i18n/de.ts +++ b/apps/web/src/lib/i18n/de.ts @@ -20,7 +20,7 @@ export const de: TranslationNode = { landing: { welcome: 'Lernkarten mit Spaced-Repetition.', intro: - 'Cardecky ist die föderierte Karteikarten-App des Vereins mana e.V. — FSRS-Scheduler, Cloze-Karten, Anki-Import.', + 'Wordeck ist die föderierte Karteikarten-App des Vereins mana e.V. — FSRS-Scheduler, Cloze-Karten, Anki-Import.', cta_login: 'Login (dev)', dev_user_prompt: 'User-ID (dev):', }, diff --git a/apps/web/src/lib/i18n/en.ts b/apps/web/src/lib/i18n/en.ts index c7bac8d..e904411 100644 --- a/apps/web/src/lib/i18n/en.ts +++ b/apps/web/src/lib/i18n/en.ts @@ -17,7 +17,7 @@ export const en: TranslationNode = { landing: { welcome: 'Spaced-repetition flashcards.', intro: - 'Cardecky is the federated flashcard app of mana e.V. — FSRS scheduler, cloze cards, Anki import.', + 'Wordeck is the federated flashcard app of mana e.V. — FSRS scheduler, cloze cards, Anki import.', cta_login: 'Login (dev)', dev_user_prompt: 'User ID (dev):', }, diff --git a/apps/web/src/lib/i18n/es.ts b/apps/web/src/lib/i18n/es.ts index 254f70b..1ee844b 100644 --- a/apps/web/src/lib/i18n/es.ts +++ b/apps/web/src/lib/i18n/es.ts @@ -17,7 +17,7 @@ export const es: TranslationNode = { landing: { welcome: 'Tarjetas de memoria con repetición espaciada.', intro: - 'Cardecky es la app federada de flashcards de mana e.V. — planificador FSRS, tarjetas cloze, importación Anki.', + 'Wordeck es la app federada de flashcards de mana e.V. — planificador FSRS, tarjetas cloze, importación Anki.', cta_login: 'Iniciar sesión (dev)', dev_user_prompt: 'ID de usuario (dev):', }, diff --git a/apps/web/src/lib/i18n/fr.ts b/apps/web/src/lib/i18n/fr.ts index 9e78b75..1ad61b2 100644 --- a/apps/web/src/lib/i18n/fr.ts +++ b/apps/web/src/lib/i18n/fr.ts @@ -17,7 +17,7 @@ export const fr: TranslationNode = { landing: { welcome: 'Fiches de révision espacée.', intro: - "Cardecky est l'application de fiches fédérée de mana e.V. — planificateur FSRS, cartes à trous, import Anki.", + "Wordeck est l'application de fiches fédérée de mana e.V. — planificateur FSRS, cartes à trous, import Anki.", cta_login: 'Connexion (dev)', dev_user_prompt: 'ID utilisateur (dev) :', }, diff --git a/apps/web/src/lib/i18n/it.ts b/apps/web/src/lib/i18n/it.ts index 60ad626..e9f9dd7 100644 --- a/apps/web/src/lib/i18n/it.ts +++ b/apps/web/src/lib/i18n/it.ts @@ -17,7 +17,7 @@ export const it: TranslationNode = { landing: { welcome: 'Flashcard con ripetizione spaziata.', intro: - "Cardecky è l'app di flashcard federata di mana e.V. — pianificatore FSRS, carte cloze, importazione Anki.", + "Wordeck è l'app di flashcard federata di mana e.V. — pianificatore FSRS, carte cloze, importazione Anki.", cta_login: 'Accesso (dev)', dev_user_prompt: 'ID utente (dev):', }, diff --git a/apps/web/src/routes/+page.svelte b/apps/web/src/routes/+page.svelte index 8e6735a..b3a367a 100644 --- a/apps/web/src/routes/+page.svelte +++ b/apps/web/src/routes/+page.svelte @@ -11,7 +11,7 @@ function callbackUrl(): string { const base = - typeof window !== 'undefined' ? window.location.origin : 'https://cardecky.mana.how'; + typeof window !== 'undefined' ? window.location.origin : 'https://wordeck.com'; const next = page.url.searchParams.get('next'); const nextParam = next ? `?next=${encodeURIComponent(next)}` : ''; return `${base}/auth/callback${nextParam}`; diff --git a/apps/web/src/routes/.well-known/apple-app-site-association/+server.ts b/apps/web/src/routes/.well-known/apple-app-site-association/+server.ts index 98b5039..3aa72c6 100644 --- a/apps/web/src/routes/.well-known/apple-app-site-association/+server.ts +++ b/apps/web/src/routes/.well-known/apple-app-site-association/+server.ts @@ -2,13 +2,13 @@ import { env } from '$env/dynamic/public'; import type { RequestHandler } from './$types'; /** - * Apple App-Site Association für die cards-native iOS-App. + * Apple App-Site Association für die Wordeck-iOS-App. * * Apple holt diese Datei beim ersten App-Launch (und gelegentlich danach) - * von `https://cardecky.mana.how/.well-known/apple-app-site-association` - * und vergleicht sie mit dem `applinks:cardecky.mana.how`-Entitlement - * der App. Bei Match werden Links auf `/d/<slug>` direkt in die App - * geöffnet statt im Browser. + * von `https://wordeck.com/.well-known/apple-app-site-association` (sowie + * von der Legacy-Domain `https://cardecky.mana.how/...`) und vergleicht + * sie mit dem `applinks:`-Entitlement der App. Bei Match werden Links + * auf `/d/<slug>` direkt in die App geöffnet statt im Browser. * * **Pflichtbedingungen:** * 1. Antwort MUSS `Content-Type: application/json` haben (nicht @@ -21,22 +21,28 @@ import type { RequestHandler } from './$types'; * Developer-Accounts gesetzt werden, sonst akzeptiert Apple die AASA * nicht. * - * Cross-Ref: `cards-native/docs/RELEASE_CHECKLIST.md` → "Server-seitige - * Vorbedingungen". + * Beide Bundle-IDs sind aktiv: + * - `ev.mana.cardecky` (cards-native v0.9.4, End-of-Life) + * - `ev.mana.wordeck` (Wordeck-Native ab Ω-3, neue ASC-Eintragung) + * + * Cross-Ref: `mana/docs/playbooks/WORDECK_REBRAND.md`, + * `cards-native/docs/RELEASE_CHECKLIST.md` → "Server-seitige Vorbedingungen". */ export const GET: RequestHandler = async () => { const teamId = env.PUBLIC_APPLE_TEAM_ID ?? 'XXXXXXXXXX'; - const bundleId = 'ev.mana.cardecky'; const payload = { applinks: { apps: [], details: [ { - appID: `${teamId}.${bundleId}`, - // `/d/*` Deck-Slugs, `/u/*` User-Profile, `/auth/*` für - // Reset-/Verify-Mail-Klicks von mana-auth — der Mail-Link - // öffnet damit direkt die App via Universal Link. + // Legacy: cards-native v0.9.4 (End-of-Life nach Wordeck-Cutover) + appID: `${teamId}.ev.mana.cardecky`, + paths: ['/d/*', '/u/*', '/auth/*'], + }, + { + // Aktuell: Wordeck-Native (neuer Bundle ab Ω-3) + appID: `${teamId}.ev.mana.wordeck`, paths: ['/d/*', '/u/*', '/auth/*'], }, ], diff --git a/apps/web/src/routes/auth/reset/+page.svelte b/apps/web/src/routes/auth/reset/+page.svelte index 8d6a625..fc206de 100644 --- a/apps/web/src/routes/auth/reset/+page.svelte +++ b/apps/web/src/routes/auth/reset/+page.svelte @@ -6,7 +6,7 @@ /** * Web-Fallback für die Reset-Password-Mail von mana-auth. * - * Auf iOS-Geräten mit installierter Cardecky-App öffnet Apple den + * Auf iOS-Geräten mit installierter Wordeck-App öffnet Apple den * Universal Link direkt in der App, diese Page wird nie gerendert. * * Für alle anderen User (kein iOS, App nicht installiert, Desktop) @@ -32,7 +32,7 @@ </script> <svelte:head> - <title>Passwort zurücksetzen — Cardecky + Passwort zurücksetzen — Wordeck
diff --git a/apps/web/src/routes/auth/verify/+page.svelte b/apps/web/src/routes/auth/verify/+page.svelte index ee6fc5a..ad77a53 100644 --- a/apps/web/src/routes/auth/verify/+page.svelte +++ b/apps/web/src/routes/auth/verify/+page.svelte @@ -6,7 +6,7 @@ /** * Web-Fallback für die Verify-Email-Mail von mana-auth. * - * Auf iOS-Geräten mit installierter Cardecky-App öffnet Apple den + * Auf iOS-Geräten mit installierter Wordeck-App öffnet Apple den * Universal Link direkt in der App. Für alle anderen User leiten * wir zum Better-Auth-Verify-Endpoint auf auth.mana.how weiter, * der den Token konsumiert und auf das Auth-Portal redirected. @@ -32,7 +32,7 @@ - Email bestätigen — Cardecky + Email bestätigen — Wordeck
diff --git a/apps/web/src/routes/d/[slug]/+page.svelte b/apps/web/src/routes/d/[slug]/+page.svelte index 88d0c89..a645d90 100644 --- a/apps/web/src/routes/d/[slug]/+page.svelte +++ b/apps/web/src/routes/d/[slug]/+page.svelte @@ -157,7 +157,7 @@ - {deck?.title ?? slug} · Cardecky + {deck?.title ?? slug} · Wordeck {#if loading} diff --git a/apps/web/src/routes/decks/+page.svelte b/apps/web/src/routes/decks/+page.svelte index 5bde739..a40d39c 100644 --- a/apps/web/src/routes/decks/+page.svelte +++ b/apps/web/src/routes/decks/+page.svelte @@ -163,7 +163,7 @@ - Meine Decks · Cardecky + Meine Decks · Wordeck
diff --git a/apps/web/src/routes/decks/[id]/print/+page.svelte b/apps/web/src/routes/decks/[id]/print/+page.svelte index 72a89f5..3517d2c 100644 --- a/apps/web/src/routes/decks/[id]/print/+page.svelte +++ b/apps/web/src/routes/decks/[id]/print/+page.svelte @@ -46,7 +46,7 @@ - {deck ? t('print.title', { deck: deck.name }) : t('print.loading')} · Cardecky + {deck ? t('print.title', { deck: deck.name }) : t('print.loading')} · Wordeck
diff --git a/apps/web/src/routes/explore/+page.svelte b/apps/web/src/routes/explore/+page.svelte index b3bfb5d..97d1389 100644 --- a/apps/web/src/routes/explore/+page.svelte +++ b/apps/web/src/routes/explore/+page.svelte @@ -78,12 +78,12 @@ - Explore · Cardecky + Explore · Wordeck
-

Cardecky-Library

+

Wordeck-Library

{#if loadingExplore} diff --git a/apps/web/src/routes/help/+page.svelte b/apps/web/src/routes/help/+page.svelte index 5b68eaf..c1c77c9 100644 --- a/apps/web/src/routes/help/+page.svelte +++ b/apps/web/src/routes/help/+page.svelte @@ -1,13 +1,13 @@ - Hilfe — Cardecky - + Hilfe — Wordeck +

Hilfe & Support

- Cardecky wird vom Verein mana e.V. (i. G.) betrieben. + Wordeck wird vom Verein mana e.V. (i. G.) betrieben. Bei Fragen oder Problemen melde dich direkt bei uns — wir antworten meist innerhalb eines Tages.

@@ -22,7 +22,7 @@

Wie funktioniert das Lern-Schema?

- Cardecky nutzt FSRS + Wordeck nutzt FSRS (Free Spaced Repetition Scheduler), den genauesten offenen Algorithmus für Karteikarten. Karten kommen wieder, wenn deine Erinnerung sie braucht — und nicht nach starren Intervallen. @@ -41,7 +41,7 @@ und beim nächsten Online-Moment synchronisiert.

-

Was ist mit dem Marketplace (Cardecky)?

+

Was ist mit dem Marketplace (Wordeck)?

Der Marketplace unter Entdecken ist die offene Sammlung freigegebener Decks. Subscriben heißt: das Deck wird in deine eigene diff --git a/apps/web/src/routes/me/forks/+page.svelte b/apps/web/src/routes/me/forks/+page.svelte index df1e148..4c85033 100644 --- a/apps/web/src/routes/me/forks/+page.svelte +++ b/apps/web/src/routes/me/forks/+page.svelte @@ -57,7 +57,7 @@ - Meine Forks · Cardecky + Meine Forks · Wordeck

diff --git a/apps/web/src/routes/me/published/+page.svelte b/apps/web/src/routes/me/published/+page.svelte index e6ddae1..6c69bdd 100644 --- a/apps/web/src/routes/me/published/+page.svelte +++ b/apps/web/src/routes/me/published/+page.svelte @@ -96,12 +96,12 @@ const pageSubtitle = $derived( author ? `@${author.slug} · ${decks.length} Deck${decks.length !== 1 ? 's' : ''} veröffentlicht` - : 'Lege dein Author-Profil an um eigene Decks im Cardecky-Marketplace zu veröffentlichen.' + : 'Lege dein Author-Profil an um eigene Decks im Wordeck-Marketplace zu veröffentlichen.' ); - {pageTitle} · Cardecky + {pageTitle} · Wordeck
@@ -135,7 +135,7 @@