mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-22 22:26:42 +02:00
refactor: restructure
monorepo with apps/ and services/ directories
This commit is contained in:
parent
25824ed0ac
commit
ff80aeec1f
4062 changed files with 2592 additions and 1278 deletions
447
apps/uload/docs/blog/BLOG-INTEGRATION-PROPOSALS.md
Normal file
447
apps/uload/docs/blog/BLOG-INTEGRATION-PROPOSALS.md
Normal file
|
|
@ -0,0 +1,447 @@
|
|||
# Blog-System Integration für uload - Vorschläge & Konzepte
|
||||
|
||||
## Übersicht
|
||||
|
||||
Nach Analyse des bestehenden uload-Projekts (SvelteKit + PocketBase) präsentiere ich hier verschiedene Ansätze zur Integration eines Blog-Systems. Das Projekt hat aktuell kein Blog-System, würde aber stark von Content Marketing profitieren.
|
||||
|
||||
## Option 1: Vollständige PocketBase-Integration (Empfohlen) ⭐
|
||||
|
||||
### Konzept
|
||||
Blog-System komplett in PocketBase integriert mit eigenem Admin-Interface.
|
||||
|
||||
### Architektur
|
||||
|
||||
```
|
||||
PocketBase Collections:
|
||||
├── blog_posts
|
||||
│ ├── id
|
||||
│ ├── slug (unique)
|
||||
│ ├── title
|
||||
│ ├── excerpt
|
||||
│ ├── content (rich text/markdown)
|
||||
│ ├── featured_image
|
||||
│ ├── author (relation zu users)
|
||||
│ ├── category (relation)
|
||||
│ ├── tags (relation, many-to-many)
|
||||
│ ├── status (draft/published/archived)
|
||||
│ ├── published_at
|
||||
│ ├── meta_title
|
||||
│ ├── meta_description
|
||||
│ ├── og_image
|
||||
│ ├── views_count
|
||||
│ └── reading_time
|
||||
│
|
||||
├── blog_categories
|
||||
│ ├── id
|
||||
│ ├── name
|
||||
│ ├── slug
|
||||
│ ├── description
|
||||
│ └── color
|
||||
│
|
||||
├── blog_tags
|
||||
│ ├── id
|
||||
│ ├── name
|
||||
│ ├── slug
|
||||
│ └── usage_count
|
||||
│
|
||||
└── blog_comments (optional)
|
||||
├── id
|
||||
├── post_id (relation)
|
||||
├── user_id (relation)
|
||||
├── content
|
||||
├── is_approved
|
||||
└── parent_id (für Antworten)
|
||||
```
|
||||
|
||||
### Routes-Struktur
|
||||
|
||||
```
|
||||
src/routes/
|
||||
├── blog/
|
||||
│ ├── +page.svelte # Blog-Übersicht
|
||||
│ ├── +page.server.ts # Blog-Liste laden
|
||||
│ ├── [slug]/
|
||||
│ │ ├── +page.svelte # Einzelner Artikel
|
||||
│ │ └── +page.server.ts # Artikel + Kommentare laden
|
||||
│ ├── category/[category]/
|
||||
│ │ ├── +page.svelte # Kategorie-Ansicht
|
||||
│ │ └── +page.server.ts
|
||||
│ └── tag/[tag]/
|
||||
│ ├── +page.svelte # Tag-Ansicht
|
||||
│ └── +page.server.ts
|
||||
│
|
||||
└── (app)/admin/blog/ # Admin-Bereich
|
||||
├── +page.svelte # Artikel-Liste
|
||||
├── +page.server.ts
|
||||
├── new/
|
||||
│ ├── +page.svelte # Neuer Artikel
|
||||
│ └── +page.server.ts
|
||||
└── [id]/edit/
|
||||
├── +page.svelte # Artikel bearbeiten
|
||||
└── +page.server.ts
|
||||
```
|
||||
|
||||
### Vorteile
|
||||
- ✅ Nahtlose Integration in bestehendes System
|
||||
- ✅ Nutzt vorhandene Auth & User-System
|
||||
- ✅ Einheitliche Datenbank
|
||||
- ✅ Einfaches Backup & Migration
|
||||
- ✅ DSGVO-konform mit einem System
|
||||
- ✅ Kein zusätzlicher Service
|
||||
|
||||
### Nachteile
|
||||
- ❌ Entwicklungsaufwand für Editor
|
||||
- ❌ Keine vorgefertigten Blog-Features
|
||||
|
||||
### Implementierungszeit
|
||||
- Basis-Version: 2-3 Tage
|
||||
- Vollversion mit Editor: 5-7 Tage
|
||||
|
||||
---
|
||||
|
||||
## Option 2: Markdown-basiertes System (Static/MDX)
|
||||
|
||||
### Konzept
|
||||
Blog-Artikel als Markdown-Dateien im Repository, Build-Zeit-Rendering.
|
||||
|
||||
### Struktur
|
||||
|
||||
```
|
||||
src/content/blog/
|
||||
├── 2024-01-15-psychologie-kurzer-urls.md
|
||||
├── 2024-01-20-link-tracking-guide.md
|
||||
└── _drafts/
|
||||
└── upcoming-post.md
|
||||
|
||||
# Frontmatter Example:
|
||||
---
|
||||
title: "Die Psychologie kurzer URLs"
|
||||
excerpt: "Warum 42% weniger Klicks..."
|
||||
author: "Till Schneider"
|
||||
date: "2024-01-15"
|
||||
category: "Psychology"
|
||||
tags: ["urls", "psychology", "conversion"]
|
||||
image: "/blog/images/psychology-urls.jpg"
|
||||
---
|
||||
```
|
||||
|
||||
### Vorteile
|
||||
- ✅ Versionskontrolle via Git
|
||||
- ✅ Kein CMS/Datenbank nötig
|
||||
- ✅ Sehr schnelle Ladezeiten
|
||||
- ✅ Einfache Markdown-Bearbeitung
|
||||
- ✅ Perfekt für technische Autoren
|
||||
|
||||
### Nachteile
|
||||
- ❌ Keine dynamischen Features (Kommentare, Likes)
|
||||
- ❌ Deployment nötig für neue Posts
|
||||
- ❌ Keine nicht-technischen Autoren
|
||||
|
||||
### Tools
|
||||
- mdsvex für Markdown-Processing
|
||||
- rehype/remark für Erweiterungen
|
||||
- Shiki für Syntax-Highlighting
|
||||
|
||||
### Implementierungszeit
|
||||
- 1-2 Tage
|
||||
|
||||
---
|
||||
|
||||
## Option 3: Headless CMS Integration
|
||||
|
||||
### Konzept
|
||||
Externes CMS für Content-Management, SvelteKit als Frontend.
|
||||
|
||||
### Empfohlene Services
|
||||
|
||||
#### 3a. Strapi (Self-hosted)
|
||||
```javascript
|
||||
// Integration via REST API
|
||||
const posts = await fetch('https://cms.ulo.ad/api/posts?populate=*');
|
||||
```
|
||||
|
||||
- ✅ Open Source
|
||||
- ✅ Volle Kontrolle
|
||||
- ✅ Rich Editor
|
||||
- ❌ Hosting-Aufwand
|
||||
|
||||
#### 3b. Directus (Self-hosted)
|
||||
- ✅ Bessere UI als Strapi
|
||||
- ✅ GraphQL Support
|
||||
- ✅ Sehr flexibel
|
||||
|
||||
#### 3c. Contentful (SaaS)
|
||||
- ✅ Professionelles CMS
|
||||
- ✅ Kein Hosting
|
||||
- ❌ Kosten bei Skalierung
|
||||
- ❌ Vendor Lock-in
|
||||
|
||||
### Implementierungszeit
|
||||
- 3-4 Tage (mit Setup)
|
||||
|
||||
---
|
||||
|
||||
## Option 4: Hybrid-Lösung (MDX + PocketBase)
|
||||
|
||||
### Konzept
|
||||
Artikel als MDX-Dateien, Metadaten und Interaktionen in PocketBase.
|
||||
|
||||
### Workflow
|
||||
1. Artikel schreiben in MDX
|
||||
2. Build-Process liest MDX
|
||||
3. Metadaten → PocketBase
|
||||
4. Kommentare/Likes → PocketBase
|
||||
5. Analytics → PocketBase
|
||||
|
||||
### Vorteile
|
||||
- ✅ Beste aus beiden Welten
|
||||
- ✅ Git-Versionierung für Content
|
||||
- ✅ Dynamische Features möglich
|
||||
- ✅ Optimale Performance
|
||||
|
||||
### Implementierungszeit
|
||||
- 3-4 Tage
|
||||
|
||||
---
|
||||
|
||||
## Option 5: Notion als CMS
|
||||
|
||||
### Konzept
|
||||
Notion-API als Content-Source, Cache in PocketBase.
|
||||
|
||||
```typescript
|
||||
// Notion API Integration
|
||||
import { Client } from '@notionhq/client';
|
||||
|
||||
const notion = new Client({ auth: process.env.NOTION_KEY });
|
||||
const posts = await notion.databases.query({
|
||||
database_id: BLOG_DATABASE_ID
|
||||
});
|
||||
```
|
||||
|
||||
### Vorteile
|
||||
- ✅ Fantastischer Editor
|
||||
- ✅ Team-Kollaboration
|
||||
- ✅ Keine Entwicklung nötig
|
||||
|
||||
### Nachteile
|
||||
- ❌ API-Limits
|
||||
- ❌ Abhängigkeit von Notion
|
||||
- ❌ Performance (ohne Caching)
|
||||
|
||||
### Implementierungszeit
|
||||
- 2 Tage
|
||||
|
||||
---
|
||||
|
||||
## Empfehlung & Begründung
|
||||
|
||||
### 🏆 Primär: Option 1 (PocketBase-Integration)
|
||||
|
||||
**Warum:**
|
||||
1. **Konsistenz**: Ein System für alles
|
||||
2. **Kontrolle**: Volle Datenhoheit
|
||||
3. **Performance**: Keine externen API-Calls
|
||||
4. **Features**: Alle dynamischen Features möglich
|
||||
5. **Skalierbar**: Wächst mit dem Projekt
|
||||
|
||||
### 🥈 Alternative: Option 4 (Hybrid MDX + PocketBase)
|
||||
|
||||
**Wann sinnvoll:**
|
||||
- Wenn Git-basierter Workflow gewünscht
|
||||
- Wenn mehrere technische Autoren
|
||||
- Wenn Version Control wichtig
|
||||
|
||||
---
|
||||
|
||||
## Implementierungsplan für Option 1
|
||||
|
||||
### Phase 1: Datenbank-Setup (Tag 1)
|
||||
```bash
|
||||
# Collections erstellen
|
||||
- blog_posts
|
||||
- blog_categories
|
||||
- blog_tags
|
||||
- blog_post_tags (junction table)
|
||||
```
|
||||
|
||||
### Phase 2: API & Server-Routes (Tag 1-2)
|
||||
```typescript
|
||||
// +page.server.ts Beispiele
|
||||
- GET /blog - Liste mit Pagination
|
||||
- GET /blog/[slug] - Einzelartikel
|
||||
- POST /blog/[slug]/view - View counter
|
||||
- GET /blog/feed.xml - RSS Feed
|
||||
```
|
||||
|
||||
### Phase 3: Frontend-Komponenten (Tag 2-3)
|
||||
```svelte
|
||||
<!-- Komponenten -->
|
||||
- BlogCard.svelte
|
||||
- BlogPost.svelte
|
||||
- BlogSidebar.svelte
|
||||
- ShareButtons.svelte
|
||||
- ReadingProgress.svelte
|
||||
- TableOfContents.svelte
|
||||
```
|
||||
|
||||
### Phase 4: Admin-Interface (Tag 3-4)
|
||||
```svelte
|
||||
<!-- Admin-Bereich -->
|
||||
- PostEditor.svelte (mit Tiptap/ProseMirror)
|
||||
- MediaUpload.svelte
|
||||
- SEOSettings.svelte
|
||||
- PublishSettings.svelte
|
||||
```
|
||||
|
||||
### Phase 5: Features & Optimierung (Tag 4-5)
|
||||
- SEO-Optimierung
|
||||
- Social Media Cards
|
||||
- RSS/Atom Feed
|
||||
- Sitemap-Integration
|
||||
- Search-Funktion
|
||||
- Related Posts
|
||||
- Newsletter-Integration
|
||||
|
||||
### Phase 6: Analytics & Performance (Tag 5)
|
||||
- View-Tracking
|
||||
- Reading-Time
|
||||
- Scroll-Tracking
|
||||
- Performance-Optimierung
|
||||
- Image-Lazy-Loading
|
||||
|
||||
---
|
||||
|
||||
## Technische Details für Implementation
|
||||
|
||||
### Rich-Text Editor Optionen
|
||||
|
||||
1. **Tiptap** (Empfohlen)
|
||||
```svelte
|
||||
<script>
|
||||
import { Editor } from '@tiptap/core';
|
||||
import StarterKit from '@tiptap/starter-kit';
|
||||
|
||||
const editor = new Editor({
|
||||
extensions: [StarterKit],
|
||||
content: post.content
|
||||
});
|
||||
</script>
|
||||
```
|
||||
|
||||
2. **Lexical** (Facebook)
|
||||
3. **ProseMirror** (Low-Level)
|
||||
4. **SimpleMDE** (Markdown)
|
||||
|
||||
### SEO-Optimierung
|
||||
|
||||
```svelte
|
||||
<!-- +page.svelte -->
|
||||
<svelte:head>
|
||||
<title>{post.meta_title || post.title}</title>
|
||||
<meta name="description" content={post.meta_description} />
|
||||
|
||||
<!-- Open Graph -->
|
||||
<meta property="og:title" content={post.title} />
|
||||
<meta property="og:description" content={post.excerpt} />
|
||||
<meta property="og:image" content={post.og_image} />
|
||||
|
||||
<!-- Schema.org -->
|
||||
<script type="application/ld+json">
|
||||
{JSON.stringify({
|
||||
"@context": "https://schema.org",
|
||||
"@type": "BlogPosting",
|
||||
"headline": post.title,
|
||||
"datePublished": post.published_at,
|
||||
"author": {
|
||||
"@type": "Person",
|
||||
"name": post.author.name
|
||||
}
|
||||
})}
|
||||
</script>
|
||||
</svelte:head>
|
||||
```
|
||||
|
||||
### Performance-Optimierung
|
||||
|
||||
```typescript
|
||||
// Image optimization
|
||||
import { imagetools } from 'vite-imagetools';
|
||||
|
||||
// Lazy loading
|
||||
import { inview } from 'svelte-inview';
|
||||
|
||||
// Content caching
|
||||
const CACHE_DURATION = 60 * 5; // 5 Minuten
|
||||
|
||||
// Reading time calculation
|
||||
function calculateReadingTime(content: string): number {
|
||||
const wordsPerMinute = 200;
|
||||
const words = content.split(/\s+/).length;
|
||||
return Math.ceil(words / wordsPerMinute);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Migrations-Strategie
|
||||
|
||||
Falls später ein Wechsel nötig:
|
||||
|
||||
1. **Export-Funktion** in PocketBase
|
||||
2. **Standard-Format** (JSON/Markdown)
|
||||
3. **Import-Scripts** vorbereiten
|
||||
4. **URL-Redirects** einrichten
|
||||
|
||||
---
|
||||
|
||||
## Kosten-Nutzen-Analyse
|
||||
|
||||
### Option 1 (PocketBase)
|
||||
- **Kosten**: 5-7 Tage Entwicklung
|
||||
- **Nutzen**: Vollständige Integration, keine laufenden Kosten
|
||||
- **ROI**: Hoch
|
||||
|
||||
### Option 2 (Markdown)
|
||||
- **Kosten**: 1-2 Tage Entwicklung
|
||||
- **Nutzen**: Einfach, schnell
|
||||
- **ROI**: Mittel
|
||||
|
||||
### Option 3 (Headless CMS)
|
||||
- **Kosten**: 3-4 Tage + laufende Kosten
|
||||
- **Nutzen**: Professionelles CMS
|
||||
- **ROI**: Mittel
|
||||
|
||||
---
|
||||
|
||||
## Nächste Schritte
|
||||
|
||||
1. **Entscheidung** für einen Ansatz
|
||||
2. **Prototyp** erstellen (1 Tag)
|
||||
3. **Feedback** einholen
|
||||
4. **Vollständige Implementation**
|
||||
5. **Content-Migration** (falls vorhanden)
|
||||
6. **Launch** mit 3-5 Artikeln
|
||||
|
||||
## Beispiel-Implementation starten
|
||||
|
||||
```bash
|
||||
# Für Option 1 (PocketBase):
|
||||
npm run dev:all # Backend + Frontend starten
|
||||
|
||||
# Collections via MCP erstellen
|
||||
# oder via PocketBase Admin UI
|
||||
|
||||
# Routes erstellen
|
||||
mkdir -p src/routes/blog
|
||||
touch src/routes/blog/+page.svelte
|
||||
touch src/routes/blog/+page.server.ts
|
||||
|
||||
# Komponenten
|
||||
mkdir -p src/lib/components/blog
|
||||
touch src/lib/components/blog/BlogCard.svelte
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Empfehlung**: Starten Sie mit Option 1 (PocketBase-Integration) als MVP und erweitern Sie schrittweise. Dies gibt Ihnen maximale Flexibilität bei minimalem initialen Aufwand.
|
||||
Loading…
Add table
Add a link
Reference in a new issue