# LD Connect Portal Technische Dokumentation

# Installation

# Systemvoraussetzungen

## Systemvoraussetzungen

<table id="bkmrk-komponenteminimumemp"><thead><tr><th>Komponente</th><th>Minimum</th><th>Empfohlen</th></tr></thead><tbody><tr><td>Betriebssystem</td><td>Ubuntu 22.04 LTS</td><td>Ubuntu 24.04 LTS</td></tr><tr><td>CPU</td><td>2 vCPU</td><td>2 vCPU</td></tr><tr><td>RAM</td><td>1 GB</td><td>2 GB</td></tr><tr><td>Speicher</td><td>30 GB</td><td>60 GB SSD</td></tr></tbody></table>

### Software

- Docker Engine 24+
- Docker Compose v2
- Git
- Nginx als Reverse Proxy
- SSL-Zertifikat

### Powerbird SQL-Benutzer benoetigt

- SELECT auf HWTER, HWMIT, LOURL, ELWZV, ELDVD, ELDVV, ELDVK
- INSERT und UPDATE auf HWTER

### Dimensionierung nach Mitarbeiterzahl

Die Last entsteht weniger durch die Node.js-Anwendung selbst als durch SMB-Lesevorgaenge (Werkzeugbilder, Dokumente) und MSSQL-Abfragen gegen Powerbird. Massgeblich ist die Anzahl gleichzeitig aktiver Nutzer, nicht die Gesamtzahl der Accounts.

<table id="bkmrk-mitarbeiter-%28account"><thead><tr><th>Mitarbeiter (Accounts)</th><th>Gleichzeitige Nutzer</th><th>CPU</th><th>RAM</th></tr></thead><tbody><tr><td>bis 25</td><td>bis 10</td><td>1-2 vCPU</td><td>1 GB</td></tr><tr><td>bis 75</td><td>bis 25</td><td>2 vCPU</td><td>2 GB</td></tr><tr><td>bis 150</td><td>bis 50</td><td>2-4 vCPU</td><td>4 GB</td></tr><tr><td>bis 300+</td><td>bis 100</td><td>4 vCPU</td><td>4-8 GB</td></tr></tbody></table>

Bei sehr kleinen Betrieben (unter 30 Mitarbeitern) reicht oft schon ein 1-vCPU/1-GB-Server aus. Die in der Tabelle oben genannten 2 vCPU/2 GB sind der komfortable Standardwert, mit dem auch Lastspitzen (z.B. morgens beim gleichzeitigen App-Start vieler Mitarbeiter) gut abgefedert werden. Der Sync-Job laeuft alle 5 Minuten im Hintergrund und ist fuer die genannten Groessenordnungen vernachlaessigbar.

# Installation Schritt fuer Schritt

## Installation

### 1. Docker und Git

```
curl -fsSL https://get.docker.com | sh
systemctl enable docker
apt-get install -y git
```

### 2. Repository klonen

```
cd /opt
git clone https://github.com/ldroeger/LD-Connect-Portal.git
cd LD-Connect-Portal
```

### 3. Konfiguration

```
cp .env.example .env
nano .env
# DB_HOST, DB_PORT, DB_NAME, DB_USER, DB_PASSWORD, JWT_SECRET anpassen
```

### 4. Starten

```
docker compose up -d --build
```

### 5. Nginx und SSL

```
apt-get install -y nginx certbot python3-certbot-nginx
certbot --nginx -d portal.ihrefirma.de
```

### 6. Einrichtungsassistent

Browser oeffnen: https://portal.ihrefirma.de und den Schritten folgen.

# Backup einrichten

## Backup

Nur die SQLite-Datenbank muss gesichert werden.

```
# Crontab -e
0 2 * * * cp /opt/LD-Connect-Portal/data/local.db /backup/local_$(date +%Y%m%d).db
0 3 * * * find /backup -name local_*.db -mtime +30 -delete
```

### Gesicherte Daten

- Benutzerkonten und Rollen
- Urlaubsantraege
- Krankmeldungen
- Einstellungen und Branding

# Updates

# Portal aktualisieren

## Portal Update

### Standard

```
cd /opt/LD-Connect-Portal
git fetch origin
git reset --hard origin/main
docker compose up -d --build
```

### Hot-Reload ohne Rebuild

```
docker cp backend/routes/DATEI.js ld-portal-backend-1:/app/routes/DATEI.js
docker restart ld-portal-backend-1
```

### Status pruefen

```
docker ps
docker logs ld-portal-backend-1 --tail 20
```

### Rollback

```
git log --oneline -10
git reset --hard COMMIT_HASH
docker compose up -d --build
```

# App aktualisieren

## App Update

### Versionsnummern erhoehen

app.json: version, ios buildNumber, android versionCode erhoehen. android/app/build.gradle: versionCode und versionName anpassen.

### Bauen

```
EAS_NO_VCS=1 eas build --platform all --profile production
EAS_NO_VCS=1 eas submit --platform ios
EAS_NO_VCS=1 eas submit --platform android
```

### Versionen

<table id="bkmrk-versioniosandroiddat"><thead><tr><th>Version</th><th>iOS</th><th>Android</th><th>Datum</th></tr></thead><tbody><tr><td>2.1.0</td><td>17</td><td>3</td><td>Jun 2026</td></tr><tr><td>2.2.0</td><td>18</td><td>4</td><td>Jun 2026</td></tr><tr><td>2.2.1</td><td>19</td><td>5</td><td>Jun 2026</td></tr></tbody></table>

# Changelog

# Changelog Portal

## Changelog Portal

### Jun 2026

- Dokumente Explorer-Navigation
- Push-Geraete Verwaltung
- Haftungsausschluss im Setup-Wizard
- SMB Konfiguration mit Verbindungstest
- Feature-Gates fuer Dokumente und Krankmeldung
- Sonderurlaub und Krankmeldung Hinweise
- Powerbird-Urlaube automatisch synchronisiert
- Aufgaben Archiv mit Wiederoeffnen
- Volle Bildschirmbreite ueberall

### Mai 2026

- Manager-Dashboard
- Geschaeftsfuehrer-Rolle
- Dokumente aus Powerbird via SMB
- E-Mail-Templates mit Logo
- Krankmeldungsseite
- Sync-Job

### Apr 2026

- HWTER Schreibzugriff
- Urlaubsgenehmigung mit E-Mail
- Push-Benachrichtigungen
- Mitarbeiterbildschirm
- Admin-Bereich

# Changelog App

## Changelog App

### 2.2.1

- Dokumente mit Explorer-Navigation und Vorschau
- Login mit Firmen-Branding
- Auto-Relogin bei abgelaufenem Token

### 2.2.0

- Dokumente-Screen
- Krankmeldung im Menue

### 2.1.0

- Krankmeldungsseite
- Dauerhafter Login

### 2.0.x

- Erstveroeffentlichung im App Store
- Kalender, Urlaub, Stunden, News, Werkzeuge

# Fehlerbehebung

# Backend startet nicht

## Backend startet nicht

```
docker logs ld-portal-backend-1 --tail 30
```

### SyntaxError

Datei und Zeile stehen im Log. Datei korrigieren und in Container kopieren:

```
docker cp backend/routes/DATEI.js ld-portal-backend-1:/app/routes/DATEI.js
docker restart ld-portal-backend-1
```

### ReferenceError Cannot access before initialization

Import an Dateianfang verschieben.

### Cannot connect to database

1. SQL Server erreichbar: ping 192.168.x.x
2. Port offen: nc -zv 192.168.x.x 1433
3. Zugangsdaten in .env pruefen

# SMB Fehler

## SMB Fehler

### STATUS\_OBJECT\_PATH\_NOT\_FOUND

Pfad existiert nicht. Share-Inhalt pruefen:

```
docker exec ld-portal-backend-1 node -e "
const SMB2 = require('@marsaud/smb2')
const smb2 = new SMB2({share:'\\\\192.168.x.x\\Share',domain:'WORKGROUP',username:'user',password:'pass'})
smb2.readdir('',function(e,f){console.log(e?e.message:f.join(', '));smb2.close()})
"
```

### STATUS\_ACCESS\_DENIED

Windows-Freigabeberechtigungen pruefen.

### Verbindung schlaegt fehl

- Freigabe-Name korrekt?
- Port 445 offen?
- SMB aktiviert auf Windows-Server?

# E-Mail Probleme

## E-Mail Probleme

### Microsoft 365: 535 Authentication unsuccessful

1. SMTP AUTH aktivieren im M365 Admin Center
2. PowerShell: Set-CASMailbox -Identity email@firma.de -SmtpClientAuthenticationDisabled $false
3. Einstellungen: smtp.office365.com Port 587 Secure false

### 535 Credentials incorrect

Passwort pruefen. Bei MFA: App-Passwort unter mysignins.microsoft.com erstellen.

### Logo fehlt

- Logo hochgeladen?
- App-URL mit https:// konfiguriert?

# Sync Fehler

## Sync-Fehler

### table X has no column named Y

Backend neu starten - Migrationen laufen automatisch:

```
docker restart ld-portal-backend-1
```

### NOT NULL constraint failed vacation\_requests.days

sync.js aktualisieren.

### PB-Urlaub Sync Fehler fuer XY

1. Powerbird-Kuerzel des Mitarbeiters korrekt?
2. Kuerzel stimmt mit Termin\_ResourceName in HWTER ueberein?
3. SQL-Benutzer hat SELECT auf HWTER?

# App Probleme

## App Probleme

### App meldet sich ab

Ab Version 2.2.1 Auto-Relogin. App aktualisieren. Sonst neu installieren.

### Push fehlen

- Benachrichtigungen erlaubt in Geraete-Einstellungen?
- Geraet unter Admin Push-Geraete sichtbar?

### Bilder laden nicht

1. SMB testen in Admin Netzlaufwerk
2. Datei auf der Freigabe vorhanden?

### Dokument-Download schlaegt fehl

1. Dokument-SMB konfiguriert?
2. Unterverzeichnis korrekt?
3. docker logs ld-portal-backend-1 | grep SMB

# FAQ

# FAQ Mitarbeiter

## FAQ Mitarbeiter

### Kann ich Urlaub aus Powerbird im Portal sehen?

Ja. Alle Urlaube werden alle 5 Minuten synchronisiert.

### Kann ich Sonderurlaub ueber das Portal beantragen?

Nein. Sonderurlaub muss persoenlich abgestimmt und handschriftlich beantragt werden.

### Muss ich bei Krankmeldung anrufen?

Ja. Immer zuerst telefonisch im Buero melden. Das Portal ersetzt nicht die persoenliche Meldung.

### Warum sehe ich keine Dokumente?

- Dokumente in Powerbird hinterlegt?
- Powerbird-Kuerzel korrekt?
- Funktion aktiviert?

### App meldet sich ab?

App auf Version 2.2.1 aktualisieren - Auto-Relogin ist dann aktiv.

### Warum fehlen Arbeitsstunden?

Stunden kommen direkt aus Powerbird. Dort pruefen ob korrekt erfasst.

# FAQ Administratoren

## FAQ Administratoren

### Neuen Mitarbeiter anlegen?

Admin, Benutzer, Neuer Benutzer, Daten eingeben, Einladen.

### Was ist das Powerbird-Kuerzel?

Wert in Termin\_ResourceName in HWTER z.B. LD oder AR01. Benoetigt fuer Sync.

### Logo aendern?

Admin, Einstellungen, Branding, Neues Logo hochladen.

### Push-Token bei Austritt loeschen?

Admin, Push-Geraete, Alle abmelden beim Mitarbeiter.

### Wie oft Sync?

Alle 5 Minuten. Aenderbar unter Admin Powerbird Sync.

### Backup?

Nur /opt/LD-Connect-Portal/data/local.db sichern. Taeglich per Cron genuegt.