project setup with core files including configuration, package management, and basic structure. Added .gitignore, README, and various TypeScript types for CMS components. Implemented initial components and layouts for the application.

This commit is contained in:
Peter Meier
2025-12-13 23:26:13 +01:00
parent ea288a5bbc
commit b1a556dc6d
167 changed files with 19057 additions and 131 deletions

443
README.md
View File

@@ -1,2 +1,443 @@
# sell
# GraphQL Middlelayer + Astro Frontend
Ein moderner, skalierbarer Onlineshop mit GraphQL-basiertem Middlelayer und Astro-Frontend. Der Middlelayer fungiert als flexible Abstraktionsschicht zwischen Frontend und verschiedenen Datenquellen.
## 🚀 Features
- **GraphQL API** mit Apollo Server v5
- **Astro Frontend** mit SSR und Client-Side Interaktivität
- **Adapter Pattern** für flexible Datenquellen (Mock, Headless CMS, Database)
- **Performance-Optimierungen**:
- Dataloader für Batch-Loading (verhindert N+1 Queries)
- Redis/In-Memory Caching
- Response Caching
- Query Complexity Limits
- **Monitoring & Observability**:
- Structured Logging (Winston)
- Prometheus Metrics
- Distributed Tracing
- **Type-Safe** mit TypeScript durchgängig
- **Modern UI** mit Tailwind CSS und Alpine.js
- **Internationalization (i18n)**:
- URL-basierte Locales (`/de`, `/en`)
- Übersetzungen aus Middlelayer (mit Default-Fallback)
- CMS-Inhalte mehrsprachig (vorbereitet für Contentful)
## 📋 Voraussetzungen
- Node.js 18+
- npm oder yarn
- (Optional) Redis für verteiltes Caching
## 🛠️ Installation
```bash
# Dependencies installieren
npm install
# (Optional) Redis installieren (macOS)
brew install redis
brew services start redis
```
## 🏃 Quick Start
```bash
# GraphQL Server + Astro Frontend starten
npm start
# Oder einzeln:
npm run mock:server # Nur GraphQL Server (Port 4000)
npm run dev # Nur Astro Frontend (Port 4321)
```
## 📁 Projektstruktur
```
/
├── middlelayer/ # GraphQL Middlelayer
│ ├── adapters/ # Datenquellen-Adapter (Mock, CMS, etc.)
│ ├── config/ # Konfiguration
│ ├── monitoring/ # Logging, Metrics, Tracing
│ ├── plugins/ # Apollo Server Plugins
│ ├── types/ # TypeScript Typen
│ ├── utils/ # Utilities (Cache, Dataloader, etc.)
│ ├── index.ts # Server Entry Point
│ ├── schema.ts # GraphQL Schema
│ └── resolvers.ts # GraphQL Resolvers
├── src/ # Astro Frontend
│ ├── components/ # Astro Komponenten
│ ├── layouts/ # Layout Templates
│ ├── lib/ # Utilities & GraphQL Client
│ ├── pages/ # Astro Pages
│ └── styles/ # Global Styles
└── docs/ # Dokumentation
```
## ⚙️ Konfiguration
### Environment Variables
Erstelle eine `.env` Datei im Root-Verzeichnis:
```env
# Server Ports
PORT=4000 # GraphQL Server Port
METRICS_PORT=9090 # Metrics Server Port
# Logging
LOG_LEVEL=info # debug, info, warn, error
NODE_ENV=development # development, production
# GraphQL
MAX_QUERY_COMPLEXITY=1000 # Query Complexity Limit
# Redis (Optional)
REDIS_ENABLED=true # Redis Cache aktivieren
REDIS_HOST=localhost # Redis Host
REDIS_PORT=6379 # Redis Port
REDIS_PASSWORD= # Optional: Redis Password
# Cache TTLs (in Millisekunden)
CACHE_PAGES_TTL=60000 # 60 Sekunden
CACHE_PAGE_SEO_TTL=300000 # 5 Minuten
CACHE_NAVIGATION_TTL=300000 # 5 Minuten
CACHE_PRODUCTS_TTL=30000 # 30 Sekunden
```
### Cache-Konfiguration
Cache-TTLs können über Environment Variables oder direkt in `middlelayer/config/cache.ts` konfiguriert werden.
## 🌐 Endpoints
| Service | URL | Beschreibung |
|---------|-----|--------------|
| GraphQL API | `http://localhost:4000` | GraphQL Endpoint & Playground |
| Metrics | `http://localhost:9090/metrics` | Prometheus Metrics |
| Health Check | `http://localhost:9090/health` | Service Health Status |
| Astro Frontend | `http://localhost:4321` | Frontend Application |
## 📊 GraphQL Schema
### Queries
```graphql
# Produkte
query {
products(limit: 4) {
id
name
price
originalPrice
promotion {
category
text
}
}
product(id: "prod-123") {
id
name
description
price
}
}
# CMS (mit Locale-Support)
query {
pageSeo(locale: "de") {
title
description
}
page(slug: "/about", locale: "de") {
headline
subheadline
}
pages(locale: "en") {
slug
name
}
navigation(locale: "de") {
links {
name
slug
}
}
}
# Übersetzungen
query {
translations(locale: "de", namespace: "auth") {
locale
translations {
key
value
}
}
}
}
page(slug: "/") {
slug
name
headline
}
navigation {
name
links {
name
url
}
}
}
```
## 🏗️ Architektur
### Middlelayer
Der Middlelayer verwendet das **Adapter Pattern** für flexible Datenquellen:
```
Frontend (Astro)
GraphQL API (Apollo Server)
DataService (Singleton)
DataAdapter (Interface)
┌─────────────┬──────────────┬─────────────┐
│ Mock Adapter│ CMS Adapter │ DB Adapter │
└─────────────┴──────────────┴─────────────┘
```
**Vorteile:**
- Einfaches Wechseln zwischen Datenquellen
- Testbarkeit durch Mock-Adapter
- Zentrale Logik im DataService
- Caching auf Service-Ebene
### Frontend
- **Astro** für Server-Side Rendering
- **Alpine.js** für Client-Side Interaktivität
- **Tailwind CSS** für Styling
- **GraphQL Client** für Datenabfragen
## 🔧 Entwicklung
### NPM Scripts
```bash
npm run mock:server # Startet GraphQL Server
npm run dev # Startet Astro Dev Server
npm start # Startet beide (concurrently)
npm run build # Production Build
npm run preview # Preview Production Build
```
### Neuen Adapter hinzufügen
1. Implementiere `DataAdapter` Interface:
```typescript
// middlelayer/adapters/myAdapter.ts
import type { DataAdapter } from './interface.js';
export class MyAdapter implements DataAdapter {
async getProducts(limit?: number): Promise<Product[]> {
// Implementierung
}
// ... weitere Methoden
}
```
2. In `middlelayer/adapters/config.ts` registrieren:
```typescript
export function createAdapter(): DataAdapter {
const adapterType = process.env.ADAPTER_TYPE || 'mock';
if (adapterType === 'myAdapter') {
return new MyAdapter();
}
// ...
}
```
## 📈 Monitoring
### Prometheus Metrics
Metriken sind verfügbar unter `http://localhost:9090/metrics`:
- `graphql_queries_total` - Anzahl der Queries
- `graphql_query_duration_seconds` - Query-Dauer
- `cache_hits_total` / `cache_misses_total` - Cache-Statistiken
- `dataservice_calls_total` - DataService-Aufrufe
- `errors_total` - Fehler-Anzahl
### Logging
Structured Logging mit Winston:
- Console Output (Development)
- JSON Logs (Production)
- Log-Level konfigurierbar
### Tracing
Automatische Trace-ID-Generierung für Request-Tracking.
## 🚀 Deployment
### Production Build
```bash
npm run build
```
### Docker (Beispiel)
```dockerfile
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY . .
RUN npm run build
CMD ["npm", "start"]
```
## 🧪 Testing
```bash
# GraphQL Query testen
curl -X POST http://localhost:4000 \
-H "Content-Type: application/json" \
-d '{"query":"{ products(limit: 4) { id name price } }"}'
# Health Check
curl http://localhost:9090/health
# Metrics
curl http://localhost:9090/metrics
```
## 📚 Weitere Dokumentation
- [Architektur & Skalierung](./docs/ARCHITECTURE_SCALING.md) - Detaillierte Architektur-Analyse
- [Redis Setup](./middlelayer/utils/REDIS_SETUP.md) - Redis Cache Konfiguration
- [Monitoring](./middlelayer/monitoring/README.md) - Monitoring & Observability
## 🐛 Bekannte Probleme
### Query Complexity Schema-Realm-Konflikt
**Problem:** `graphql-query-complexity` hat einen Schema-Realm-Konflikt mit Apollo Server.
**Workaround:** Das Plugin überspringt den Check bei Realm-Konflikten automatisch. Funktioniert, aber Complexity-Check wird manchmal übersprungen.
**Status:** Funktioniert, permanente Lösung in Arbeit.
## 🌍 Internationalization (i18n)
### URL-basierte Locales
Das System unterstützt URL-basierte Locales:
- `/de` - Deutsche Version
- `/en` - Englische Version
- `/` - Auto-Redirect zu Browser-Locale oder Cookie
### Übersetzungen
**Architektur:**
- **Defaults**: Fallback-Übersetzungen in `src/lib/i18n/defaults.ts`
- **Middlelayer**: Übersetzungen können vom GraphQL-Server geladen werden
- **Überschreibungen**: Middlelayer-Übersetzungen überschreiben Defaults
**Verwendung in React:**
```tsx
import { useI18n } from "../lib/i18n/useI18n.js";
function MyComponent() {
const { t } = useI18n("auth");
return <h1>{t("login.title")}</h1>;
}
```
**Verwendung in Alpine.js:**
```html
<div x-data="{ t: window.i18n?.t || ((key) => key) }">
<button x-text="t('nav.login')"></button>
</div>
```
### CMS-Locale-Support
**Contentful-Ansatz:**
Contentful verwendet ein Locale-System, bei dem:
- Jedes Content-Feld lokalisiert werden kann
- Standard-Locale wird definiert (z.B. `en-US`)
- Fallback-Locales können konfiguriert werden
- API-Aufrufe enthalten `locale`-Parameter: `fields.headline['en-US']`
**Unser System:**
- GraphQL-Schema unterstützt `locale`-Parameter für alle CMS-Queries
- Adapter-Interface ist vorbereitet für Locale-Parameter
- Mock-Adapter gibt aktuell alle Locales gleich zurück (TODO: Locale-spezifische Mock-Daten)
- Bei Contentful-Integration: Adapter würde `locale`-Parameter an Contentful API weitergeben
**Beispiel GraphQL Query:**
```graphql
query {
page(slug: "/about", locale: "de") {
headline # Deutsche Übersetzung
subheadline
}
page(slug: "/about", locale: "en") {
headline # Englische Übersetzung
subheadline
}
}
```
## 🔮 Roadmap
- [ ] Query Complexity Schema-Realm-Problem dauerhaft lösen
- [ ] Database Adapter (PostgreSQL, MySQL)
- [ ] Headless CMS Adapter (Contentful, Strapi)
- [ ] Locale-spezifische Inhalte implementieren
- [ ] Fallback-Locales konfigurieren
- [ ] Rate Limiting
- [ ] Authentication/Authorization ✅ (implementiert)
- [ ] GraphQL Subscriptions
- [ ] i18n: Weitere Sprachen hinzufügen
- [ ] i18n: Locale-spezifische Mock-Daten für CMS
- [ ] E2E Tests
## 🤝 Beitragen
1. Fork das Repository
2. Erstelle einen Feature Branch (`git checkout -b feature/AmazingFeature`)
3. Committe deine Änderungen (`git commit -m 'Add some AmazingFeature'`)
4. Push zum Branch (`git push origin feature/AmazingFeature`)
5. Öffne einen Pull Request
## 📝 Lizenz
Dieses Projekt ist privat.
## 👥 Autoren
- Entwickelt mit ❤️ für moderne E-Commerce-Lösungen
---
**Hinweis:** Dieses Projekt ist in aktiver Entwicklung. Für Fragen oder Probleme öffne bitte ein Issue.