chore(mana): citycorners + food + wardrobe aus unified-App entfernen

Citycorners-Reste vom vorherigen Sprint mit committet. food → Nutriphi,
wardrobe → Werdrobe sind als Standalone-Apps live; die mana.how-unified-
App trägt die Modul-Surfaces nicht mehr.

Gelöscht / abgebaut:
- Module: apps/mana/.../modules/{food,wardrobe} + Routen + Locales
- Landing-Apps: apps/{food,citycorners}/ Top-Level
- Backend: apps/api/src/modules/{food,wardrobe} + MCP-Tools log_meal /
  nutrition_summary, picture-routes verifyMediaOwnership-Allowlist
- shared-branding: APP_BRANDING, APP_ICONS, MANA_APPS, Logos, Onboarding
- shared-ai, mana-tool-registry, credits, shared-types/spaces,
  shared-utils/analytics, spiral-db/MANA_APP_INDEX, website-blocks
- Cross-Module: Body-CalorieWeightChart, Comic-CharacterPicker-Wardrobe,
  website-Embed wardrobe.outfits, DaySnapshot.nutrition, FoodEventType,
  MealLogged/Meal*-Streaks/Goals/Companion/Trigger, AI-Agent-Policy,
  GoalEditor MealLogged, MyDay/RitualRunner/Rules nutrition-Refs,
  Crypto-Registry meals/wardrobeGarments/wardrobeOutfits
- Generic: PlaceCategory 'food' (places + geocoding + Locales),
  spaces.ts 'food'/'wardrobe' Modul-IDs
- Infrastruktur: cloudflared, docker-compose CORS, nginx-Landing,
  prometheus-Probe, load-tests, package.json dev-Scripts,
  generate-env, mac-mini/build-landings, dependabot

Dexie v62 Migration:
- droppt meals, goals, foodFavorites, mealTags, wardrobeGarments,
  wardrobeOutfits Tabellen
- entfernt wardrobeOutfitId / wardrobeGarmentId aus images-Index
- Upgrade-Callback strippt die toten FK-Properties aus alten image-Rows

Test/Doku:
- module-registry.test.ts: Snapshot refresht auf aktuellen Stand mit
  56 Modulen (vorher 32, statisch eingefroren pre-refactor). Plus
  LEGACY_TABLES-Exclusion für nicht-mehr-registrierte Tabellen aus
  cards/citycorners/moodlit/rituals/wishes/who.
- streaks.test.ts: MealLogged-Test in TaskCompleted-Test umgebaut
- apps/mana/CLAUDE.md: food-Refs in AI-Tool-Tabelle und
  AiProposalInbox-Liste entfernt
- validate-i18n-keys.mjs + validate-no-recursive-turbo.mjs:
  existsSync-Guard, damit die Skripte mit gestaged-aber-rm'ten Dateien
  klarkommen

mana-web svelte-check 0 errors / 7436 files, betroffene Tests grün
(streaks, dashboard, module-registry), validate:pg-schema,
validate:turbo, validate:i18n-parity grün.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Till JS 2026-05-18 12:47:33 +02:00
parent 932bd98d84
commit ae04c9e194
260 changed files with 234 additions and 21506 deletions

View file

@ -326,33 +326,8 @@ const APP_CONFIGS = [
},
// Food Server (Hono/Bun)
{
path: 'apps/food/apps/server/.env',
vars: {
NODE_ENV: () => 'development',
PORT: (env) => env.FOOD_BACKEND_PORT || '3002',
DATABASE_URL: (env) => env.FOOD_DATABASE_URL,
MANA_AUTH_URL: (env) => env.MANA_AUTH_URL,
GEMINI_API_KEY: (env) => env.FOOD_GEMINI_API_KEY,
S3_ENDPOINT: (env) => env.FOOD_S3_ENDPOINT,
S3_ACCESS_KEY_ID: (env) => env.FOOD_S3_ACCESS_KEY_ID,
S3_SECRET_ACCESS_KEY: (env) => env.FOOD_S3_SECRET_ACCESS_KEY,
S3_BUCKET_NAME: (env) => env.FOOD_S3_BUCKET_NAME,
S3_REGION: (env) => env.FOOD_S3_REGION,
S3_PUBLIC_URL: (env) => env.FOOD_S3_PUBLIC_URL,
},
},
// Food Web (SvelteKit)
{
path: 'apps/food/apps/web/.env',
vars: {
PUBLIC_BACKEND_URL: (env) => `http://localhost:${env.FOOD_BACKEND_PORT || '3002'}`,
PUBLIC_MANA_AUTH_URL: (env) => env.MANA_AUTH_URL,
PUBLIC_MIDDLEWARE_APP_ID: (env) => env.FOOD_APP_ID || 'food',
PUBLIC_GLITCHTIP_DSN: (env) => env.PUBLIC_GLITCHTIP_DSN || '',
},
},
// Quotes Backend: REMOVED — migrated to local-first
@ -590,17 +565,7 @@ const APP_CONFIGS = [
},
},
// CityCorners Backend: REMOVED — migrated to local-first
// CityCorners Web (SvelteKit)
{
path: 'apps/citycorners/apps/web/.env',
vars: {
PUBLIC_BACKEND_URL: (env) => `http://localhost:${env.CITYCORNERS_BACKEND_PORT || '3025'}`,
PUBLIC_MANA_AUTH_URL: (env) => env.MANA_AUTH_URL,
PUBLIC_GLITCHTIP_DSN: (env) => env.PUBLIC_GLITCHTIP_DSN || '',
},
},
// CityCorners: REMOVED — module entfernt 2026-05-18
// TechBase: REMOVED
@ -785,12 +750,6 @@ const APP_CONFIGS = [
},
// Food Landing
{
path: 'apps/food/apps/landing/.env',
vars: {
PUBLIC_UMAMI_WEBSITE_ID: (env) => env.UMAMI_WEBSITE_ID_FOOD_LANDING || '',
},
},
// Presi Landing
{

View file

@ -54,7 +54,6 @@
"apps/mana/apps/web/src/lib/modules/articles/views/HighlightsView.svelte": 4,
"apps/mana/apps/web/src/lib/modules/articles/widgets/ArticlesUnreadWidget.svelte": 1,
"apps/mana/apps/web/src/lib/modules/augur/SharedAugurEntryView.svelte": 1,
"apps/mana/apps/web/src/lib/modules/body/components/CalorieWeightChart.svelte": 1,
"apps/mana/apps/web/src/lib/modules/body/components/ExerciseProgressionChart.svelte": 1,
"apps/mana/apps/web/src/lib/modules/body/components/PhaseManager.svelte": 1,
"apps/mana/apps/web/src/lib/modules/body/components/RoutineManager.svelte": 3,

View file

@ -33,14 +33,6 @@
"apps/mana/apps/web/src/lib/modules/times/components/EntryList.svelte": 2,
"apps/mana/apps/web/src/lib/modules/times/components/TimerCard.svelte": 6,
"apps/mana/apps/web/src/lib/modules/times/components/TimerIndicator.svelte": 2,
"apps/mana/apps/web/src/lib/modules/wardrobe/components/CategoryTabs.svelte": 1,
"apps/mana/apps/web/src/lib/modules/wardrobe/components/GarmentCard.svelte": 1,
"apps/mana/apps/web/src/lib/modules/wardrobe/components/GarmentForm.svelte": 1,
"apps/mana/apps/web/src/lib/modules/wardrobe/components/OutfitCard.svelte": 1,
"apps/mana/apps/web/src/lib/modules/wardrobe/components/OutfitComposer.svelte": 3,
"apps/mana/apps/web/src/lib/modules/wardrobe/views/DetailGarmentView.svelte": 1,
"apps/mana/apps/web/src/lib/modules/wardrobe/views/DetailOutfitView.svelte": 3,
"apps/mana/apps/web/src/lib/modules/wardrobe/views/GridView.svelte": 2,
"apps/mana/apps/web/src/lib/modules/writing/components/BriefingForm.svelte": 2,
"apps/mana/apps/web/src/lib/modules/writing/components/ReferencePicker.svelte": 1,
"apps/mana/apps/web/src/lib/modules/writing/views/DetailView.svelte": 2,

View file

@ -24,8 +24,6 @@ declare -A LANDINGS=(
["presi"]="apps/presi/apps/landing"
["clock"]="apps/clock/apps/landing"
["cards"]="apps/cards/apps/landing"
["food"]="apps/food/apps/landing"
["citycorners"]="apps/citycorners/apps/landing"
)
cd "$PROJECT_ROOT"

View file

@ -72,7 +72,9 @@ function scanUsages() {
const dynamicPrefixes = new Set();
for (const f of files) {
const src = readFileSync(join(REPO_ROOT, f), 'utf8');
const abs = join(REPO_ROOT, f);
if (!existsSync(abs)) continue; // tracked but deleted-on-disk (rm without commit)
const src = readFileSync(abs, 'utf8');
// $_('a.b.c') or _('a.b.c')
for (const m of src.matchAll(/\$?_\(\s*['"]([a-zA-Z][\w.-]*)['"]/g)) {
@ -177,7 +179,9 @@ function main() {
}
if (violations.length > 0) {
console.error(`\n✗ i18n missing-key check FAILED — ${violations.length} file(s) over baseline:\n`);
console.error(
`\n✗ i18n missing-key check FAILED — ${violations.length} file(s) over baseline:\n`
);
for (const v of violations.slice(0, 20)) {
console.error(` ${v.file}: ${v.current} (was ${v.baseline}, +${v.delta})`);
for (const k of v.keys.slice(0, 3)) console.error(` - ${k}`);

View file

@ -20,7 +20,7 @@
*/
import { execSync } from 'node:child_process';
import { readFileSync } from 'node:fs';
import { readFileSync, existsSync } from 'node:fs';
import { fileURLToPath } from 'node:url';
import { dirname, join } from 'node:path';
@ -50,8 +50,9 @@ function validate() {
for (const rel of paths) {
if (rel === rootRel) continue; // root is ALLOWED to orchestrate turbo
scanned++;
const abs = join(REPO_ROOT, rel);
if (!existsSync(abs)) continue; // tracked but deleted-on-disk (rm without commit)
scanned++;
let pkg;
try {
pkg = JSON.parse(readFileSync(abs, 'utf8'));