<<<<<<< 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