new file: .env.example

new file:   .gitignore
	new file:   Dockerfile
	new file:   README.md
	new file:   app.py
	new file:   auth.py
	new file:   config.py
	new file:   db.py
	new file:   db_helpers.py
	new file:   docker-compose.yml
	new file:   requirements.txt
	new file:   routes/__init__.py
	new file:   routes/admin_routes.py
	new file:   routes/auth_routes.py
	new file:   routes/journal_routes.py
	new file:   static/css/style.css
	new file:   static/js/main.js
	new file:   templates/admin/dashboard.html
	new file:   templates/admin/users.html
	new file:   templates/base.html
	new file:   templates/day.html
	new file:   templates/future.html
	new file:   templates/index.html
	new file:   templates/login.html
	new file:   templates/week.html
This commit is contained in:
SimolZimol
2026-08-02 20:41:24 +02:00
commit 0e7efe4b74
25 changed files with 1590 additions and 0 deletions

97
README.md Normal file
View File

@@ -0,0 +1,97 @@
# 📓 Bullet Journal (Flask)
Eine eigene **Bullet-Journal-Webanwendung** mit Benutzerkonten, Tagesseiten (MontagSonntag),
Wochenübersicht und Future Log. Läuft in **Docker** und ist für **Coolify** optimiert.
Die Daten liegen in **MySQL**.
## Features
- 🔐 **Login-System** mit **jedem eigenen Journal** pro Benutzer (Daten-Isolation)
- 📅 **7 Tagesseiten** (MontagSonntag) mit 3 Spalten: **Bullet | Notiz | Priorität**
- 🗓 **Wochenübersicht** (offene / erledigte Aufgaben je Tag)
- 📌 **Future Log** langfristiger Kalender
- ✅ Aufgaben **erledigt** markieren, in einen anderen Tag oder ins **Future Log verschieben**
- 🛡 **Admin-Panel** zum Erstellen und Verwalten von Accounts
- 🔒 Passwörter mit **Salz + Pfeffer** gehasht (PBKDF2-SHA256)
## Bullet-Typen
| Symbol | Bedeutung |
|--------|-----------|
| `.` | Aufgabe |
| `x` | Termin |
| `-` | Notiz |
| `?` | Frage |
Prioritäten: `0` Niedrig, `1` Mittel, `2` Hoch.
## Projektstruktur
```
Journal/
├── Dockerfile # Production-Image (Gunicorn)
├── docker-compose.yml # Lokale Entwicklung (App + MySQL)
├── requirements.txt
├── .env.example
├── app.py # Flask-App + Blueprints
├── config.py # Konfiguration aus Env-Variablen
├── db.py # PyMySQL + Schema-Init
├── db_helpers.py # Benutzer-/Admin-Helfer
├── auth.py # Passwort-Hash (Salz+Pfeffer), Guards
├── routes/
│ ├── auth_routes.py # Login / Logout
│ ├── journal_routes.py # Index, Wochenübersicht, Tage, Future Log
│ └── admin_routes.py # Admin-Panel
├── templates/ # Jinja2-Seiten
└── static/ # eigenes CSS + JS
```
## Lokale Entwicklung
1. **Umgebungsvariablen** kopieren:
```bash
copy .env.example .env
```
`SECRET_KEY`, `PEPPER` sowie `ADMIN_USERNAME` / `ADMIN_PASSWORD` anpassen.
2. **Starten** (App + MySQL):
```bash
docker compose up --build
```
3. Öffnen: http://localhost:8000
Der **erste Admin** wird beim Start automatisch aus `ADMIN_USERNAME` / `ADMIN_PASSWORD` angelegt.
Melde dich damit an und lege im **Admin-Panel** weitere Benutzer an.
## Deployment auf Coolify
1. Repository in Coolify als **Public Repository** verknüpfen.
2. **MySQL** als Dienst hinzufügen (Coolify verbindet die Folgenden automatisch als Env-Variablen).
3. Env-Variablen als **Secrets** setzen:
| Variable | Beschreibung |
|-------------------|-------------------------------------------------|
| `DB_HOST` | Host der MySQL (von Coolify gesetzt) |
| `DB_PORT` | Port der MySQL (von Coolify gesetzt) |
| `DB_USER` | DB-Benutzer (von Coolify gesetzt) |
| `DB_PASSWORD` | DB-Passwort (von Coolify gesetzt) |
| `DB_DATABASE` | DB-Name (von Coolify gesetzt) |
| `SECRET_KEY` | Geheimer Wert für Flask-Sessions (**Secret**) |
| `PEPPER` | Globaler „Pfeffer“ für Passwort-Hashing (**Secret** wird NIE in der DB gespeichert) |
| `ADMIN_USERNAME` | Name des ersten Admins |
| `ADMIN_PASSWORD` | Passwort des ersten Admins (**Secret**) |
4. Port `8000` freigeben. TLS/Reverse-Proxy übernimmt Coolify automatisch.
> **Wichtig:** Ändere `ADMIN_PASSWORD`, `SECRET_KEY` und `PEPPER` unbedingt verwende keine
> Standardwerte. `PEPPER` darf nach dem ersten Hash-Vorgang nicht mehr geändert werden,
> sonst lassen sich bestehende Passwörter nicht mehr prüfen.
## Sicherheit
- Passwörter werden mit zufälligem **Salz** (pro Benutzer, in DB) und einem globalen **Pfeffer**
(aus der Umgebung, nie in der DB) über **PBKDF2-SHA256** gehasht.
- Jede Abfrage ist über die Session an den angemeldeten Benutzer (`user_id`) gebunden.
- Seitenzugriffe sind durch `@login_required` / `@admin_required` geschützt.
- Es gibt **keine** offene Registrierung nur Admins legen Accounts an.