2025-10-11 01:17:31 +02:00
2025-10-11 01:17:31 +02:00
2025-10-11 01:17:31 +02:00
2025-10-11 01:17:31 +02:00
2025-10-11 01:17:31 +02:00
2025-10-11 01:17:31 +02:00
2025-10-11 01:17:31 +02:00
2025-10-11 01:17:31 +02:00
2025-10-11 01:17:31 +02:00
2025-10-11 01:17:31 +02:00
2025-10-11 01:17:31 +02:00

Paperless Contract Companion (TypeScript + React)

Begleitservice zur Verwaltung von Vertragsmetadaten (Laufzeiten, Kündigungsfristen, Preise) als Ergänzung zu einer bestehenden 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.

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

Build & Run (Docker)

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:

{
  "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.

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.
Description
No description provided
Readme 3.7 MiB
Languages
TypeScript 99.1%
Dockerfile 0.6%
HTML 0.3%