Projekt: HydrationFreeze (Technische Spezifikation)
Version: 1.4.3 (Abgeglichen mit Quellcode & Lastenheft v1.4.3)
Status: Aktiv / Finalisiert für Release v1.4.3
| Version | Datum | Status | Änderungen | Autor |
|---|---|---|---|---|
| 1.0.0 | 15.02.2024 | Initial | Grundgerüst der technischen Spezifikation (PF10-30). | D. Obendorf |
| 1.2.0 | 25.02.2024 | Review | Ergänzung der Statistik-Engine und Swift Charts Logik. | D. Obendorf |
| 1.4.0 | 01.03.2024 | Update | Refactoring des Konfigurations-Managements (PF40). | D. Obendorf |
| 1.4.1 | 04.03.2024 | Bugfix | Korrektur der Skalierungslogik für Multi-Monitor-Betrieb. | D. Obendorf |
| 1.4.2 | 05.03.2024 | Final | UML-Live-Rendering fixiert (Mermaid-JS). | D. Obendorf |
| 1.4.3 | 06.03.2024 | Release | Präzisions-Update (%.2f), Auto-Close-Logik & NSCalendarDayChanged Reset. | D. Obendorf |
SwiftUI: Gesamte Benutzeroberfläche und Datenbindung.
AppKit: Fenster-Management (NSPanel) für die System-Sperre.Swift Charts: Visualisierung der Trink-Historie.@AppStorage (UserDefaults) zur Persistenz von Konfigurationsdaten und JSON-Kodierung für das Langzeit-Log ([HydrationLog]).MenuBarExtra sorgt für einen ressourcensparenden Betrieb in der macOS Statusleiste.OverlayManager.NSPanel-Instanzen mit styleMask: [.borderless, .fullSizeContentView] auf dem Level .screenSaver.OverlayView berechnet die Icon-Größe $S_{Icon}$ dynamisch in Abhängigkeit der Gesamtzahl der benötigten Gläser ($n_{Total}$), um die Bildschirmbreite optimal zu nutzen:
\(S_{Icon} = \begin{cases} 45 & \text{wenn } n \leq 8 \\ 35 & \text{wenn } 8 < n \leq 12 \\ 25 & \text{wenn } 12 < n \leq 20 \\ 20 & \text{wenn } n > 20 \end{cases}\)sequenceDiagram
autonumber
participant App as AppState / User
participant OM as OverlayManager
participant Calc as Logic (dynamicIconSize)
participant NS as NSScreen.screens
participant UI as OverlayView (NSPanel)
App->>OM: Trigger: Intervall erreicht
Note over OM: Start Lock-Prozess
OM->>Calc: Sende n_Total (Gläser für Ziel)
Calc-->>OM: Return S_Icon (optimierte Größe)
OM->>NS: Erfrage alle aktiven Displays
loop Für jeden gefundenen Monitor
OM->>UI: Initialisiere Vollbild-Overlay
UI->>UI: Rendere Grid mit S_Icon
Note over UI: Level: .screenSaver (Topmost)
end
OM-->>App: Status: System gesperrt
max(glassesNeededForGoal, glassesDrunk) für die Generierung der Button-Reihe. Dies stellt sicher, dass das Ziel visualisiert wird, auch wenn noch nichts getrunken wurde.glassesRow in eine horizontale ScrollView und dynamisches Spacing, um Überlappungen bei extremen Konfigurationen (z. B. 100ml Gläser bei 5L Ziel) zu verhindern..green und checkmark.circle.fill bei Erreichung von isGoalReached.%.2f. Dies stellt eine mathematisch korrekte Anzeige sicher (0.25L, 0.50L, 0.75L).symbolEffect(.pulse), um das aktuell zu loggende Glas visuell hervorzuheben.addWater()-Funktion. Dies geschieht über ein delegiertes onFinished()-Signal an den OverlayManager.stateDiagram-v2
[*] --> Idle: App-Start
state Idle {
[*] --> WarteAufIntervall
WarteAufIntervall --> CountdownAktiv: Timer läuft (60 min)
}
CountdownAktiv --> OverlaySperre: Timer = 0 & Ziel nicht erreicht
CountdownAktiv --> ZielErreicht: Tagesziel erfüllt
state OverlaySperre {
[*] --> SichtbarAufAllenMonitoren
SichtbarAufAllenMonitoren --> Interaktion: User trinkt Glas
Interaktion --> SichtbarAufAllenMonitoren: Update Progress
}
OverlaySperre --> Idle: Glas geloggt (Sperre hebt auf)
ZielErreicht --> Idle: Neues Glas getrunken (optional)
Idle --> [*]: App Schließen
RuleMark auf der Y-Achse, die an die Variable dailyGoal (in Litern) gebunden ist.getHistory() aggregiert die Tageswerte und stellt sicher, dass Änderungen der Glasgröße rückwirkend für den aktuellen Tag korrekt berechnet werden.SettingsView auf Apple Human Interface Guidelines (HIG) konformes Layout:
Form-Clustern zur Strukturierung.LabeledContent zur sauberen Trennung von Deskriptor und Steuerelement..controlSize(.regular) und .buttonStyle(.borderless).NSSavePanel. Export-Format: Datum;Liter (Dezimal-Komma-Konvertierung für EU-Excel-Kompatibilität).NSCalendarDayChanged: System-Notifikation, die exakt um 00:00 Uhr triggert.didWakeNotification: Erkennt das Erwachen aus dem Standby und validiert das gespeicherte Datum.glassesDrunk) in ein JSON-Objekt serialisiert und in der 14-Tage-Historie persistiert.sequenceDiagram
autonumber
participant S as macOS System
participant AD as AppDelegate
participant UD as UserDefaults (AppStorage)
participant H as JSON History
S->>AD: Notification: .NSCalendarDayChanged / .didWake
AD->>AD: checkNewDay()
alt Datum ungleich lastUpdateDay
AD->>UD: Hole glassesDrunk
AD->>H: Archiviere HydrationLog(yesterday, amount)
AD->>UD: Reset glassesDrunk = 0
AD->>UD: Setze lastUpdateDay = today
else Datum identisch
Note over AD: Keine Aktion erforderlich
end
Zur Sicherstellung der Softwarequalität wurden spezifische Testmethoden (Black-Box-Testing) angewandt:
| Referenz | Testmethode | Szenario / Eingabe | Erwartetes Ergebnis | Status |
|---|---|---|---|---|
| PF10 / LF30 | Äquivalenzklasse | Ziel: 4L, Glas: 200ml (20 Icons) | Icons skalieren auf 25pt; Layout bleibt stabil. | ✅ |
| PF40 / LF35 | UI-Regression | Öffnen der Einstellungen | LabeledContent-Alignment gemäß macOS HIG. | ✅ |
| PF20 / LF60 | Zustandswechsel | Zielerreichung im Overlay | Header wechselt zu grünem Haken & Checkmark. | ✅ |
| PF10 / TC-10 | Grenzwertanalyse | Ziel: 5L, Glas: 100ml (50 Icons) | Korrekte Berechnung ($V_{total} = 5.0L$); ScrollView aktiv. | ✅ |
| PF10 / TC-11 | Entscheidungstabelle | Timer abgelaufen + Ziel bereits erreicht | Sperre triggert trotzdem (Pause-Funktion); Erfolg angezeigt. | ✅ |
| PF10 / TC-12 | Robustheitstest | Monitor-Trennung während Sperre | OverlayManager berechnet Layout sofort neu. |
✅ |
| PF40 / LF70 | Datenvalidierung | CSV-Export (EU-Format) | Valide Datei; Dezimal-Komma statt Punkt genutzt. | ✅ |
| PF20 / TC-14 | Präzision | Glasgröße: 250ml | Anzeige folgt 0.25L Schritten (kein Rundungsfehler). | ✅ |
| PF10 / TC-04 | Regression | Klick auf Tropfen-Icon | Glas wird geloggt UND Overlay schließt sofort. | ✅ |
| PF60 / TC-13 | Zustandsvalidierung | Systemuhr auf 00:00 stellen | Zähler springt auf 0; Historie wird erstellt. | ✅ |
| PF10 / TC-12 | Robustheit | Monitor-Hotplugging | Layout-Rekalkulation erfolgt verzugslos. | ✅ |
Hinweis: Eine detaillierte Aufschlüsselung der Testdurchführung inklusive Zeitstempel und Defect-Reports findet sich in der separaten Testdokumentation.