# Architektur

## Überblick

Das Chronolite-Ökosystem verbindet drei Rollen zu einem geschlossenen Regelkreis für
chronobiologisch wirksame Beleuchtung:

1. **Chronolite App** — das nutzerzentrierte Frontend. Hier geben Nutzer*innen ihre
   Präferenzen (Chronotyp, Geburtsjahr, Lichtfarb-Präferenz) und Routinen ein und
   melden ihren Aufenthaltsort (Raum).
2. **Chronolite Data Hub** — die zentrale, datensparsame Plattform. Sie speichert die
   anonymen Profile, verwaltet die Anwesenheit in Räumen und erzeugt daraus mit der
   Chronolite-Lichtlogik personalisierte **Tageskurven** (Subsystem „Curvis").
3. **IoT Controller** — die lokale Steuerungsinstanz eines Raums. Er abonniert
   Anwesenheitsänderungen seines Raums, holt sich die aktuellen Kurven und rechnet sie
   minütlich in konkrete Stellwerte (Dimmwert, Farbtemperatur) für die
   Raumbeleuchtung um.

```
                 1. anonyme Registrierung, Präferenzen,
                    Routinen, Anwesenheit (REST)
┌──────────────────┐          ┌──────────────────────────┐
│  Chronolite App  │─────────▶│   Chronolite Data Hub    │
│   (Port 4100)    │◀─────────│       (Port 4000)        │
└──────────────────┘ Kurven   │  Lichtlogik („Curvis")   │
                              │  JSON-Persistenz         │
                              └───────────┬──────────────┘
                        2. presenceChanged│ (WebSocket)
                           Kurven (REST)  │
                              ┌───────────▼──────────────┐
                              │      IoT Controller      │
                              │       (Port 4200)        │
                              │  Steuerschleife 1×/min   │
                              └───────────┬──────────────┘
                        3. Dimmwert + CCT │ (hier: console.log)
                              ┌───────────▼──────────────┐
                              │     Raumbeleuchtung      │
                              └──────────────────────────┘
```

## Datenfluss einer typischen Sitzung

1. Die App registriert sich anonym (`POST /api/users`) und erhält eine zufällige ID,
   die sie im Local Storage ablegt.
2. Die Nutzerin hinterlegt Präferenzen (`PUT /api/users/:id/preferences`) und Routinen
   (`POST /api/users/:id/routines`).
3. Sie betritt einen Raum (`POST /api/rooms/:roomId/presence`). Im realen System wird
   dieser Schritt durch QR-Code-Scan, GPS-Geofencing oder BLE-Raumbeacons ausgelöst;
   die Referenzimplementierung nutzt eine manuelle Auswahl aus drei Demo-Räumen.
4. Der Hub benachrichtigt alle WebSocket-Abonnenten des Raums
   (`{"type": "presenceChanged", ...}`).
5. Der IoT Controller des Raums lädt daraufhin die aktuellen Kurven
   (`GET /api/rooms/:roomId/curves`). Der Hub personalisiert sie für die **erste
   anwesende Person** (siehe „Bewusste Vereinfachungen").
6. Die Steuerschleife des Controllers wertet die Kurven einmal pro Minute an der
   aktuellen Tagesminute aus, zieht den (gemockten) Tageslichtanteil ab und übergibt
   Dimmwert und Farbtemperatur an die Beleuchtung — in der Referenz als formatierte
   Konsolenausgabe.
7. Beim Verlassen des Raums wiederholt sich Schritt 4–6; ohne anwesende Person liefert
   der Hub die Basiskurven.

## Komponenten im Detail

### `packages/curves` — geteilte Kurven-Bibliothek

Die fachliche Kernlogik ist bewusst in ein eigenes, von allen drei Anwendungen
genutztes Paket ausgelagert:

- `polygen.js` — erzeugt aus Stützpunkten `[Tagesminute, Wert]` stückweise
  Polynomfunktionen (Newton-Interpolation). Kurven werden als Polynom-Koeffizienten
  über die API transportiert: kompakt, auflösungsunabhängig und von Controllern mit
  wenigen Multiplikationen auswertbar.
- `baseCurves.js` — die Basiskurven (Ziel-mEDI und CCT-Präferenz) für eine
  Referenzperson.
- `adapt.js` — die Personalisierungs-Pipeline (Chronotyp, Alter, Jahreszeit, Routinen,
  Lichtfarb-Präferenz), siehe [ALGORITHMEN.md](ALGORITHMEN.md).

### `apps/hub` — Chronolite Data Hub

Ein einzelner Express-Prozess mit REST-API und WebSocket-Endpunkt
(vollständige API: [API.md](API.md)). Die Persistenz ist eine einzelne, menschenlesbare
JSON-Datei (`apps/hub/data/hub-data.json`), die nach jeder Änderung geschrieben wird.

### `apps/app` — Chronolite App

Eine bewusst schlichte React-Single-Page-App (kein Router, kein
State-Management-Framework). Sie visualisiert zusätzlich die vom Hub gelieferten
Kurven mit Chart.js — so wird das Wirkprinzip der Personalisierung unmittelbar
sichtbar.

### `apps/iot-controller` — IoT Controller

Ein Prozess pro Raum (`ROOM_ID`-Umgebungsvariable). Verbindungsverluste zum Hub werden
automatisch überbrückt (Reconnect + erneutes Abonnieren + Kurven-Resync). Ein kleiner
Status-Endpunkt (`GET :4200/status`) macht den letzten Steuerungs-Tick inspizierbar.

## Datenschutz (Privacy by Design)

Der Hub kennt **keinerlei personenbezogene Daten**: keine Namen, keine Konten, keine
Kontaktdaten. Apps registrieren sich anonym und erhalten eine zufällige UUID; alle
Präferenzen und Routinen sind ausschließlich an diese ID gebunden. Die Raumzuordnung
speichert nur „ID X ist in Raum Y" und wird beim Verlassen wieder gelöscht. Dieses
Prinzip stammt unverändert aus dem Projektsystem und ist eines der zentralen
Wirkprinzipien, die diese Referenz demonstriert.

## Bewusste Vereinfachungen gegenüber dem Projektsystem

Im Förderprojekt lief eine komplexere, hochskalierbare Variante (serverlose
Cloud-Plattform, native Apps, reale Sensorik und Leuchten-Gateways). Für die
Nachvollziehbarkeit wurde hier vereinfacht:

| Thema | Vereinfachung | Im Projektsystem |
| --- | --- | --- |
| Skalierung | Ein Prozess, JSON-Datei | Serverlose Cloud-Architektur, verwaltete Datenbanken |
| App | Lokale Webapp | Native iOS-/Android-App |
| Raumerkennung | Manuelle Auswahl (3 Demo-Räume) | QR-Code, GPS, BLE-Raumbeacons |
| Raumverwaltung | Statische Liste im Code | Registrierung über API/Portal |
| Chronotyp-Erhebung | Direkte MSFsc-Eingabe mit Verweis auf externen Test | Vollständiger MCTQ-Fragebogen in der App |
| Mehrpersonen-Räume | Kurven der **ersten** Person; leerer Raum → Basiskurven. Das Zusammenführen der Präferenzen mehrerer Personen in einem Raum wurde im Rahmen des Projekts noch nicht definiert. | offen (Forschungsfrage) |
| Helligkeitsmessung | Virtueller Tageslicht-Mock | Sensor-Hierarchie (individuell / infrastrukturgebunden / virtuell) |
| Leuchtenansteuerung | `console.log` | IoT-Protokolle (z. B. DALI/KNX, Kabinenbeleuchtungssysteme) |
| Authentifizierung | keine (lokaler Demo-Betrieb) | abgesicherte APIs |

## Erweiterungspunkte

- **Reale Leuchten:** Im Controller die Ausgabe in `controlTick()` durch eine Anbindung
  an das jeweilige Lichtsteuerungssystem ersetzen.
- **Reale Sensorik:** `apps/iot-controller/src/sensor.js` gegen echte Messwerte oder
  ein besseres virtuelles Sensormodell austauschen.
- **Automatische Raumerkennung:** In der App die manuelle Raumauswahl durch
  QR-Scan/GPS/BLE ersetzen; die Hub-API bleibt unverändert.
- **Präferenz-Fusion:** Die „erste Person"-Regel im Hub
  (`GET /api/rooms/:roomId/curves`) durch eine Strategie zum Zusammenführen mehrerer
  Profile ersetzen.
