Komplett clientseitige Implementierung (alle Ressourcen werden einmal geladen,
dann in-memory gefiltert/sortiert/paginiert).
- Suche: Freitext über Titel und Autor (sofort-Filter via oninput)
- Sortierung: Titel, Autor, Hochgeladen, Größe (A-Z/Z-A, asc/desc)
Klickbare Tabellen-Header mit Sortierungspfeilen (↑↓)
- Filter-Dropdowns: Format (ePub/PDF), Autor, Kategorie (Tag)
Dropdowns werden dynamisch aus geladenen Daten befüllt
- Gruppierung: Optional nach Typ/Autor/Kategorie mit visuellen Gruppen-Trennzeilen
- Paging: 20/50/100 Einträge pro Seite, Vor/Zurück + Seitenzahlen (5 sichtbar)
Anzeige: 'Zeigt 1–20 von 138 · Seite 1 von 7'
- CSS: #resources-table th sortierbar (wie #inv-table)
Closes#130
- New POST /api/admin/send-message endpoint (admin-only)
- Messages prefixed with [PLAINTEXT] bypass E2EE decryption
- App recognizes [PLAINTEXT] marker and strips it before display
- Allows easy chat testing without E2EE key management
- Add getUndeliveredStorageBytes() and evictOldestUndelivered() to MessageRepository
- Check mailbox size before saving; evict oldest undelivered messages if over 10 MB
- Return systemMessage in SendMessageResponse when eviction occurs
- App parses systemMessage and displays it in the sender's conversation
- Add SendMessageResponse to shared module for server/app interop
- Update existing tests to use new response format
- Add 3 new tests for eviction behavior
- Add VersionStore that persists versionCode/versionName to data/version.json
- Add POST /api/admin/version secured by BOLLWERK_ADMIN_TOKEN bearer auth
- GET /api/version now reads from VersionStore (fallback to env-vars)
- Update publish-apk.ps1 to use API call instead of SSH+sed+restart
- Update publish SKILL.md and vps-deploy SKILL.md documentation
Closes#100
- Add EncryptionService (AES-256-GCM) with passthrough when no key set
- Flyway V3: enable pgcrypto extension + widen name columns to TEXT
- DatabaseFactory: init EncryptionService from BOLLWERK_DB_ENCRYPTION_KEY,
run migrateEncryptData() to encrypt existing plaintext rows on startup
- InventoryRepository: encrypt on write, decrypt on read for
items.name, items.notes, categories.name, locations.name, settings.value
- MessageRepository: encrypt body on write, decrypt on read
- docker-compose.yml: document BOLLWERK_DB_ENCRYPTION_KEY env var
- docker-compose-vps.yml: pass BOLLWERK_DB_ENCRYPTION_KEY from .env
- .env.example: add key generation template
- .gitignore: add .env to ignore list
Closes#98
- AlertDialog in MainScreen zeigt verfuegbare Version mit Bestaetigung
- UpdateBanner blendet bei UpdateStatus.Available aus (Dialog uebernimmt)
- FEATURE_CAMERA_ENABLED temporaer deaktiviert
fix(server): Logo-Pfad und statische Ressourcen bereinigen
- /res-Route fuer classpath-Assets (logo.png etc.) hinzugefuegt
- Logo-Pfad von /static/logo.png auf /res/logo.png korrigiert
- Build-Nummer aus Versionsanzeige auf der Homepage entfernt
ci: GitHub Actions Workflow fuer Swift-Tests hinzugefuegt
style: Tabellenformatierung im Code-Reviewer-Agenten bereinigt
- Altes Vektor-Foreground (IKEA Gosig-Style) durch PNG-basiertes Logo ersetzt
- Neue Ratte: grau, illustrativ, bronzener Plättchenpanzer, Patronengurt
- Adaptive-Icon-Foreground als PNG in allen Density-Stufen (mdpi–xxxhdpi)
- Legacy-Launcher-Icons mit dunklem Hintergrund (#16140F)
- Hintergrund von Olivgrün (#3D5229) auf App-Theme-Dunkel (#16140F) geändert
- Web-Logo auf Download-Seite eingebunden (/static/logo.png)
- Quelldatei unter docs/ratti.png archiviert
Closes#93
- Neues DTO: InventoryStatsPerInventoryDto (inventoryId, inventoryName,
totalItems, totalLocations, totalCategories, recentTransactions,
lastUpdated, userCount)
- InventoryRepository.getStatsPerInventory(): Stats pro Inventar
- Neuer Endpoint: GET /api/admin/stats/inventories (Admin-only)
- Admin-UI: aufklappbarer Bereich Statistiken pro Inventar (sortierbar)
- Admin-UI: Inventar-Karten durch Tabelle ersetzt mit
- Paging (10/25/50 Eintraege pro Seite)
- Sortierung per Klick auf Spaltenheader
- Filter (alle / mit Benutzern / ohne Benutzer)
- Freitextsuche nach Name oder Inventar-ID
- Tests: 3 neue InventoryRepositoryTests, 3 neue InventoryStatsTests
(401/403/Inhalt fuer neuen Endpoint), setUp bereinigt alle Tabellen
- Alle 148 Tests gruen
#qrcode-Container nutzt jetzt display:flex + justify-content:center
statt margin:0 auto, damit das von QRCode.js generierte Canvas
korrekt mittig angezeigt wird.
Ktor RateLimit-Plugin mit abgestuften Limits pro Endpoint-Gruppe:
- Auth (/api/auth/*): 10 req/min per IP (Brute-Force-Schutz)
- Messages (/api/messages/*): 30 req/min per IP (Spam-Schutz)
- Inventory (/api/inventory/*): 60 req/min per IP (DoS-Schutz)
- Admin (/api/admin/*): 20 req/min per IP
Neue Dateien:
- RateLimiting.kt: Plugin-Konfiguration mit 4 benannten Limitern
- RateLimitingTest.kt: 5 Tests (Limit-Ueberschreitung, Within-Limit,
Health-Endpoint ohne Limit, Retry-After-Header)
Geaenderte Dateien:
- Routing.kt: rateLimit()-Wrapper um Route-Gruppen
- Application.kt: configureRateLimiting() in Plugin-Pipeline
- libs.versions.toml + build.gradle.kts: ktor-server-rate-limit Dep
Closes#75
- Route empfängt JsonObject statt ItemDto, nur übergebene Felder werden aktualisiert
- validatePartialItem() validiert nur vorhandene Felder (name, unit, expiryDate)
- patchItemPartial() im Repository: Guard für leere Felder, kein SQL-Update wenn nichts zu ändern
- Response liefert das aktualisierte Item aus der DB (loadItem) statt des Inputs
- Bestehende Tests in InputValidationTest angepasst (senden nun partielle JSON-Bodys)
- Neue PatchItemTest-Klasse: 10 Tests (Happy Path, 404, Auth, Validierung, Persistenz)
- Alle 554 Tests grün
Closes#56
Closes#66
Server (Serialization.kt):
- ContentNegotiation explizit mit charset=UTF-8 konfiguriert, damit
Response-Header immer 'application/json; charset=utf-8' enthält
App (ChatScreen.kt):
- Emoji-Button (Face-Icon) zur MessageInputBar hinzugefügt, der bei Klick
den Fokus auf das Eingabefeld setzt und die Soft-Keyboard öffnet (System-
IME mit Emoji-Panel-Zugang)
- FocusRequester + LocalSoftwareKeyboardController integriert
Tests:
- Utf8MessagingTest (Server): 6 Tests für Umlaute, Emojis, Multi-Codepoint-
Emojis, gemischte Nachrichten, Konversationsabruf, charset-Header
- ChatViewModelTest (App): 4 neue Tests für Umlaut-, Emoji- und gemischte
Nachrichten
- run-integration-tests.ps1: Szenario 6a mit 5 Testfällen (Umlaute, Emojis,
gemischt, Konversation, WebSocket-Delivery mit UTF-8)