Veranstaltungen-APP/README.md

386 lines
9.9 KiB
Markdown

<<<<<<< HEAD
# 🎪 Veranstaltungen-App Dresden - Laravel Event Portal
Ein modernes, skalierbares Event-Portal für Dresden mit automatisiertem Import aus externen Veranstaltungsquellen (APIs, Web-Scraping).
## ⚡ Features
**Event-Management**
- Veranstaltungen mit mehreren Terminen/Öffnungszeiten
- Flexible Kategorisierung und Ortsfilter
- Slug-basierte SEO-URLs
- Soft Deletes (weiche Löschung)
**Datenquellen-Integration**
- Multi-Source Import (Stadt Dresden, Kulturzentrum, etc.)
- Queue-basierte asynchrone Verarbeitung
- Upsert-Logik (automatisches Update bei Duplikaten)
- Last-Import-Tracking
**REST API**
- `/api/events` - Events mit Filtern (Datum, Kategorie, Ort)
- `/api/events/{id}` - Einzelnes Event mit allen Terminen
- `/api/events/categories/list` - Verfügbare Kategorien
- `/api/events/locations/list` - Verfügbare Orte
**Scheduler-Integration**
- Tägliche automatische Imports (03:00 Uhr)
- Stündliche Updates für häufig aktualisierte Quellen
- Automatische Wartung (markiere abgelaufene Termine, Archive)
## 🏗️ Technologie-Stack
| Komponente | Technologie |
|-----------|------------|
| **PHP** | 8.2+ |
| **Framework** | Laravel 11 LTS |
| **Datenbank** | MariaDB 10.4+ |
| **Task-Verarbeitung** | Queue (database/redis/beanstalkd) |
| **Scheduling** | Laravel Scheduler + Cron |
| **HTTP-Client** | Laravel HTTP Client / Guzzle |
| **Web-Scraping** | Symfony DomCrawler (optional) |
## 📁 Projektstruktur
```
Veranstaltungen-APP/
├── app/
│ ├── Models/ # Eloquent Models
│ │ ├── Source.php # Quelle (Stadt Dresden, etc.)
│ │ ├── Event.php # Veranstaltung
│ │ └── EventOccurrence.php # Einzelne Termine/Öffnungszeiten
│ ├── Http/Controllers/
│ │ └── EventController.php # REST API Controller
│ ├── Jobs/
│ │ └── ImportEventsJob.php # Queue Job für Event-Import
│ ├── Commands/
│ │ └── ImportEventsCommand.php # Artisan Command
│ └── Services/
│ └── EventImportService.php # Import-Business-Logic
├── database/
│ └── migrations/ # Database Schema
│ ├── create_sources_table.php
│ ├── create_events_table.php
│ └── create_event_occurrences_table.php
├── routes/
│ └── api.php # REST API Routen
└── docs/ # 📚 Dokumentation
├── SETUP.md # Installation & Setup-Anleitung
├── EXAMPLE_QUERIES.php # 10+ Eloquent Query-Beispiele
├── API_RESPONSES.md # API Response-Formate
├── IMPORT_SCRAPER_INTEGRATION.md # Import/Scraper-Dokumentation
└── KERNEL_SCHEDULER_EXAMPLE.php # Scheduler-Konfiguration
```
## 🚀 Quick Start
### 1. Installation
```bash
# Frisches Laravel-Projekt
composer create-project laravel/laravel Veranstaltungen-APP
cd Veranstaltungen-APP
# Dateien aus diesem Paket kopieren
# (siehe SETUP.md für detaillierte Anleitung)
```
### 2. Konfiguration
```bash
# .env einrichten
cp .env.example .env
php artisan key:generate
# MariaDB konfigurieren
# DB_CONNECTION=mysql
# DB_DATABASE=veranstaltungen_app
```
### 3. Datenbank
```bash
# Migrations ausführen
php artisan migrate
# Event-Quellen erstellen
php artisan tinker
>>> \App\Models\Source::create(['name' => 'Stadt Dresden', 'status' => 'active']);
```
### 4. Events importieren
```bash
# Synchron (blockierend)
php artisan events:import --sync
# Oder asynchron (Queue)
php artisan events:import
php artisan queue:work --verbose # Worker starten
```
### 5. API testen
```bash
# Events auflisten
curl "http://localhost:8000/api/events?from=2026-04-15&to=2026-05-31&location=Dresden"
# Einzelnes Event
curl "http://localhost:8000/api/events/1"
```
## 📚 Dokumentation
| Datei | Inhalt |
|-------|--------|
| [`SETUP.md`](docs/SETUP.md) | Komplette Installations- & Setup-Anleitung |
| [`EXAMPLE_QUERIES.php`](docs/EXAMPLE_QUERIES.php) | 10+ Eloquent Query-Beispiele |
| [`API_RESPONSES.md`](docs/API_RESPONSES.md) | API Endpoint-Doku mit Response-Beispielen |
| [`IMPORT_SCRAPER_INTEGRATION.md`](docs/IMPORT_SCRAPER_INTEGRATION.md) | Import/Scraper, Queue, Scheduler, Rate Limiting |
| [`KERNEL_SCHEDULER_EXAMPLE.php`](docs/KERNEL_SCHEDULER_EXAMPLE.php) | Komplette Scheduler-Konfiguration |
## 🔑 API Endpoints
### 📋 Events auflisten
```
GET /api/events
?from=2026-04-15 # Ab Datum (Standard: heute)
&to=2026-05-31 # Bis Datum (Standard: +3 Monate)
&category=Kultur # Nach Kategorie
&location=Dresden # Nach Ort
&limit=20 # Pro Seite
```
**Response:**
```json
{
"success": true,
"data": [
{
"id": 1,
"title": "Ostermarkt",
"location": "Dresden",
"category": "Kultur",
"occurrences": [
{
"id": 5,
"start_datetime": "2026-04-18T10:00:00+02:00",
"end_datetime": "2026-04-20T18:00:00+02:00"
}
]
}
],
"pagination": { "total": 42, "per_page": 20, "current_page": 1 }
}
```
Weitere Endpoints: 👉 [Siehe API_RESPONSES.md](docs/API_RESPONSES.md)
## 🎯 Datenmodell
### Events ↔ EventOccurrences (1:N Beziehung)
Ein **Event** ist eine Veranstaltung mit stabilen Eigenschaften:
- `title`, `description`, `location`, `category`
- `slug` (für SEO-URLs)
- `status` (draft, published, archived)
Ein **EventOccurrence** ist ein einzelner Termin mit Zeitinformation:
- `start_datetime`, `end_datetime`
- `is_all_day` (ganztägig?)
- `location_details` (z.B. "Saal A")
- `capacity`, `available_tickets`
- `price`
- `status` (scheduled, cancelled, completed)
### Beispiel:
```
📌 Event: "Ostermarkt auf der Altstadt"
├─ 🗓️ Occurrence 1: Sa 18.04., 10:00-18:00 (Kapazität: 1000)
├─ 🗓️ Occurrence 2: So 19.04., 10:00-18:00 (Kapazität: 1000)
└─ 🗓️ Occurrence 3: Mo 20.04., 10:00-18:00 (Kapazität: 800)
```
## 📊 Import-Workflow
```
External Source (API/Scraper)
ImportEventsCommand
ImportEventsJob (Queue)
upsertEvent() [updateOrCreate]
upsertOccurrences() [updateOrCreate]
Database (MariaDB)
REST API
```
**Upsert-Logik:**
- Events werden anhand `[source_id, external_id]` abgeglichen
- Existierende Events werden aktualisiert
- Neue Events werden angelegt
- Verhindert Duplikate durch Unique Index
## ⏰ Geplante Imports (Scheduler)
Die Integration mit Laravel Scheduler (tägliche Cron-Regel):
```
03:00 Uhr → Täglich alle Quellen importieren
Stündlich → Stadt-Dresden-Quelle (häufige Updates)
Alle 6h → Andere Quellen
04:00 Uhr → Markiere abgelaufene Termine
Sonntag → Archive alte Events
```
Weitere Details: 👉 [IMPORT_SCRAPER_INTEGRATION.md](docs/IMPORT_SCRAPER_INTEGRATION.md)
## 🛠️ Commands & Artisan
```bash
# Manueller Import
php artisan events:import [--source=ID|Name] [--sync]
# Queue Worker starten
php artisan queue:work --verbose
# Scheduler testen (nur für Entwicklung)
php artisan schedule:run
# Queue debuggen
php artisan queue:failed
php artisan queue:retry {id}
php artisan queue:flush
```
## 🔐 Best Practices (implementiert)
**Datenbank-Design:**
- Foreign Keys mit CASCADE DELETE
- Composite Indizes für häufige Filter-Kombinationen
- Unique Index auf `[source_id, external_id]` gegen Duplikate
- MariaDB-spezifische Optimierungen (InnoDB Engine, utf8mb4)
**Code-Qualität:**
- Eloquent Models mit Relationships & Scopes
- Type Hints (PHP 8.2+)
- Request Validation
- Error Logging
- Transaction Support
**Performance:**
- Query Optimization mit eager loading (`.with()`)
- Effiziente Composite Indizes
- Pagination für API-Response
- Queue-basierte Background Jobs
**Wartbarkeit:**
- Service-Layer für Business Logic
- Commands für CLI-Interface
- Job-Klassen für Queue-Verarbeitung
- Dokumentierte Code-Beispiele
## 🚀 Production Deployment
1. **Queue Worker setup** (Supervisor)
2. **Scheduler Cron-Job** (täglicher Scheduler:run)
3. **Redis/Beanstalkd** für Queue (statt database)
4. **Error Monitoring** (Sentry, etc.)
5. **Backup** vor Production-Launch
Siehe: 👉 [SETUP.md - Production Deployment](docs/SETUP.md)
## 📚 Beispiele
### Query: "Nächste 10 Events in Dresden"
```php
$events = Event::published()
->byLocation('Dresden')
->with(['occurrences' => function ($q) {
$q->upcoming()->limit(1);
}])
->limit(10)
->get();
```
### Query: "Alle Events am 15. April"
```php
$date = Carbon::parse('2026-04-15');
$events = Event::published()
->with(['occurrences' => function ($q) use ($date) {
$q->onDate($date)->scheduled();
}])
->whereHas('occurrences', function ($q) use ($date) {
$q->onDate($date)->scheduled();
})
->get();
```
Weitere: 👉 [EXAMPLE_QUERIES.php](docs/EXAMPLE_QUERIES.php)
## 🤝 Integration Beispiele
### Stadt-Dresden-API
```php
$response = Http::get('https://api.stadt-dresden.de/events', [
'limit' => 1000,
]);
```
### Web-Scraping
```bash
composer require symfony/dom-crawler
```
### Google-Calendar (iCal)
```php
$feed = file_get_contents('https://calendar.google.com/.../basic.ics');
// Parse mit Spatie iCalendar Parser
```
## 🐛 FAQ & Troubleshooting
**F: Migrations schlagen fehl**
```bash
A: MariaDB Version checken, dann:
php artisan migrate:refresh
php artisan migrate
```
**F: Queue-Jobs werden nicht verarbeitet**
```bash
A: Worker-Prozess nicht laufend?
php artisan queue:work --verbose
```
**F: API gibt 404 zurück**
```bash
A: php artisan serve
dann http://localhost:8000/api/events testen
```
## 📄 Lizenz
Laravel ist unter der MIT-Lizenz lizenziert.
## 👨‍💻 Autor
Vollständig arbeitsfertiges Event-Portal für Dresden
**Erstellt:** 9. April 2026
---
### 📖 Dokumentation starten mit:
👉 [**SETUP.md** - Installations-Anleitung](docs/SETUP.md)
=======
# Veranstaltungen-APP
>>>>>>> 220c3e47427d7ebd5927cd513bf43274163b5d0a