feat(feedback): rename community → feedback (module + routes + domain)

Modul, Routen und Public-Domain heißen jetzt einheitlich "feedback":

- App-Registry: id 'community' → 'feedback', name 'Community' → 'Feedback',
  Icon Megaphone → HeartHalf (passt zum bereits-globalen heart-half-Icon
  am Module-Header und im PillNav-Usermenü)
- Modul-Config: communityModuleConfig → feedbackModuleConfig
- Routen-Refs: alle href/goto-Aufrufe in Modul-Views, MyWishesView,
  Onboarding-Wish, Profile-MyWishes auf /feedback umgestellt
- /feedback/+layout: Brand "Mana Community" → "Mana Feedback", Megaphone
  → HeartHalf, "In Mana öffnen"-CTA zeigt jetzt auf /?app=feedback
- Public-Mirror Domain: community.mana.how → feedback.mana.how
  (cloudflared-config.yml + docker-compose.macmini.yml CORS_ORIGINS +
  PUBLIC_MANA_ANALYTICS_URL_CLIENT). DNS muss separat angelegt werden.
- Settings-Section: Hilfe-Text nennt jetzt feedback.mana.how

Internal: community_show_real_name + community_karma DB-Spalten bleiben
(Migration nicht im Scope dieses Renames). Settings-Search-Index-Kategorie
'community' bleibt ebenfalls — sie spiegelt das DB-Schema, nicht den
User-Begriff.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Till JS 2026-04-28 16:18:45 +02:00
parent 698e09b88c
commit 112e2cc1b4
20 changed files with 51 additions and 51 deletions

View file

@ -83,7 +83,7 @@ import {
NotePencil,
FilmStrip,
Hourglass,
Megaphone,
HeartHalf,
} from '@mana/shared-icons';
// ── Apps with entity capabilities ───────────────────────────
@ -1324,12 +1324,12 @@ registerApp({
});
registerApp({
id: 'community',
name: 'Community',
id: 'feedback',
name: 'Feedback',
color: '#F59E0B',
icon: Megaphone,
icon: HeartHalf,
views: {
list: { load: () => import('$lib/modules/community/ListView.svelte') },
list: { load: () => import('$lib/modules/feedback/ListView.svelte') },
},
});

View file

@ -157,8 +157,8 @@
<div>
<div class="toggle-label">Klarnamen neben dem Pseudonym zeigen</div>
<div class="toggle-hint">
Wenn aktiv, sehen eingeloggte Mana-User in der Community deinen Namen ({authStore.user
?.name ?? 'kein Name'}) neben deiner Eule. Auf der öffentlichen community.mana.how-Seite
Wenn aktiv, sehen eingeloggte Mana-User im Feedback-Feed deinen Namen ({authStore.user
?.name ?? 'kein Name'}) neben deiner Eule. Auf der öffentlichen feedback.mana.how-Seite
(ohne Login) wird der Klarname <strong>nie</strong> gezeigt.
</div>
</div>

View file

@ -73,7 +73,7 @@
/** Module identifier passed to the inline FeedbackHook. */
moduleId?: string;
/** Suppress the auto-injected FeedbackHook (e.g. on the
* /community-/feedback-pages where it's redundant). */
* /feedback-page where it's redundant). */
hideFeedback?: boolean;
/** When provided, the heart-half button calls this instead of
* opening its own modal. The host renders feedback inline (used

View file

@ -89,7 +89,7 @@
<footer class="item-footer">
<a
class="author-link"
href={`/community/eule/${item.displayHash}`}
href={`/feedback/eule/${item.displayHash}`}
onclick={(e) => e.stopPropagation()}
title={`Profil von ${item.displayName} öffnen · ${tierCfg.label}-Eule (${item.karma ?? 0} Karma)`}
>

View file

@ -1,12 +1,12 @@
/**
* Community module server-only feedback hub. No Dexie tables, so the
* module-config is mostly nominal (registers the appId for module-context
* tagging on inline FeedbackHook submissions).
* Feedback module server-only public-feedback hub. No Dexie tables,
* so the module-config is mostly nominal (registers the appId for
* module-context tagging on inline FeedbackHook submissions).
*/
import type { ModuleConfig } from '$lib/data/module-registry';
export const communityModuleConfig: ModuleConfig = {
appId: 'community',
export const feedbackModuleConfig: ModuleConfig = {
appId: 'feedback',
tables: [],
};

View file

@ -53,7 +53,7 @@
function handleClickItem(id: string) {
openItemId = id;
void goto(`/community/${id}`);
void goto(`/feedback/${id}`);
}
</script>

View file

@ -103,7 +103,7 @@
}
function goToItem(id: string) {
void goto(`/community/${id}`);
void goto(`/feedback/${id}`);
}
</script>
@ -160,9 +160,9 @@
{:else if active === 'mine'}
{#if myItems.length === 0}
<div class="state">
Noch keine eigenen Wünsche. Schreib einen über das Idee-Lämpchen oder die Pille unten rechts
— oder über
<a class="link" href="/community">/community</a>.
Noch keine eigenen Wünsche. Schreib einen über das Herz-Halb-Icon im Modul-Header oder den
Eintrag „Idee teilen" im Usermenü — oder direkt unter
<a class="link" href="/feedback">/feedback</a>.
</div>
{:else}
<div class="grid">
@ -204,7 +204,7 @@
{#if reactedItems.length === 0}
<div class="state">
Du hast noch nichts unterstützt. Reagier mit 👍 / ❤️ / 🚀 auf einen Wunsch im
<a class="link" href="/community">Community-Feed</a>.
<a class="link" href="/feedback">Community-Feed</a>.
</div>
{:else}
<div class="grid">

View file

@ -26,7 +26,7 @@
}));
function handleClick(id: string) {
void goto(`/community/${id}`);
void goto(`/feedback/${id}`);
}
async function handleReact(feedRef: { items: PublicFeedbackItem[] }, id: string, emoji: string) {

View file

@ -3,7 +3,7 @@
Free-text "what do you want from Mana?" capture. Posts to the central
@mana/feedback hub as category='onboarding-wish'.
Public by default — appears in the /community feed under a Tier-
Public by default — appears in the /feedback feed under a Tier-
pseudonym ("Wachsame Eule #4528"). Users can opt out via the visibility
toggle, in which case the wish stays private (admin-only).

View file

@ -1,6 +1,6 @@
<script lang="ts">
import { ModuleShell } from '$lib/components/shell';
import MyWishesView from '$lib/modules/community/views/MyWishesView.svelte';
import MyWishesView from '$lib/modules/feedback/views/MyWishesView.svelte';
import { Megaphone } from '@mana/shared-icons';
</script>
@ -13,7 +13,7 @@
title="Meine Wünsche"
color="#F59E0B"
icon={Megaphone}
backHref="/community"
backHref="/feedback"
moduleId="community"
hideFeedback
>

View file

@ -1,11 +1,11 @@
<!--
Public community route — outside (app)/ on purpose so AuthGate doesn't
Public feedback route — outside (app)/ on purpose so AuthGate doesn't
bounce non-logged-in visitors. Renders a thin shell with brand header
and Login CTA so the surface stands on its own as a marketing-asset.
-->
<script lang="ts">
import { authStore } from '$lib/stores/auth.svelte';
import { Megaphone } from '@mana/shared-icons';
import { HeartHalf } from '@mana/shared-icons';
let { children } = $props();
</script>
@ -13,17 +13,17 @@
<div class="public-shell">
<header class="public-header">
<a class="brand" href="/">
<Megaphone size={20} weight="bold" />
<HeartHalf size={20} weight="bold" />
<span class="brand-text">
<strong>Mana Community</strong>
<strong>Mana Feedback</strong>
<small>Stimmen aus der Mana-Welt</small>
</span>
</a>
<nav class="nav-links">
<a href="/community">Feed</a>
<a href="/community/roadmap">Roadmap</a>
<a href="/feedback">Feed</a>
<a href="/feedback/roadmap">Roadmap</a>
{#if authStore.user}
<a class="cta" href="/?app=community">In Mana öffnen</a>
<a class="cta" href="/?app=feedback">In Mana öffnen</a>
{:else}
<a class="cta" href="/login">Login</a>
{/if}

View file

@ -1,11 +1,11 @@
<!--
/community — Public community feed.
/feedback — Public feedback feed.
SSR pre-renders the items from the anonymous endpoint; once mounted,
the client-side ListView (auth-enriched if logged in) takes over with
filters + reactions.
-->
<script lang="ts">
import ListView from '$lib/modules/community/views/ListView.svelte';
import ListView from '$lib/modules/feedback/views/ListView.svelte';
// data is from +page.server.ts — used as initial paint for SEO/non-JS,
// but the ListView re-fetches on mount (client-side, possibly authenticated).

View file

@ -1,6 +1,6 @@
<script lang="ts">
import { page } from '$app/stores';
import DetailView from '$lib/modules/community/views/DetailView.svelte';
import DetailView from '$lib/modules/feedback/views/DetailView.svelte';
let { data } = $props();
let id = $derived($page.params.id ?? data.item.id);
@ -12,7 +12,7 @@
</svelte:head>
<div class="detail-public">
<a href="/community" class="back-link">← Zurück zum Feed</a>
<a href="/feedback" class="back-link">← Zurück zum Feed</a>
<DetailView {id} />

View file

@ -1,7 +1,7 @@
<!--
/community/admin — Founder/Admin triage hub.
/feedback/admin — Founder/Admin triage hub.
Lives in the public /community route tree, but client-side gates on
Lives in the public /feedback route tree, but client-side gates on
authStore.user.role === 'admin'. Lets the founder filter all feedback
(public + private), update status, write admin responses, and toggle
visibility.
@ -22,7 +22,7 @@
$effect(() => {
if (authStore.initialized && !authStore.loading && !isAdmin) {
goto('/community');
goto('/feedback');
}
});

View file

@ -30,7 +30,7 @@
}
function goToItem(id: string) {
void goto(`/community/${id}`);
void goto(`/feedback/${id}`);
}
</script>
@ -43,7 +43,7 @@
</svelte:head>
<div class="profile">
<a href="/community" class="back-link">← Zurück zum Feed</a>
<a href="/feedback" class="back-link">← Zurück zum Feed</a>
<header class="hero">
<EulenAvatar displayHash={data.displayHash} size={96} title={data.displayName ?? ''} />

View file

@ -1,5 +1,5 @@
<script lang="ts">
import RoadmapView from '$lib/modules/community/views/RoadmapView.svelte';
import RoadmapView from '$lib/modules/feedback/views/RoadmapView.svelte';
</script>
<svelte:head>