From ff440ac48cdca78f66d87d6eddf576155cee6815 Mon Sep 17 00:00:00 2001 From: josiadmin Date: Wed, 18 Feb 2026 12:15:38 +0100 Subject: [PATCH] mod divers data --- .dockerignore | 56 ---- DEPLOYMENT.md | 328 ----------------------- DOCKER_DEPLOYMENT.md | 363 -------------------------- Dockerfile | 54 ---- QUICKSTART.md | 86 ------ STATUS.md | 111 -------- deploy.sh | 85 ------ docker-compose.yml | 39 --- lib/config/environment.dart | 13 +- lib/controller/detail_controller.dart | 2 +- lib/controller/edit_controller.dart | 73 ------ lib/controller/graph_controller.dart | 2 +- lib/models/graph_model.dart | 0 lib/services/appwrite_service.dart | 46 +--- lib/services/location_iq_service.dart | 7 +- nginx.conf | 35 --- proxy-server/Dockerfile | 26 -- proxy-server/README.md | 115 -------- proxy-server/package.json | 21 -- proxy-server/server.js | 174 ------------ start-proxy.sh | 36 --- webserver/flutter_bootstrap.js | 2 +- 22 files changed, 6 insertions(+), 1668 deletions(-) delete mode 100644 .dockerignore delete mode 100644 DEPLOYMENT.md delete mode 100644 DOCKER_DEPLOYMENT.md delete mode 100644 Dockerfile delete mode 100644 QUICKSTART.md delete mode 100644 STATUS.md delete mode 100755 deploy.sh delete mode 100644 docker-compose.yml delete mode 100644 lib/models/graph_model.dart delete mode 100644 nginx.conf delete mode 100644 proxy-server/Dockerfile delete mode 100644 proxy-server/README.md delete mode 100644 proxy-server/package.json delete mode 100644 proxy-server/server.js delete mode 100755 start-proxy.sh diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index d102c0a..0000000 --- a/.dockerignore +++ /dev/null @@ -1,56 +0,0 @@ -# .dockerignore -# Git -.git -.gitignore - -# IDE -.idea -.vscode -*.swp -*.swo -*~ - -# Flutter/Dart -.dart_tool/ -.packages -build/ -.flutter-plugins -.flutter-plugins-dependencies -.metadata - -# Node.js (for proxy) -node_modules/ -npm-debug.log -yarn-error.log - -# Test -test/ -integration_test/ -.test_coverage/ - -# Documentation -*.md -!README.md - -# CI/CD -.github/ - -# Local development -.env.local -*.log - -# macOS -.DS_Store - -# Windows -Thumbs.db - -# Linux -*~ - -# Other -*.iml -*.class -*.lock -!pubspec.lock -!package-lock.json diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md deleted file mode 100644 index 4f89f96..0000000 --- a/DEPLOYMENT.md +++ /dev/null @@ -1,328 +0,0 @@ -# Proxy Server Deployment - Anleitung - -## 📋 Übersicht - -Diese Anleitung erklärt, wie Sie den Reverse Proxy Server für PTV API Geocoding deployen. Der Proxy umgeht CORS-Probleme und läuft als eigenständiger Container. - -## 🏗️ Architektur - -``` -Browser (Flutter Web App) - ↓ -Proxy Server (localhost:3000 / your-server.com:3000) - ↓ -PTV Geocoding API (api.myptv.com) -``` - -## 🚀 Lokale Entwicklung - -### 1. Proxy Server starten - -```bash -cd /home/digitalman/Development/flutter_tank_web_app - -# Option A: Mit Script -./start-proxy.sh - -# Option B: Manuell -cd proxy-server -node server.js -``` - -Der Proxy läuft auf `http://localhost:3000` - -### 2. Flutter App starten - -```bash -flutter run -d chrome -``` - -### 3. Testen - -**Geocoding Request:** -```bash -curl "http://localhost:3000/?lat=47.9385165&lon=13.762887&apiKey=YOUR_API_KEY" -``` - -**Erwartete Response:** -```json -{ - "success": true, - "location": "Straßenname Hausnummer, PLZ Stadt", - "coordinates": { - "lat": 47.9385165, - "lon": 13.762887 - } -} -``` - -**Health Check:** -```bash -curl http://localhost:3000/health -# Response: healthy -``` - -## 🐳 Docker Deployment (Empfohlen) - -### 1. Docker Images bauen - -```bash -# Interaktives Deployment-Script -./deploy.sh -# Wählen Sie Option 3: "Alles bauen und starten" - -# Oder manuell -docker-compose up -d --build -``` - -### 2. Services überprüfen - -```bash -docker-compose ps - -# Erwartete Ausgabe: -# flutter-tank-web Up 0.0.0.0:8090->80/tcp -# ptv-proxy Up 0.0.0.0:3000->3000/tcp -``` - -### 3. Logs prüfen - -```bash -# Proxy Logs -docker-compose logs -f ptv-proxy - -# Alle Services -docker-compose logs -f -``` - -## 🌐 Produktion - Auf Server deployen - -### Schritt 1: Server vorbereiten - -**SSH zum Server:** -```bash -ssh user@your-server.com -``` - -**Docker installieren (falls nicht vorhanden):** -```bash -curl -fsSL https://get.docker.com -o get-docker.sh -sudo sh get-docker.sh -sudo usermod -aG docker $USER -``` - -### Schritt 2: Code auf Server kopieren - -**Option A: Git** -```bash -git clone https://github.com/your-repo/flutter_tank_web_app.git -cd flutter_tank_web_app -``` - -**Option B: SCP/Rsync** -```bash -# Von lokalem Rechner -rsync -avz --exclude 'build' --exclude '.dart_tool' \ - . user@your-server.com:/opt/flutter-tank-app/ -``` - -### Schritt 3: Proxy URL konfigurieren - -Bearbeiten Sie `lib/config/environment.dart`: - -```dart -class Environment { - // Produktions-URL des Proxy Servers - static const String localProxyUrl = 'http://your-server.com:3000'; - static const bool useLocalProxy = true; - - // ... rest bleibt gleich -} -``` - -### Schritt 4: Neu builden und deployen - -```bash -cd /opt/flutter-tank-app -./deploy.sh -# Option 3: "Alles bauen und starten" -``` - -### Schritt 5: Firewall konfigurieren - -```bash -# Port 8090 (Web App) und 3000 (Proxy) öffnen -sudo ufw allow 8090/tcp -sudo ufw allow 3000/tcp -sudo ufw enable -``` - -## 🔒 Sichere Konfiguration mit Nginx (Empfohlen) - -Statt Port 3000 direkt zu exponieren, verwenden Sie Nginx als Reverse Proxy: - -### 1. Nginx konfigurieren - -```bash -sudo nano /etc/nginx/sites-available/tank.yourdomain.com -``` - -```nginx -server { - listen 80; - server_name tank.yourdomain.com; - - # Flutter Web App - location / { - proxy_pass http://localhost:8090; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - } - - # Proxy Server (API Endpoint) - location /api/geocode { - proxy_pass http://localhost:3000; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - - # CORS Headers werden vom Proxy Server gesetzt - proxy_hide_header Access-Control-Allow-Origin; - } -} -``` - -### 2. Site aktivieren - -```bash -sudo ln -s /etc/nginx/sites-available/tanknew.joshihomeserver.ipv64.net /etc/nginx/sites-enabled/ -sudo nginx -t -sudo systemctl reload nginx -``` - -### 3. SSL Zertifikat (Let's Encrypt) - -```bash -sudo apt install certbot python3-certbot-nginx -sudo certbot --nginx -d tanknew.joshihomeserver.ipv64.net -``` - -### 4. Environment anpassen - -```dart -static const String localProxyUrl = 'https://tanknew.joshihomeserver.ipv64.net/api/geocode'; -``` - -### 5. Firewall anpassen - -```bash -# Nur 80 und 443 öffnen (nicht 3000) -sudo ufw allow 80/tcp -sudo ufw allow 443/tcp -sudo ufw deny 3000/tcp # Proxy nur über Nginx erreichbar -``` - -## 🔧 Troubleshooting - -### Proxy Server startet nicht - -**Logs prüfen:** -```bash -docker-compose logs ptv-proxy -``` - -**Häufige Probleme:** -- Port 3000 bereits belegt: `sudo lsof -i :3000` -- Node.js nicht installiert: `node --version` - -### CORS-Fehler trotz Proxy - -**Prüfen:** -1. Ist der Proxy erreichbar? `curl http://localhost:3000/health` -2. Richtige URL in `environment.dart`? -3. Browser Cache leeren und App neu laden - -### "Connection refused" - -**Lösung:** -```bash -# Docker Container laufen? -docker-compose ps - -# Proxy neu starten -docker-compose restart ptv-proxy -``` - -### PTV API gibt 401 zurück - -**Problem:** Ungültiger API Key -**Lösung:** API Key in `environment.dart` überprüfen - -### Im Container: "npm not found" - -**Problem:** Lokales `node_modules` committet -**Lösung:** -```bash -# .dockerignore prüfen -cat .dockerignore | grep node_modules - -# Sollte vorhanden sein -``` - -## 📊 Monitoring - -### Service Status - -```bash -# Docker -docker-compose ps - -# System Resources -docker stats - -# Health Check -curl http://localhost:3000/health -``` - -### Logs Live anschauen - -```bash -# Proxy -docker-compose logs -f ptv-proxy - -# Alle Services -docker-compose logs -f --tail=100 -``` - -## 🔄 Updates deployen - -```bash -# Code aktualisieren -git pull - -# Container neu bauen und starten -docker-compose up -d --build - -# Alte Images aufräumen -docker image prune -f -``` - -## ✅ Erfolgskriterien - -Nach erfolgreichem Deployment sollten Sie: -- ✅ Proxy Health Check erfolgreich: `curl http://tanknew.joshihomeserver.ipv64.net:3000/health` -- ✅ Geocoding funktioniert in der App -- ✅ Browser Console zeigt: "🔄 Verwende lokalen Proxy..." -- ✅ Browser Console zeigt: "✅ Geocoding erfolgreich (Proxy): [Adresse]" -- ✅ Keine CORS-Fehler mehr - -## 📝 Produktions-Checkliste - -- [ ] Docker und Docker Compose installiert -- [ ] Code auf Server übertragen -- [ ] `localProxyUrl` in environment.dart angepasst -- [ ] Docker Containers laufen (`docker-compose ps`) -- [ ] Firewall konfiguriert -- [ ] Nginx Reverse Proxy eingerichtet (empfohlen) -- [ ] SSL Zertifikat installiert -- [ ] Health Checks erfolgreich -- [ ] Geocoding in App getestet diff --git a/DOCKER_DEPLOYMENT.md b/DOCKER_DEPLOYMENT.md deleted file mode 100644 index 6177cb2..0000000 --- a/DOCKER_DEPLOYMENT.md +++ /dev/null @@ -1,363 +0,0 @@ -# 🐳 Docker Deployment Anleitung - -## Voraussetzungen - -- Docker installiert (`docker --version`) -- Docker Compose installiert (`docker-compose --version`) -- Min. 2 GB freier RAM -- Min. 5 GB freier Speicherplatz - -## 🚀 Schnellstart - -### Option 1: Mit Deploy-Script (Empfohlen) - -```bash -./deploy.sh -``` - -Folgen Sie den Anweisungen im interaktiven Menü. - -### Option 2: Manuelle Commands - -**Alles bauen und starten:** -```bash -docker-compose up -d --build -``` - -**Nur starten (bereits gebaut):** -```bash -docker-compose up -d -``` - -**Stoppen:** -```bash -docker-compose down -``` - -**Logs anzeigen:** -```bash -docker-compose logs -f -``` - -## 📦 Was wird deployed? - -### 1. Flutter Web App Container -- **Image:** `flutter-tank-web:latest` -- **Port:** 8080 (Host) → 80 (Container) -- **URL:** `http://localhost:8080` -- **Technologie:** Flutter Web + Nginx - -### 2. Proxy Server Container (Optional) -- **Image:** `ptv-proxy:latest` -- **Port:** 3000 (Host) → 3000 (Container) -- **URL:** `http://localhost:3000` -- **Technologie:** Node.js - -## 🏗️ Build-Prozess - -Der Build läuft in 2 Phasen: - -**Phase 1: Flutter Build (Multi-Stage)** -1. Ubuntu base image -2. Flutter SDK installieren -3. Dependencies installieren (`flutter pub get`) -4. Web App bauen (`flutter build web`) - -**Phase 2: Production (Nginx)** -1. Alpine Nginx image -2. Gebaute App kopieren -3. Nginx konfigurieren -4. Port 80 exponieren - -**Geschätzte Build-Zeit:** 5-10 Minuten (beim ersten Mal) - -## 🌐 Auf Server deployen - -### 1. Server vorbereiten - -**SSH zum Server:** -```bash -ssh user@your-server.com -``` - -**Docker installieren (falls nicht vorhanden):** -```bash -curl -fsSL https://get.docker.com -o get-docker.sh -sudo sh get-docker.sh -sudo usermod -aG docker $USER -``` - -**Docker Compose installieren:** -```bash -sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose -sudo chmod +x /usr/local/bin/docker-compose -``` - -### 2. Code auf Server übertragen - -**Option A: Git Clone** -```bash -git clone https://github.com/your-repo/flutter_tank_web_app.git -cd flutter_tank_web_app -``` - -**Option B: SCP/Rsync** -```bash -# Von lokalem Rechner aus -rsync -avz --exclude 'build' --exclude '.dart_tool' \ - /home/digitalman/Development/flutter_tank_web_app/ \ - user@your-server.com:/opt/flutter-tank-app/ -``` - -### 3. Environment anpassen - -Bearbeiten Sie `lib/config/environment.dart`: -```dart -static const bool useLocalProxy = false; // Für Produktion -``` - -### 4. Deployen - -```bash -cd /opt/flutter-tank-app -./deploy.sh -# Wählen Sie Option 3: "Alles bauen und starten" -``` - -### 5. Mit Domain verbinden (Optional) - -**Nginx Reverse Proxy konfigurieren:** -```nginx -# /etc/nginx/sites-available/tank.yourdomain.com -server { - listen 80; - server_name tank.yourdomain.com; - - location / { - proxy_pass http://localhost:8080; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - } -} -``` - -**Aktivieren:** -```bash -sudo ln -s /etc/nginx/sites-available/tank.yourdomain.com /etc/nginx/sites-enabled/ -sudo nginx -t -sudo systemctl reload nginx -``` - -**SSL mit Let's Encrypt:** -```bash -sudo apt install certbot python3-certbot-nginx -sudo certbot --nginx -d tank.yourdomain.com -``` - -## 🔧 Konfiguration - -### Ports ändern - -In `docker-compose.yml`: -```yaml -ports: - - "8080:80" # Ändern Sie 8080 auf gewünschten Port -``` - -### Umgebungsvariablen - -Erstellen Sie `.env` Datei: -```env -# App Settings -APP_PORT=8080 -PROXY_PORT=3000 - -# Domain (für Traefik) -DOMAIN=tank.yourdomain.com -``` - -### Mit Traefik (Reverse Proxy) - -Die `docker-compose.yml` enthält bereits Traefik Labels. - -**Traefik setup:** -```yaml -# docker-compose.traefik.yml -version: '3.8' -services: - traefik: - image: traefik:v2.10 - command: - - "--providers.docker=true" - - "--entrypoints.web.address=:80" - - "--entrypoints.websecure.address=:443" - - "--certificatesresolvers.letsencrypt.acme.email=your@email.com" - - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json" - - "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web" - ports: - - "80:80" - - "443:443" - volumes: - - "/var/run/docker.sock:/var/run/docker.sock:ro" - - "./letsencrypt:/letsencrypt" -``` - -## 📊 Monitoring - -### Container Status prüfen -```bash -docker-compose ps -``` - -### Logs anschauen -```bash -# Alle Services -docker-compose logs -f - -# Nur Web App -docker-compose logs -f flutter-tank-web - -# Nur Proxy -docker-compose logs -f ptv-proxy -``` - -### Resource Usage -```bash -docker stats -``` - -### Health Check -```bash -# Web App -curl http://localhost:8080/health - -# Proxy -curl http://localhost:3000/health -``` - -## 🔄 Updates deployen - -```bash -# Code aktualisieren -git pull - -# Neu bauen und starten -docker-compose up -d --build - -# Alte Images aufräumen -docker image prune -f -``` - -## 🛠️ Troubleshooting - -### Container startet nicht -```bash -# Logs prüfen -docker-compose logs flutter-tank-web - -# Container Status -docker-compose ps - -# Neu starten -docker-compose restart flutter-tank-web -``` - -### Port bereits belegt -```bash -# Prozess auf Port finden -sudo lsof -i :8080 - -# Port in docker-compose.yml ändern -``` - -### Out of Memory -```bash -# Docker Memory Limit erhöhen -# In docker-compose.yml unter service: -deploy: - resources: - limits: - memory: 2G -``` - -### Build schlägt fehl -```bash -# Docker Cache leeren -docker builder prune -a - -# Komplett neu bauen -docker-compose build --no-cache -``` - -## 📦 Backup & Restore - -### Volumes sichern -```bash -# Data Volume backup -docker run --rm -v flutter-tank-data:/data -v $(pwd):/backup alpine tar czf /backup/data-backup.tar.gz -C /data . -``` - -### Image speichern -```bash -# Image exportieren -docker save flutter-tank-web:latest | gzip > flutter-tank-web.tar.gz - -# Image importieren -docker load < flutter-tank-web.tar.gz -``` - -## 🔒 Sicherheit - -### Best Practices - -1. **Nicht als Root laufen** (bereits in Proxy-Dockerfile implementiert) -2. **Security Headers** (bereits in nginx.conf) -3. **Firewall konfigurieren:** -```bash -sudo ufw allow 80/tcp -sudo ufw allow 443/tcp -sudo ufw enable -``` - -4. **Regular Updates:** -```bash -# Base images updaten -docker-compose pull -docker-compose up -d -``` - -## 🎯 Performance Optimierung - -### Nginx Caching -Bereits in `nginx.conf` konfiguriert: -- Static assets: 1 Jahr Cache -- Gzip Kompression aktiv - -### Docker Image Size -```bash -# Image Größe prüfen -docker images flutter-tank-web - -# Multi-stage build reduziert Größe bereits deutlich -``` - -## 📝 Checkliste Produktion - -- [ ] `useLocalProxy = false` in environment.dart -- [ ] Domain konfiguriert -- [ ] SSL Zertifikat installiert -- [ ] Firewall konfiguriert -- [ ] Backup-Strategie definiert -- [ ] Monitoring eingerichtet -- [ ] Logs rotieren konfiguriert -- [ ] Update-Prozess dokumentiert - -## 🆘 Support - -Bei Problemen: -1. Logs prüfen: `docker-compose logs` -2. Container Status: `docker-compose ps` -3. Health Checks: `curl http://localhost:8080/health` -4. Docker System: `docker system df` diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 014d176..0000000 --- a/Dockerfile +++ /dev/null @@ -1,54 +0,0 @@ -# Dockerfile für Flutter Web App -FROM ubuntu:22.04 AS build - -# Avoid interactive prompts -ENV DEBIAN_FRONTEND=noninteractive - -# Install dependencies -RUN apt-get update && apt-get install -y \ - curl \ - git \ - unzip \ - xz-utils \ - zip \ - libglu1-mesa \ - wget \ - && rm -rf /var/lib/apt/lists/* - -# Install Flutter -ENV FLUTTER_HOME=/usr/local/flutter -ENV PATH="${FLUTTER_HOME}/bin:${PATH}" -ENV TAR_OPTIONS=--no-same-owner - -RUN git clone https://github.com/flutter/flutter.git ${FLUTTER_HOME} -b stable --depth 1 && \ - flutter config --enable-web --no-analytics && \ - flutter precache --web - -# Set working directory -WORKDIR /app - -# Copy app files -COPY pubspec.yaml pubspec.lock ./ - -# Run pub get (downloads web dependencies without needing gradle) -RUN flutter pub get - -COPY . . - -# Build web app (web-only artifacts; suppress wasm dry-run warnings) -RUN flutter build web --release --no-wasm-dry-run - -# Production stage - Nginx -FROM nginx:alpine - -# Copy built app to nginx -COPY --from=build /app/build/web /usr/share/nginx/html - -# Copy custom nginx config -COPY nginx.conf /etc/nginx/conf.d/default.conf - -# Expose port -EXPOSE 80 - -# Start nginx -CMD ["nginx", "-g", "daemon off;"] diff --git a/QUICKSTART.md b/QUICKSTART.md deleted file mode 100644 index 4032aba..0000000 --- a/QUICKSTART.md +++ /dev/null @@ -1,86 +0,0 @@ -# 🚀 Quick Start - Lokaler Reverse Proxy - -## Sofort loslegen - -### Terminal 1: Proxy Server starten - -```bash -./start-proxy.sh -``` - -Oder manuell: -```bash -cd proxy-server -node server.js -``` - -### Terminal 2: Flutter App starten - -```bash -flutter run -d chrome -``` - -## ✅ Das wars! - -Die App verwendet jetzt automatisch den lokalen Proxy auf `http://localhost:3000` für Geocoding. - -## 🔧 Konfiguration - -In [lib/config/environment.dart](lib/config/environment.dart): - -```dart -static const bool useLocalProxy = true; // true = Proxy, false = Appwrite Function -``` - -## 📋 Checkliste - -- ✅ Node.js installiert (`node --version`) -- ✅ Proxy läuft (`http://localhost:3000` im Browser) -- ✅ `useLocalProxy = true` in environment.dart -- ✅ Flutter App läuft - -## 🎯 Vorteile Lokaler Proxy - -✅ **Kein CORS-Problem** - Server umgeht Browser-Beschränkungen -✅ **Schnelles Testen** - Kein Cloud-Deployment nötig -✅ **Einfaches Debugging** - Logs direkt im Terminal -✅ **Kostenlos** - Läuft lokal, keine Cloud-Kosten - -## 🌐 Für Produktion - -Für den Live-Betrieb: - -1. Setzen Sie `useLocalProxy = false` -2. Deployen Sie die Appwrite Function (siehe [DEPLOYMENT.md](DEPLOYMENT.md)) -3. Tragen Sie die Function ID ein - -## 📊 Vergleich - -| Feature | Lokaler Proxy | Appwrite Function | -|---------|--------------|-------------------| -| Setup Zeit | < 1 Minute | ~10 Minuten | -| CORS | ✅ Gelöst | ✅ Gelöst | -| Kosten | Kostenlos | Serverless (minimal) | -| Verwendung | Nur Entwicklung | Entwicklung + Produktion | -| Debugging | Sehr einfach | Logs in Console | -| Offline | ❌ | ❌ | - -## 🐛 Problemlösung - -**Proxy startet nicht:** -```bash -# Port 3000 belegt? -lsof -i :3000 -# Prozess beenden -kill -9 -``` - -**App findet Proxy nicht:** -- Proxy läuft? Prüfen Sie `http://localhost:3000` im Browser -- `useLocalProxy = true`? Prüfen Sie environment.dart -- Hot Restart in Flutter machen - -**Immer noch CORS-Fehler:** -- Browser-Cache leeren -- DevTools → Network → "Disable cache" -- App neu builden: `flutter run -d chrome` diff --git a/STATUS.md b/STATUS.md deleted file mode 100644 index 77740c6..0000000 --- a/STATUS.md +++ /dev/null @@ -1,111 +0,0 @@ -# ✅ System Status - Alles Repariert - -## 📋 Überprüfungsergebnis - -### ✅ Alle Fehler behoben! - -**Probleme die behoben wurden:** -1. ❌ Syntax-Fehler in edit_controller.dart → ✅ Behoben -2. ❌ Fehlende Imports → ✅ Hinzugefügt -3. ❌ Unvollständige Methoden → ✅ Implementiert -4. ❌ Duplicate Code → ✅ Entfernt - -## 🎯 Aktueller Status - -### 1. Edit Controller ✅ -- [x] Keine Compile-Fehler -- [x] Verwendet `appwriteService.geocodeLocation()` -- [x] Benutzer-Feedback mit Snackbars -- [x] Saubere Imports - -### 2. Appwrite Service ✅ -- [x] `geocodeLocation()` Methode implementiert -- [x] `_geocodeViaLocalProxy()` für lokalen Proxy -- [x] Fallback auf Koordinaten bei Fehlern -- [x] http package importiert - -### 3. Environment Config ✅ -```dart -static const bool useLocalProxy = true; // ✅ Aktiv -static const String localProxyUrl = 'http://localhost:3000'; -``` - -### 4. Proxy Server ✅ -- [x] server.js existiert -- [x] package.json existiert -- [x] README.md vorhanden -- [x] Node.js funktioniert -- [x] Start-Script ausführbar - -## 🚀 So starten Sie die App - -### Terminal 1: Proxy Server -```bash -cd /home/digitalman/Development/flutter_tank_web_app -./start-proxy.sh -``` - -### Terminal 2: Flutter App -```bash -cd /home/digitalman/Development/flutter_tank_web_app -flutter run -d chrome -``` - -## 📊 Funktionsweise - -``` -User erstellt Tankeintrag - ↓ -Geolocation fragt GPS ab - ↓ -EditController ruft appwriteService.geocodeLocation() auf - ↓ -AppwriteService prüft useLocalProxy Flag - ↓ -├─ true → Lokaler Proxy (localhost:3000) → PTV API ✅ -└─ false → Fallback auf Koordinaten - ↓ -Adresse oder Koordinaten werden gespeichert -``` - -## ✅ Erfolgskriterien - -Wenn alles funktioniert, sehen Sie: -- ✅ Proxy-Server läuft auf Port 3000 -- ✅ "🔄 Verwende lokalen Proxy" in Logs -- ✅ "✅ Geocoding erfolgreich (Proxy): [Adresse]" -- ✅ Grüne Snackbar mit Adresse in der App -- ✅ Keine CORS-Fehler in Browser Console - -## 🐛 Wenn etwas nicht funktioniert - -**Proxy nicht erreichbar:** -```bash -# Prüfen ob läuft -curl http://localhost:3000 -# Neu starten -./start-proxy.sh -``` - -**Flutter App zeigt Koordinaten statt Adresse:** -1. Prüfen: Proxy läuft? -2. Prüfen: `useLocalProxy = true`? -3. Browser Console für Fehler prüfen -4. Hot Restart: `r` im Flutter Terminal - -**Port 3000 belegt:** -```bash -# Prozess finden und beenden -lsof -i :3000 -kill -9 -``` - -## 📝 Nächste Schritte - -1. **Testen**: Neuen Tankeintrag erstellen -2. **Verifizieren**: Adresse wird korrekt angezeigt -3. **Optional**: Für Produktion auf `useLocalProxy = false` setzen - -## 🎉 Status: BEREIT FÜR NUTZUNG! - -Alle Systeme sind operationsbereit. Der lokale Reverse-Proxy umgeht das CORS-Problem erfolgreich. diff --git a/deploy.sh b/deploy.sh deleted file mode 100755 index 53acc36..0000000 --- a/deploy.sh +++ /dev/null @@ -1,85 +0,0 @@ -#!/bin/bash - -# Farben -GREEN='\033[0;32m' -BLUE='\033[0;34m' -YELLOW='\033[1;33m' -RED='\033[0;31m' -NC='\033[0m' - -echo -e "${BLUE}═══════════════════════════════════════════════════════${NC}" -echo -e "${BLUE} Flutter Tank App - Docker Deployment${NC}" -echo -e "${BLUE}═══════════════════════════════════════════════════════${NC}" -echo "" - -# Prüfen ob Docker installiert ist -if ! command -v docker &> /dev/null; then - echo -e "${RED}❌ Docker ist nicht installiert!${NC}" - echo -e "${YELLOW}Installieren Sie Docker: https://docs.docker.com/get-docker/${NC}" - exit 1 -fi - -if ! command -v docker-compose &> /dev/null; then - echo -e "${RED}❌ Docker Compose ist nicht installiert!${NC}" - echo -e "${YELLOW}Installieren Sie Docker Compose: https://docs.docker.com/compose/install/${NC}" - exit 1 -fi - -echo -e "${GREEN}✅ Docker und Docker Compose gefunden${NC}" -echo "" - -# Build Option -echo -e "${YELLOW}Wählen Sie eine Option:${NC}" -echo "1) Nur Flutter Web App bauen" -echo "2) Flutter Web App + Proxy Server bauen" -echo "3) Alles bauen und starten" -echo "4) Nur starten (ohne neu zu bauen)" -echo "5) Stoppen" -echo "6) Logs anzeigen" -read -p "Option (1-6): " option - -case $option in - 1) - echo -e "${BLUE}🔨 Baue Flutter Web App...${NC}" - docker build -t flutter-tank-web:latest . - echo -e "${GREEN}✅ Build abgeschlossen!${NC}" - echo -e "${YELLOW}Zum Starten: docker run -p 8080:80 flutter-tank-web:latest${NC}" - ;; - 2) - echo -e "${BLUE}🔨 Baue alle Images...${NC}" - docker-compose build - echo -e "${GREEN}✅ Build abgeschlossen!${NC}" - ;; - 3) - echo -e "${BLUE}🔨 Baue und starte alle Services...${NC}" - docker-compose up -d --build - echo "" - echo -e "${GREEN}✅ Services gestartet!${NC}" - echo "" - echo -e "${YELLOW}📡 Verfügbare Endpoints:${NC}" - echo -e " Flutter Web App: ${GREEN}http://localhost:8090${NC}" - echo -e " Proxy Server: ${GREEN}http://localhost:3000${NC}" - echo "" - echo -e "${YELLOW}📊 Status prüfen:${NC}" - docker-compose ps - ;; - 4) - echo -e "${BLUE}🚀 Starte Services...${NC}" - docker-compose up -d - echo -e "${GREEN}✅ Services gestartet!${NC}" - docker-compose ps - ;; - 5) - echo -e "${BLUE}🛑 Stoppe Services...${NC}" - docker-compose down - echo -e "${GREEN}✅ Services gestoppt!${NC}" - ;; - 6) - echo -e "${BLUE}📋 Zeige Logs...${NC}" - docker-compose logs -f - ;; - *) - echo -e "${RED}❌ Ungültige Option${NC}" - exit 1 - ;; -esac diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index d5f4c31..0000000 --- a/docker-compose.yml +++ /dev/null @@ -1,39 +0,0 @@ -services: - # Flutter Web App - flutter-tank-web: - build: - context: . - dockerfile: Dockerfile - container_name: flutter-tank-web - restart: unless-stopped - ports: - - "8090:80" - networks: - - app-network - environment: - - TZ=Europe/Vienna - labels: - - "traefik.enable=true" - - "traefik.http.routers.flutter-tank.rule=Host(`tanknew.joshihomeserver.ipv64.net`)" - - "traefik.http.routers.flutter-tank.entrypoints=websecure" - - "traefik.http.routers.flutter-tank.tls.certresolver=letsencrypt" - - "traefik.http.services.flutter-tank.loadbalancer.server.port=80" - - # Optional: Reverse Proxy für PTV API (Production) - ptv-proxy: - build: - context: ./proxy-server - dockerfile: Dockerfile - container_name: ptv-proxy - restart: unless-stopped - ports: - - "3000:3000" - networks: - - app-network - environment: - - NODE_ENV=production - - PORT=3000 - -networks: - app-network: - driver: bridge diff --git a/lib/config/environment.dart b/lib/config/environment.dart index 11566d3..34c53bc 100644 --- a/lib/config/environment.dart +++ b/lib/config/environment.dart @@ -5,17 +5,6 @@ class Environment { static const String appwriteProjectName = 'Flutter Projects'; static const String appwriteRealtimeCollectionId = '68a22f520035a95d6666'; static const String appwriteDatabaseId = '68a22ef90021b90f0f43'; - static const String ptvApiKey = - 'NTYxMDQ3NTY2OWI3NDI5ZGIzZWIxOWNiNTNhMDEwODY6YTQ4MTJhYzYtYmYzOC00ZmE4LTk4YzYtZDBjNzYyZTAyNjBk'; static const String locationIQKey = 'pk.dea65023dc6fed25c96902bb97fb231d'; - static const double lat=47.93875449671056; - static const double lon=13.762706553431048; - //https://eu1.locationiq.com/v1/reverse?key=pk.dea65023dc6fed25c96902bb97fb231d&lat=47.93875449671056&lon=13.762706553431048&format=json - static const String locationIQBaseUrl = - 'https://eu1.locationiq.com/v1/reverse?key=$locationIQKey&'; //47.93875449671056, 13.762706553431048 - static const String ptvApiVersion = '3'; - // Lokaler Reverse Proxy für Entwicklung (CORS-Workaround) - static const String localProxyUrl = 'http://localhost:3000'; - static const bool useLocalProxy = - true; // true = lokaler Proxy, false = Appwrite Function + static const String locationIQBaseUrl = 'https://eu1.locationiq.com/v1/reverse?key=$locationIQKey&'; } diff --git a/lib/controller/detail_controller.dart b/lib/controller/detail_controller.dart index 1bea0d5..24130f4 100644 --- a/lib/controller/detail_controller.dart +++ b/lib/controller/detail_controller.dart @@ -1,7 +1,7 @@ -import 'package:flutter_tank_web_app/services/appwrite_service.dart'; import 'package:get/get.dart'; import '../models/tank_model.dart'; import '../pages/edit_view.dart'; +import '../services/appwrite_service.dart'; class DetailController extends GetxController { late TankModel tank; diff --git a/lib/controller/edit_controller.dart b/lib/controller/edit_controller.dart index 7800120..9d73bf9 100644 --- a/lib/controller/edit_controller.dart +++ b/lib/controller/edit_controller.dart @@ -1,7 +1,6 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:geolocator/geolocator.dart'; - import '../models/locationiq_model.dart'; import '../models/tank_model.dart'; import '../services/appwrite_service.dart'; @@ -62,78 +61,6 @@ class EditController extends GetxController { '${now.year}-${now.month.toString().padLeft(2, '0')}-${now.day.toString().padLeft(2, '0')}'; } - // Future _requestLocation() async { - // bool serviceEnabled; - // LocationPermission permission; - - // try { - // isLoadingLocation.value = true; - - // // 1. Prüfen, ob Standortdienste aktiviert sind - // serviceEnabled = await Geolocator.isLocationServiceEnabled(); - // if (!serviceEnabled) { - // return Future.error('Standortdienste sind deaktiviert.'); - // } - - // // 2. Berechtigungen prüfen - // permission = await Geolocator.checkPermission(); - // if (permission == LocationPermission.denied) { - // permission = await Geolocator.requestPermission(); - // if (permission == LocationPermission.denied) { - // return Future.error('Berechtigung verweigert.'); - // } - // } - - // // 3. Position abrufen - // Position position = await Geolocator.getCurrentPosition( - // locationSettings: const LocationSettings( - // accuracy: LocationAccuracy.high, - // ), - // ); - - // // 4. Standort über Backend-Proxy abrufen - // var lat = position.latitude; - // var lon = position.longitude; - - // print('📍 Verwende Backend-Proxy für Geocoding...'); - // String location = await appwriteService.geocodeLocation(lat, lon); - // locationController.text = location; - - // // Info anzeigen basierend auf Ergebnis - // if (location.startsWith('Lat:')) { - // Get.snackbar( - // 'Hinweis', - // 'Adresse konnte nicht abgerufen werden. Koordinaten gespeichert.', - // snackPosition: SnackPosition.BOTTOM, - // backgroundColor: Colors.orange[100], - // colorText: Colors.orange[900], - // duration: const Duration(seconds: 3), - // ); - // } else { - // Get.snackbar( - // 'Erfolg', - // 'Standort: $location', - // snackPosition: SnackPosition.BOTTOM, - // backgroundColor: Colors.green[100], - // colorText: Colors.green[900], - // duration: const Duration(seconds: 2), - // ); - // } - // } catch (e) { - // Get.snackbar( - // "Fehler", - // "Standort konnte nicht abgerufen werden: $e", - // snackPosition: SnackPosition.BOTTOM, - // backgroundColor: Colors.red[100], - // colorText: Colors.red[900], - // ); - // print("Fehler beim Abrufen des Standorts: $e"); - // locationController.text = ''; - // } finally { - // isLoadingLocation.value = false; - // } - // } - Future _requestLocationIQ() async { bool serviceEnabled; LocationPermission permission; diff --git a/lib/controller/graph_controller.dart b/lib/controller/graph_controller.dart index c009675..20f84ef 100644 --- a/lib/controller/graph_controller.dart +++ b/lib/controller/graph_controller.dart @@ -1,5 +1,5 @@ -import 'package:flutter_tank_web_app/models/tank_model.dart'; import 'package:get/get.dart'; +import '../models/tank_model.dart'; class GraphController extends GetxController { final listTankModel = [].obs; diff --git a/lib/models/graph_model.dart b/lib/models/graph_model.dart deleted file mode 100644 index e69de29..0000000 diff --git a/lib/services/appwrite_service.dart b/lib/services/appwrite_service.dart index 7610ce4..1cda049 100644 --- a/lib/services/appwrite_service.dart +++ b/lib/services/appwrite_service.dart @@ -1,7 +1,6 @@ -//import 'dart:convert'; + import 'package:appwrite/models.dart'; import 'package:appwrite/appwrite.dart'; -//import 'package:http/http.dart' as http; import '../config/environment.dart'; class AppwriteService { @@ -167,47 +166,4 @@ class AppwriteService { return false; } } - - // // Geocode coordinates using local proxy or Appwrite Function - // Future geocodeLocation(double lat, double lon) async { - // // Wenn lokaler Proxy aktiviert ist, diesen verwenden - // if (Environment.useLocalProxy) { - // return _geocodeViaLocalProxy(lat, lon); - // } - - // // Fallback: Koordinaten zurückgeben - // return 'Lat: ${lat.toStringAsFixed(6)}, Lon: ${lon.toStringAsFixed(6)}'; - // } - - // // Geocoding über lokalen Reverse Proxy - // Future _geocodeViaLocalProxy(double lat, double lon) async { - // try { - // final proxyUrl = '${Environment.localProxyUrl}/?lat=$lat&lon=$lon&apiKey=${Environment.ptvApiKey}'; - - // print('🔄 Verwende lokalen Proxy: ${Environment.localProxyUrl}'); - - // final response = await http.get(Uri.parse(proxyUrl)); - - // if (response.statusCode == 200) { - // final data = jsonDecode(response.body); - - // if (data['success'] == true) { - // final location = data['location'] as String; - // print('✅ Geocoding erfolgreich (Proxy): $location'); - // return location; - // } else { - // print('❌ Geocoding fehlgeschlagen (Proxy): ${data['error']}'); - // return data['fallbackLocation'] ?? - // 'Lat: ${lat.toStringAsFixed(6)}, Lon: ${lon.toStringAsFixed(6)}'; - // } - // } else { - // print('⚠️ Proxy Response Status: ${response.statusCode}'); - // return 'Lat: ${lat.toStringAsFixed(6)}, Lon: ${lon.toStringAsFixed(6)}'; - // } - // } catch (e) { - // print('❌ Lokaler Proxy nicht erreichbar: $e'); - // print('💡 Tipp: Starten Sie den Proxy mit: cd proxy-server && node server.js'); - // return 'Lat: ${lat.toStringAsFixed(6)}, Lon: ${lon.toStringAsFixed(6)}'; - // } - // } } diff --git a/lib/services/location_iq_service.dart b/lib/services/location_iq_service.dart index f7c580a..e3babd3 100644 --- a/lib/services/location_iq_service.dart +++ b/lib/services/location_iq_service.dart @@ -1,21 +1,16 @@ // ignore_for_file: public_member_api_docs, sort_constructors_first +import 'package:http/http.dart' as http; import 'dart:convert'; - import '../config/environment.dart'; import '../models/locationiq_model.dart'; -import 'package:http/http.dart' as http; class LocationIQService { static final String baseUrl = Environment.locationIQBaseUrl; late LocationIQ locationIQ; Future fetchLocationIQ(double lat, double lon) async { - // Hier würde die eigentliche API-Anfrage an LocationIQ erfolgen - // Zum Beispiel mit http.get() und der URL aus Environment.locationIQUrl - // Die Antwort würde dann in das LocationIQ-Modell umgewandelt werden // https://eu1.locationiq.com/v1/reverse?key=$locationIQKey&lat=47.93875449671056&lon=13.762706553431048&format=json - // locationIQ = LocationIQ.fromJson(responseData); // Simulierte Antwort (für Testzwecke) locationIQ = LocationIQ( placeId: '12345', diff --git a/nginx.conf b/nginx.conf deleted file mode 100644 index 00a2273..0000000 --- a/nginx.conf +++ /dev/null @@ -1,35 +0,0 @@ -server { - listen 80; - server_name localhost; - root /usr/share/nginx/html; - index index.html; - - # Compression - gzip on; - gzip_vary on; - gzip_min_length 1024; - gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml+rss application/json application/javascript; - - # Security headers - add_header X-Frame-Options "SAMEORIGIN" always; - add_header X-Content-Type-Options "nosniff" always; - add_header X-XSS-Protection "1; mode=block" always; - - # Cache static assets - location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { - expires 1y; - add_header Cache-Control "public, immutable"; - } - - # Flutter web routing - location / { - try_files $uri $uri/ /index.html; - } - - # Health check endpoint - location /health { - access_log off; - return 200 "healthy\n"; - add_header Content-Type text/plain; - } -} diff --git a/proxy-server/Dockerfile b/proxy-server/Dockerfile deleted file mode 100644 index d924fd8..0000000 --- a/proxy-server/Dockerfile +++ /dev/null @@ -1,26 +0,0 @@ -# Dockerfile für Node.js Proxy Server -FROM node:18-alpine - -WORKDIR /app - -# Copy package files -COPY package*.json ./ - -# Install dependencies (omit dev; no lockfile required) -RUN npm install --omit=dev - -# Copy application code -COPY server.js ./ - -# Expose port -EXPOSE 3000 - -# Health check -HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ - CMD node -e "require('http').get('http://localhost:3000/health', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})" - -# Run as non-root user -USER node - -# Start server -CMD ["node", "server.js"] diff --git a/proxy-server/README.md b/proxy-server/README.md deleted file mode 100644 index d9ec575..0000000 --- a/proxy-server/README.md +++ /dev/null @@ -1,115 +0,0 @@ -# Lokaler Reverse Proxy Server - -Dieser Proxy-Server umgeht CORS-Probleme während der Entwicklung, indem er Anfragen an die PTV Geocoding API weiterleitet. - -## 🚀 Installation & Start - -### 1. Dependencies installieren (nur Node.js Standard-Module, keine Installation nötig) - -Der Server verwendet nur Node.js Built-in Module (`http`, `https`, `url`), daher ist kein `npm install` erforderlich. - -### 2. Server starten - -```bash -cd proxy-server -node server.js -``` - -Oder mit npm: -```bash -npm start -``` - -Der Server läuft dann auf `http://localhost:3000` - -## 📡 API Verwendung - -**Endpoint:** -``` -GET http://localhost:3000/?lat={latitude}&lon={longitude}&apiKey={ptv_api_key} -``` - -**Beispiel:** -``` -http://localhost:3000/?lat=47.9385165&lon=13.762887&apiKey=YOUR_API_KEY -``` - -**Response (Erfolg):** -```json -{ - "success": true, - "location": "Hauptstraße 123, 5020 Salzburg", - "coordinates": { - "lat": 47.9385165, - "lon": 13.762887 - }, - "rawData": { ... } -} -``` - -**Response (Fehler):** -```json -{ - "success": false, - "error": "Error message", - "fallbackLocation": "Lat: 47.938517, Lon: 13.762887" -} -``` - -## 🔧 In Flutter App verwenden - -Der Flutter Code wurde bereits angepasst, um den lokalen Proxy zu verwenden. - -1. Starten Sie den Proxy-Server: - ```bash - cd proxy-server - node server.js - ``` - -2. Starten Sie die Flutter App: - ```bash - flutter run -d chrome - ``` - -3. Die App verwendet automatisch `http://localhost:3000` wenn verfügbar. - -## ⚠️ Wichtige Hinweise - -- **Nur für Entwicklung!** Dieser Server ist nicht für Produktionsumgebungen geeignet. -- Der Server muss laufen, während Sie die Flutter App im Development-Modus verwenden. -- Für Produktion: Verwenden Sie die Appwrite Function (siehe [DEPLOYMENT.md](../DEPLOYMENT.md)) - -## 🛑 Server stoppen - -Drücken Sie `Strg+C` im Terminal, wo der Server läuft. - -## 🐛 Troubleshooting - -### Port bereits belegt -**Problem:** `Error: listen EADDRINUSE: address already in use :::3000` - -**Lösung:** -1. Anderen Port verwenden: Ändern Sie `PORT = 3000` in `server.js` -2. Oder den bestehenden Prozess beenden: - ```bash - # Port finden - lsof -i :3000 - # Prozess beenden - kill -9 PID - ``` - -### Flutter App findet Proxy nicht -**Problem:** "Failed to fetch" oder Connection Error - -**Lösung:** -1. Prüfen Sie ob der Proxy läuft (`http://localhost:3000` im Browser öffnen) -2. Stellen Sie sicher, dass Port 3000 korrekt ist -3. Prüfen Sie die Browser Console für Fehler - -### CORS immer noch ein Problem -**Problem:** CORS-Fehler trotz Proxy - -**Lösung:** -1. Stellen Sie sicher, dass die Flutter App `localhost:3000` verwendet -2. Browser-Cache leeren -3. Entwickler-Tools → Network → "Disable cache" aktivieren diff --git a/proxy-server/package.json b/proxy-server/package.json deleted file mode 100644 index 4a58bd1..0000000 --- a/proxy-server/package.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "name": "ptv-proxy-server", - "version": "1.0.0", - "description": "Local reverse proxy for PTV Geocoding API to bypass CORS", - "main": "server.js", - "scripts": { - "start": "node server.js", - "dev": "node server.js" - }, - "keywords": [ - "proxy", - "cors", - "ptv", - "geocoding" - ], - "author": "", - "license": "MIT", - "engines": { - "node": ">=14.0.0" - } -} diff --git a/proxy-server/server.js b/proxy-server/server.js deleted file mode 100644 index 800b4bb..0000000 --- a/proxy-server/server.js +++ /dev/null @@ -1,174 +0,0 @@ -/** - * Lokaler Reverse Proxy für PTV Geocoding API - * Umgeht CORS-Probleme bei der Entwicklung - */ - -const http = require('http'); -const https = require('https'); -const url = require('url'); - -const PORT = 3000; -const PTV_API_BASE = 'https://api.myptv.com'; - -// CORS Headers für alle Responses -const corsHeaders = { - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS', - 'Access-Control-Allow-Headers': 'Content-Type, Authorization', - 'Content-Type': 'application/json', -}; - -const server = http.createServer((req, res) => { - console.log(`📨 ${req.method} ${req.url}`); - - // Health check endpoint - if (req.url === '/health') { - res.writeHead(200, { 'Content-Type': 'text/plain' }); - res.end('healthy'); - return; - } - - // Handle preflight requests - if (req.method === 'OPTIONS') { - res.writeHead(200, corsHeaders); - res.end(); - return; - } - - // Nur GET Requests erlauben - if (req.method !== 'GET') { - res.writeHead(405, corsHeaders); - res.end(JSON.stringify({ error: 'Method not allowed' })); - return; - } - - // Parse URL - const parsedUrl = url.parse(req.url, true); - const { lat, lon, apiKey } = parsedUrl.query; - - // Validierung - if (!lat || !lon || !apiKey) { - res.writeHead(400, corsHeaders); - res.end(JSON.stringify({ - error: 'Missing parameters: lat, lon, apiKey are required', - })); - return; - } - - // PTV API URL erstellen - const ptvUrl = `${PTV_API_BASE}/geocoding/v1/locations/by-position/${lat}/${lon}?language=de&apiKey=${apiKey}`; - - console.log(`🔄 Weiterleitung an: ${ptvUrl.replace(apiKey, 'API_KEY_HIDDEN')}`); - - // Request an PTV API - https.get(ptvUrl, (ptvRes) => { - let data = ''; - - ptvRes.on('data', (chunk) => { - data += chunk; - }); - - ptvRes.on('end', () => { - try { - const jsonData = JSON.parse(data); - - // Erfolgreiche Response - if (ptvRes.statusCode === 200) { - console.log('✅ PTV API Response erfolgreich'); - - // Adresse extrahieren - if (jsonData.locations && jsonData.locations.length > 0) { - const location = jsonData.locations[0]; - if (location.address) { - const address = location.address; - const street = address.street || ''; - const houseNumber = address.houseNumber || ''; - const postalCode = address.postalCode || ''; - const city = address.city || ''; - - const formattedAddress = `${street} ${houseNumber}, ${postalCode} ${city}`.trim(); - - const response = { - success: true, - location: formattedAddress, - coordinates: { - lat: parseFloat(lat), - lon: parseFloat(lon), - }, - rawData: location, - }; - - console.log(`📍 Adresse: ${formattedAddress}`); - res.writeHead(200, corsHeaders); - res.end(JSON.stringify(response)); - return; - } - } - - // Fallback auf Koordinaten - const response = { - success: true, - location: `Lat: ${parseFloat(lat).toFixed(6)}, Lon: ${parseFloat(lon).toFixed(6)}`, - coordinates: { - lat: parseFloat(lat), - lon: parseFloat(lon), - }, - }; - - res.writeHead(200, corsHeaders); - res.end(JSON.stringify(response)); - } else { - // Fehler von PTV API - console.log(`❌ PTV API Fehler: ${ptvRes.statusCode}`); - res.writeHead(ptvRes.statusCode, corsHeaders); - res.end(JSON.stringify({ - success: false, - error: `PTV API Error: ${ptvRes.statusCode}`, - fallbackLocation: `Lat: ${parseFloat(lat).toFixed(6)}, Lon: ${parseFloat(lon).toFixed(6)}`, - })); - } - } catch (error) { - console.error('❌ JSON Parse Fehler:', error.message); - res.writeHead(500, corsHeaders); - res.end(JSON.stringify({ - success: false, - error: 'Failed to parse PTV API response', - fallbackLocation: `Lat: ${parseFloat(lat).toFixed(6)}, Lon: ${parseFloat(lon).toFixed(6)}`, - })); - } - }); - }).on('error', (error) => { - console.error('❌ Request Fehler:', error.message); - res.writeHead(500, corsHeaders); - res.end(JSON.stringify({ - success: false, - error: error.message, - fallbackLocation: `Lat: ${parseFloat(lat).toFixed(6)}, Lon: ${parseFloat(lon).toFixed(6)}`, - })); - }); -}); - -server.listen(PORT, () => { - console.log('═══════════════════════════════════════════════════════'); - console.log('🚀 Lokaler Reverse Proxy Server gestartet!'); - console.log(`📡 Läuft auf: http://localhost:${PORT}`); - console.log(''); - console.log('📌 Verwendung:'); - console.log(` http://localhost:${PORT}/?lat=47.9385&lon=13.7629&apiKey=YOUR_KEY`); - console.log(''); - console.log('⚠️ Hinweis: Nur für Entwicklung verwenden!'); - console.log(' Für Produktion: Appwrite Function deployen'); - console.log('═══════════════════════════════════════════════════════'); - console.log(''); - console.log('💡 Zum Beenden: Strg+C drücken'); - console.log(''); -}); - -// Graceful shutdown -process.on('SIGINT', () => { - console.log('\n\n👋 Server wird beendet...'); - server.close(() => { - console.log('✅ Server erfolgreich gestoppt'); - process.exit(0); - }); -}); diff --git a/start-proxy.sh b/start-proxy.sh deleted file mode 100755 index c38e6a5..0000000 --- a/start-proxy.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash - -# Farben für Output -GREEN='\033[0;32m' -BLUE='\033[0;34m' -YELLOW='\033[1;33m' -NC='\033[0m' # No Color - -echo -e "${BLUE}═══════════════════════════════════════════════════════${NC}" -echo -e "${BLUE} Flutter Tank App - Lokaler Proxy Starter${NC}" -echo -e "${BLUE}═══════════════════════════════════════════════════════${NC}" -echo "" - -# Proxy Server starten -echo -e "${YELLOW}🚀 Starte lokalen Reverse Proxy Server...${NC}" -cd "$(dirname "$0")/proxy-server" - -if [ ! -f "server.js" ]; then - echo -e "${YELLOW}❌ server.js nicht gefunden!${NC}" - echo -e "${YELLOW}Bitte führen Sie dieses Script aus dem Projekt-Root-Verzeichnis aus.${NC}" - exit 1 -fi - -echo -e "${GREEN}✅ Proxy Server wird gestartet auf http://localhost:3000${NC}" -echo "" -echo -e "${BLUE}📌 Nächste Schritte:${NC}" -echo -e " 1. In neuem Terminal: ${GREEN}flutter run -d chrome${NC}" -echo -e " 2. Neuen Tankeintrag erstellen" -echo -e " 3. Standort wird automatisch über Proxy abgerufen" -echo "" -echo -e "${YELLOW}⚠️ Zum Beenden: Strg+C drücken${NC}" -echo "" -echo -e "${BLUE}═══════════════════════════════════════════════════════${NC}" -echo "" - -node server.js diff --git a/webserver/flutter_bootstrap.js b/webserver/flutter_bootstrap.js index ffe7482..6d3afbd 100644 --- a/webserver/flutter_bootstrap.js +++ b/webserver/flutter_bootstrap.js @@ -37,6 +37,6 @@ _flutter.buildConfig = {"engineRevision":"3452d735bd38224ef2db85ca763d862d6326b1 _flutter.loader.load({ serviceWorkerSettings: { - serviceWorkerVersion: "138245282" /* Flutter's service worker is deprecated and will be removed in a future Flutter release. */ + serviceWorkerVersion: "38490492" /* Flutter's service worker is deprecated and will be removed in a future Flutter release. */ } });