# Paperless Contract Companion (TypeScript + React)

Begleitservice zur Verwaltung von Vertragsmetadaten (Laufzeiten, Kündigungsfristen, Preise) als Ergänzung zu einer bestehenden [paperless-ngx](https://github.com/paperless-ngx/paperless-ngx) Instanz. Dokumente verbleiben in paperless, der Service liefert zusätzliche Struktur, Fristüberwachung, Web-GUI und optionale Mail-Benachrichtigungen.

## Features
- REST-API (Express) zum Anlegen, Aktualisieren und Löschen von Verträgen.
- Speicherung der Metadaten in SQLite (via `better-sqlite3`).
- Periodischer Scheduler prüft anstehende Kündigungsfristen und schreibt diese ins Log bzw. versendet auf Wunsch E-Mails.
- Paperless-Integration ruft zugehörige Dokument-Metadaten über API-Token ab.
- JWT-basierte Authentifizierung mit Login-Endpunkt (optional aktivierbar).
- Moderne React-UI (Vite + MUI) mit Dashboard, Tabellen, Kalender und Settings.
- Einstellbare Integrationen direkt im Browser (Paperless, Mail, ntfy, Scheduler).
- Komfortable Paperless-Suche beim Verknüpfen von Dokumenten.
- Optionaler ntfy-Push für Fristenmeldungen.
- iCal-Feed zum Abonnieren der Kündigungsfristen.
- Test-Buttons für Mail- und ntfy-Konfiguration direkt in der Oberfläche.
- Läuft als Docker-Container, konfigurierbar über Umgebungsvariablen oder `.env` (beim Kopieren auf den Zielhost).

## Projektstruktur
```
backend/
src/
  index.ts              # Express-Server und Routing
  config.ts             # Umgebungsvariablen & Defaults
  db.ts                 # SQLite-Initialisierung
  contractsStore.ts     # CRUD-Logik auf DB-Ebene
  scheduler.ts          # Fristenmonitor
  paperlessClient.ts    # HTTP-Client für paperless-ngx
  notifications.ts      # SMTP-Integration (optional)
  validators.ts         # Zod-Schemas für Payloads
frontend/
  src/                  # React App (Dashboard, Login, Verträge, Kalender, Settings)
```

## Frontend (Vite + React)

Die Web-Oberfläche liegt im Ordner `frontend/` und kommuniziert ausschließlich über die gesicherte REST-API.

```bash
cd frontend
npm install
npm run dev         # Lokale Entwicklung (http://localhost:5173)
npm run build       # Produktionsbuild in frontend/dist
```

## Build & Run (Docker)

```bash
docker compose up --build
```

Die API lauscht per Default auf Port `8000`, extern über Compose auf `8080`. Die SQLite-Datenbank wird im Volume `contracts-data` unter `/app/data/contracts.db` persistiert. Das Frontend ist über `http://localhost:8081` (laut Compose) erreichbar.

### Wichtige Umgebungsvariablen

| Variable | Standard | Beschreibung |
| --- | --- | --- |
| `PORT` | `8000` | HTTP-Port des Dienstes. |
| `LOG_LEVEL` | `info` | `debug`, `info`, `warn`, `error`. |
| `DATABASE_PATH` | `/app/data/contracts.db` | Pfad zur SQLite-Datei (Volume nicht vergessen). |
| `PAPERLESS_BASE_URL` | *(leer)* | Basis-URL der paperless-ngx API (z.B. `http://paperless:8000`). |
| `PAPERLESS_EXTERNAL_URL` | *(leer)* | Optionale externe URL für Direkt-Link aus der Web-Oberfläche (z.B. `https://paperless.example.com`). |
| `PAPERLESS_TOKEN` | *(leer)* | Personal Token aus paperless-ngx (read-only genügt). |
| `SCHEDULER_INTERVAL_MINUTES` | `60` | Prüffrequenz für Fristen (mind. 5). |
| `ALERT_DAYS_BEFORE` | `30` | Wie viele Tage vor Deadline gewarnt wird. |
| `AUTH_USERNAME` / `AUTH_PASSWORD` | *(leer)* | Aktiviert das Login (JWT) – beide Werte müssen gesetzt werden. |
| `AUTH_JWT_SECRET` | *(leer)* | Geheimnis zum Signieren der Tokens (Pflicht, wenn Auth aktiv). |
| `AUTH_TOKEN_EXPIRES_IN_HOURS` | `12` | Lebensdauer der JWTs. |
| `NTFY_SERVER_URL` / `NTFY_TOPIC` | *(leer)* | ntfy-Server & Topic für Push-Benachrichtigungen. |
| `NTFY_TOKEN` / `NTFY_PRIORITY` | *(leer)* | Optionaler Bearer-Token & Priorität für ntfy. |
| `MAIL_*` | *(leer)* | Optional: SMTP-Einstellungen für Benachrichtigungs-E-Mails. |
| `ICAL_SECRET` | *(leer)* | Optional vordefiniertes Token für den iCal-Feed (ansonsten automatisch). |

Mail-Setup (optional): `MAIL_SERVER`, `MAIL_PORT`, `MAIL_USERNAME`, `MAIL_PASSWORD`, `MAIL_USE_TLS`, `MAIL_FROM`, `MAIL_TO`.

> Tipp: Bei gesetzter Authentifizierung muss sich die Web-UI einmalig per Login anmelden; Tokens werden im LocalStorage gespeichert.

## API Übersicht

- `GET /healthz` – einfacher Gesundheitscheck.
- `GET /auth/status` – zeigt, ob Authentifizierung aktiviert ist.
- `POST /auth/login` – Login mit Benutzername/Passwort, liefert JWT.
- `GET /contracts?skip=0&limit=100` – Liste aller Verträge (max. 500 pro Anfrage).
- `POST /contracts` – Neuen Vertrag anlegen.
- `GET /contracts/:id` – Einzelnen Vertrag abrufen.
- `PUT /contracts/:id` – Vertrag aktualisieren (Felder optional/teilweise).
- `DELETE /contracts/:id` – Vertrag löschen.
- `GET /contracts/:id/paperless-document` – Zugehöriges paperless-Dokument abrufen (wenn verknüpft).
- `GET /reports/upcoming?days=N` – Anstehende Kündigungsdeadlines innerhalb der nächsten `N` Tage (Default = `ALERT_DAYS_BEFORE`).

Beispiel-JSON für Create/Update:

```json
{
  "title": "KFZ-Versicherung 2024",
  "paperlessDocumentId": 123,
  "provider": "Versicherung AG",
  "category": "Automotive",
  "contractStartDate": "2024-01-01",
  "contractEndDate": "2025-12-31",
  "terminationNoticeDays": 30,
  "renewalPeriodMonths": 12,
  "autoRenew": true,
  "price": 54.99,
  "currency": "EUR",
  "tags": ["kfz", "privat"],
  "notes": "SFR prüfen im Herbst."
}
```

## Lokale Entwicklung – Backend

> Hinweis: Im aktuellen Arbeitsverzeichnis wurden noch keine Node-Module installiert (`npm install`). Auf dem Zielhost bitte einmal ausführen, damit `package-lock.json` entsteht und der Build reproduzierbar wird.

```bash
npm install
npm run dev          # Hot-Reload via tsx
# oder
npm run build && npm start
```

Die API ist anschließend unter `http://localhost:8000` erreichbar. Für Tests ohne paperless-Verbindung kann `PAPERLESS_*` weggelassen werden.

## Integration mit paperless-ngx

- Companion-Service und paperless-Container sollten im gleichen Docker-Netz laufen, damit `http://paperless:8000` erreichbar ist.
- Token in paperless-ngx erstellen (`Einstellungen → Tokens`) und als `PAPERLESS_TOKEN` setzen.
- Contract-IDs können mit Custom Fields/Tags in paperless verknüpft werden; die Companion-API hält zusätzliche Metadaten und erinnert an Fristen.
- Nutze `PAPERLESS_EXTERNAL_URL`, wenn die API intern erreichbar ist, die Benutzer im Browser aber eine andere URL (z. B. Reverse-Proxy mit TLS) verwenden sollen.
- Einstellungen (Paperless, Mail, ntfy, Scheduler) lassen sich komfortabel unter „Einstellungen“ in der Weboberfläche pflegen.
- Aktiviere Push-Benachrichtigungen via ntfy oder abonniere den iCal-Feed unter `https://<host>/api/calendar/feed.ics?token=<...>` (Token im Settings-Dialog sichtbar).

## Weiterführende Ideen

- Webhook/Chat-Integration (z.B. Matrix, Slack).
- ICS/CalDAV-Export der Deadlines.
- Intelligente Importer, die paperless-Tags automatisch auswerten.
- Multi-User-Unterstützung inkl. Rollen und Audit-Logs.
- Optionaler Reverse-Proxy mit TLS-Termination und Single-Sign-On.
