updated readme
This commit is contained in:
241
README.md
241
README.md
@@ -1,139 +1,176 @@
|
||||
# Paperless Contract Companion (TypeScript + React)
|
||||
# Paperless Contract Companion
|
||||
|
||||
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.
|
||||
Begleitdienst zur Verwaltung von Vertragsmetadaten (Laufzeiten, Kündigungsfristen, Kosten) mit moderner Weboberfläche, Terminüberwachung und Benachrichtigungen. Der Service ist in TypeScript geschrieben (Express + React) und kann eigenständig oder als Ergänzung zu [paperless-ngx](https://github.com/paperless-ngx/paperless-ngx) betrieben werden.
|
||||
|
||||
## 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).
|
||||
---
|
||||
|
||||
## Highlights
|
||||
|
||||
- ✅ **Eigenständige Vertragsdatenbank** auf SQLite (`better-sqlite3`) mit REST-API (Express).
|
||||
- ✅ **Paperless-Integration (optional):** Verknüpft Verträge mit Dokumenten, zieht Metadaten per Token, durchsucht paperless direkt aus der UI.
|
||||
- ✅ **Modernes React-Frontend** (Vite + MUI) mit Dashboard, Vertragsliste, Kalender, Detailansicht und umfangreichen Einstellungen.
|
||||
- ✅ **Benachrichtigungen & Automatisierung:** Scheduler prüft Deadlines, optionaler Mailversand, ntfy-Push, iCal-Feed zum Abonnieren.
|
||||
- ✅ **Konfigurierbare Authentifizierung:** Optionales Login mit JWT, Benutzername/Passwort verwaltbar in den Settings.
|
||||
- ✅ **Mehrsprachigkeit:** UI derzeit auf Deutsch und Englisch lokalisiert.
|
||||
- ✅ **Docker-ready:** Backend und Frontend als Container, Konfiguration via `docker-compose.yml`.
|
||||
|
||||
---
|
||||
|
||||
## Projektüberblick
|
||||
|
||||
## 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)
|
||||
backend/ (TypeScript)
|
||||
src/
|
||||
index.ts # Express-Server, Routing, Auth, Settings, Calendar, Paperless-Suche
|
||||
contractsStore.ts # CRUD auf SQLite
|
||||
scheduler.ts # Deadline-Monitor
|
||||
paperlessClient.ts # Paperless-Proxy mit Korrespondenten/Tag-Anreicherung
|
||||
notifications.ts # SMTP & ntfy-Tests, Benachrichtigungen
|
||||
runtimeSettings.ts # Persistente Einstellungen (z.B. Mail, ntfy, Paperless)
|
||||
validators.ts # Zod-Schemas
|
||||
|
||||
frontend/ (React + Vite)
|
||||
src/
|
||||
routes/ # Dashboard, Contracts, Calendar, Settings, Login
|
||||
components/ # Listen, Dialoge, Layout, Snackbar etc.
|
||||
api/ # REST-Client (fetch)
|
||||
locales/ # de/en Übersetzungen
|
||||
```
|
||||
|
||||
## Frontend (Vite + React)
|
||||
---
|
||||
|
||||
Die Web-Oberfläche liegt im Ordner `frontend/` und kommuniziert ausschließlich über die gesicherte REST-API.
|
||||
## Getting Started
|
||||
|
||||
### Voraussetzungen
|
||||
|
||||
- Node.js ≥ 20.x (Backend & Frontend)
|
||||
- npm oder pnpm
|
||||
- optional Docker / Docker Compose
|
||||
|
||||
### Lokale Entwicklung
|
||||
|
||||
```bash
|
||||
# Backend
|
||||
npm install
|
||||
npm run dev # startet Express per tsx (Hot-Reload)
|
||||
|
||||
# Frontend
|
||||
cd frontend
|
||||
npm install
|
||||
npm run dev # Lokale Entwicklung (http://localhost:5173)
|
||||
npm run build # Produktionsbuild in frontend/dist
|
||||
npm run dev # http://localhost:5173 (Proxy auf http://localhost:8000/api)
|
||||
```
|
||||
|
||||
## Build & Run (Docker)
|
||||
> **Hinweis:** Die `node_modules` Verzeichnisse sind aus dem Repository ausgenommen. Vor jedem Build/Start zunächst `npm install` im jeweiligen Ordner ausführen, damit TypeScript (`tsc`) verfügbar ist.
|
||||
|
||||
### Docker Compose
|
||||
|
||||
```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.
|
||||
- API: `http://localhost:8112` (siehe Compose)
|
||||
- Frontend: `http://localhost:8113`
|
||||
- SQLite-Datenbank: Volume `contracts-data` → `/app/data/contracts.db`
|
||||
|
||||
### Wichtige Umgebungsvariablen
|
||||
---
|
||||
|
||||
## Konfiguration
|
||||
|
||||
| Variable | Standard | Beschreibung |
|
||||
| --- | --- | --- |
|
||||
| `PORT` | `8000` | HTTP-Port des Dienstes. |
|
||||
| `PORT` | `8000` | Port des Express-Servers. |
|
||||
| `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). |
|
||||
| `DATABASE_PATH` | `/app/data/contracts.db` | Pfad zur SQLite-Datei (Volume mounten). |
|
||||
| `SCHEDULER_INTERVAL_MINUTES` | `60` | Intervall für Deadline-Checks (5–1440). |
|
||||
| `ALERT_DAYS_BEFORE` | `30` | Vorlauf in Tagen für Warnungen. |
|
||||
| `AUTH_USERNAME` / `AUTH_PASSWORD` | *(leer)* | Aktiviert JWT-Login, wenn beide gesetzt sind. |
|
||||
| `AUTH_JWT_SECRET` | *(leer)* | Signatur-Secret (Pflicht bei aktivem Login). |
|
||||
| `AUTH_TOKEN_EXPIRES_IN_HOURS` | `12` | Lebensdauer der Tokens. |
|
||||
| `PAPERLESS_BASE_URL` | *(leer)* | API-URL deiner paperless-ngx Instanz. |
|
||||
| `PAPERLESS_EXTERNAL_URL` | *(leer)* | Optionale externe URL für Direktlinks im Browser. |
|
||||
| `PAPERLESS_TOKEN` | *(leer)* | API-Token aus paperless-ngx. |
|
||||
| `NTFY_SERVER_URL` / `NTFY_TOPIC` | *(leer)* | Aktiviert ntfy-Push-Benachrichtigungen. |
|
||||
| `NTFY_TOKEN` / `NTFY_PRIORITY` | *(leer)* | Optionaler Bearer-Token & Priorität. |
|
||||
| `MAIL_SERVER` / `MAIL_PORT` / `MAIL_USERNAME` / `MAIL_PASSWORD` | *(leer)* | SMTP-Settings (TLS optional über `MAIL_USE_TLS`). |
|
||||
| `MAIL_FROM` / `MAIL_TO` | *(leer)* | Absender/Empfänger für Mail-Benachrichtigungen. |
|
||||
| `ICAL_SECRET` | *(leer)* | Optional vorgegebenes Token für den iCal-Feed. |
|
||||
|
||||
Mail-Setup (optional): `MAIL_SERVER`, `MAIL_PORT`, `MAIL_USERNAME`, `MAIL_PASSWORD`, `MAIL_USE_TLS`, `MAIL_FROM`, `MAIL_TO`.
|
||||
### Paperless optional nutzen
|
||||
|
||||
> Tipp: Bei gesetzter Authentifizierung muss sich die Web-UI einmalig per Login anmelden; Tokens werden im LocalStorage gespeichert.
|
||||
Paperless ist **nicht verpflichtend**. Lässt du `PAPERLESS_*` leer, bleibt die Vertragsverwaltung voll funktionsfähig (Deadlines, Benachrichtigungen, iCal, ntfy, etc.). Die UI blendet paperless-spezifische Funktionen aus bzw. deaktiviert Buttons und zeigt Hinweise an. Sobald du später eine URL/Token hinterlegst, werden Suche und Direktlinks automatisch freigeschaltet.
|
||||
|
||||
## 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`).
|
||||
## Integrationen
|
||||
|
||||
Beispiel-JSON für Create/Update:
|
||||
### Bereits vorhanden
|
||||
|
||||
```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."
|
||||
}
|
||||
```
|
||||
- **paperless-ngx (optional):** Sucht Dokumente, verknüpft sie mit Verträgen, zeigt Metadaten und öffnet Direktlinks zur paperless-Oberfläche.
|
||||
- **SMTP-Mail:** Verschickt Erinnerungen sowie Testmails aus den Einstellungen.
|
||||
- **ntfy:** Sendet Push-Alerts (Test-Button in den Settings).
|
||||
- **iCal-Feed:** Kündigungsfristen abonnierbar in gängigen Kalendern.
|
||||
|
||||
## Lokale Entwicklung – Backend
|
||||
### Perspektivische Erweiterungen
|
||||
|
||||
> 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.
|
||||
Einige sinnvolle Ergänzungen, falls du die Plattform weiter denkst:
|
||||
|
||||
```bash
|
||||
npm install
|
||||
npm run dev # Hot-Reload via tsx
|
||||
# oder
|
||||
npm run build && npm start
|
||||
```
|
||||
- **Nextcloud / ownCloud** – Dokumentenverknüpfung oder Dateiimporte via WebDAV/REST.
|
||||
- **Seafile / S3 (MinIO, Wasabi)** – Ablage von Vertrags-PDFs in einem Objektspeicher.
|
||||
- **Slack / Microsoft Teams / Mattermost** – Deadlines als Channel-Notifications.
|
||||
- **Jira / Asana / Trello** – Automatische Tasks zur Kündigung bzw. Verlängerung.
|
||||
- **Banking / Finance APIs** – Abgleich von Zahlungen oder Lastschriften mit Vertragskosten.
|
||||
- **CRM-Integration (HubSpot, Salesforce, Pipedrive)** – Verträge direkt im Kundenkontext.
|
||||
|
||||
Die API ist anschließend unter `http://localhost:8000` erreichbar. Für Tests ohne paperless-Verbindung kann `PAPERLESS_*` weggelassen werden.
|
||||
Diese Ideen sind in diesem Repository noch **nicht umgesetzt**, aber durch die REST-Architektur vergleichsweise leicht nachrüstbar.
|
||||
|
||||
## 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).
|
||||
## Status & Roadmap
|
||||
|
||||
## Weiterführende Ideen
|
||||
### Erledigt
|
||||
|
||||
- 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.
|
||||
- Backend-API mit Contracts CRUD, Settings-Storage und optionaler Authentifizierung.
|
||||
- Scheduler + Notification-Pipeline (Mail, ntfy).
|
||||
- Paperless-Integration inkl. Suchdialog, Dokumentdetail, Metadaten-Anreicherung.
|
||||
- React-UI mit Dashboard, Kalender, Vertragsliste/-details, Settings.
|
||||
- Mehrsprachigkeit (Deutsch/Englisch) inkl. Language Switch.
|
||||
- iCal-Feed mit granularen Einträgen und Direktlinks zu Verträgen.
|
||||
- Docker-Setup für Backend und Frontend.
|
||||
|
||||
### In Arbeit / Offene Punkte
|
||||
|
||||
- Opt-in/Opt-out-Schalter für Paperless in der Oberfläche (UI zeigt bereits Hinweise).
|
||||
- Additional Integrations (z. B. Nextcloud, Slack) – Konzept klar, Implementation offen.
|
||||
- Weitere Automatisierungen (z. B. automatische Erstellung von Tasks/Kalendereinträgen).
|
||||
- Testsuite / CI-Pipeline (derzeit keine automatisierten Tests).
|
||||
- Mehrbenutzer-Unterstützung & Rechteverwaltung (derzeit Single-User + optionaler Login).
|
||||
|
||||
Fühle dich frei, Pull Requests oder Issues mit neuen Ideen zu eröffnen.
|
||||
|
||||
---
|
||||
|
||||
## Entwicklung & Beiträge
|
||||
|
||||
1. Repository klonen, `npm install` im Root und in `frontend/`.
|
||||
2. Backend mit `npm run dev`, Frontend mit `npm run dev` starten.
|
||||
3. Die jeweiligen `.env` Dateien (oder Docker-Compose Variablen) für deine Umgebung setzen.
|
||||
4. Änderungen strukturieren, `npm run build` im Root und im Frontend ausführen, um Typfehler zu erkennen (TypeScript läuft nur mit installierten Modulen).
|
||||
5. Pull Request eröffnen.
|
||||
|
||||
**Coding Guidelines**
|
||||
|
||||
- TypeScript überall (Backend & Frontend).
|
||||
- Zod-Schemas für Request-Validierung.
|
||||
- Lass `paperlessClient` die einzige Stelle sein, an der Paperless-HTTP-Aufrufe passieren.
|
||||
- UI nutzt React Query + React Hook Form, MUI-Komponenten (Varianten/Theme konsistent halten).
|
||||
- Lokalisierte Strings über `react-i18next`.
|
||||
|
||||
---
|
||||
|
||||
## Lizenz
|
||||
|
||||
Noch keine Lizenz festgelegt – bei Bedarf ergänzen (z. B. MIT). Bis dahin gelten die Standardrechte des Autoren.
|
||||
|
||||
---
|
||||
|
||||
Viel Spaß mit dem Paperless Contract Companion! Wenn du Feedback oder Integrationsideen hast, gerne melden.
|
||||
|
||||
Reference in New Issue
Block a user