Project_Manager/CLAUDE.md
2026-06-26 18:21:22 +02:00

213 lines
10 KiB
Markdown

# CLAUDE.md — Projekt-Hub
Diese Datei beschreibt den Kontext, die Architektur und die Konventionen für dieses Projekt.
Sie dient Claude (und anderen Entwicklern) als Einstiegspunkt, bevor Code geschrieben wird.
## Hintergrund / Idee
Der Nutzer hat ADHS und führt ein analoges Bullet Journal (Logbuch, Weekly Bridge, Monthly
Log). Projektbezogene Arbeitsaufgaben sollen davon getrennt digital verwaltet werden.
Ein erster Prototyp war eine einzelne HTML-Datei mit LocalStorage (Projekte, Aufgaben,
Fälligkeitsdaten, Export/Import als JSON). Diese Datei dient als **funktionale Referenz**
für Feature-Set und UI/UX — siehe `reference/projekte.html` (wird vom Nutzer bereitgestellt).
Das Ziel jetzt: aus dieser Idee eine **Flask-Webapp** machen, die auf einem eigenen VPS
läuft (volle Datenhoheit, kein Drittanbieter-Cloud-Dienst). Diese App ist der erste Baustein
eines **Hubs**, der später um weitere kleine Apps/Module erweitert wird — alle hinter einem
gemeinsamen Login.
## Kernprinzipien
1. **Datenschutz / Selbsthosting**: Alle Daten bleiben auf dem eigenen VPS. Keine externen
Tracker, kein CDN-Zwang für kritische Funktionen (Fallback ohne Internet sollte
funktionieren oder zumindest nicht hart brechen).
2. **ADHS-freundlich**: Niedrigschwellig, wenig Klicks, schnelles Erfassen ("Brain dump"),
sofortiges visuelles Feedback (Fälligkeits-Badges: überfällig/bald/ok), keine
überladenen Screens.
3. **Erweiterbarkeit**: Architektur so anlegen, dass weitere "Mini-Apps" als eigene
Module/Blueprints unter demselben Login + derselben Navigation ergänzt werden können,
ohne den Kern umzubauen.
4. **Einfacher Login**: Kein Passwort. Login per E-Mail-Adresse + zeitlich begrenztem
Code (10 Minuten gültig), der per Mail zugeschickt wird ("Magic Code" / OTP-Login).
## Tech-Stack
- **Backend**: Python, Flask
- **Datenbank**: SQLite (ausreichend für Einzelnutzer/kleine Gruppe; Pfad konfigurierbar,
später ggf. auf Postgres migrierbar — daher SQLAlchemy als ORM verwenden)
- **Auth**: Flask-Login für Session-Verwaltung + eigene Logik für E-Mail-Code-Versand
(Flask-Mail oder smtplib, SMTP-Zugangsdaten über Umgebungsvariablen)
- **Frontend**: Server-seitig gerenderte Templates (Jinja2) + minimal JavaScript für
interaktive Elemente (Checkbox-Toggle, Filter, evtl. htmx für dynamische Updates ohne
vollständigen Page-Reload). Kein schweres SPA-Framework — Ladezeit und Einfachheit
haben Priorität.
- **Styling**: Eigenes CSS im Stil des Prototyps (Dark Theme, siehe Referenzdatei) als
Basis-Theme für den ganzen Hub, das von allen Modulen genutzt wird.
- **Deployment**: VPS, lauffähig hinter einem Reverse Proxy (nginx) via gunicorn.
`.env`-Datei für Secrets (SMTP, SECRET_KEY, Datenbankpfad). `requirements.txt` pflegen.
## Architektur-Überblick
```
projekt-hub/
├── app/
│ ├── __init__.py # App-Factory, Extensions-Init, Blueprint-Registrierung
│ ├── config.py # Config-Klassen (liest aus .env)
│ ├── extensions.py # db, login_manager, mail etc.
│ ├── models.py # User, LoginCode (gemeinsame Modelle)
│ ├── auth/ # Auth-Modul (Blueprint)
│ │ ├── __init__.py
│ │ ├── routes.py # /login, /verify, /logout
│ │ └── forms.py # E-Mail-Eingabe, Code-Eingabe
│ ├── projects/ # Modul 1: Projekte & Aufgaben (aus dem Prototyp)
│ │ ├── __init__.py
│ │ ├── routes.py
│ │ ├── models.py # Project, Task
│ │ └── templates/projects/
│ ├── templates/
│ │ ├── base.html # gemeinsames Layout, Navigation, Theme
│ │ └── auth/
│ │ ├── login.html
│ │ └── verify.html
│ └── static/
│ └── css/main.css # Dark-Theme-Basis aus dem Prototyp
├── migrations/ # Flask-Migrate / Alembic
├── instance/ # SQLite-Datei (nicht versionieren)
├── .env.example
├── requirements.txt
├── wsgi.py
└── run.py # lokaler Dev-Server
```
### Erweiterbarkeit für künftige Module
Jedes neue Mini-App-Modul:
- ist ein eigenes Python-Package mit eigenem Blueprint (`app/<modulname>/`)
- bringt eigene Models, Routes, Templates mit (Templates unter `templates/<modulname>/`)
- wird in `app/__init__.py` per `app.register_blueprint(...)` eingebunden
- erscheint automatisch als Eintrag in der gemeinsamen Navigation (`base.html`), idealerweise
über eine zentrale Liste/Registry, die Modulname + URL + Icon enthält
- nutzt denselben `current_user` (Flask-Login) — kein eigenes Auth nötig
Ziel: ein neues Modul hinzufügen = neuen Ordner anlegen, Blueprint registrieren,
Navigationseintrag ergänzen. Kern-App, Auth und Theme bleiben unangetastet.
## Datenmodell (Modul "Projekte")
**User**
- id
- email (unique)
- created_at
**LoginCode**
- id
- user_id (FK)
- code (6-stellig, numerisch)
- created_at
- expires_at (created_at + 10 Minuten)
- used (bool)
**Project**
- id
- user_id (FK)
- name
- color (Hex-Wert, aus fester Palette wie im Prototyp)
- created_at
**Task**
- id
- user_id (FK)
- project_id (FK, nullable — Aufgaben ohne Projekt erlaubt)
- text
- due_date (nullable)
- done (bool, default False)
- created_at
## Auth-Flow (E-Mail-Code-Login)
1. Nutzer gibt E-Mail-Adresse auf `/login` ein.
2. Backend prüft, ob User mit dieser E-Mail existiert — falls nicht, wird er angelegt
(passwortlose Self-Registration; ggf. später auf Allowlist beschränkbar für
Einzelnutzer-Setup).
3. Backend generiert 6-stelligen Code, speichert Hash + `expires_at = now + 10min`,
sendet Code per E-Mail (Betreff klar, kurzer Text, kein HTML-Tracking).
4. Nutzer landet auf `/verify`, gibt Code ein.
5. Backend prüft: Code korrekt, nicht abgelaufen, nicht bereits benutzt → Login via
Flask-Login (`login_user`), Code als `used` markieren.
6. Alte/abgelaufene Codes regelmäßig aufräumen (z.B. bei jedem neuen Code-Request für
denselben User).
7. Rate-Limiting: max. X Code-Anfragen pro E-Mail pro Stunde, um Spam/Missbrauch zu
verhindern (z.B. Flask-Limiter).
Sicherheitsaspekte:
- Code wird gehasht gespeichert (nicht im Klartext in der DB).
- Session-Cookie: `Secure`, `HttpOnly`, `SameSite=Lax`.
- HTTPS wird vom Reverse Proxy (nginx + Let's Encrypt) terminiert — App selbst geht von
HTTPS aus (`PREFERRED_URL_SCHEME = 'https'`).
## Feature-Set Modul "Projekte" (aus dem Prototyp übernehmen)
- Projekte anlegen/löschen, mit fester Farbpalette (zyklisch zugewiesen)
- Aufgaben anlegen mit: Text, optionalem Projekt, optionalem Fälligkeitsdatum
- Aufgaben abhaken (done/undone), löschen
- Fälligkeits-Badges: überfällig (rot), diese Woche (orange), normal (grün), kein Datum
- Ansicht "Nach Projekt" (gruppiert, mit Klapp-/Zähl-Funktion) + Ansicht "Alle Aufgaben"
(gefiltert: alle / offen / überfällig / diese Woche / erledigt)
- Statistik-Leiste (offen / erledigt / überfällig / Anzahl Projekte)
- Da Daten jetzt serverseitig in SQLite liegen und auf dem VPS gesichert werden,
entfällt der JSON-Export/Import als Sync-/Backup-Mechanismus. Stattdessen:
**PDF-Export** — eine projektbasierte To-Do-Liste zum Ausdrucken (offene und
erledigte Aufgaben, erledigte abgehakt/durchgestrichen, Aufgaben ohne Projekt in
eigenem Abschnitt). Erzeugt mit fpdf2 (reines Python, keine System-Abhängigkeiten);
DejaVu-Schrift im Repo mitgeliefert für identisches Rendering auf dem VPS.
## Nicht-Ziele (für jetzt)
- Keine Multi-Tenant-Mandantentrennung über User hinaus (Familien-/Team-Sharing später,
falls gewünscht)
- Kein OAuth/Social Login
- Kein Offline-First/PWA-Sync (kann später ergänzt werden)
- Kein Rich-Text/Markdown in Aufgaben (bewusst simpel halten)
## Nächste Schritte (Vorschlag für Umsetzungsreihenfolge)
1. Projektgerüst (App-Factory, Config, `.env.example`, `requirements.txt`)
2. Models + DB-Migration (User, LoginCode, Project, Task)
3. Auth-Modul (E-Mail-Code-Login, Templates für `login.html` / `verify.html`)
4. Basis-Layout `base.html` mit Navigation + Dark-Theme-CSS (aus Prototyp übernehmen)
5. Modul "Projekte": Routes + Templates, 1:1-Funktionsumfang aus dem HTML-Prototyp
6. PDF-Export (projektbasierte To-Do-Liste zum Ausdrucken, fpdf2)
7. Deployment-Vorbereitung: `wsgi.py`, gunicorn-Konfiguration, Beispiel-nginx-Config,
systemd-Service-Datei
## Entscheidungen (geklärt)
- **SMTP-Anbieter**: Proton Mail (eigene Adresse). Da Proton Mail Bridge eine
Desktop-Anwendung ist und nur mit zahlendem Plan läuft, wird sie testweise auf dem
VPS via Docker betrieben (lokaler SMTP-Relay auf `127.0.0.1`). Falls das auf dem
Server unzuverlässig läuft, ist ein **Fallback auf einen EU-SMTP-Relay-Dienst**
(z.B. Infomaniak, Mailjet EU-Region) als austauschbare Alternative vorgesehen — die
App liest SMTP-Host/Port/User/Passwort ausschließlich aus `.env`, sodass der Anbieter
ohne Codeänderung wechselbar ist.
- **Self-Registration**: Vorerst nur **eine** erlaubte E-Mail-Adresse (Allowlist mit
einem Eintrag in `.env`, z.B. `ALLOWED_EMAILS=deine@adresse.com`). Spätere
Erweiterung auf mehrere Adressen ist durch eine kommagetrennte Liste oder eigene
DB-Tabelle vorbereitet, aber jetzt nicht nötig.
- **Domain**: Noch nicht final. App wird so konfiguriert, dass Domain/Host über `.env`
(`SERVER_NAME` bzw. Reverse-Proxy-Konfiguration) gesetzt wird. Bis zur
Domain-Entscheidung ist die App über IP:Port oder eine Subdomain-Platzhalter
erreichbar; Cookie-Settings (`SESSION_COOKIE_DOMAIN`) werden erst final gesetzt,
wenn die Domain feststeht.
## Referenzdatei
`reference/projekte.html` — der funktionsfähige HTML/JS-Prototyp (Dark Theme,
LocalStorage, Export/Import). Dient als Vorlage für:
- Farbpalette und CSS-Variablen (Basis für `static/css/main.css`)
- UI-Struktur (Stats-Leiste, Formular, Projekt-Karten, Aufgabenliste, Filter-Buttons)
- Fälligkeits-Badge-Logik (`dueBadge`-Funktion → als Jinja-Filter oder Python-Helper
übernehmen)
- Datenmodell-Felder (Project: id/name/color; Task: id/text/project/due/done)