- Add missing packages to MANACORE_SHARED_PACKAGES list - Migrate all SvelteKit apps to use createViteConfig/mergeViteConfig - Matrix preserves special WASM config for matrix-js-sdk crypto - Update consolidation docs with completed Vite config task Savings: ~350 LOC (-318 net lines)
13 KiB
Konsolidierungsmöglichkeiten - Monorepo Analyse
Erstellt: 29. Januar 2026 Geschätzte Gesamteinsparung: ~6.500-8.000 LOC
Übersicht nach Priorität
| Priorität | Bereich | Geschätzte Einsparung | Aufwand |
|---|---|---|---|
| HOCH | Skeleton Components | 800-1.000 LOC | Mittel |
| HOCH | Main.ts/CORS Patterns | 1.800 LOC | Mittel |
| MITTEL | UI Component Cleanup | 400 LOC | Niedrig |
| MITTEL | Navigation Stores | 50 LOC | Niedrig |
| NIEDRIG | Drizzle Configs | 200 LOC | Niedrig |
| NIEDRIG | Logger Utilities | 130 LOC | Niedrig |
1. Backend Patterns (NestJS)
1.1 KRITISCH: Metrics Migration ✅ ERLEDIGT (709 LOC entfernt)
Status: 6 Backends zu @manacore/shared-nestjs-metrics migriert (29.01.2026)
Migrierte Backends:
✅apps/chat/apps/backend/src/metrics/✅apps/calendar/apps/backend/src/metrics/✅apps/todo/apps/backend/src/metrics/✅apps/contacts/apps/backend/src/metrics/✅apps/skilltree/apps/backend/src/metrics/✅apps/clock/apps/backend/src/metrics/
Hinweis: planta hatte keine lokale Metrics-Implementation.
// Vorher (50 LOC pro Backend)
@Injectable()
export class MetricsService implements OnModuleInit {
private readonly register: client.Registry;
// ... 45 weitere Zeilen
}
// Nachher (5 LOC)
import { MetricsModule } from '@manacore/shared-nestjs-metrics';
@Module({ imports: [MetricsModule.forRoot({ prefix: 'chat_' })] })
1.2 HOCH: Main.ts/CORS Setup (1.800 LOC)
Problem: 14 Backends haben fast identische main.ts mit CORS, ValidationPipe, GlobalPrefix.
Empfehlung: Erstelle @manacore/shared-nestjs-setup
// packages/shared-nestjs-setup/src/bootstrap.ts
export interface BootstrapOptions {
corsOrigins?: string[];
apiPrefix?: string;
excludeFromPrefix?: string[];
enableMetrics?: boolean;
defaultPort?: number;
}
export async function bootstrapApp(
AppModule: Type<any>,
options: BootstrapOptions = {}
): Promise<INestApplication> {
const app = await NestFactory.create(AppModule);
// CORS (25 LOC -> 1 LOC)
setupCors(app, options.corsOrigins);
// Validation (10 LOC -> 0 LOC)
app.useGlobalPipes(new ValidationPipe({
whitelist: true,
transform: true,
forbidNonWhitelisted: true,
}));
// Prefix (5 LOC -> 0 LOC)
app.setGlobalPrefix(options.apiPrefix || 'api/v1', {
exclude: options.excludeFromPrefix || ['health', 'metrics'],
});
return app;
}
Vorher (85 LOC pro Backend):
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const corsOrigins = process.env.CORS_ORIGINS?.split(',') || [...];
app.enableCors({ origin: corsOrigins, ... });
app.useGlobalPipes(new ValidationPipe({ ... }));
app.setGlobalPrefix('api/v1', { exclude: ['health'] });
// ...
}
Nachher (15 LOC):
import { bootstrapApp } from '@manacore/shared-nestjs-setup';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await bootstrapApp(AppModule, {
defaultPort: 3002,
enableMetrics: true,
});
await app.listen(process.env.PORT || 3002);
}
bootstrap();
1.3 MITTEL: Health Endpoints (170 LOC)
Problem: 13 Backends haben identische Health-Controller.
Empfehlung: Erstelle @manacore/shared-nestjs-health
// Vorher (14 LOC pro Backend)
@Controller('health')
export class HealthController {
@Get()
check() {
return { status: 'ok', timestamp: new Date().toISOString(), service: 'chat' };
}
}
// Nachher (1 LOC)
import { HealthModule } from '@manacore/shared-nestjs-health';
@Module({ imports: [HealthModule.forRoot('chat-backend')] })
2. Frontend Stores (Svelte 5)
2.1 HOCH: App Settings Stores ✅ ERLEDIGT (323 LOC gespart)
Status: createAppSettingsStore<T>() Factory erstellt und 3 Apps migriert (29.01.2026)
Erstellte Factory: packages/shared-stores/src/settings.svelte.ts
- Type-safe Settings Store mit localStorage Persistenz
- Optional:
onSettingsChangeCallback für Cloud-Sync - Reduziert Boilerplate von ~100 LOC pro App auf ~20 LOC
Migrierte Apps:
✅ (259 → 159 LOC = 100 LOC)apps/todo/apps/web/src/lib/stores/settings.svelte.ts✅ (278 → 173 LOC = 105 LOC)apps/contacts/apps/web/src/lib/stores/settings.svelte.ts✅ (433 → 315 LOC = 118 LOC)apps/calendar/apps/web/src/lib/stores/settings.svelte.ts
// Nachher (Beispiel Todo)
import { createAppSettingsStore } from '@manacore/shared-stores';
const baseStore = createAppSettingsStore<TodoAppSettings>('todo-settings', DEFAULT_SETTINGS);
export const todoSettings = {
get settings() { return baseStore.settings; },
initialize: baseStore.initialize,
set: baseStore.set,
// ... convenience getters
};
2.2 MITTEL: Navigation Stores (50 LOC)
Problem: 9 Apps haben fast identische Navigation-Stores.
Pattern (5-6 LOC pro App):
import { writable } from 'svelte/store';
export const isSidebarMode = writable(false);
export const isNavCollapsed = writable(false);
Ausnahme: Clock (36 LOC) mit localStorage Persistenz + Media Query Listeners
Empfehlung: Factory in @manacore/shared-stores
export function createNavigationStore(options?: {
persist?: boolean;
mediaQueryCollapse?: string;
}) {
// ...
}
2.3 NIEDRIG: Theme Stores Migration
Problem: 2 Apps nutzen nicht @manacore/shared-theme:
apps/storage/apps/web/src/lib/stores/theme.svelte.ts(96 LOC - custom)apps/questions/apps/web/src/lib/stores/theme.ts(custom)
Aktion: Migriere zu createThemeStore() aus @manacore/shared-theme
3. UI Components
3.1 HOCH: Skeleton Components (800-1.000 LOC)
Problem: 31 Skeleton-Komponenten über Apps verteilt, obwohl shared-ui Primitives hat.
Betroffene Apps:
apps/contacts/- 11 Skeletons (925 LOC)apps/calendar/- 5 Skeletons (338 LOC)apps/todo/- 5 Skeletons
Shared-UI hat bereits:
SkeletonBox,SkeletonAvatar,SkeletonCard,SkeletonGrid,SkeletonList,SkeletonRow,SkeletonText
Empfehlung:
- Dokumentation für Skeleton-Komposition aus Primitives
- Page-Level Presets erstellen:
ListPageSkeleton,DetailPageSkeleton,GridPageSkeleton
3.2 MITTEL: Sofort löschbare Duplikate (144 LOC)
Picture App hat lokale Kopien von shared-ui Komponenten:
| Datei | LOC | shared-ui Alternative |
|---|---|---|
apps/picture/apps/web/src/lib/components/ui/Button.svelte |
53 | @manacore/shared-ui/Button |
apps/picture/apps/web/src/lib/components/ui/Input.svelte |
70 | @manacore/shared-ui/Input |
apps/picture/apps/web/src/lib/components/ui/Card.svelte |
21 | @manacore/shared-ui/Card |
Aktion: Lösche lokale Dateien, importiere aus shared-ui.
3.3 MITTEL: AppSlider Cleanup (240 LOC)
Problem: 8 Apps haben lokale AppSlider.svelte Kopien, obwohl shared-ui Version existiert.
Betroffene Apps: calendar, chat, contacts, manadeck, manacore, picture, presi, todo
Aktion: Verifiziere Import aus @manacore/shared-ui, lösche lokale Kopien.
3.4 NIEDRIG: LanguageSelector (75 LOC)
Problem: 5+ Apps haben identische LanguageSelector Implementierungen.
Empfehlung: Verschiebe nach @manacore/shared-ui/navigation/LanguageSelector.svelte
4. Konfigurationsdateien
4.1 MITTEL: TypeScript Configs ✅ ERLEDIGT (~280 LOC gespart)
Status: @manacore/shared-tsconfig Package erstellt und 13 Backends migriert (29.01.2026)
Erstelltes Package: packages/shared-tsconfig/
base.json- Gemeinsame Basis-Optionennestjs.json- NestJS Backend Config (erweitert base)sveltekit.json- SvelteKit Web Configexpo.json- Expo Mobile Configastro.json- Astro Landing Config
Migrierte Backends (13 von 14):
- ✅ calendar, chat, clock, contacts, nutriphi, picture, planta, presi, questions, skilltree, storage, todo, zitare
- ⏭️ manadeck (übersprungen - verwendet
nodenextstattcommonjs)
Vorher (25 LOC pro Backend):
{
"compilerOptions": {
"module": "commonjs",
"moduleResolution": "node",
// ... 20+ weitere Zeilen
}
}
Nachher (3 LOC):
{
"extends": "@manacore/shared-tsconfig/nestjs"
}
Einsparung: 13 Backends × ~22 LOC = ~280 LOC
4.2 MITTEL: Vite Configs ✅ ERLEDIGT (~350 LOC gespart)
Status: @manacore/shared-vite-config erweitert und 15 SvelteKit Apps migriert (29.01.2026)
Erweitertes Package: packages/shared-vite-config/
createViteConfig()- Factory mit Port und additionalPackagesmergeViteConfig()- Deep-merge für App-spezifische OverridesMANACORE_SHARED_PACKAGES- 22+ Pakete für SSR/optimizeDeps
Migrierte Apps (15 von 15):
- ✅ calendar, chat, clock, contacts, manadeck, manacore, matrix, nutriphi, picture, planta, presi, questions, skilltree, storage, todo
Vorher (30-60 LOC pro App):
export default defineConfig({
plugins: [tailwindcss(), sveltekit()],
server: { port: 5174, strictPort: true },
ssr: { noExternal: ['@manacore/shared-icons', ...] },
optimizeDeps: { exclude: ['@manacore/shared-icons', ...] },
});
Nachher (12-14 LOC):
import { createViteConfig, mergeViteConfig } from '@manacore/shared-vite-config';
const baseConfig = createViteConfig({
port: 5174,
additionalPackages: ['@app/shared'], // optional
});
export default defineConfig(mergeViteConfig(baseConfig, {
plugins: [tailwindcss(), sveltekit()],
}));
Hinweis: Matrix behält spezielle WASM-Konfiguration für matrix-js-sdk crypto.
Einsparung: 15 Apps × ~23 LOC = ~350 LOC
4.3 NIEDRIG: Drizzle Configs (200 LOC)
Problem: 12 Backends haben 90% identische drizzle.config.ts.
Empfehlung: Factory-Funktion
// Vorher (17 LOC pro Backend)
export default defineConfig({
schema: './src/db/schema/index.ts',
out: './src/db/migrations',
dialect: 'postgresql',
dbCredentials: { url: process.env.DATABASE_URL || '...' },
});
// Nachher (5 LOC)
import { createDrizzleConfig } from '@manacore/shared-drizzle-config';
export default createDrizzleConfig('chat');
5. Utility Functions
5.1 NIEDRIG: Logger Utilities (130 LOC)
Problem: 2 Mobile Apps haben eigene Logger:
apps/manadeck/apps/mobile/utils/logger.ts(34 LOC)apps/picture/apps/mobile/utils/logger.ts(92 LOC - erweitert)
Empfehlung: Erstelle @manacore/shared-logger mit:
logger.debug/info/warn/error/successperfLogger.start/endnetworkLogger.request/response/error
5.2 NIEDRIG: Sleep Function Duplikat
Problem: sleep() existiert in:
packages/shared-utils/src/async.ts(8 LOC)packages/shared-api-client/src/utils.ts(3 LOC)
Aktion: Entferne aus shared-api-client, importiere aus shared-utils.
Aktionsplan
Phase 1: Quick Wins (1-2 Tage, ~1.000 LOC)
| Aufgabe | LOC | Aufwand | Status |
|---|---|---|---|
| ✅ Erledigt | |||
| ✅ Erledigt | |||
| ✅ Erledigt | |||
| Picture UI-Komponenten (Button/Card) | 74 | Niedrig | Offen |
| AppSlider Wrapper evaluieren (8 Apps) | - | Niedrig | Nicht nötig (sind Lokalisierungs-Wrapper) |
Phase 2: Stores & Configs (3-5 Tage, ~1.500 LOC)
| Aufgabe | LOC | Aufwand | Status |
|---|---|---|---|
createAppSettingsStore() Factory erstellen |
✅ Erledigt | ||
@manacore/shared-tsconfig Package erstellen |
✅ Erledigt | ||
@manacore/shared-vite-config erweitern (15 Apps) |
✅ Erledigt | ||
| Navigation Store Factory erstellen | 50 | Niedrig | Offen |
Phase 3: Backend Setup (5-7 Tage, ~2.000 LOC)
| Aufgabe | LOC | Aufwand |
|---|---|---|
@manacore/shared-nestjs-setup erstellen |
1.800 | Mittel |
@manacore/shared-nestjs-health erstellen |
170 | Niedrig |
| Drizzle Config Factory erstellen | 200 | Niedrig |
Phase 4: Skeleton Refactoring (Optional, ~800 LOC)
| Aufgabe | LOC | Aufwand |
|---|---|---|
| Page-Level Skeleton Presets erstellen | 400 | Mittel |
| Bestehende Skeletons refactoren | 400 | Mittel |
Zusammenfassung
| Kategorie | Geschätzte Einsparung |
|---|---|
| Backend (NestJS) | 2.300 LOC |
| Frontend Stores | 700 LOC |
| UI Components | 1.200 LOC |
| Konfigurationen | 900 LOC |
| Utilities | 130 LOC |
| Gesamt | ~5.200-6.500 LOC |
Plus Wartungsvorteile:
- Einheitliche Patterns über alle Apps
- Single Point of Change für Updates
- Bessere Onboarding-Erfahrung für neue Entwickler
- Reduzierte Fehlerquellen durch Duplikate