<!-- /docs/architecture.md -->

# 🧠 Architekturübersicht – NodeMap

Dieses Dokument beschreibt die technische Gesamtarchitektur des Projekts **NodeMap**, einer
kartenbasierten Webanwendung zur Anzeige, Bearbeitung und Verwaltung von GIS-Daten, POIs und
Gerätestatus.

---

## ⚙️ Technologie-Stack

| Komponente            | Beschreibung                                                           |
| --------------------- | ---------------------------------------------------------------------- |
| **Frontend**          | React 18 + Next.js (App Router)                                        |
| **State-Management**  | Redux Toolkit mit zentralem Store, Thunks & Slices                     |
| **UI**                | Tailwind CSS + Leaflet + React-Icons                                   |
| **Backend-Anbindung** | Webservices via `WebServiceMap.asmx` (IIS) + lokale Next.js API für DB |
| **Datenbank**         | MySQL (Produktiv & Entwicklung, z. T. via Docker)                      |
| **Deployment**        | Windows Server (IIS), optional per `nssm` als Dienst                   |

---

## 🔄 Systemübersicht (Ablauf)

```mermaid
sequenceDiagram
  participant Browser
  participant TALASweb
  participant NodeMap
  participant MySQL

  Browser->>TALASweb: mapTypC.aspx?m=12&u=484
  TALASweb-->>Browser: iFrame lädt NodeMap
  Browser->>NodeMap: Liest m & u aus URL
  NodeMap->>TALASweb: WebService-Requests (5 APIs)
  NodeMap->>MySQL: API-Anfragen zu POIs, Geräten, Linien
  NodeMap-->>Browser: Interaktive Karte anzeigen

```

---

## 🗺️ Architekturüberblick

```
+------------------+       +------------------+       +------------------+
|   Leaflet Map    | <---> |   Redux Store    | <---> |   Webservices    |
| (Interaktivität) |       |  (Status & Data) |       |  (IIS, .asmx)    |
+------------------+       +------------------+       +------------------+
        ^
        |
        v
+------------------+       +------------------+        +-------------------+
|  POI-Komponenten | <---> |   Redux Slices   | <--->  | Next.js API-Routen|
|   (Add/Edit)     |       | (z. B. poiSlice) |        |   (Datenbank)     |
+------------------+       +------------------+        +-------------------+
```

---

## 🔁 Datenfluss (Beispiel: POI anzeigen)

1. Leaflet-Karte lädt bei `MapComponent` Mounting
2. Redux-Thunk `fetchPoiMarkersThunk` wird ausgelöst
3. Thunk ruft `fetchPoiDataService.js` (DB) oder Webservice (IIS) auf
4. Ergebnisse werden im Slice `readPoiMarkersStoreSlice` gespeichert
5. Komponenten lesen POI-Daten über `useSelector(...)` aus dem Store
6. POIs werden als Marker in Leaflet gesetzt

---

## 📁 Schlüsselfunktionen & Module

| Bereich       | Datei/Modul                                     | Aufgabe                                  |
| ------------- | ----------------------------------------------- | ---------------------------------------- |
| Kartenlogik   | `MapComponent.js`                               | Zentrale Initialisierung und Layer-Logik |
| Webservices   | `services/webservice/`                          | Kommunikation mit TALAS V5 Webservice    |
| Datenbank     | `services/database/`                            | Zugriff auf lokale Next.js-API & DB      |
| POIs          | `AddPOIModal.js`, `PoiUpdateModal.js`           | UI für POI-Erstellung & -Bearbeitung     |
| Redux         | `redux/slices/`, `redux/thunks/`, `redux/store` | Globaler State, API-Steuerung            |
| Konfiguration | `.env.local`, `config.js`, dynamic URLs         | IP, basePath, Ports                      |

---

## 🧩 Besonderheiten

- **Konfigurierbarer basePath:**  
  Pfad wie `/talas5` ist optional und kann per `NEXT_PUBLIC_BASE_PATH` in `.env.local` gesetzt
  werden.
- **Rechteabhängige UI:**  
  Funktionen (z. B. POI bearbeiten) basieren auf Benutzerrechten (`IdRight`) vom Server.
- **Zentrale Komponentensteuerung:**  
  Komponenten wie `MapLayersControlPanel` oder `CoordinatePopup` kontrollieren Layer & Interaktion.
- **Kontextmenü-Logik:**  
  Marker & Polylinien besitzen eigene Kontextmenüs – dynamisch zusammengesetzt und verwaltet.

---

## 📦 Versionierung & Builds

- Version ist in `appVersion.js` definiert → wird über `NEXT_PUBLIC_APP_VERSION` eingeblendet
- Build erfolgt via `npm run build`, Auslieferung über `.next/`
- Nicht benötigte Dateien wie `__tests__`, `docs/`, `scripts/` etc. werden nicht in den Build
  aufgenommen

---

## 📚 Weiterführende Dokumentation

- [`build-and-deploy.md`](./build-and-deploy.md)
- [`env.local.schema.md`](./env.local.schema.md)
- [`redux/slices/`](./redux/slices/)
- [`services/webservice/`](./services/webservice/)

---

## Dynamische Layer-Verwaltung mit Redux

```mermaid
flowchart TD
    %% Webservice
    subgraph Webservice
        A1[GisSystemStatic API]
        A2[GisStationsStaticDistrict API]
    end

    %% Redux
    subgraph Redux
        B1[fetchGisSystemStaticThunk]
        B2[fetchGisStationsStaticDistrictThunk]
        C1["gisSystemStaticSlice → selectGisSystemStatic"]
        C2["gisStationsStaticDistrictSlice → selectGisStationsStaticDistrict"]
        C3["mapLayersSlice → mapLayersVisibility"]
    end

    %% React
    subgraph React-Komponente
        D1[MapComponent.js]
        D2["useEffect: dynamische Layer"]
        D3["createAndSetDevices"]
        D4["layerRefs (useRef)"]
        D5["markerStates (useState)"]
        D6["useEffect: Sichtbarkeit prüfen"]
        D7["Map aktualisieren / add/remove"]
        D8["checkOverlappingMarkers"]
    end

    %% Datenfluss
    A1 --> B1 --> C1 --> D2
    A2 --> B2 --> C2 --> D3
    C3 --> D6
    D2 --> D3
    D3 --> D4
    D3 --> D5
    D5 --> D6
    D6 --> D7
    D6 --> D8
    D7 --> D1




```

---

Jetzt (dynamisch & Redux-basiert): MapComponent.js ruft folgenden Hook auf:

js Copy Edit const { markerStates, layerRefs } = useDynamicDeviceLayers(map, GisSystemStatic,
mapLayersVisibility, priorityConfig, oms); useDynamicDeviceLayers.js verarbeitet die
GisSystemStatic-Liste:

Jedes System (z. B. "TALAS", "ECI", "Cisco") bekommt einen eigenen Marker-Layer.

Die Marker werden erstellt durch:

js Copy Edit createAndSetDevices(...) // Systemweise Marker erzeugen createAndSetDevices.js:

Filtert alle Stations aus staticDistrictData, deren System === IdSystem.

Erstellt Marker für jedes Gerät.

Bindet Popup, Kontextmenü, Styling, Bounce usw.

Ruft setMarkersFunction(markers) auf → Übergibt die Marker zurück an den Hook.

Der Hook speichert:

js Copy Edit setMarkerStates((prev) => ({ ...prev, [Name]: newMarkers })); MapComponent.js hat dann:

Zugriff auf alle Marker dynamisch über markerStates (ein Objekt mit Schlüssel = Systemname)

Sichtbarkeit und OverlappingMarkerSpiderfier werden damit verarbeitet.

---

🔁 Die Geräte-Marker sind nicht mehr fest codiert, sondern werden dynamisch erzeugt anhand der
Webservice-Daten GisSystemStatic.

🔄 Sichtbarkeit (Checkbox im Control Panel) löst ein Event visibilityChanged aus → MapComponent
reagiert und rendert Marker neu.

🕷️ Überlappende Marker werden mit checkOverlappingMarkers + PlusRoundIcon verarbeitet.

```mermaid
flowchart TD
    A1[MapComponent] --> B1[useDynamicDeviceLayers]
    B1 --> C1[loop über GisSystemStatic]
    C1 --> D1[createAndSetDevices]
    D1 --> E1[Filter stations aus Redux]
    E1 --> F1[erstelle Marker /Leaflet]
    F1 --> G1[Marker in LayerGroup einfügen]
    G1 --> H1[setMarkerStates im Hook]
    H1 --> A2[markerStates zurück nach MapComponent]

    A2 --> I1[Map aktualisiert Marker]
    A2 --> I2[checkOverlappingMarkers mit OMS]
```

---

10.06.2025

# Datenfluss-Konzept: WebSocket ↔ Redux ↔ UI

Dieses Dokument beschreibt den technischen Ablauf des Live-Datenflusses im NodeMap-Projekt, um neue
Entwickler\:innen beim Onboarding zu unterstützen.

## ᵀᵃᵗᵉᵖᵏᴼᵏᴼᵉ: Architekturübersicht

```mermaid
sequenceDiagram
    autonumber
    participant WS_Server as WebSocket Server
    participant WebService as TALAS WebService
    participant Browser
    participant ReduxStore as Redux Store
    participant UI as React Leaflet UI

    loop Alle 5 Sekunden
        WS_Server->>WebService: fetch endpointX
        alt Daten haben sich geändert
            WS_Server-->>Browser: emit 'endpointXUpdated'
            Browser->>ReduxStore: dispatch(fetchEndpointXThunk())
            ReduxStore->>WebService: fetch endpointX
            WebService-->>ReduxStore: JSON response
            ReduxStore-->>UI: update Slice
            UI-->>User: re-render Markers
        else Keine Änderung
            WS_Server-->>WS_Server: keine Aktion
        end
    end
```

## Beteiligte Komponenten

### WebSocket Server (`server.js`)

- Ruft regelmäßig (`setInterval`) die Webservice-Endpunkte auf.
- Erkennt Änderungen durch JSON-Vergleich (`JSON.stringify`).
- Sendet WebSocket-Events nur bei echten Änderungen.

### Client: MapComponent

- Hört auf `socket.on("endpointXUpdated")`.
- Ruft dann gezielt den passenden Redux-Thunk auf (z. B. `fetchGisLinesStatusThunk`).

### Redux Store & Thunks

- Jeder Endpunkt besitzt:

  - einen `Service` (API-Fetch)
  - einen `Thunk` (Redux-Logik)
  - einen `Slice` (State-Verwaltung)

### React UI (Leaflet Map)

- Beobachtet relevante Redux-Slices via `useSelector()`.
- Aktualisiert Marker, Tooltip und Popup über `createAndSetDevices()` und
  `useDynamicDeviceLayers()`.

## Beispiel-Endpunkte

| Endpunktname                | WebSocket Event                    | Redux Thunk                             |
| --------------------------- | ---------------------------------- | --------------------------------------- |
| `GisLinesStatus`            | `GisLinesStatusUpdated`            | `fetchGisLinesStatusThunk()`            |
| `GisStationsMeasurements`   | `GisStationsMeasurementsUpdated`   | `fetchGisStationsMeasurementsThunk()`   |
| `GisStationsStaticDistrict` | `GisStationsStaticDistrictUpdated` | `fetchGisStationsStaticDistrictThunk()` |
| `GisStationsStatusDistrict` | `GisStationsStatusDistrictUpdated` | `fetchGisStationsStatusDistrictThunk()` |

## Vorteile

- UI aktualisiert sich nur bei echten Datenänderungen → weniger Re-Renders.
- Live-Synchronisation zwischen Datenquelle und Anzeige.
- Skalierbar für beliebige Endpunkte.

## ToDo/Erweiterungen

- Automatische Reconnect-Logik für WebSocket.
- Anzeige des letzten Update-Zeitpunkts in UI.
- Logging-UI für WebSocket-Messages zur Diagnose.

---

> Letzte Änderung: `{{heutiges Datum}}` von Ismail Ali
