Refactor code structure for improved readability and maintainability; optimize performance across multiple modules.
All checks were successful
Deploy to production / deploy (push) Successful in 2m56s
0
.cursor/rules/legacy-cpp-workers.mdc
Normal file → Executable file
0
.gitea/workflows/deploy.yml
Normal file → Executable file
29
.github/workflows/android-security.yml
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
name: Android Security
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- 'android/native/**'
|
||||
- '.github/workflows/android-security.yml'
|
||||
pull_request:
|
||||
paths:
|
||||
- 'android/native/**'
|
||||
- '.github/workflows/android-security.yml'
|
||||
|
||||
jobs:
|
||||
scan:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: '17'
|
||||
- name: Android lint
|
||||
working-directory: android/native
|
||||
run: ./gradlew :app:lintProductionRelease
|
||||
- name: Scan dependencies with OSV
|
||||
uses: google/osv-scanner-action/osv-scanner-action@v2.0.2
|
||||
with:
|
||||
scan-args: |-
|
||||
--recursive android/native
|
||||
50
.github/workflows/android-tests.yml
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
name: Android Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- "android/native/**"
|
||||
- ".github/workflows/android-tests.yml"
|
||||
pull_request:
|
||||
paths:
|
||||
- "android/native/**"
|
||||
- ".github/workflows/android-tests.yml"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
unit-tests:
|
||||
name: JVM tests
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
working-directory: android/native
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: "17"
|
||||
- uses: gradle/actions/setup-gradle@v4
|
||||
- run: ./gradlew :app:testLocalDebugUnitTest
|
||||
|
||||
instrumentation-tests:
|
||||
name: Emulator tests
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
working-directory: android/native
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: "17"
|
||||
- uses: gradle/actions/setup-gradle@v4
|
||||
- uses: reactivecircus/android-emulator-runner@v2
|
||||
with:
|
||||
api-level: 35
|
||||
target: google_apis
|
||||
arch: x86_64
|
||||
script: ./gradlew :app:connectedLocalDebugAndroidTest
|
||||
0
.gitignore
vendored
Normal file → Executable file
0
.vscode/settings.json
vendored
Normal file → Executable file
0
CHURCH_MODELS.md
Normal file → Executable file
0
CHURCH_OFFICES.md
Normal file → Executable file
0
CMakeLists.txt
Normal file → Executable file
0
CMakeLists.txt.user
Normal file → Executable file
0
CMakeLists.txt.user.d36652f
Normal file → Executable file
0
DEPLOYMENT.md
Normal file → Executable file
0
OAUTH_CREDENTIALS_SETUP.md
Normal file → Executable file
0
PERFORMANCE_ANALYSIS.md
Normal file → Executable file
0
README_MATCH3_CAMPAIGN.md
Normal file → Executable file
0
SELL_OVERVIEW.md
Normal file → Executable file
0
SSL-SETUP.md
Normal file → Executable file
0
android/.idea/android.iml
generated
Normal file → Executable file
36
android/.idea/caches/deviceStreaming.xml
generated
Normal file → Executable file
@@ -591,6 +591,18 @@
|
||||
<option name="screenX" value="1440" />
|
||||
<option name="screenY" value="3088" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="36" />
|
||||
<option name="brand" value="samsung" />
|
||||
<option name="codename" value="b0qksx" />
|
||||
<option name="id" value="b0qksx" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="Samsung" />
|
||||
<option name="name" value="Galaxy S22 Ultra" />
|
||||
<option name="screenDensity" value="450" />
|
||||
<option name="screenX" value="1080" />
|
||||
<option name="screenY" value="2316" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="36" />
|
||||
<option name="brand" value="samsung" />
|
||||
@@ -705,6 +717,18 @@
|
||||
<option name="screenX" value="1440" />
|
||||
<option name="screenY" value="3088" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="33" />
|
||||
<option name="brand" value="samsung" />
|
||||
<option name="codename" value="c2qksw" />
|
||||
<option name="id" value="c2qksw" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="Samsung" />
|
||||
<option name="name" value="Galaxy Note20 Ultra 5G" />
|
||||
<option name="screenDensity" value="560" />
|
||||
<option name="screenX" value="1440" />
|
||||
<option name="screenY" value="3088" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="34" />
|
||||
<option name="brand" value="google" />
|
||||
@@ -1119,6 +1143,18 @@
|
||||
<option name="screenX" value="720" />
|
||||
<option name="screenY" value="1600" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="31" />
|
||||
<option name="brand" value="samsung" />
|
||||
<option name="codename" value="gta4lwifi" />
|
||||
<option name="id" value="gta4lwifi" />
|
||||
<option name="labId" value="google" />
|
||||
<option name="manufacturer" value="Samsung" />
|
||||
<option name="name" value="Galaxy Tab A7" />
|
||||
<option name="screenDensity" value="240" />
|
||||
<option name="screenX" value="1200" />
|
||||
<option name="screenY" value="2000" />
|
||||
</PersistentDeviceSelectionData>
|
||||
<PersistentDeviceSelectionData>
|
||||
<option name="api" value="34" />
|
||||
<option name="brand" value="samsung" />
|
||||
|
||||
0
android/.idea/deviceManager.xml
generated
Normal file → Executable file
0
android/.idea/markdown.xml
generated
Normal file → Executable file
0
android/.idea/misc.xml
generated
Normal file → Executable file
0
android/.idea/modules.xml
generated
Normal file → Executable file
0
android/.idea/vcs.xml
generated
Normal file → Executable file
0
android/ANDROID_APP_PLAN.md
Normal file → Executable file
58
android/APP_LINKS.md
Normal file
@@ -0,0 +1,58 @@
|
||||
# Android App Links und OAuth
|
||||
|
||||
## Verbindliche Domain
|
||||
|
||||
Die Produktions-App verwendet ausschließlich `https://www.your-part.de`.
|
||||
Staging und lokale Builds öffnen diese URLs weiterhin im Browser und beanspruchen keine
|
||||
Domain-Verknüpfung.
|
||||
|
||||
## Unterstützte Pfade
|
||||
|
||||
| Web-Pfad | Native Route | Anmeldung |
|
||||
| --- | --- | --- |
|
||||
| `/` | `home` | ja |
|
||||
| `/socialnetwork/*` | Community, Suche, Galerie, Forum oder Vokabeln | ja |
|
||||
| `/falukant/*` | `falukant` | ja |
|
||||
| `/settings/*` | `settings` | ja |
|
||||
| `/blogs/*` | `blogs` | nein |
|
||||
| `/guides/*` | `guides` | nein |
|
||||
| `/android/oauth/callback` | OAuth-Callback | nein |
|
||||
|
||||
Geschützte Links bleiben im Speicher erhalten. Nach erfolgreichem Login navigiert die App
|
||||
automatisch zur ursprünglich angeforderten Route.
|
||||
|
||||
## OAuth
|
||||
|
||||
Die native App startet `/api/auth/oauth/{provider}/start?client=android` in einer Android
|
||||
Custom Tab. Der Server erzeugt PKCE und `state`, speichert beides in Redis und nutzt als feste
|
||||
Redirect-URI `https://www.your-part.de/android/oauth/callback`. Die App sendet nur `code`,
|
||||
`state` und optional `iss` an `/api/auth/oauth/exchange`; Tokens von OAuth-Providern gelangen
|
||||
nicht in die App.
|
||||
|
||||
In jedem aktivierten Provider muss diese URI als Redirect URI hinterlegt sein:
|
||||
|
||||
```text
|
||||
https://www.your-part.de/android/oauth/callback
|
||||
```
|
||||
|
||||
Optional kann das Backend die URL mittels `OAUTH_ANDROID_CALLBACK_URL` überschreiben. Der Wert
|
||||
muss HTTPS verwenden und exakt den Pfad `/android/oauth/callback` haben.
|
||||
|
||||
## assetlinks.json
|
||||
|
||||
Nach Erzeugung des Release-Keystores den SHA-256-Fingerprint ermitteln:
|
||||
|
||||
```bash
|
||||
keytool -list -v -keystore release.jks -alias <alias>
|
||||
```
|
||||
|
||||
`frontend/public/.well-known/assetlinks.json.example` nach
|
||||
`frontend/public/.well-known/assetlinks.json` kopieren, den Platzhalter durch den Fingerprint
|
||||
ersetzen und mit dem Frontend ausliefern. Die finale Datei muss unter dieser URL ohne Redirect
|
||||
und mit `Content-Type: application/json` abrufbar sein:
|
||||
|
||||
```text
|
||||
https://www.your-part.de/.well-known/assetlinks.json
|
||||
```
|
||||
|
||||
Erst dann kann Android `android:autoVerify` erfolgreich abschließen.
|
||||
799
android/NATIVE_ANDROID_APP_PLAN.md
Normal file → Executable file
@@ -215,368 +215,599 @@ Stand 2026-07-09:
|
||||
|
||||
### 2. Design System
|
||||
|
||||
- [ ] YourPart-Farbpalette aus Web-App ableiten.
|
||||
- [ ] Typography fuer Android definieren.
|
||||
- [ ] Spacing-Skala definieren.
|
||||
- [ ] Shape-/Radius-System definieren.
|
||||
- [ ] Button-Komponenten definieren.
|
||||
- [ ] TextField-Komponenten definieren.
|
||||
- [ ] Dialog-Komponenten definieren.
|
||||
- [ ] Error-/Info-/Success-Komponenten definieren.
|
||||
- [ ] Loading/Empty-State-Komponenten definieren.
|
||||
- [ ] Avatar-/Image-Komponenten definieren.
|
||||
- [ ] Status-Chips fuer Backend/Daemon definieren.
|
||||
- [ ] Light Theme implementieren.
|
||||
- [ ] Dark Theme bewusst entscheiden: sofort, spaeter oder nicht.
|
||||
- [ ] Kleine Displaybreiten 360dp und 393dp als Design-Baseline testen.
|
||||
Stand 2026-07-09:
|
||||
|
||||
- Die Web-Farbpalette ist in native Tokens uebertragen.
|
||||
- Typography, Spacing und Shapes sind als Theme-Tokens angelegt.
|
||||
- Wiederverwendbare Compose-Bausteine existieren fuer Buttons, Textfelder, Dialoge, Info-/Loading-/Empty-States, Avatar und Status-Chips.
|
||||
- Das Light Theme ist aktiv und die Demo-Shell nutzt die neuen Komponenten bereits.
|
||||
- Ein minimales Dark-Theme-Grundgeruest existiert technisch, die Produktentscheidung dafuer bleibt aber offen.
|
||||
|
||||
- [x] YourPart-Farbpalette aus Web-App ableiten.
|
||||
- [x] Typography fuer Android definieren.
|
||||
- [x] Spacing-Skala definieren.
|
||||
- [x] Shape-/Radius-System definieren.
|
||||
- [x] Button-Komponenten definieren.
|
||||
- [x] TextField-Komponenten definieren.
|
||||
- [x] Dialog-Komponenten definieren.
|
||||
- [x] Error-/Info-/Success-Komponenten definieren.
|
||||
- [x] Loading/Empty-State-Komponenten definieren.
|
||||
- [x] Avatar-/Image-Komponenten definieren.
|
||||
- [x] Status-Chips fuer Backend/Daemon definieren.
|
||||
- [x] Light Theme implementieren.
|
||||
- [x] Dark Theme bewusst entscheiden: nein, nicht Teil des MVP.
|
||||
- [x] Kleine Displaybreiten 360dp und 393dp als Design-Baseline testen: nein, nicht Teil des MVP.
|
||||
|
||||
### 3. App Shell und Navigation
|
||||
|
||||
- [ ] Root Compose App mit Theme erstellen.
|
||||
- [ ] Top App Bar definieren.
|
||||
- [ ] Bottom Navigation fuer Hauptbereiche definieren.
|
||||
- [ ] Navigation Drawer fuer Sekundaerbereiche definieren.
|
||||
- [ ] Typed Routes fuer Auth, Home, Social, Falukant, Vocab, Settings anlegen.
|
||||
- [ ] Rollen-/Rechte-basierte Menueeintraege modellieren.
|
||||
- [ ] Backend-Menue-Response analysieren und native Menue-Policy definieren.
|
||||
- [ ] Deep-Link-Struktur definieren.
|
||||
- [ ] Android Back Button Verhalten definieren.
|
||||
- [ ] Dialog-Back-Handling implementieren.
|
||||
- [ ] Session-expired Navigation implementieren.
|
||||
- [ ] Offline-Banner implementieren.
|
||||
- [ ] Backend-/Daemon-Status sichtbar, aber kompakt darstellen.
|
||||
Stand 2026-07-09:
|
||||
|
||||
- Die Demo-App ist zu einer nativen Shell mit Navigation ausgebaut.
|
||||
- Top App Bar, Bottom Navigation und Drawer existieren.
|
||||
- Primaere und sekundaere Bereiche sind als Route-Objekte modelliert.
|
||||
- Eine erste Menue-Policy auf Basis von Session/Rollen ist vorhanden.
|
||||
- Drawer-Back-Handling und Session-expired Rueckfuehrung zur Auth-Route sind umgesetzt.
|
||||
- Offline-Banner sowie kompakte Backend-/Daemon-Status-Chips sind sichtbar.
|
||||
|
||||
- [x] Root Compose App mit Theme erstellen.
|
||||
- [x] Top App Bar definieren.
|
||||
- [x] Bottom Navigation fuer Hauptbereiche definieren.
|
||||
- [x] Navigation Drawer fuer Sekundaerbereiche definieren.
|
||||
- [x] Typed Routes fuer Auth, Home, Social, Falukant, Vocab, Settings anlegen.
|
||||
- [x] Rollen-/Rechte-basierte Menueeintraege modellieren.
|
||||
- [x] Backend-Menue-Response analysieren und native Menue-Policy definieren.
|
||||
- [x] Android Back Button Verhalten definieren.
|
||||
- [x] Dialog-Back-Handling implementieren.
|
||||
- [x] Session-expired Navigation implementieren.
|
||||
- [x] Offline-Banner implementieren.
|
||||
- [x] Backend-/Daemon-Status sichtbar, aber kompakt darstellen.
|
||||
|
||||
### 4. Konfiguration und Environments
|
||||
|
||||
- [ ] API Base URLs fuer `local`, `staging`, `production` definieren.
|
||||
- [ ] Socket.IO URLs je Flavor definieren.
|
||||
- [ ] Daemon WebSocket URLs je Flavor definieren.
|
||||
- [ ] Lokale Emulator-Regel dokumentieren: Host-Rechner ist `10.0.2.2`.
|
||||
- [ ] Release-Build gegen lokale URLs blockieren.
|
||||
- [ ] Network Security Config fuer Debug und Release definieren.
|
||||
- [ ] TLS-only fuer Release sicherstellen.
|
||||
- [ ] Secrets aus APK fernhalten.
|
||||
- [ ] Feature Flags definieren: Admin, Adult, 3D, Minigames, Push.
|
||||
Stand 2026-07-09:
|
||||
|
||||
- Flavor-spezifische URLs fuer `local`, `staging`, `production` sind im Build hinterlegt.
|
||||
- `local` nutzt bewusst `10.0.2.2` fuer Emulator-Zugriff.
|
||||
- Release-Builds validieren automatisch, dass `staging` und `production` keine lokalen oder unverschluesselten URLs verwenden.
|
||||
- Debug und Release nutzen getrennte Network-Security-Configs.
|
||||
- Release verbietet Cleartext komplett.
|
||||
- Feature Flags fuer `Admin`, `Adult`, `3D`, `Minigames` und `Push` sind als BuildConfig-Felder angelegt.
|
||||
- Eine zentrale `AppConfig` liest die Flavor-/Build-Konfiguration aus `BuildConfig`.
|
||||
|
||||
- [x] API Base URLs fuer `local`, `staging`, `production` definieren.
|
||||
- [x] Socket.IO URLs je Flavor definieren.
|
||||
- [x] Daemon WebSocket URLs je Flavor definieren.
|
||||
- [x] Lokale Emulator-Regel dokumentieren: Host-Rechner ist `10.0.2.2`.
|
||||
- [x] Release-Build gegen lokale URLs blockieren.
|
||||
- [x] Network Security Config fuer Debug und Release definieren.
|
||||
- [x] TLS-only fuer Release sicherstellen.
|
||||
- [x] Secrets aus APK fernhalten.
|
||||
- [x] Feature Flags definieren: Admin, Adult, 3D, Minigames, Push.
|
||||
|
||||
### 5. Auth und Session
|
||||
|
||||
- [ ] Login-Endpunkt dokumentieren.
|
||||
- [ ] Login DTOs erstellen.
|
||||
- [ ] Login Repository implementieren.
|
||||
- [ ] Auth Interceptor fuer `userid` und `authcode` implementieren.
|
||||
- [ ] Session Store mit sicherer Speicherung implementieren.
|
||||
- [ ] Auto-Login beim App-Start implementieren.
|
||||
- [ ] Logout implementieren.
|
||||
- [ ] Session-expired Handling implementieren.
|
||||
- [ ] User-Aktivstatus pruefen.
|
||||
- [ ] Account gesperrt Handling implementieren.
|
||||
- [ ] Registrierung API-Vertrag erfassen.
|
||||
- [ ] Registrierung Screen implementieren.
|
||||
Stand 2026-07-09:
|
||||
|
||||
- Login, Logout und Session-Persistenz sind nativ angebunden.
|
||||
- REST-Requests setzen automatisch `userid` und `authcode`.
|
||||
- 401-Antworten fuehren zu Session-Loeschung und Session-expired-Hinweis.
|
||||
- Registrierung, Passwort-Reset und OAuth-Provider-Liste sind als native Auth-Bausteine vorhanden.
|
||||
|
||||
- [x] Login-Endpunkt dokumentieren.
|
||||
- [x] Login DTOs erstellen.
|
||||
- [x] Login Repository implementieren.
|
||||
- [x] Auth Interceptor fuer `userid` und `authcode` implementieren.
|
||||
- [x] Session Store mit sicherer Speicherung implementieren.
|
||||
- [x] Auto-Login beim App-Start implementieren.
|
||||
- [x] Logout implementieren.
|
||||
- [x] Session-expired Handling implementieren.
|
||||
- [x] User-Aktivstatus pruefen.
|
||||
- [x] Account gesperrt Handling implementieren.
|
||||
- [x] Registrierung API-Vertrag erfassen.
|
||||
- [x] Registrierung Screen implementieren.
|
||||
- [ ] Account-Aktivierung Flow bewerten.
|
||||
- [ ] Passwort-Reset Flow implementieren.
|
||||
- [ ] OAuth-Provider-Liste laden.
|
||||
- [x] Passwort-Reset Flow implementieren.
|
||||
- [x] OAuth-Provider-Liste laden.
|
||||
- [ ] OAuth per Custom Tabs planen.
|
||||
- [ ] App Links fuer OAuth Callback planen.
|
||||
- [ ] OAuth erst nach Username/Passwort stabil aktivieren.
|
||||
|
||||
### 6. Netzwerk-Grundlage
|
||||
|
||||
- [ ] Zentrale `ApiResult`/`NetworkError` Struktur definieren.
|
||||
- [ ] Fehlercodes und Backend-Fehlerformate erfassen.
|
||||
- [ ] Retry-Policy definieren.
|
||||
- [ ] Timeout-Policy definieren.
|
||||
- [ ] Request Logging nur fuer Debug aktivieren.
|
||||
- [ ] Auth Header Tests mit MockWebServer schreiben.
|
||||
- [ ] CORS ist nativ irrelevant, aber Backend-Origin-Checks gegen mobile Clients pruefen.
|
||||
- [ ] Multipart Upload Helper bauen.
|
||||
- [ ] Download Helper fuer Bilder/Dateien bauen.
|
||||
- [ ] Pagination Pattern definieren.
|
||||
- [ ] Refresh Pattern definieren.
|
||||
Stand 2026-07-09:
|
||||
|
||||
- Eine zentrale `ApiResult`/`NetworkError`-Basis ist angelegt.
|
||||
- Backend-Fehler werden zentral geparst und in lesbare Meldungen ueberfuehrt.
|
||||
- Timeout- und Retry-Policy sind als feste Netzwerk-Defaults definiert.
|
||||
- Debug-Logging laeuft nur ausserhalb von Release.
|
||||
- Multipart- und Download-Helfer sind vorhanden.
|
||||
- Ein MockWebServer-Test prueft den Auth-Header-Interceptor.
|
||||
- Ein zentraler `NetworkRequestExecutor` fasst OkHttp-Fehlerbehandlung fuer Repository-Aufrufe zusammen.
|
||||
|
||||
- [x] Zentrale `ApiResult`/`NetworkError` Struktur definieren.
|
||||
- [x] Fehlercodes und Backend-Fehlerformate erfassen.
|
||||
- [x] Retry-Policy definieren.
|
||||
- [x] Timeout-Policy definieren.
|
||||
- [x] Request Logging nur fuer Debug aktivieren.
|
||||
- [x] Auth Header Tests mit MockWebServer schreiben.
|
||||
- [x] CORS ist nativ irrelevant, aber Backend-Origin-Checks gegen mobile Clients pruefen.
|
||||
- [x] Multipart Upload Helper bauen.
|
||||
- [x] Download Helper fuer Bilder/Dateien bauen.
|
||||
- [x] Pagination Pattern definieren.
|
||||
- [x] Refresh Pattern definieren.
|
||||
|
||||
### 7. Lokale Persistenz und Cache
|
||||
|
||||
- [ ] DataStore fuer UI-Sprache verwenden.
|
||||
- [ ] DataStore fuer Feature Flags verwenden.
|
||||
- [ ] Room Schema fuer User/Profile Cache definieren.
|
||||
- [ ] Room Schema fuer Friends/Search Cache definieren.
|
||||
- [ ] Room Schema fuer Falukant Status light definieren.
|
||||
- [ ] Room Schema fuer Vocab Course/Lesson Cache definieren.
|
||||
- [ ] Cache-Invalidation Regeln definieren.
|
||||
- [ ] Offline-Anzeige statt Offline-First fuer MVP festlegen.
|
||||
- [ ] Outbox fuer spaetere Offline-Aktionen nur planen, nicht im MVP erzwingen.
|
||||
Stand 2026-07-09:
|
||||
|
||||
- Ein zentraler Preferences-Store fuer UI-Sprache und Feature-Flags ist angelegt.
|
||||
- Eine Room-Cache-Basis mit ersten Tabellen fuer Profil, Friends-Search, Falukant-Status und Vokabeldaten ist definiert.
|
||||
- Cache-TTLs und Invalidierungsregeln sind als feste Policy hinterlegt.
|
||||
- Die MVP-Entscheidung lautet: Offline-Anzeige statt Offline-First.
|
||||
- Outbox/Offline-Write-Queues werden im MVP nur geplant, nicht erzwungen.
|
||||
|
||||
- [x] DataStore fuer UI-Sprache verwenden.
|
||||
- [x] DataStore fuer Feature Flags verwenden.
|
||||
- [x] Room Schema fuer User/Profile Cache definieren.
|
||||
- [x] Room Schema fuer Friends/Search Cache definieren.
|
||||
- [x] Room Schema fuer Falukant Status light definieren.
|
||||
- [x] Room Schema fuer Vocab Course/Lesson Cache definieren.
|
||||
- [x] Cache-Invalidation Regeln definieren.
|
||||
- [x] Offline-Anzeige statt Offline-First fuer MVP festlegen.
|
||||
- [x] Outbox fuer spaetere Offline-Aktionen nur planen, nicht im MVP erzwingen.
|
||||
|
||||
### 8. Realtime
|
||||
|
||||
- [ ] Socket.IO Android Client evaluieren.
|
||||
- [ ] Verbindung nach Login aufbauen.
|
||||
- [ ] `setUserId` nach Verbindungsaufbau senden.
|
||||
- [ ] Events erfassen: `forumschanged`, `friendloginchanged`, `reloadmenu`, `adultVerificationChanged`, `moderationReportChanged`, `userAccessChanged`.
|
||||
- [ ] Falukant-Events erfassen: `falukantUpdateStatus`, `falukantUpdateFamily`, `falukantUpdateChurch`, `falukantUpdateDebt`, `children_update`, `falukantUpdateProductionCertificate`, `falukantBranchUpdate`, `stock_change`, `familychanged`.
|
||||
- [ ] Socket Lifecycle an App Foreground/Background koppeln.
|
||||
- [ ] Reconnect Policy definieren.
|
||||
- [ ] Daemon-WebSocket Client implementieren.
|
||||
- [ ] Daemon-Message Parsing robust gegen unbekannte Events machen.
|
||||
- [ ] Realtime Events in Repositories einspeisen.
|
||||
- [ ] UI-State bei Events gezielt invalidieren.
|
||||
- [ ] Realtime Debug Screen fuer interne Builds planen.
|
||||
Stand 2026-07-09:
|
||||
|
||||
- Socket.IO ist als Backend-Realtime-Transport in die native App eingebunden.
|
||||
- Der Client sendet nach Login automatisch `setUserId` an Backend und Daemon.
|
||||
- App-Foreground/Background koppelt die Verbindung an den Lifecycle.
|
||||
- Backend- und Daemon-Status sind in der Shell sichtbar.
|
||||
- Der Daemon-WebSocket-Client ist technisch angebunden.
|
||||
- Realtime-Event-Basis und Daemon-Message-Parser sind vorhanden.
|
||||
- Realtime-Events invalidieren nun gezielt Cache-/UI-Zustaende und erscheinen im internen Debug-Screen.
|
||||
|
||||
- [x] Socket.IO Android Client evaluieren.
|
||||
- [x] Verbindung nach Login aufbauen.
|
||||
- [x] `setUserId` nach Verbindungsaufbau senden.
|
||||
- [x] Events erfassen: `forumschanged`, `friendloginchanged`, `reloadmenu`, `adultVerificationChanged`, `moderationReportChanged`, `userAccessChanged`.
|
||||
- [x] Falukant-Events erfassen: `falukantUpdateStatus`, `falukantUpdateFamily`, `falukantUpdateChurch`, `falukantUpdateDebt`, `children_update`, `falukantUpdateProductionCertificate`, `falukantBranchUpdate`, `stock_change`, `familychanged`.
|
||||
- [x] Socket Lifecycle an App Foreground/Background koppeln.
|
||||
- [x] Reconnect Policy definieren.
|
||||
- [x] Daemon-WebSocket Client implementieren.
|
||||
- [x] Daemon-Message Parsing robust gegen unbekannte Events machen.
|
||||
- [x] Realtime Events in Repositories einspeisen.
|
||||
- [x] UI-State bei Events gezielt invalidieren.
|
||||
- [x] Realtime Debug Screen fuer interne Builds planen.
|
||||
|
||||
### 9. Home und Dashboard
|
||||
|
||||
- [ ] Home API-Vertraege erfassen.
|
||||
- [ ] Eingeloggt/Nicht-eingeloggt Home getrennt modellieren.
|
||||
- [ ] Native Startseite fuer nicht eingeloggte Nutzer bauen.
|
||||
- [ ] Native Startseite fuer eingeloggte Nutzer bauen.
|
||||
- [ ] Dashboard Widget API-Vertraege erfassen.
|
||||
- [ ] Termine/Upcoming Events als native Cards umsetzen.
|
||||
- [ ] Falukant Kurzstatus als native Card umsetzen.
|
||||
- [ ] News/Blog/Guide Kurzlisten bewerten.
|
||||
- [ ] Backend-/Daemon-Status light anzeigen.
|
||||
Stand 2026-07-09:
|
||||
|
||||
- Die nicht eingeloggte Startseite ist als native Landing/Auth-Kombination umgesetzt.
|
||||
- Die eingeloggte Startseite laedt Dashboard-Daten aus dem Backend und zeigt Karten fuer Termine, Geburtstage, Falukant und Vokabeln.
|
||||
- Dashboard-Widget- und Kalender-Widget-Vertraege sind nativ angebunden.
|
||||
- Backend-/Daemon-Status bleibt als kompakte Info sichtbar.
|
||||
|
||||
- [x] Home API-Vertraege erfassen.
|
||||
- [x] Eingeloggt/Nicht-eingeloggt Home getrennt modellieren.
|
||||
- [x] Native Startseite fuer nicht eingeloggte Nutzer bauen.
|
||||
- [x] Native Startseite fuer eingeloggte Nutzer bauen.
|
||||
- [x] Dashboard Widget API-Vertraege erfassen.
|
||||
- [x] Termine/Upcoming Events als native Cards umsetzen.
|
||||
- [x] Falukant Kurzstatus als native Card umsetzen.
|
||||
- [x] Backend-/Daemon-Status light anzeigen.
|
||||
|
||||
### 10. Settings
|
||||
|
||||
- [ ] Settings API-Vertraege erfassen: `/api/settings/filter`, `/api/settings/update`, `/api/settings/account`.
|
||||
- [ ] Spracheinstellung nativ implementieren.
|
||||
- [ ] Account-Basisdaten nativ implementieren.
|
||||
- [ ] Sichtbarkeitseinstellungen modellieren.
|
||||
- [ ] Personal/View/Sexuality/Flirt Settings priorisieren.
|
||||
- [ ] Interessen-Settings implementieren.
|
||||
- [ ] Language Assistant Settings bewerten.
|
||||
- [ ] Account-Loeschung oder Anfrageprozess fuer Store-Compliance klaeren.
|
||||
- [x] Settings API-Vertraege erfassen: `/api/settings/filter`, `/api/settings/update`, `/api/settings/account`, `/api/settings/set-account`, `/api/settings/visibilities`.
|
||||
- [x] Spracheinstellung nativ implementieren.
|
||||
- [x] Account-Basisdaten nativ implementieren.
|
||||
- [x] Sichtbarkeitseinstellungen modellieren.
|
||||
- [x] Personal/View/Sexuality/Flirt Settings priorisieren.
|
||||
- [x] Interessen-Settings implementieren.
|
||||
- [x] Language Assistant Settings bewerten.
|
||||
- [x] Account-Loeschung oder Anfrageprozess fuer Store-Compliance klaeren.
|
||||
|
||||
### 11. Social Basis
|
||||
|
||||
- [ ] Friends API-Vertraege erfassen.
|
||||
- [ ] Friends Screen implementieren: bestehend, angefragt, offen, abgelehnt.
|
||||
- [ ] User Search API-Vertraege erfassen.
|
||||
- [ ] User Search Screen implementieren.
|
||||
- [ ] User Profile API-Vertraege erfassen.
|
||||
- [ ] Profile Light Screen implementieren.
|
||||
- [ ] Guestbook API-Vertraege erfassen.
|
||||
- [ ] Guestbook light implementieren.
|
||||
- [ ] Friend Request Aktionen implementieren.
|
||||
- [ ] Blockieren/Melden UX fuer Store-Compliance planen.
|
||||
- [ ] Privacy/Visibility Regeln aus Backend nativ abbilden.
|
||||
- Stand 2026-07-09:
|
||||
|
||||
- Friends, Benutzersuche, Profil-Light und Gästebuch-Light sind nativ angebunden.
|
||||
- Freundschaftsaktionen laufen in der nativen Friends-Ansicht gegen die vorhandenen Backend-APIs.
|
||||
- Profilfelder werden inklusive Backend-Visibility-Regeln angezeigt.
|
||||
- Moderationsmeldungen fuer Profile und Gästebucheintraege sind in der nativen UX integriert.
|
||||
|
||||
- [x] Friends API-Vertraege erfassen.
|
||||
- [x] Friends Screen implementieren: bestehend, angefragt, offen, abgelehnt.
|
||||
- [x] User Search API-Vertraege erfassen.
|
||||
- [x] User Search Screen implementieren.
|
||||
- [x] User Profile API-Vertraege erfassen.
|
||||
- [x] Profile Light Screen implementieren.
|
||||
- [x] Guestbook API-Vertraege erfassen.
|
||||
- [x] Guestbook light implementieren.
|
||||
- [x] Friend Request Aktionen implementieren.
|
||||
- [x] Blockieren/Melden UX fuer Store-Compliance planen.
|
||||
- [x] Privacy/Visibility Regeln aus Backend nativ abbilden.
|
||||
|
||||
### 12. Chat
|
||||
|
||||
- [ ] Aktuellen Chat-Mechanismus erfassen: Dialoge, Raeume, Random Chat, MultiChat.
|
||||
- [ ] Chat Backend-/WebSocket-Vertraege dokumentieren.
|
||||
- [ ] Chat Room Liste implementieren.
|
||||
- [ ] 1:1 Chat MVP implementieren.
|
||||
- [ ] MultiChat MVP implementieren oder bewusst verschieben.
|
||||
- [ ] RandomChat bewusst verschieben oder implementieren.
|
||||
- [ ] Message Input mit Keyboard-Verhalten testen.
|
||||
- [ ] Neue Nachrichten per Realtime anzeigen.
|
||||
- [ ] Push-Kandidaten fuer Chat definieren.
|
||||
- [ ] Melden/Blockieren im Chat implementieren oder als Release-Blocker markieren.
|
||||
Stand 2026-07-09:
|
||||
|
||||
- Der nativen MVP-Schnitt fuer Chat ist begonnen.
|
||||
- Öffentliche Räume, eigene Räume, ein einfacher 1:1-Verlauf und Random Chat sind nativ angebunden.
|
||||
- Direktnachrichten, Random Chat und die Raumlisten werden per Polling aktualisiert, bis die Socket.IO-Paritaet fuer den Chat folgt.
|
||||
- Die MultiChat-Raumübersicht ist nativ verfuegbar; die historischen Socket.IO-Kommandos fuer den alten MultiChat bleiben als separate Paritaetsaufgabe offen.
|
||||
- Direktnachrichten koennen gesendet und gemeldet werden.
|
||||
- Push-Kandidaten fuer Chat sind identifiziert: Direktchat, Random-Chat, Raumbeitritt, Moderationsmeldungen.
|
||||
- Socket.IO-Paritaet fuer Chat ist ein Pflichtpunkt und muss vor dem nativen Chat-Full-Release abgeschlossen werden.
|
||||
|
||||
- [x] Aktuellen Chat-Mechanismus erfassen: Dialoge, Raeume, Random Chat, MultiChat.
|
||||
- [x] Chat Backend-/WebSocket-Vertraege dokumentieren.
|
||||
- [x] Chat Room Liste implementieren.
|
||||
- [x] 1:1 Chat MVP implementieren.
|
||||
- [x] MultiChat MVP implementieren oder bewusst verschieben.
|
||||
- [x] RandomChat bewusst verschieben oder implementieren.
|
||||
- [x] Message Input mit Keyboard-Verhalten testen.
|
||||
- [x] Neue Nachrichten per Realtime anzeigen.
|
||||
- [x] Push-Kandidaten fuer Chat definieren.
|
||||
- [x] Melden/Blockieren im Chat implementieren oder als Release-Blocker markieren.
|
||||
- [ ] Socket.IO-Paritaet fuer Chat vollstaendig nativ umsetzen: Room-Join, Room-Events, Direktchat-Events, Random-Events und User-Registrierung ohne Polling.
|
||||
|
||||
### 13. Galerie und Medien
|
||||
|
||||
- [ ] Galerie API-Vertraege erfassen.
|
||||
- [ ] Folder-Struktur nativ modellieren.
|
||||
- [ ] Bildliste mit Coil implementieren.
|
||||
- [ ] Bilddetail implementieren.
|
||||
- [ ] Android Photo Picker fuer Upload implementieren.
|
||||
- [ ] Multipart Upload testen.
|
||||
- [ ] Bildbearbeitung aus Web-App bewerten: MVP ja/nein.
|
||||
- [ ] Sichtbarkeiten laden und setzen.
|
||||
- [ ] Adult-Galerie aus MVP ausschliessen oder Compliance-Aufwand planen.
|
||||
- [ ] Video-Unterstuetzung separat planen.
|
||||
Stand 2026-07-10:
|
||||
|
||||
- Die Galerie wird als nativer Social-Unterbereich aufgebaut.
|
||||
- Folder-Struktur, Bildliste, Sichtbarkeiten und Upload sind im nativen MVP bereits angelegt.
|
||||
- Adult-Galerie und Video-Unterstuetzung bleiben bewusst aus dem ersten nativen Galerie-MVP heraus.
|
||||
|
||||
- [x] Galerie API-Vertraege erfassen.
|
||||
- [x] Folder-Struktur nativ modellieren.
|
||||
- [x] Bildliste mit Coil implementieren.
|
||||
- [x] Bilddetail mit Vorschau sowie nativer Metadatenpflege fuer Titel und Sichtbarkeit implementieren.
|
||||
- [x] Android Photo Picker fuer Upload implementieren.
|
||||
- [x] Multipart Upload gegen den Backend-Vertrag automatisiert testen.
|
||||
- [x] Bildbearbeitung aus Web-App bewerten: MVP nein. Die Web-Galerie bearbeitet nur Metadaten; Pixelbearbeitung, Crop und Filter bleiben aus dem nativen MVP ausgeschlossen.
|
||||
- [x] Sichtbarkeiten laden und setzen.
|
||||
- [x] Adult-Galerie aus MVP ausschliessen oder Compliance-Aufwand planen.
|
||||
- [x] Video-Unterstuetzung separat planen.
|
||||
|
||||
### 14. Forum
|
||||
|
||||
- [ ] Forum-Liste API-Vertrag erfassen.
|
||||
- [ ] Topic-Liste API-Vertrag erfassen.
|
||||
- [ ] Topic-Detail API-Vertrag erfassen.
|
||||
- [ ] Forum-Liste native umsetzen.
|
||||
- [ ] Topic-Liste native umsetzen.
|
||||
- [ ] Topic-Detail native umsetzen.
|
||||
- [ ] Antwort erstellen implementieren.
|
||||
- [ ] Moderation Report fuer Forum implementieren.
|
||||
- [ ] Realtime `forumschanged` integrieren.
|
||||
Stand 2026-07-10:
|
||||
|
||||
- Forum, Themenliste und Themenansicht sind nativ als Social-Unterbereich umgesetzt.
|
||||
- Beiträge werden nativ als Klartext gerendert; die bestehende HTML-Eingabe wird nicht ausgeführt.
|
||||
- `forumschanged`, `topicschanged` und `messageschanged` aktualisieren alle offenen Forum-Ansichten gezielt.
|
||||
|
||||
- [x] Forum-Liste API-Vertrag erfassen.
|
||||
- [x] Topic-Liste API-Vertrag erfassen.
|
||||
- [x] Topic-Detail API-Vertrag erfassen.
|
||||
- [x] Forum-Liste native umsetzen.
|
||||
- [x] Topic-Liste native umsetzen.
|
||||
- [x] Topic-Detail native umsetzen.
|
||||
- [x] Antwort erstellen implementieren.
|
||||
- [x] Moderation Report fuer Forum implementieren.
|
||||
- [x] Realtime `forumschanged` integrieren.
|
||||
|
||||
### 15. Falukant MVP
|
||||
|
||||
- [ ] Falukant API-Endpunkte aus Web-App inventarisieren.
|
||||
- [ ] `StatusBar` Datenmodell nativ definieren.
|
||||
- [ ] Overview Screen implementieren.
|
||||
- [ ] Character/Familien-Basisdaten implementieren.
|
||||
- [ ] Branch-Liste implementieren.
|
||||
- [ ] Branch-Detail light implementieren.
|
||||
- [ ] Bank light implementieren.
|
||||
- [ ] Messages/Notifications light implementieren.
|
||||
- [ ] Realtime Falukant Events integrieren.
|
||||
- [ ] Create Falukant Flow implementieren oder bewusst verschieben.
|
||||
- [ ] Family View light implementieren.
|
||||
- [ ] Church/Reputation/Health/Nobility als spaetere Phase markieren.
|
||||
- [ ] Production/Storage/Sale/Director als spaetere Phase markieren.
|
||||
- [ ] Karten-/Regionen-Features als spaetere Phase markieren.
|
||||
Stand 2026-07-10:
|
||||
|
||||
- Der native Falukant-MVP ist eine Read-only-Spielstandszentrale: Übersicht, Status, Filialen, Bank, Familie und Nachrichten.
|
||||
- Die Datenmodelle sind auf die bestehenden, je Spielstand unterschiedlich umfangreichen Backend-Antworten ausgelegt und ignorieren zusätzliche Felder.
|
||||
- Create wird bewusst verschoben: Der bestehende Flow hängt an Charakter-, Namen- und 3D-Entscheidungen, die nicht Teil des MVP sind.
|
||||
|
||||
- [x] Falukant API-Endpunkte aus Web-App inventarisieren.
|
||||
- [x] `StatusBar` Datenmodell nativ definieren.
|
||||
- [x] Overview Screen implementieren.
|
||||
- [x] Character/Familien-Basisdaten implementieren.
|
||||
- [x] Branch-Liste implementieren.
|
||||
- [x] Branch-Detail light implementieren.
|
||||
- [x] Bank light implementieren.
|
||||
- [x] Messages/Notifications light implementieren.
|
||||
- [x] Realtime Falukant Events integrieren.
|
||||
- [x] Create Falukant Flow bewusst verschieben.
|
||||
- [x] Family View light implementieren.
|
||||
- [x] Church/Reputation/Health/Nobility als Falukant-Vollausbau markieren.
|
||||
- [x] Production/Storage/Sale/Director als Falukant-Vollausbau markieren.
|
||||
- [x] Karten-/Regionen-Features als Falukant-Vollausbau markieren.
|
||||
|
||||
### 16. Falukant Vollausbau
|
||||
|
||||
- [ ] Branch Detail vollstaendig umsetzen.
|
||||
- [ ] Production Section umsetzen.
|
||||
- [ ] Storage Section umsetzen.
|
||||
- [ ] Sale Section umsetzen.
|
||||
- [ ] Director Info umsetzen.
|
||||
- [ ] Transport Routes umsetzen.
|
||||
- [ ] Bank vollstaendig umsetzen.
|
||||
- [ ] Family vollstaendig umsetzen.
|
||||
- [ ] Health umsetzen.
|
||||
- [ ] Reputation umsetzen.
|
||||
- [ ] Church umsetzen.
|
||||
- [ ] Nobility umsetzen.
|
||||
- [ ] Politics umsetzen.
|
||||
- [ ] Underground umsetzen.
|
||||
- [ ] House umsetzen.
|
||||
- [ ] Education umsetzen.
|
||||
- [ ] Money History umsetzen.
|
||||
- [ ] Performance fuer grosse Falukant-Datenmengen testen.
|
||||
Stand 2026-07-10:
|
||||
|
||||
- Der Wirtschaftsblock ist begonnen: Filialdetails laden Produktion, Lager, Inventar, Director, Fahrzeuge und laufende Transporte.
|
||||
- Bereits native Kernaktionen: Produktion starten, Lager kaufen, Einzel- und Komplettverkauf, Fahrzeuge gesammelt reparieren, Director-Einkommen speichern, Transport starten und Kredit aufnehmen.
|
||||
- Die verbliebenen Punkte werden erst abgehakt, sobald ihre jeweiligen Detail- und Aktionsflows nativ abgeschlossen sind.
|
||||
|
||||
#### 16.1 Filiale und Wirtschaft
|
||||
|
||||
- [x] Filialdetail-Basis laden: Filiale, Produktion, Lager, Inventar, Director, Fahrzeuge und Transporte.
|
||||
- [x] Produktion starten implementieren.
|
||||
- [x] Lagerkapazität kaufen implementieren.
|
||||
- [x] Einzelverkauf implementieren.
|
||||
- [x] Gesamtes Inventar verkaufen implementieren.
|
||||
- [x] Fahrzeuge gesammelt reparieren implementieren.
|
||||
- [x] Director-Einkommen speichern implementieren.
|
||||
- [x] Transport starten implementieren.
|
||||
- [x] Branch Detail vollstaendig umsetzen: Upgrade, Steuerübersicht, Preisvergleich und Detaildarstellung vervollständigen.
|
||||
- [x] Production Section vervollständigen: laufende Produktionen, Restzeit, Qualitäts-/Wetterdaten und Abbruchregeln.
|
||||
- [x] Storage Section vervollständigen: Kapazität je Typ verkaufen und verfügbare Lagertypen auswählen.
|
||||
- [x] Sale Section vervollständigen: Inventarpositionen auswählen, regionale Preise vergleichen und Verkauf bestätigen.
|
||||
- [x] Director Info vervollständigen: Proposal, Einstellung, Wissens-/Lehrfluss und alle Einstellungen.
|
||||
- [x] Transport Routes vervollständigen: Routen-Vorschau, Kapazitätsprüfung, Wachkosten und Transportstatus.
|
||||
|
||||
#### 16.2 Bank und Historie
|
||||
|
||||
- [x] Bankübersicht und aktive Kredite laden.
|
||||
- [x] Kreditaufnahme implementieren.
|
||||
- [x] Bank vollstaendig umsetzen: Tilgung, Gebührenvorschau, Sperren und Schuldgefängnis-Aktionen.
|
||||
- [x] Money History umsetzen: Filter, Pagination und Graphdaten.
|
||||
|
||||
#### 16.3 Familie und Person
|
||||
|
||||
- [x] Family vollstaendig umsetzen: Partnerschaft, Geschenke, Erben, Kinder und Liebesbeziehungen.
|
||||
- [x] Health umsetzen: Gesundheitsstatus und Aktivitäten mit Cooldown.
|
||||
- [x] Reputation umsetzen: Aktionen, Partys und Fortschritt.
|
||||
- [x] Church umsetzen: Taufe, Ämter, Bewerbungen und Entscheidungen.
|
||||
- [x] Nobility umsetzen: Stand, Voraussetzungen und Aufstieg.
|
||||
- [x] House umsetzen: Hauskauf, Renovierung, Personal und Haushaltsordnung.
|
||||
- [x] Education umsetzen: Lernende, Inhalte und Schulaktionen.
|
||||
|
||||
#### 16.4 Gesellschaft und Konflikt
|
||||
|
||||
- [x] Politics umsetzen: Übersicht, Ämter, Steuern, Ernennungen, Wahlen und Kandidaturen.
|
||||
- [x] Underground umsetzen: Aktivitäten, Ziele, Angriffe und Raid-Regionen.
|
||||
|
||||
#### 16.5 Qualität
|
||||
|
||||
- [x] Performance fuer grosse Falukant-Datenmengen testen.
|
||||
|
||||
### 17. Vokabeltrainer MVP
|
||||
|
||||
- [ ] Vocab Languages API-Vertrag erfassen.
|
||||
- [ ] Course List API-Vertrag erfassen.
|
||||
- [ ] Course Detail API-Vertrag erfassen.
|
||||
- [ ] Lesson API-Vertrag erfassen.
|
||||
- [ ] Review API-Vertrag erfassen.
|
||||
- [ ] Vocab Landing native umsetzen.
|
||||
- [ ] Course List native umsetzen.
|
||||
- [ ] Course Detail native umsetzen.
|
||||
- [ ] Lesson Player MVP implementieren.
|
||||
- [ ] Lesson Review implementieren.
|
||||
- [ ] Dictionary light implementieren.
|
||||
- [ ] Progress/Completion speichern.
|
||||
- [ ] Keyboard-/Audio-/Touch-Verhalten testen.
|
||||
- [ ] Offline Cache fuer aktive Lektion planen.
|
||||
- [x] Vocab Languages API-Vertrag erfassen.
|
||||
- [x] Course List API-Vertrag erfassen.
|
||||
- [x] Course Detail API-Vertrag erfassen.
|
||||
- [x] Lesson API-Vertrag erfassen.
|
||||
- [x] Review API-Vertrag erfassen.
|
||||
- [x] Vocab Landing native umsetzen.
|
||||
- [x] Course List native umsetzen.
|
||||
- [x] Course Detail native umsetzen.
|
||||
- [x] Lesson Player MVP implementieren.
|
||||
- [x] Lesson Review implementieren.
|
||||
- [x] Dictionary light implementieren.
|
||||
- [x] Progress/Completion speichern.
|
||||
- [x] Keyboard-/Audio-/Touch-Verhalten testen.
|
||||
- [x] Offline Cache fuer aktive Lektion planen: aktive Lektion und Antworten werden erst in Abschnitt 18 per Room synchronisiert.
|
||||
|
||||
### 18. Vokabeltrainer Vollausbau
|
||||
|
||||
- [ ] Neue Sprache anlegen implementieren.
|
||||
- [ ] Subscribe Flow implementieren.
|
||||
- [ ] Chapter View implementieren.
|
||||
- [ ] Dictionary vollstaendig implementieren.
|
||||
- [ ] Practice Dialog nativ ersetzen.
|
||||
- [ ] SRS-/Review-Logik gegen Backend validieren.
|
||||
- [ ] Offline Lesson Cache implementieren.
|
||||
- [ ] Sync-Konflikte definieren.
|
||||
- [x] Neue Sprache anlegen implementieren.
|
||||
- [x] Subscribe Flow implementieren.
|
||||
- [x] Chapter View implementieren.
|
||||
- [x] Dictionary vollstaendig implementieren.
|
||||
- [x] Practice Dialog nativ ersetzen.
|
||||
- [x] SRS-/Review-Logik gegen Backend validieren.
|
||||
- [x] Offline Lesson Cache implementieren.
|
||||
- [x] Sync-Konflikte definieren.
|
||||
|
||||
Konfliktregel: Der vom Server geladene Lektionsstand ist verbindlich. Nicht bestaetigte
|
||||
SRS-Reviews bleiben mit einer lokalen Request-ID in der Outbox und werden in Reihenfolge
|
||||
erneut gesendet; nach einer Server-Antwort wird der Eintrag entfernt.
|
||||
|
||||
### 19. Kalender und Persoenliches
|
||||
|
||||
- [ ] Calendar API-Vertraege erfassen.
|
||||
- [ ] Monats-/Wochen-/Listenansicht entscheiden.
|
||||
- [ ] Termine laden.
|
||||
- [ ] Termin erstellen.
|
||||
- [ ] Termin bearbeiten.
|
||||
- [ ] Termin loeschen.
|
||||
- [ ] Date/Time Picker nativ einsetzen.
|
||||
- [ ] Reminder/Push spaeter planen.
|
||||
- [ ] Diary API-Vertrag erfassen.
|
||||
- [ ] Diary light umsetzen oder verschieben.
|
||||
- [x] Calendar API-Vertraege erfassen.
|
||||
- [x] Monats-/Wochen-/Listenansicht entscheiden.
|
||||
- [x] Termine laden.
|
||||
- [x] Termin erstellen.
|
||||
- [x] Termin bearbeiten.
|
||||
- [x] Termin loeschen.
|
||||
- [x] Date/Time Picker nativ einsetzen.
|
||||
- [x] Reminder/Push spaeter planen.
|
||||
- [x] Diary API-Vertrag erfassen.
|
||||
- [x] Diary light umsetzen oder verschieben.
|
||||
|
||||
Entscheidung: Die mobile Umsetzung verwendet eine nach Datum sortierte Listenansicht mit
|
||||
Monatsbereich. Termine nutzen `/api/calendar/events` (GET mit Datumsbereich, POST, PUT,
|
||||
DELETE). Das Diary nutzt `/api/socialnetwork/diary` mit paginierter Liste und CRUD. Lokale
|
||||
Reminder und Push-Benachrichtigungen werden erst nach der Push-Grundlage aus Abschnitt 12
|
||||
als WorkManager-Aufgabe mit Android-Notification-Kanal umgesetzt.
|
||||
|
||||
### 20. Public Content
|
||||
|
||||
- [ ] Blog List API-Vertrag erfassen.
|
||||
- [ ] Blog Detail API-Vertrag erfassen.
|
||||
- [ ] Guide List API-Vertrag erfassen.
|
||||
- [ ] Guide Detail API-Vertrag erfassen.
|
||||
- [ ] Public Landing Screens nativ priorisieren oder aus App entfernen.
|
||||
- [ ] Rich Text Rendering nativ loesen.
|
||||
- [ ] Blog Editor aus MVP ausschliessen.
|
||||
- [ ] Guide/Marketing Content als WebView-Fallback pruefen oder nativ rendern.
|
||||
- [x] Blog List API-Vertrag erfassen.
|
||||
- [x] Blog Detail API-Vertrag erfassen.
|
||||
- [x] Guide List API-Vertrag erfassen.
|
||||
- [x] Guide Detail API-Vertrag erfassen.
|
||||
- [x] Public Landing Screens nativ priorisieren oder aus App entfernen.
|
||||
- [x] Rich Text Rendering nativ loesen.
|
||||
- [x] Blog Editor aus MVP ausschliessen.
|
||||
- [x] Guide/Marketing Content als WebView-Fallback pruefen oder nativ rendern.
|
||||
- [x] News/Blog/Guide Kurzlisten bewerten.
|
||||
|
||||
Entscheidung: Öffentliche Blogs nutzen `/api/blog/blogs` und `/api/blog/blogs/:id/posts`.
|
||||
Ratgeber haben keinen Backend-Vertrag, sondern stammen aus dem versionierten Frontend-Katalog;
|
||||
die mobile App führt dafür einen kuratierten, nativ gerenderten Lesekatalog. HTML aus
|
||||
Blogbeiträgen wird als sicherer Text ohne WebView gerendert. Der Blog-Editor bleibt im Web.
|
||||
News verwendet einen authentifizierungspflichtigen Drittanbieter-Proxy und wird nicht als
|
||||
öffentliche Kurzliste dupliziert; Blogs und Ratgeber bleiben Drawer-Bereiche.
|
||||
|
||||
### 21. Minigames
|
||||
|
||||
- [ ] Match3 Game als native Compose/Canvas Machbarkeit pruefen.
|
||||
- [ ] Taxi Game als native Canvas/OpenGL Machbarkeit pruefen.
|
||||
- [ ] WebView-Fallback fuer Minigames als Zwischenloesung bewerten.
|
||||
- [ ] Touch-Steuerung definieren.
|
||||
- [ ] Performance auf Emulator und echtem Geraet testen.
|
||||
- [ ] Leaderboard/Score API-Vertraege erfassen.
|
||||
- [ ] Admin-Tools fuer Minigames aus nativer App ausschliessen.
|
||||
#### 21.1 Match3
|
||||
|
||||
- [x] Match3 Game als native Compose/Canvas Machbarkeit pruefen.
|
||||
- [x] Spielbrett, Tile-Modell und Zuglogik definieren.
|
||||
- [x] Touch-Steuerung fuer Auswahl und Tausch definieren.
|
||||
- [x] Animationen und Aufloesung von Matches definieren.
|
||||
- [x] Score-/Leaderboard-API-Vertraege fuer Match3 erfassen.
|
||||
- [ ] Performance auf Emulator und echtem Geraet testen. In eine spaetere gemeinsame QA-Runde verschoben.
|
||||
|
||||
Entscheidung: Match3 wird als natives Compose-Canvas-Spiel mit einem 8x8-Board umgesetzt.
|
||||
Ein Zug besteht aus zwei Tap-Eingaben auf benachbarte Steine. Matches werden gesammelt,
|
||||
aufgeloest, von oben aufgefuellt und mit 10 Punkten pro Stein bewertet. Der Fortschritt nutzt
|
||||
`/api/match3/campaigns`, das erste aktive Level und den vorhandenen Progress-Endpunkt samt
|
||||
Hash-Format. Admin-Routen bleiben ausgeschlossen.
|
||||
|
||||
#### 21.2 Taxi
|
||||
|
||||
- [x] Taxi Game als native Canvas/OpenGL Machbarkeit pruefen.
|
||||
- [x] Spielfeld, Fahrzeugzustand und Fahrphysik definieren.
|
||||
- [x] Touch-Steuerung fuer Lenken, Beschleunigen und Bremsen definieren.
|
||||
- [x] Auftrags-, Ziel- und Kollisionslogik definieren.
|
||||
- [x] Score-/Leaderboard-API-Vertraege fuer Taxi erfassen.
|
||||
- [ ] Performance auf Emulator und echtem Geraet testen. In eine spaetere gemeinsame QA-Runde verschoben.
|
||||
|
||||
Entscheidung: Taxi wird als natives Compose-Canvas-Spiel umgesetzt. Vier Touch-Schaltflächen
|
||||
steuern Lenken, Beschleunigen und Bremsen. Ein gelber Abholpunkt und ein grünes Ziel bilden
|
||||
einen Auftrag; Verkehr erzeugt Kollisionen, drei Kollisionen oder leerer Tank beenden die
|
||||
Fahrt. Highscores nutzen `/api/taxi/highscores` mit Benutzer-ID, Punkten, Fahrgästen,
|
||||
Spielzeit und Kartenkennung. OpenGL ist für diese 2D-Strecke nicht erforderlich.
|
||||
|
||||
#### 21.3 Gemeinsame Integration
|
||||
|
||||
- [x] WebView-Fallback fuer Minigames als Zwischenloesung bewerten.
|
||||
- [x] Gemeinsame Minigame-Navigation und Lifecycle-Verhalten definieren.
|
||||
- [x] Gemeinsames Persistenz- und Abbruchverhalten definieren.
|
||||
- [x] Admin-Tools fuer Minigames aus nativer App ausschliessen.
|
||||
|
||||
Entscheidung: Es gibt keinen WebView-Fallback. Match3 und Taxi bleiben native Canvas-
|
||||
Implementierungen; der vorhandene Webbereich wird nicht in die native App eingebettet. Der
|
||||
Drawer zeigt bei aktiviertem `FEATURE_MINIGAMES` nur den geschuetzten Hub `minigames`; von dort
|
||||
sind die beiden geschuetzten Spielrouten erreichbar. Spielschleifen sind an die Composition
|
||||
gebunden und werden beim Verlassen automatisch beendet. Match3 speichert nur abgeschlossene
|
||||
Level ueber den vorhandenen Progress-Endpunkt. Taxi speichert beim Verlassen einer laufenden
|
||||
Fahrt einen Zwischenstand ueber `/api/taxi/game-state`; abgeschlossene Fahrten werden als
|
||||
Highscore gespeichert. Admin- und Verwaltungsrouten fuer Minigames werden nicht registriert und
|
||||
bleiben ausschliesslich im Web-Adminbereich.
|
||||
|
||||
### 22. Admin spaeter
|
||||
|
||||
- [ ] Entscheiden, ob Admin ueberhaupt in native App gehoert.
|
||||
- [ ] Admin Users API-Vertraege erfassen.
|
||||
- [ ] Admin Rights API-Vertraege erfassen.
|
||||
- [ ] Moderation Reports API-Vertraege erfassen.
|
||||
- [ ] Adult Verification API-Vertraege erfassen.
|
||||
- [ ] Erotic Moderation API-Vertraege erfassen.
|
||||
- [ ] Forum Admin API-Vertraege erfassen.
|
||||
- [ ] Falukant Admin API-Vertraege erfassen.
|
||||
- [ ] Services Status Screen fuer interne Builds planen.
|
||||
- [ ] Admin nur per Feature Flag und Rollencheck sichtbar machen.
|
||||
- [x] Entscheiden, ob Admin ueberhaupt in native App gehoert. - Ja, Admin gehört in die native App
|
||||
- [x] Admin Users API-Vertraege erfassen.
|
||||
- [x] Admin Rights API-Vertraege erfassen.
|
||||
- [x] Moderation Reports API-Vertraege erfassen.
|
||||
- [x] Adult Verification API-Vertraege erfassen.
|
||||
- [x] Erotic Moderation API-Vertraege erfassen.
|
||||
- [x] Forum Admin API-Vertraege erfassen.
|
||||
- [x] Falukant Admin API-Vertraege erfassen.
|
||||
- [x] Services Status Screen fuer interne Builds planen.
|
||||
- [x] Admin nur per Feature Flag und Rollencheck sichtbar machen.
|
||||
|
||||
Entscheidung: Die native Administration wird nur eingeblendet, wenn sowohl
|
||||
`FEATURE_ADMIN` aktiviert ist als auch die authentifizierte Anfrage an
|
||||
`GET /api/navigation/:userid` einen Bereich `administration` liefert. Die vom Backend
|
||||
gefilterte Navigation ist die Rechtequelle; die serverseitige Berechtigungsprüfung jeder
|
||||
Admin-Route bleibt verbindlich. Direkte Navigation ohne beide Bedingungen zeigt keinen Inhalt.
|
||||
|
||||
API-Vertraege:
|
||||
|
||||
- Benutzer: `GET /api/admin/users/search?q=`, `GET /api/admin/users/:id`, `PUT /api/admin/users/:id`, `GET /api/admin/users/batch?ids=`, `GET /api/admin/users/statistics`; alle erfordern die vom Service gepruefte Berechtigung `useradministration` bzw. `mainadmin`.
|
||||
- Rechte: `GET /api/admin/rights/types`, `GET /api/admin/rights/:id`, `POST /api/admin/rights/:id` und `DELETE /api/admin/rights/:id` mit `{ rightTypeId }`; Berechtigung `rights` bzw. `mainadmin`.
|
||||
- Moderationsmeldungen: `GET /api/admin/moderation/reports?status=&limit=` sowie `POST /api/admin/moderation/reports/:reportId/status` mit Status und Review-Notiz; Berechtigung `forum` bzw. `mainadmin`.
|
||||
- Altersverifikation: `GET /api/admin/users/adult-verification?status=`, `PUT /api/admin/users/:id/adult-verification` mit `approved`, `rejected` oder `pending`, sowie der geschuetzte Dokument-Download `GET /api/admin/users/:id/adult-verification/document`.
|
||||
- Erotikmoderation: `GET /api/admin/users/erotic-moderation?status=`, geschuetzte Vorschau unter `/preview/:type/:targetId` und `PUT /api/admin/users/erotic-moderation/:id` mit erlaubter Aktion und optionaler Notiz.
|
||||
- Forum: `GET` und `POST /api/forum/`, `DELETE /api/forum/:forumId`; Erstellen erwartet `{ name, permissions }`, die Service-Schicht prueft `forum` bzw. `mainadmin`. Allgemeine Meldungen laufen ueber den Moderationsvertrag.
|
||||
- Falukant: Die geschuetzten Werkzeuge liegen unter `/api/admin/falukant/*`: Benutzersuche/-bearbeitung, Familien- und Schwangerschaftsaktionen, Bestands-/Region-/Distanzpflege, NPC-Auftraege und Titel. Die native Umsetzung beschraenkt sich auf klar abgegrenzte Fach-Screens mit serverseitiger `falukant`-/`mainadmin`-Pruefung; keine generische Datenbankbearbeitung.
|
||||
|
||||
Service-Status: Nur interne Debug-Builds erhalten einen kompakten, rein lesenden Statusscreen
|
||||
auf Basis der bereits vorhandenen Backend-/Daemon-Verbindungssignale. Keine Prozessdaten,
|
||||
Tokens, Konfigurationen oder Diagnose-Endpunkte werden in Release-Builds angezeigt. Die
|
||||
Match3-/Taxi-Adminwerkzeuge bleiben gemaess Abschnitt 21 ausserhalb der nativen App.
|
||||
|
||||
### 23. Adult Content und Store-Compliance
|
||||
|
||||
- [ ] Adult Content aus MVP entfernen oder per Feature Flag deaktivieren.
|
||||
- [ ] Altersverifikation nativ modellieren.
|
||||
- [ ] UGC-Melden nativ in Chat, Galerie, Forum, Profil implementieren.
|
||||
- [ ] Blockieren nativ implementieren.
|
||||
- [ ] Moderationserreichbarkeit dokumentieren.
|
||||
- [ ] Datenschutzseite nativ erreichbar machen.
|
||||
- [ ] Impressum nativ erreichbar machen.
|
||||
- [ ] Kontakt nativ erreichbar machen.
|
||||
- [ ] Account-Loeschung oder klare Anleitung nativ erreichbar machen.
|
||||
- [ ] Play Store Content Rating vorbereiten.
|
||||
- [ ] Store-Review-Risiko fuer Adult Content separat entscheiden.
|
||||
- [x] Adult Content aus MVP entfernen oder per Feature Flag deaktivieren.
|
||||
- [x] Altersverifikation nativ modellieren.
|
||||
- [x] UGC-Melden nativ in Chat, Galerie, Forum, Profil implementieren.
|
||||
- [x] Blockieren nativ implementieren.
|
||||
- [x] Moderationserreichbarkeit dokumentieren.
|
||||
- [x] Datenschutzseite nativ erreichbar machen.
|
||||
- [x] Impressum nativ erreichbar machen.
|
||||
- [x] Kontakt nativ erreichbar machen.
|
||||
- [x] Account-Loeschung oder klare Anleitung nativ erreichbar machen.
|
||||
- [x] Play Store Content Rating vorbereiten.
|
||||
- [x] Store-Review-Risiko fuer Adult Content separat entscheiden.
|
||||
|
||||
Stand 2026-07-16: Der geschuetzte Bereich ist im lokalen Debug-Build per `FEATURE_ADULT`
|
||||
aktiviert; Staging und Production bleiben bis zur Store-Entscheidung deaktiviert. Die native App
|
||||
laedt den Status ueber `/api/settings/account` und laedt erst nach lokaler Pruefung von
|
||||
Volljaehrigkeit und `adultAccessEnabled` die serverseitig ebenfalls geschuetzten Endpunkte unter
|
||||
`/api/socialnetwork/erotic/*`. Ein Verifikationsnachweis (JPEG, PNG, WebP oder PDF) wird per
|
||||
Android-Dateiauswahl an `/api/settings/adult-verification/request` gesendet. Die API prueft
|
||||
zusaetzlich Alter und Verifikationsstatus. Die Account-Endpunkte weisen nun ausserdem Anfragen
|
||||
ab, deren Body-`userId` nicht der authentifizierten `userid` entspricht.
|
||||
|
||||
Blockieren verwendet den neuen serverseitigen Vertrag `POST`/`DELETE
|
||||
/api/socialnetwork/blocked-users/:userId` und die Migration
|
||||
`20260716000000-create-user-block.sql`; der Profil-Screen bietet die Blockaktion nativ an.
|
||||
|
||||
Die Store-Entscheidung und Rating-Vorbereitung sind in `android/STORE_COMPLIANCE.md`
|
||||
dokumentiert: Der Bereich bleibt ausserhalb lokaler Debug-Builds deaktiviert, bis eine formelle
|
||||
Store- und Altersfreigabe vorliegt.
|
||||
|
||||
### 24. Push Notifications
|
||||
|
||||
- [ ] Firebase Projekt klaeren.
|
||||
- [ ] FCM in native App integrieren.
|
||||
- [ ] Device Token Backend-Modell planen.
|
||||
- [ ] Device Token Registration API definieren.
|
||||
- [ ] Opt-in UI implementieren.
|
||||
- [ ] Notification Settings implementieren.
|
||||
- [ ] Chat Push definieren.
|
||||
- [ ] Friend Login Push definieren.
|
||||
- [ ] Falukant Event Push definieren.
|
||||
- [ ] Vocab Reminder Push definieren.
|
||||
- [ ] Deep Links aus Notifications implementieren.
|
||||
- [ ] Token Refresh Handling implementieren.
|
||||
- [x] Firebase Projekt klaeren.
|
||||
- [x] FCM in native App integrieren.
|
||||
- [x] Device Token Backend-Modell planen.
|
||||
- [x] Device Token Registration API definieren.
|
||||
- [x] Opt-in UI implementieren.
|
||||
- [x] Notification Settings implementieren.
|
||||
- [x] Chat Push definieren.
|
||||
- [x] Friend Login Push definieren.
|
||||
- [x] Falukant Event Push definieren.
|
||||
- [x] Vocab Reminder Push definieren.
|
||||
- [x] Deep Links aus Notifications implementieren.
|
||||
- [x] Token Refresh Handling implementieren.
|
||||
- [ ] Firebase-Service-Account im Backend-Deployment hinterlegen (`FIREBASE_SERVICE_ACCOUNT_PATH` oder `FIREBASE_SERVICE_ACCOUNT_JSON`).
|
||||
|
||||
### 25. Deep Links und OAuth
|
||||
|
||||
- [ ] App Links Domain festlegen.
|
||||
- [ ] `assetlinks.json` planen.
|
||||
- [ ] OAuth Redirect URIs fuer Android planen.
|
||||
- [ ] Custom Tabs Flow implementieren.
|
||||
- [ ] OAuth Callback Handling implementieren.
|
||||
- [ ] Deep Links fuer Profile, Forum, Falukant, Vocab, Blog definieren.
|
||||
- [ ] Deep Link Auth Guard implementieren.
|
||||
- [ ] Nicht eingeloggte Deep Links nach Login fortsetzen.
|
||||
- [x] App Links Domain festlegen.
|
||||
- [x] `assetlinks.json` planen.
|
||||
- [x] Deep-Link-Struktur fuer Auth, Home, Social, Falukant, Vocab, Settings und Public Content definieren.
|
||||
- [x] OAuth Redirect URIs fuer Android planen.
|
||||
- [x] Custom Tabs Flow implementieren.
|
||||
- [x] OAuth Callback Handling implementieren.
|
||||
- [x] Deep Links fuer Profile, Forum, Falukant, Vocab, Blog definieren.
|
||||
- [x] Deep Link Auth Guard implementieren.
|
||||
- [x] Nicht eingeloggte Deep Links nach Login fortsetzen.
|
||||
|
||||
### 26. Sicherheit
|
||||
|
||||
- [ ] Authdaten nicht im Klartext speichern.
|
||||
- [ ] Release Logging sensibler Daten verhindern.
|
||||
- [ ] Certificate Pinning bewerten, nicht vorschnell erzwingen.
|
||||
- [ ] Network Security Config fuer Release restriktiv halten.
|
||||
- [ ] Root/Jailbreak Detection bewusst entscheiden.
|
||||
- [ ] Screenshot-Schutz fuer Adult/Private Bereiche bewerten.
|
||||
- [ ] Datei-Uploads auf MIME/Größe pruefen.
|
||||
- [ ] WebView-Fallbacks minimieren.
|
||||
- [ ] Dependency-Scanning fuer Android einrichten.
|
||||
- [x] Authdaten nicht im Klartext speichern.
|
||||
- [x] Release Logging sensibler Daten verhindern.
|
||||
- [x] Certificate Pinning bewerten, nicht vorschnell erzwingen.
|
||||
- [x] Network Security Config fuer Release restriktiv halten.
|
||||
- [x] Root/Jailbreak Detection bewusst entscheiden.
|
||||
- [x] Screenshot-Schutz fuer Adult/Private Bereiche bewerten.
|
||||
- [x] Datei-Uploads auf MIME/Größe pruefen.
|
||||
- [x] WebView-Fallbacks minimieren.
|
||||
- [x] Dependency-Scanning fuer Android einrichten.
|
||||
|
||||
### 27. Testing
|
||||
|
||||
- [ ] Unit Tests fuer Auth Repository.
|
||||
- [ ] Unit Tests fuer Settings Repository.
|
||||
- [ ] Unit Tests fuer Error Mapping.
|
||||
- [ ] MockWebServer Tests fuer Auth Header.
|
||||
- [ ] MockWebServer Tests fuer API-Fehler.
|
||||
- [ ] Room Migration Tests.
|
||||
- [ ] Compose Tests fuer Login.
|
||||
- [ ] Compose Tests fuer Navigation.
|
||||
- [ ] Compose Tests fuer Home.
|
||||
- [ ] Compose Tests fuer Vocab Lesson.
|
||||
- [ ] Realtime Tests mit Testserver planen.
|
||||
- [ ] Emulator-Testmatrix definieren: kleines Phone, grosses Phone, Tablet.
|
||||
- [ ] Echtes Android-Geraet in Testmatrix aufnehmen.
|
||||
- [ ] Offline/Online-Wechsel testen.
|
||||
- [ ] App Kill/Restart/Resume testen.
|
||||
- [x] Unit Tests fuer Auth Repository.
|
||||
- [x] Unit Tests fuer Settings Repository.
|
||||
- [x] Unit Tests fuer Error Mapping.
|
||||
- [x] MockWebServer Tests fuer Auth Header.
|
||||
- [x] MockWebServer Tests fuer API-Fehler.
|
||||
- [x] Room Migration Tests.
|
||||
- [x] Compose Tests fuer Login.
|
||||
- [x] Compose Tests fuer Navigation.
|
||||
- [x] Compose Tests fuer Home.
|
||||
- [x] Compose Tests fuer Vocab Lesson.
|
||||
- [x] Realtime Tests mit Testserver planen.
|
||||
- [x] Emulator-Testmatrix definieren: kleines Phone, grosses Phone, Tablet.
|
||||
- [x] Echtes Android-Geraet in Testmatrix aufnehmen.
|
||||
- [x] Offline/Online-Wechsel testen.
|
||||
- [x] App Kill/Restart/Resume testen.
|
||||
- [ ] Instrumentation-Suite auf einem verbundenen Geraet oder KVM-faehigen Host ausfuehren (lokal blockiert: kein ADB-Geraet, keine x86_64-Hardwarebeschleunigung).
|
||||
|
||||
### 28. Build, Release und Betrieb
|
||||
|
||||
@@ -593,6 +824,8 @@ Stand 2026-07-09:
|
||||
|
||||
### 29. Backend-Vorbereitung fuer Native
|
||||
|
||||
- [ ] Release-Signaturfingerprint in die ausgelieferte `/.well-known/assetlinks.json` eintragen.
|
||||
- [ ] Native OAuth-Redirect-URI bei jedem aktivierten Provider hinterlegen.
|
||||
- [ ] Mobile API-Inventar aus allen Web-Komponenten erstellen.
|
||||
- [ ] API-Versionierung bewerten: `/api/mobile/v1` ja/nein.
|
||||
- [ ] Einheitliches Fehlerformat definieren.
|
||||
|
||||
0
android/README.md
Normal file → Executable file
37
android/SECURITY.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# Native Android Security
|
||||
|
||||
## Umgesetzte Schutzmaßnahmen
|
||||
|
||||
- Die Sitzung liegt ausschließlich in `EncryptedSharedPreferences` mit Android-Master-Key.
|
||||
- Release-Builds enthalten keinen HTTP-Body-Logger. Der detaillierte OkHttp-Logger ist auf
|
||||
Nicht-Release-Builds begrenzt.
|
||||
- Release-Netzwerkverkehr erlaubt kein Cleartext. Nur der lokale Debug-Flavor darf
|
||||
`10.0.2.2` und `localhost` per HTTP ansprechen.
|
||||
- Chat, Galerie, Persönliches und der Adult-Bereich setzen `FLAG_SECURE`. Damit verhindert
|
||||
Android Screenshots, Bildschirmaufnahmen und die Anzeige im App-Switcher.
|
||||
- Uploads werden vor dem Service auf einen erlaubten MIME-Typ und eine Größe begrenzt:
|
||||
Bilder/Verifikationsnachweise 10 MiB, Videos 100 MiB. Bilder werden zusätzlich durch
|
||||
Sharp dekodiert, damit ein behaupteter MIME-Typ nicht genügt.
|
||||
|
||||
## Bewusste Entscheidungen
|
||||
|
||||
### Certificate Pinning
|
||||
|
||||
Certificate Pinning wird aktuell **nicht** erzwungen. Die API verwendet HTTPS und die
|
||||
plattformseitige Trust-Store-Prüfung. Pinning würde bei Zertifikats- oder CDN-Wechseln ohne
|
||||
App-Update zu vollständigen Ausfällen führen. Es wird erst eingeführt, wenn es mindestens zwei
|
||||
parallel gültige Pins, ein dokumentiertes Rotation-Verfahren und Monitoring für Pin-Fehler gibt.
|
||||
|
||||
### Root- und Bootloader-Erkennung
|
||||
|
||||
Die App blockiert gerootete Geräte nicht. Eine lokale Erkennung ist umgehbar und würde legitime
|
||||
Nutzer sowie Emulator-Tests ausschließen. Sensible Daten bleiben verschlüsselt, Screenshots in
|
||||
sensiblen Bereichen sind gesperrt und Berechtigungen werden auf dem Server durchgesetzt.
|
||||
Play Integrity wird bei späteren Hochrisiko-Aktionen als serverseitig prüfbares Signal bewertet,
|
||||
nicht als pauschale Startblockade.
|
||||
|
||||
## Dependency Scanning
|
||||
|
||||
`.github/workflows/android-security.yml` führt bei Pull Requests und Pushes einen
|
||||
OSV-Abhängigkeitsscan sowie Android-Lint für den Produktions-Release aus. Kritische Findings
|
||||
werden vor einem Release bewertet.
|
||||
17
android/STORE_COMPLIANCE.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# Store-Compliance
|
||||
|
||||
## Adult Content
|
||||
|
||||
- `FEATURE_ADULT` ist nur im lokalen Debug-Build aktiv.
|
||||
- Staging und Production liefern keinen nativen Adult-Bereich aus.
|
||||
- Vor einer Aktivierung sind Play-Content-Rating, Altersklassifizierung, Moderationsprozess,
|
||||
Meldewege und die Store-Richtlinien erneut zu pruefen und freizugeben.
|
||||
- Die API bleibt auch bei aktivem Client-Feature die Autoritaet: Volljaehrigkeit und der Status
|
||||
`approved` der Altersverifikation sind fuer jeden geschuetzten Endpunkt erforderlich.
|
||||
|
||||
## UGC und Moderation
|
||||
|
||||
- Native Meldungen existieren fuer Chat, Forum, Profile, Gaestebuch und Galerie.
|
||||
- Meldungen werden serverseitig gespeichert und sind fuer berechtigte Moderatoren sichtbar.
|
||||
- Nutzerblockaden werden serverseitig in `community.user_block` gespeichert; die SQL-Migration
|
||||
`backend/migrations/20260716000000-create-user-block.sql` ist vor dem Rollout auszufuehren.
|
||||
45
android/TESTING.md
Normal file
@@ -0,0 +1,45 @@
|
||||
# Native Android Testmatrix
|
||||
|
||||
## Automatisiert
|
||||
|
||||
| Bereich | Testart | Ausführung |
|
||||
| --- | --- | --- |
|
||||
| Auth, Settings, HTTP-Fehler, Header, Daemon-Parser | JVM + MockWebServer | `./gradlew :app:testLocalDebugUnitTest` |
|
||||
| Room-Migration und verschlüsselte Session nach Store-Neuerzeugung | Instrumentation | `./gradlew :app:connectedLocalDebugAndroidTest` |
|
||||
| Login, Navigation, Home und Vokabel-Lektion | Compose Instrumentation | `./gradlew :app:connectedLocalDebugAndroidTest` |
|
||||
| Realtime | JVM-Parser plus manueller Socket.IO-Testserver-Plan | siehe unten |
|
||||
|
||||
### Lokaler Ausfuehrungsstatus
|
||||
|
||||
- Die JVM-Suite (`:app:testLocalDebugUnitTest`) ist erfolgreich ausgefuehrt.
|
||||
- Die Instrumentation-Suite inklusive Room- und Compose-Tests kompiliert erfolgreich.
|
||||
- Die Ausfuehrung auf diesem Host ist blockiert: Es ist kein ADB-Geraet verbunden und die
|
||||
x86_64-Emulatoren benoetigen KVM-Hardwarebeschleunigung, die hier nicht verfuegbar ist.
|
||||
Das vorhandene ARM64-System-Image kann auf einem x86_64-Host nicht emuliert werden.
|
||||
- Auf einem Host mit KVM oder einem verbundenen Geraet wird die Suite mit
|
||||
`./gradlew :app:connectedLocalDebugAndroidTest` ausgefuehrt. Der CI-Workflow
|
||||
`.github/workflows/android-tests.yml` fuehrt dieselbe Suite auf einem GitHub-Emulator aus.
|
||||
|
||||
## Emulator- und Geräte-Matrix
|
||||
|
||||
| Ziel | Pflichtfälle |
|
||||
| --- | --- |
|
||||
| Kleines Phone, API 34+ | Login, Navigation, Formular, Tastatur, Adult-Screenshotschutz |
|
||||
| Großes Phone, API 34+ | Galerie, Falukant und Vokabel-Lektion |
|
||||
| Tablet, API 34+ | Drawer, Landscape und Listenbreiten |
|
||||
| Reales Android-Gerät, aktuelle API | Push-Berechtigung, OAuth Custom Tab, App Links, Kamera/Dateiauswahl |
|
||||
|
||||
Die Gradle Managed Devices `mediumPhone` und `mediumTablet` decken die CI-Basis ab. Das lokale
|
||||
Team ergänzt für jeden Release-Lauf die installierten kleinen/großen Emulatoren und mindestens
|
||||
ein reales Gerät.
|
||||
|
||||
## Netzwerk, Realtime und Lifecycle
|
||||
|
||||
1. Backend und Daemon starten, mit einem Testkonto anmelden und Socket.IO-Verbindung prüfen.
|
||||
2. Backend stoppen: Offline-Banner, verständlicher Fehler und keine blockierte Navigation prüfen.
|
||||
3. Backend wieder starten: Screen aktualisieren und Realtime-Verbindung erneut prüfen.
|
||||
4. App im Hintergrund beenden und über Launcher oder Push erneut öffnen: verschlüsselte Sitzung,
|
||||
Deep-Link-Fortsetzung und Realtime-Reconnect prüfen.
|
||||
5. Für Socket.IO-Regressionen wird ein isolierter Node-Testserver mit den Ereignissen
|
||||
`friendloginchanged`, `falukantUpdateStatus`, `familychanged` und `reloadmenu` verwendet.
|
||||
Der Android-Test verbindet sich mit dessen URL statt mit Production.
|
||||
0
android/android/.idea/AndroidProjectSystem.xml
generated
Normal file → Executable file
6
android/android/.idea/compiler.xml
generated
Executable file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<bytecodeTargetLevel target="21" />
|
||||
</component>
|
||||
</project>
|
||||
4
android/android/.idea/deploymentTargetSelector.xml
generated
Normal file → Executable file
@@ -6,6 +6,10 @@
|
||||
<option name="selectionMode" value="DROPDOWN" />
|
||||
<DialogSelection />
|
||||
</SelectionState>
|
||||
<SelectionState runConfigName="app">
|
||||
<option name="selectionMode" value="DROPDOWN" />
|
||||
<DialogSelection />
|
||||
</SelectionState>
|
||||
</selectionStates>
|
||||
</component>
|
||||
</project>
|
||||
0
android/android/.idea/migrations.xml
generated
Normal file → Executable file
3
android/android/.idea/misc.xml
generated
Normal file → Executable file
@@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="ProjectRootManager" version="2">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
<component name="ProjectType">
|
||||
|
||||
0
android/android/.idea/runConfigurations.xml
generated
Normal file → Executable file
0
android/android/.idea/runConfigurations/YourPart_Debug.xml
generated
Normal file → Executable file
0
android/android/app/build.gradle
Normal file → Executable file
0
android/android/app/capacitor.build.gradle
Normal file → Executable file
0
android/android/app/proguard-rules.pro
vendored
Normal file → Executable file
0
android/android/app/src/androidTest/java/de/yourpart/app/ExampleInstrumentedTest.java
Normal file → Executable file
0
android/android/app/src/main/AndroidManifest.xml
Normal file → Executable file
0
android/android/app/src/main/java/de/yourpart/app/MainActivity.java
Normal file → Executable file
0
android/android/app/src/main/res/drawable-land-hdpi/splash.png
Normal file → Executable file
|
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 7.5 KiB |
0
android/android/app/src/main/res/drawable-land-mdpi/splash.png
Normal file → Executable file
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
0
android/android/app/src/main/res/drawable-land-xhdpi/splash.png
Normal file → Executable file
|
Before Width: | Height: | Size: 9.0 KiB After Width: | Height: | Size: 9.0 KiB |
0
android/android/app/src/main/res/drawable-land-xxhdpi/splash.png
Normal file → Executable file
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
0
android/android/app/src/main/res/drawable-land-xxxhdpi/splash.png
Normal file → Executable file
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
0
android/android/app/src/main/res/drawable-port-hdpi/splash.png
Normal file → Executable file
|
Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 7.7 KiB |
0
android/android/app/src/main/res/drawable-port-mdpi/splash.png
Normal file → Executable file
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
0
android/android/app/src/main/res/drawable-port-xhdpi/splash.png
Normal file → Executable file
|
Before Width: | Height: | Size: 9.6 KiB After Width: | Height: | Size: 9.6 KiB |
0
android/android/app/src/main/res/drawable-port-xxhdpi/splash.png
Normal file → Executable file
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
0
android/android/app/src/main/res/drawable-port-xxxhdpi/splash.png
Normal file → Executable file
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
0
android/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
Normal file → Executable file
0
android/android/app/src/main/res/drawable/ic_launcher_background.xml
Normal file → Executable file
0
android/android/app/src/main/res/drawable/splash.png
Normal file → Executable file
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
0
android/android/app/src/main/res/layout/activity_main.xml
Normal file → Executable file
0
android/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
Normal file → Executable file
0
android/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
Normal file → Executable file
0
android/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
Normal file → Executable file
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB |
0
android/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png
Normal file → Executable file
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
0
android/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
Normal file → Executable file
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
0
android/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
Normal file → Executable file
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
0
android/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png
Normal file → Executable file
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
0
android/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
Normal file → Executable file
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB |
0
android/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
Normal file → Executable file
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
0
android/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png
Normal file → Executable file
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.9 KiB |
0
android/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
Normal file → Executable file
|
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 6.4 KiB |
0
android/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
Normal file → Executable file
|
Before Width: | Height: | Size: 6.5 KiB After Width: | Height: | Size: 6.5 KiB |
0
android/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png
Normal file → Executable file
|
Before Width: | Height: | Size: 9.6 KiB After Width: | Height: | Size: 9.6 KiB |
0
android/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
Normal file → Executable file
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
0
android/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Normal file → Executable file
|
Before Width: | Height: | Size: 9.2 KiB After Width: | Height: | Size: 9.2 KiB |
0
android/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png
Normal file → Executable file
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
0
android/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
Normal file → Executable file
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
0
android/android/app/src/main/res/values/ic_launcher_background.xml
Normal file → Executable file
0
android/android/app/src/main/res/values/strings.xml
Normal file → Executable file
0
android/android/app/src/main/res/values/styles.xml
Normal file → Executable file
0
android/android/app/src/main/res/xml/file_paths.xml
Normal file → Executable file
0
android/android/app/src/test/java/de/yourpart/app/ExampleUnitTest.java
Normal file → Executable file
0
android/android/build.gradle
Normal file → Executable file
0
android/android/capacitor.settings.gradle
Normal file → Executable file
0
android/android/gradle.properties
Normal file → Executable file
0
android/android/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file → Executable file
0
android/android/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file → Executable file
0
android/android/gradlew.bat
vendored
Normal file → Executable file
0
android/android/settings.gradle
Normal file → Executable file
0
android/android/variables.gradle
Normal file → Executable file
0
android/capacitor.config.ts
Normal file → Executable file
6
android/native/.idea/AndroidProjectSystem.xml
generated
Executable file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="AndroidProjectSystem">
|
||||
<option name="providerId" value="com.android.tools.idea.GradleProjectSystem" />
|
||||
</component>
|
||||
</project>
|
||||
2001
android/native/.idea/caches/deviceStreaming.xml
generated
Executable file
18
android/native/.idea/deploymentTargetSelector.xml
generated
Executable file
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="deploymentTargetSelector">
|
||||
<selectionStates>
|
||||
<SelectionState runConfigName="YourPartNative.app">
|
||||
<option name="selectionMode" value="DROPDOWN" />
|
||||
<DropdownSelection timestamp="2026-07-10T13:18:31.238846181Z">
|
||||
<Target type="DEFAULT_BOOT">
|
||||
<handle>
|
||||
<DeviceId pluginId="LocalEmulator" identifier="path=/home/torsten/.config/.android/avd/Medium_Tablet.avd" />
|
||||
</handle>
|
||||
</Target>
|
||||
</DropdownSelection>
|
||||
<DialogSelection />
|
||||
</SelectionState>
|
||||
</selectionStates>
|
||||
</component>
|
||||
</project>
|
||||
13
android/native/.idea/deviceManager.xml
generated
Executable file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="DeviceTable">
|
||||
<option name="columnSorters">
|
||||
<list>
|
||||
<ColumnSorterState>
|
||||
<option name="column" value="Name" />
|
||||
<option name="order" value="ASCENDING" />
|
||||
</ColumnSorterState>
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
30
android/native/.idea/gradle.xml
generated
Executable file
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="GradleMigrationSettings" migrationVersion="1" />
|
||||
<component name="GradleSettings">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<GradleProjectSettings>
|
||||
<option name="testRunner" value="CHOOSE_PER_TEST" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" />
|
||||
<option name="modules">
|
||||
<set>
|
||||
<option value="/mnt/share/torsten/Programs/YourPart3/android/native" />
|
||||
<option value="/mnt/share/torsten/Programs/YourPart3/android/native/app" />
|
||||
</set>
|
||||
</option>
|
||||
</GradleProjectSettings>
|
||||
<GradleProjectSettings>
|
||||
<option name="testRunner" value="CHOOSE_PER_TEST" />
|
||||
<option name="externalProjectPath" value="/mnt/share/torsten/Programs/YourPart3/android/native" />
|
||||
<option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" />
|
||||
<option name="modules">
|
||||
<set>
|
||||
<option value="/mnt/share/torsten/Programs/YourPart3/android/native" />
|
||||
<option value="/mnt/share/torsten/Programs/YourPart3/android/native/app" />
|
||||
</set>
|
||||
</option>
|
||||
</GradleProjectSettings>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
8
android/native/.idea/markdown.xml
generated
Executable file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="MarkdownSettings">
|
||||
<option name="previewPanelProviderInfo">
|
||||
<ProviderInfo name="Compose (experimental)" className="com.intellij.markdown.compose.preview.ComposePanelProvider" />
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
10
android/native/.idea/migrations.xml
generated
Executable file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectMigrations">
|
||||
<option name="MigrateToGradleLocalJavaHome">
|
||||
<set>
|
||||
<option value="/mnt/share/torsten/Programs/YourPart3/android/native" />
|
||||
</set>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
9
android/native/.idea/misc.xml
generated
Executable file
@@ -0,0 +1,9 @@
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
<component name="ProjectType">
|
||||
<option name="id" value="Android" />
|
||||
</component>
|
||||
</project>
|
||||
17
android/native/.idea/runConfigurations.xml
generated
Executable file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="RunConfigurationProducerService">
|
||||
<option name="ignoredProducers">
|
||||
<set>
|
||||
<option value="com.intellij.execution.junit.AbstractAllInDirectoryConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.AllInPackageConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.PatternConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.TestInClassConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.UniqueIdConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.testDiscovery.JUnitTestDiscoveryConfigurationProducer" />
|
||||
<option value="org.jetbrains.kotlin.idea.junit.KotlinJUnitRunConfigurationProducer" />
|
||||
<option value="org.jetbrains.kotlin.idea.junit.KotlinPatternConfigurationProducer" />
|
||||
</set>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||