# DÜSK - Flutter Cross-Platform App **DÜSK** ist eine professionelle Cross-Platform Anwendung zur Erfassung und Auswertung von Selbst- und Fremdeinschätzungen von Schülerkompetenzen. Die App wurde mit **Flutter** entwickelt und läuft auf **6 Plattformen** mit einer einzigen Codebasis. --- ## 📋 Inhaltsverzeichnis - [Überblick](#-überblick) - [Features](#-features) - [Unterstützte Plattformen](#-unterstützte-plattformen) - [Technologie-Stack](#-technologie-stack) - [Screenshots](#-screenshots) - [API-Dokumentation](#-api-dokumentation) - [Datenbankstruktur](#-datenbankstruktur) - [Installation](#-installation) - [Projektstruktur](#-projektstruktur) - [Berechnungslogik](#-berechnungslogik) - [Konfiguration](#-konfiguration) - [Build & Deployment](#-build--deployment) - [Fehlerbehandlung](#-fehlerbehandlung) - [Entwicklung](#-entwicklung) --- ## 🎯 Überblick DÜSK (Düsseldorfer Schülerinventar) ist ein diagnostisches Instrument zur Erfassung von Schülerkompetenzen in sechs Bereichen: | Bereich | Beschreibung | |---------|--------------| | 1. **Arbeitsverhalten** | Zuverlässigkeit, Arbeitstempo, Planung, Organisation | | 2. **Lernverhalten** | Selbstständigkeit, Belastbarkeit, Konzentration, Merkfähigkeit | | 3. **Sozialverhalten** | Teamfähigkeit, Hilfsbereitschaft, Kommunikation, Konfliktfähigkeit | | 4. **Fachkompetenz** | Schreiben, Lesen, Mathematik, Naturwissenschaften, Fremdsprachen | | 5. **Personale Kompetenz** | Kreativität, Problemlösung, Abstraktion, Reflexion | | 6. **Methodenkompetenz** | Präsentation, PC-Kenntnisse, fächerübergreifendes Denken | Die Anwendung ermöglicht den Vergleich von **Selbsteinschätzung (SE)** und **Fremdeinschätzung (FE)** mit Normtabellen für Hauptschulen (HS) und Förderschulen (FS). --- ## ✨ Features ### Kernfunktionen - ✅ **Login/Logout** mit Session-Verwaltung und persistenter Authentifizierung - ✅ **CRUD-Operationen** für Schülerprofile (Erstellen, Lesen, Aktualisieren, Löschen) - ✅ **36 Items** pro Einschätzung (4-stufige Likert-Skala: 1-4) - ✅ **Automatische Kompetenzberechnung** aus 72 Items - ✅ **Normwertvergleich** (HS/FS Normtabellen) - ✅ **Profilansicht** mit Tabellen, interaktiven Diagrammen und Textinterpretation ### Erweiterte Funktionen - 📊 **Zeitreihenanalyse** für Gruppenentwicklung über Zeit - 📈 **Vergleichsdiagramme** (SE vs. FE mit Pearson-Korrelation) - 📐 **Korrelationsberechnung** mit statistischer Interpretation - 📑 **Exportfunktion** (Teilen als Text/PDF) - 🔍 **Such- und Filterfunktionen** (nach Namen und Gruppen) - 📁 **Gruppenverwaltung** (CRUD mit Umbenennung) - 🌙 **Dark Mode Support** (automatisch) - 💾 **Offline-Cache** (SharedPreferences für Sessions) - 📱 **Responsive Design** für alle Bildschirmgrößen - 🖥️ **Desktop-Unterstützung** (Windows, macOS, Linux) --- ## 💻 Unterstützte Plattformen | Plattform | Status | Mindestversion | |-----------|--------|----------------| | **iOS** | ✅ Vollständig | iOS 12.0 | | **Android** | ✅ Vollständig | Android 5.0 (API 21) | | **Web** | ✅ Vollständig | Alle modernen Browser | | **Windows** | ✅ Vollständig | Windows 10 | | **macOS** | ✅ Vollständig | macOS 10.15 | | **Linux** | ✅ Vollständig | Ubuntu 20.04+ | --- ## 🛠 Technologie-Stack ### Flutter App | Komponente | Technologie | Version | |------------|-------------|---------| | Framework | Flutter | 3.16+ | | Sprache | Dart | 3.0+ | | State Management | Provider | 6.0.5 | | HTTP-Client | http | 1.1.0 | | Charts | FL Chart | 0.66.0 | | Persistenz | SharedPreferences | 2.2.2 | | Dateipfade | path_provider | 2.1.1 | | Sharing | share_plus | 7.2.1 | | Splash Screen | flutter_native_splash | 2.3.5 | | Launcher Icons | flutter_launcher_icons | 0.13.1 | ### Server (PHP API) | Komponente | Technologie | |------------|-------------| | Backend | PHP 7.4+ | | Datenbank | MySQL 5.7+ | | Webserver | Apache/Nginx | | Format | JSON | --- ## 📡 API-Dokumentation Die REST-API ist unter `https://paul-koop.org/api/` verfügbar. ### Authentifizierung #### POST `/api_login.php` ```json // Request { "username": "gast", "password": "gast" } // Response (Success) { "success": true, "userID": "12345", "session": "abc123def456789" } // Response (Error) { "success": false, "error": "Invalid credentials" } ``` ### Profile-Endpunkte > **Wichtig:** Alle Profile-Endpunkte benötigen die Header: > - `X-User-ID`: Benutzer-ID aus Login > - `X-Session`: Session-Token aus Login #### GET `/api_profiles.php` **Response**: Array aller Profile des Benutzers ```json [ { "profilID": "1", "name": "Max Mustermann", "gruppename": "Klasse 8a", "gruppeID": "5", "created_at": "2024-01-15 10:30:00", "item1": 4, "item2": 3, ..., "item36": 2, "feitem1": 3, "feitem2": 4, ..., "feitem36": 3 } ] ``` #### GET `/api_profiles.php?id={profileId}` **Response**: Einzelnes Profil #### POST `/api_profiles.php` **Request Body**: Vollständiges Profil-Objekt (alle 72 Items) **Response**: `200 OK` bei Erfolg #### PUT `/api_profiles.php` **Request Body**: Aktualisiertes Profil-Objekt **Response**: `200 OK` bei Erfolg #### DELETE `/api_profiles.php?id={profileId}` **Response**: `200 OK` bei Erfolg ### Gruppen-Endpunkte #### GET `/api_groups.php` **Response**: ```json [ {"gruppeID": 1, "name": "Klasse 8a"}, {"gruppeID": 2, "name": "Klasse 8b"}, {"gruppeID": 3, "name": "Klasse 9a"} ] ``` #### POST `/api_groups.php` **Request Body**: `{"name": "Neue Gruppe"}` **Response**: `200 OK` bei Erfolg #### DELETE `/api_groups.php?id={groupId}` **Response**: `200 OK` bei Erfolg --- ## 🗄 Datenbankstruktur ### ER-Diagramm ``` ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ users │ │ groups │ │ profiles │ ├─────────────┤ ├─────────────┤ ├─────────────┤ │ userID (PK) │────<│ userID (FK) │ │ profilID(PK)│ │ username │ │ gruppeID(PK)│<────│ userID (FK) │ │ password │ │ name │ │ gruppeID(FK)│ │ session │ │ created_at │ │ name │ │ created_at │ └─────────────┘ │ item1-36 │ └─────────────┘ │ feitem1-36 │ │ created_at │ │ updated_at │ └─────────────┘ ``` ### SQL-Schema ```sql -- Users Tabelle CREATE TABLE users ( userID INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) UNIQUE NOT NULL, password_hash VARCHAR(255) NOT NULL, session_token VARCHAR(255), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- Groups Tabelle CREATE TABLE groups ( gruppeID INT AUTO_INCREMENT PRIMARY KEY, userID INT NOT NULL, name VARCHAR(255) NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (userID) REFERENCES users(userID) ON DELETE CASCADE, UNIQUE KEY unique_group_per_user (userID, name) ); -- Profiles Tabelle CREATE TABLE profiles ( profilID INT AUTO_INCREMENT PRIMARY KEY, userID INT NOT NULL, name VARCHAR(255) NOT NULL, gruppeID INT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 36 SE-Items (Werte 1-4) item1 TINYINT DEFAULT 2, item2 TINYINT DEFAULT 2, ..., item36 TINYINT DEFAULT 2, -- 36 FE-Items (Werte 1-4) feitem1 TINYINT DEFAULT 2, feitem2 TINYINT DEFAULT 2, ..., feitem36 TINYINT DEFAULT 2, FOREIGN KEY (userID) REFERENCES users(userID) ON DELETE CASCADE, FOREIGN KEY (gruppeID) REFERENCES groups(gruppeID) ON DELETE SET NULL ); ``` --- ## 💻 Installation ### Voraussetzungen - **Flutter SDK** 3.16+ ([Installation](https://docs.flutter.dev/get-started/install)) - **Dart SDK** 3.0+ (wird mit Flutter installiert) - **Für iOS:** Xcode 14+ (nur macOS) - **Für Android:** Android Studio mit SDK - **Für Windows:** Visual Studio 2022 mit C++ Desktop-Entwicklung - **Für macOS:** Xcode 14+ - **Für Linux:** clang, cmake, ninja-build - **Für Web:** Chrome für Debugging ### Schritt-für-Schritt Installation ```bash # 1. Repository klonen git clone https://github.com/yourusername/duesk-flutter.git cd duesk-flutter # 2. Abhängigkeiten installieren flutter pub get # 3. Plattformspezifische Setup (optional) # Für iOS: cd ios && pod install && cd .. # Für Windows: flutter config --enable-windows-desktop # Für macOS: flutter config --enable-macos-desktop # Für Linux: flutter config --enable-linux-desktop # 4. App starten flutter run -d windows # Windows Desktop flutter run -d macos # macOS Desktop flutter run -d linux # Linux Desktop flutter run -d chrome # Web flutter run -d android # Android flutter run -d ios # iOS (nur macOS) ``` ### Schnellstart mit der Batch-Datei (Windows) ```batch # Projektstruktur erstellen create_flutter_project.bat # In das Projekt wechseln cd duesk_flutter # Abhängigkeiten installieren flutter pub get # App starten flutter run -d windows ``` --- ## 📁 Projektstruktur ``` duesk_flutter/ ├── lib/ │ ├── main.dart # App-Einstiegspunkt │ ├── models/ │ │ ├── profile.dart # Profil Datenmodell │ │ ├── group.dart # Gruppen Datenmodell │ │ └── norms.dart # Normtabellen & Konstanten │ ├── services/ │ │ ├── session_manager.dart # Session & Auth │ │ ├── api_service.dart # Netzwerk-API Calls │ │ └── calculator.dart # Berechnungslogik │ ├── screens/ │ │ ├── login_screen.dart # Login-Screen │ │ ├── main_screen.dart # Hauptansicht mit Sidebar │ │ ├── profile_detail_screen.dart # Profildetails mit Charts │ │ ├── profile_edit_screen.dart # Profil bearbeiten/erstellen │ │ ├── group_manager_screen.dart # Gruppenverwaltung │ │ └── time_series_screen.dart # Zeitreihenanalyse │ └── widgets/ │ ├── competence_table.dart # X-Markierungstabelle │ ├── competence_chart.dart # Liniendiagramm │ ├── profile_card.dart # Profilkarte für Liste │ ├── loading_spinner.dart # Ladezustandsanzeige │ └── item_rating_card.dart # Item-Bewertungskarte ├── assets/ # Bilder, Fonts, Icons ├── android/ # Android native Code ├── ios/ # iOS native Code ├── windows/ # Windows native Code ├── macos/ # macOS native Code ├── linux/ # Linux native Code ├── web/ # Web native Code ├── pubspec.yaml # Abhängigkeiten └── README.md ``` --- ## 🧮 Berechnungslogik ### Item-zu-Kompetenz-Zuordnung ```dart // Kompetenz 1: Arbeitsverhalten (Items 1-10) for (int i = 0; i < 10; i++) sums[1] += items[i]; // Kompetenz 2: Lernverhalten (Items 11-20) for (int i = 10; i < 20; i++) sums[2] += items[i]; // Kompetenz 3: Sozialverhalten (Items 21-28 + Items 9-10) for (int i = 20; i < 28; i++) sums[3] += items[i]; sums[3] += items[8] + items[9]; // Kompetenz 4: Fachkompetenz (Items 29-36) for (int i = 28; i < 36; i++) sums[4] += items[i]; // Kompetenz 5: Personale Kompetenz (spezifische Items) sums[5] = items[0] + items[1] + items[5] + items[6] + items[7] + items[8] + items[9] + items[11] + items[12] + items[13] + items[14]; // Kompetenz 6: Methodenkompetenz (spezifische Items) sums[6] = items[2] + items[3] + items[4] + items[8] + items[9] + items[10] + items[16] + items[17]; ``` ### Profilwertberechnung ```dart int calculateProfileValue(int rawSum, List normTable) { // 1 = weit unterdurchschnittlich // 2 = unterdurchschnittlich // 3 = durchschnittlich // 4 = überdurchschnittlich // 5 = weit überdurchschnittlich for (int i = 0; i < normTable.length; i++) { if (rawSum < normTable[i]) { return i + 1; } } return 5; } ``` ### Korrelationsberechnung (Pearson) ```dart double pearsonCorrelation(List seValues, List feValues) { final n = seValues.length; double sumSE = 0, sumFE = 0, sumSEFE = 0, sumSE2 = 0, sumFE2 = 0; for (int i = 0; i < n; i++) { sumSE += seValues[i]; sumFE += feValues[i]; sumSEFE += seValues[i] * feValues[i]; sumSE2 += seValues[i] * seValues[i]; sumFE2 += feValues[i] * feValues[i]; } final numerator = n * sumSEFE - sumSE * sumFE; final denominator = sqrt((n * sumSE2 - sumSE * sumSE) * (n * sumFE2 - sumFE * sumFE)); return denominator == 0 ? 0 : numerator / denominator; } ``` ### Normtabellen (Vollständig) | Kompetenz | HS SE Grenzwerte | HS FE Grenzwerte | |-----------|------------------|------------------| | Arbeitsverhalten | 21.33, 25.33, 29.33, 33.32, 37.32 | 12.66, 18.16, 23.66, 29.16, 34.66 | | Lernverhalten | 20.87, 24.95, 29.03, 33.13, 37.18 | 13.33, 18.42, 23.51, 28.60, 33.69 | | Sozialverhalten | 17.93, 21.37, 24.80, 28.23, 31.67 | 10.75, 15.41, 20.07, 24.73, 29.39 | | Fachkompetenz | 13.98, 17.71, 21.44, 25.17, 28.90 | 14.22, 15.30, 16.38, 17.46, 18.54 | | Personale Kompetenz | 24.60, 28.55, 33.04, 37.53, 42.01 | 14.12, 20.21, 26.30, 32.39, 38.48 | | Methodenkompetenz | 15.53, 18.97, 22.40, 25.83, 29.27 | 10.53, 14.51, 18.49, 22.47, 26.45 | *Für FS (Förderschule) existieren separate Normtabellen.* --- ## ⚙️ Konfiguration ### API Base URL ändern ```dart // lib/services/api_service.dart static const String baseUrl = 'https://your-server.com/api/'; ``` ### Umgebungsvariablen (optional) ```dart // lib/utils/env.dart class Env { static const String apiUrl = String.fromEnvironment( 'API_URL', defaultValue: 'https://paul-koop.org/api/' ); static const bool debugMode = bool.fromEnvironment( 'DEBUG_MODE', defaultValue: false ); } ``` ### App Icons und Splash Screen ```bash # Icons generieren flutter pub run flutter_launcher_icons:main # Splash Screen generieren flutter pub run flutter_native_splash:create ``` --- ## 🚀 Build & Deployment ### Plattformspezifische Builds ```bash # Android APK flutter build apk --release # Android App Bundle (Google Play) flutter build appbundle --release # iOS IPA (nur macOS) flutter build ios --release # Web flutter build web --release # Windows flutter build windows --release # macOS flutter build macos --release # Linux flutter build linux --release ``` ### Release-Konfiguration ```yaml # pubspec.yaml - Versionierung version: 1.0.0+1 # Android: android/app/build.gradle defaultConfig { applicationId "com.duesk.flutter" minSdkVersion 21 targetSdkVersion 33 versionCode 1 versionName "1.0.0" } # iOS: ios/Runner.xcodeproj # Minimum Deployment Target: 12.0 ``` --- ## 🐛 Fehlerbehandlung ### HTTP-Statuscodes | Code | Bedeutung | Behandlung | |------|-----------|------------| | 200 | Erfolg | Daten verarbeiten | | 400 | Bad Request | Validierungsfehler prüfen | | 401 | Unauthorized | Neu anmelden | | 403 | Forbidden | Berechtigung prüfen | | 404 | Not Found | Ressource existiert nicht | | 500 | Server Error | Erneut versuchen, Support kontaktieren | ### Typische Fehler und Lösungen ```dart try { final profiles = await apiService.getProfiles(); } catch (e) { if (e is http.ClientException) { _showError('Keine Internetverbindung'); } else if (e is TimeoutException) { _showError('Verbindung zeitüberschritten'); } else { _showError('Netzwerkfehler: $e'); } } ``` --- ## 👨‍💻 Entwicklung ### Hot Reload / Hot Restart ```bash # Hot Reload (Erhält den Zustand) r # Hot Restart (Setzt den Zustand zurück) R # Debugging öffnen d ``` ### Testing ```bash # Unit Tests ausführen flutter test # Widget Tests flutter test --tags=widget # Integration Tests flutter test integration_test/ ``` ### Code Generation ```bash # Code Generator ausführen flutter pub run build_runner build # Watch-Modus für automatische Generierung flutter pub run build_runner watch ``` ### Linting ```bash # Analyse durchführen flutter analyze # Automatische Korrekturen dart fix --apply ``` --- ## 🔄 Vergleich der Implementierungen | Feature | Flutter | React Native | Swift (iOS) | Java (Swing) | |---------|---------|--------------|-------------|--------------| | Plattformen | 6 | 2 | 1 | 3 | | Code-Wiederverwendung | 95% | 70% | - | - | | Performance | Sehr gut | Gut | Exzellent | Exzellent | | Lernkurve | Mittel | Gering | Hoch | Mittel | | Charts | FL Chart | React Native Chart Kit | Swift Charts | JFreeChart | | State Management | Provider | Context/Hooks | SwiftUI | MVC | --- ## 📄 Lizenz Dieses Projekt ist unter der MIT-Lizenz lizenziert. Siehe [LICENSE](LICENSE) Datei für Details.