# Projekt-Kontext: GraphQL Middlelayer + Astro Frontend ## Projekt-Übersicht Ein GraphQL-basierter Middlelayer mit Astro-Frontend für einen Onlineshop. Der Middlelayer fungiert als Abstraktionsschicht zwischen Frontend und verschiedenen Datenquellen (aktuell Mock-Daten, später Headless CMS, etc.). ## Architektur ### Middlelayer (`middlelayer/`) - **GraphQL Server** (Apollo Server v5) auf Port 4000 - **Adapter Pattern** für Datenquellen-Abstraktion - **DataService** als Singleton-Aggregator - **Monitoring & Observability**: - Structured Logging (Winston) - Prometheus Metrics (Port 9090) - Distributed Tracing - **Performance-Optimierungen**: - Dataloader für Batch-Loading (verhindert N+1 Queries) - Response Caching - Query Complexity Limits (mit Workaround für Schema-Realm-Konflikt) ### Frontend (`src/`) - **Astro Framework** mit SSR - **Tailwind CSS** für Styling - **Alpine.js** für Client-Side Interaktivität - **GraphQL Client** für Datenabfragen ## Datenstrukturen ### Produkte - `Product` mit `originalPrice` (Streichpreis) und `promotion` (Objekt mit `category` und `text`) - Promotion-Typen: `"sale"` oder `"topseller"` - Promotion-Text: z.B. `"-30%"` oder `"top"` ### CMS-Daten - `Page` - Seiten mit SEO, Headlines, Bannern (mit Locale-Support) - `PageSeo` - SEO-Metadaten (mit Locale-Support) - `Navigation` - Navigationsstruktur mit Links (mit Locale-Support) ### Content-System - **CMS-Typen** (`middlelayer/types/cms/`) - Struktur wie Daten vom CMS kommen - `*Skeleton` - Wrapper mit `contentTypeId` und `fields` - Verwendet `ComponentLayout` (Alias für `contentLayout`) - Nur für Mapper und Mock-Daten - **Domain-Typen** (`middlelayer/types/c_*.ts`) - Struktur wie Daten in der App verwendet werden - `c_*` - Content-Item-Typen mit `type`-Feld für Discriminated Union - Verwendet `contentLayout` direkt - Für GraphQL Schema, Astro Components, etc. - **Content-Komponenten**: HTML, Markdown, Iframe, ImageGallery, Image, Quote, YoutubeVideo, Headline - **Mapper** (`middlelayer/mappers/pageMapper.ts`) - Konvertiert CMS-Typen zu Domain-Typen ### Internationalization (i18n) - **URL-basierte Locales**: `/de` und `/en` URLs - **Übersetzungen**: Defaults + Middlelayer-Überschreibungen - **React**: `useI18n()` Hook für Komponenten - **Alpine.js**: `window.i18n.t()` für Navigation - **CMS**: Locale-Parameter in allen CMS-Queries - **Contentful-Ansatz**: Vorbereitet für Contentful Locale-System (jedes Feld lokalisiert) ## Wichtige Dateien ### Middlelayer - `middlelayer/index.ts` - Server-Entry-Point - `middlelayer/schema.ts` - GraphQL Schema - `middlelayer/resolvers.ts` - GraphQL Resolvers - `middlelayer/dataService.ts` - DataService (Singleton) - `middlelayer/adapters/interface.ts` - DataAdapter Interface - `middlelayer/adapters/mockdata.ts` - MockdataAdapter - `middlelayer/adapters/Mock/_cms/` - Mock-Daten für CMS - `middlelayer/mappers/pageMapper.ts` - Konvertiert CMS-Typen zu Domain-Typen - `middlelayer/types/cms/` - CMS-spezifische Typen (für Mapper/Mock) - `middlelayer/types/c_*.ts` - Domain-Typen (für App) - `middlelayer/types/contentLayout.ts` - Einheitlicher Layout-Typ - `middlelayer/utils/dataloaders.ts` - Dataloader für Batch-Loading + GraphQLContext - `middlelayer/utils/cache.ts` - In-Memory Cache mit Metrics - `middlelayer/monitoring/` - Logging, Metrics, Tracing - `middlelayer/plugins/` - Apollo Server Plugins ### Frontend - `src/components/Product.astro` - Produkt-Komponente mit Promotion & Streichpreis - `src/components/LoginModal.tsx` - React Login-Modal mit i18n - `src/components/RegisterModal.tsx` - React Register-Modal mit i18n - `src/lib/graphql/client.ts` - GraphQL Client - `src/lib/graphql/queries.ts` - Produkt-Queries - `src/lib/graphql/cmsQueries.ts` - CMS-Queries (mit Locale-Support) - `src/lib/i18n/` - i18n-System (defaults, i18n.ts, useI18n.tsx, alpine.ts) - `src/layouts/Layout.astro` - Layout mit Navigation & SEO - `src/middleware.ts` - URL-basierte Locale-Routing - `src/pages/[locale]/` - Locale-basierte Routen ## Konfiguration ### Environment Variables ```bash PORT=4000 # GraphQL Server Port METRICS_PORT=9090 # Metrics Server Port LOG_LEVEL=info # Log-Level (debug, info, warn, error) MAX_QUERY_COMPLEXITY=1000 # Query Complexity Limit NODE_ENV=development # Environment ``` ### Cache-TTLs (konfigurierbar via Environment oder `middlelayer/config/cache.ts`) - Pages: 60 Sekunden - SEO/Navigation: 5 Minuten - Products: 30 Sekunden ## Bekannte Probleme & Workarounds 1. **Query Complexity Schema-Realm-Konflikt** - Problem: `graphql-query-complexity` hat Schema-Realm-Konflikt mit Apollo Server - Workaround: Plugin überspringt Check bei Realm-Konflikten (siehe `middlelayer/plugins/queryComplexity.ts`) - Status: Funktioniert, aber Complexity-Check wird manchmal übersprungen 2. **GraphQL Version** - Alle Pakete verwenden `graphql@16.12.0` - `overrides` in `package.json` stellt sicher, dass nur eine Version verwendet wird ## NPM Scripts ```bash npm run mock:server # Startet nur GraphQL Server npm start # Startet GraphQL Server + Astro (concurrently) npm run dev # Startet nur Astro ``` ## Endpoints - **GraphQL**: `http://localhost:4000` - **GraphQL Playground**: `http://localhost:4000` - **Metrics**: `http://localhost:9090/metrics` - **Health Check**: `http://localhost:9090/health` - **Astro**: `http://localhost:4321` ## Implementierte Features ✅ GraphQL Server mit Apollo Server v5 ✅ Adapter Pattern für Datenquellen ✅ Mock-Daten für Produkte und CMS ✅ Product-Komponente mit Promotion & Streichpreis ✅ Structured Logging (Winston) ✅ Prometheus Metrics ✅ Distributed Tracing ✅ Dataloader für Batch-Loading ✅ Response Caching ✅ Query Complexity Limits (mit Workaround) ✅ Cache mit Metrics-Tracking ✅ DataService mit Metrics-Tracking ## Nächste Schritte / Offene Punkte - [ ] Query Complexity Schema-Realm-Problem dauerhaft lösen - [ ] Redis Cache Integration (statt In-Memory) - [ ] Database Adapter (für echte Datenbank) - [ ] Headless CMS Adapter (Contentful, Strapi, etc.) - [ ] Rate Limiting - [ ] Authentication/Authorization - [ ] GraphQL Subscriptions (falls benötigt) ## Wichtige Design-Entscheidungen 1. **Adapter Pattern**: Ermöglicht einfaches Wechseln zwischen Datenquellen 2. **Singleton DataService**: Zentrale Stelle für alle Datenoperationen 3. **Monitoring First**: Von Anfang an Monitoring integriert 4. **Type Safety**: TypeScript durchgängig verwendet 5. **Structured Logging**: JSON-Logs für bessere Analyse 6. **Metrics**: Prometheus-kompatible Metriken für Monitoring ## Code-Stil - TypeScript mit ES Modules - Doppelte Anführungszeichen für Strings (Prettier) - Deutsche Kommentare und Fehlermeldungen - Englische Code-Namen und API-Namen