28aab3b16a
Drops Evidenzlevel from models, admin, public UI, and draft workflow while keeping Nachweise file uploads unchanged. Co-authored-by: Cursor <cursoragent@cursor.com>
322 lines
8.7 KiB
Markdown
322 lines
8.7 KiB
Markdown
# Faktenkompass – Wissensdatenbank für überprüfbare Behauptungen
|
||
|
||
Eine Django-Webplattform zum schnellen Nachschlagen von Fakten, Quellen und Gegenargumenten zu häufigen Aussagen in Diskussionen.
|
||
|
||
## Voraussetzungen
|
||
|
||
- Python 3.10 oder höher
|
||
- pip
|
||
|
||
## Installation
|
||
|
||
### 1. Virtuelle Umgebung erstellen
|
||
|
||
```bash
|
||
cd /pfad/zu/ArgumentAtlas
|
||
python3 -m venv .venv
|
||
source .venv/bin/activate # Linux/macOS
|
||
# .venv\Scripts\activate # Windows
|
||
```
|
||
|
||
Falls `python3 -m venv` fehlschlägt, nutzen Sie explizit den System-Python:
|
||
|
||
```bash
|
||
/usr/bin/python3 -m venv .venv
|
||
```
|
||
|
||
### 2. Abhängigkeiten installieren
|
||
|
||
```bash
|
||
pip install -r requirements.txt
|
||
```
|
||
|
||
### 3. Datenbank migrieren
|
||
|
||
```bash
|
||
python manage.py migrate
|
||
```
|
||
|
||
### 4. Beispieldaten laden
|
||
|
||
```bash
|
||
python manage.py load_sample_data
|
||
```
|
||
|
||
Dies erstellt 7 Kategorien mit insgesamt 15 Behauptungen, Quellen und Gegenargumenten.
|
||
|
||
### 5. Admin-Zugang einrichten
|
||
|
||
```bash
|
||
python manage.py createsuperuser
|
||
```
|
||
|
||
### 6. Entwicklungsserver starten
|
||
|
||
```bash
|
||
python manage.py runserver
|
||
```
|
||
|
||
Die Anwendung ist unter [http://127.0.0.1:8000/](http://127.0.0.1:8000/) erreichbar.
|
||
Das Django-Admin-Interface liegt unter [http://127.0.0.1:8000/admin/](http://127.0.0.1:8000/admin/).
|
||
|
||
Falls `runserver` mit einem Python-Pfadfehler abbricht, starten Sie mit:
|
||
|
||
```bash
|
||
python manage.py runserver --noreload
|
||
```
|
||
|
||
## PostgreSQL (Produktion)
|
||
|
||
Setzen Sie folgende Umgebungsvariablen:
|
||
|
||
```bash
|
||
export DB_ENGINE=django.db.backends.postgresql
|
||
export DB_NAME=faktenkompass
|
||
export DB_USER=ihr_benutzer
|
||
export DB_PASSWORD=ihr_passwort
|
||
export DB_HOST=localhost
|
||
export DB_PORT=5432
|
||
```
|
||
|
||
Installieren Sie zusätzlich `psycopg2-binary` und führen Sie `migrate` erneut aus.
|
||
|
||
## Produktion (Daphne + Nginx)
|
||
|
||
Für den Serverbetrieb wird [Daphne](https://github.com/django/daphne) als ASGI-Server empfohlen. Nginx dient als Reverse Proxy und liefert statische Dateien sowie Uploads aus.
|
||
|
||
### 1. Umgebungsvariablen
|
||
|
||
Legen Sie z. B. `/etc/faktenkompass.env` an:
|
||
|
||
```bash
|
||
DJANGO_SETTINGS_MODULE=faktenkompass.settings
|
||
DJANGO_DEBUG=False
|
||
DJANGO_SECRET_KEY=lange-zufaellige-zeichenkette
|
||
ALLOWED_HOSTS=faktenkompass.example.com,www.faktenkompass.example.com
|
||
CSRF_TRUSTED_ORIGINS=https://faktenkompass.example.com,https://www.faktenkompass.example.com
|
||
USE_HTTPS=True
|
||
|
||
DB_ENGINE=django.db.backends.postgresql
|
||
DB_NAME=faktenkompass
|
||
DB_USER=faktenkompass
|
||
DB_PASSWORD=geheim
|
||
DB_HOST=127.0.0.1
|
||
DB_PORT=5432
|
||
|
||
OPENAI_API_KEY=sk-...
|
||
```
|
||
|
||
`CSRF_TRUSTED_ORIGINS` muss die **exakte URL** sein, mit der Sie die Seite aufrufen (Schema + Domain, ohne Pfad). Bei HTTP statt HTTPS z. B. `http://192.168.178.10` setzen und `USE_HTTPS=False`.
|
||
|
||
`USE_HTTPS=True` aktiviert Proxy-Header und sichere Cookies hinter Nginx mit HTTPS.
|
||
|
||
### 2. Deployment vorbereiten
|
||
|
||
```bash
|
||
cd /pfad/zu/ArgumentAtlas
|
||
source .venv/bin/activate
|
||
pip install -r requirements.txt
|
||
|
||
set -a && source /etc/faktenkompass.env && set +a
|
||
python manage.py migrate
|
||
python manage.py collectstatic --noinput
|
||
python manage.py createsuperuser # falls noch nicht vorhanden
|
||
```
|
||
|
||
**Wichtig:** `collectstatic` immer mit denselben Umgebungsvariablen ausführen wie der Daphne-Dienst (`DJANGO_DEBUG=False`). Sonst fehlen gehashte Dateinamen bzw. `staticfiles.json` und die Seite antwortet mit 500.
|
||
|
||
Nach jedem `git pull` mit geänderten Static-Dateien:
|
||
|
||
```bash
|
||
set -a && source /etc/faktenkompass.env && set +a
|
||
python manage.py collectstatic --clear --noinput
|
||
sudo systemctl restart faktenkompass
|
||
```
|
||
|
||
Erfolg prüfen: `staticfiles/staticfiles.json` existiert, CSS heißt z. B. `custom.<hash>.css`.
|
||
|
||
Stellen Sie sicher, dass der Prozessnutzer Schreibrechte für `media/` und die Datenbank hat.
|
||
|
||
### 3. Daphne manuell testen
|
||
|
||
```bash
|
||
set -a && source /etc/faktenkompass.env && set +a
|
||
daphne -b 127.0.0.1 -p 8001 faktenkompass.asgi:application
|
||
```
|
||
|
||
Die App lauscht dann nur lokal auf Port `8001` – der öffentliche Zugriff erfolgt über Nginx.
|
||
|
||
### 4. systemd-Dienst
|
||
|
||
Datei `/etc/systemd/system/faktenkompass.service`:
|
||
|
||
```ini
|
||
[Unit]
|
||
Description=Faktenkompass (Daphne ASGI)
|
||
After=network.target postgresql.service
|
||
|
||
[Service]
|
||
Type=simple
|
||
User=www-data
|
||
Group=www-data
|
||
WorkingDirectory=/pfad/zu/ArgumentAtlas
|
||
EnvironmentFile=/etc/faktenkompass.env
|
||
ExecStart=/pfad/zu/ArgumentAtlas/.venv/bin/daphne \
|
||
-b 127.0.0.1 \
|
||
-p 8001 \
|
||
--access-log /var/log/faktenkompass/access.log \
|
||
--proxy-headers \
|
||
faktenkompass.asgi:application
|
||
Restart=always
|
||
RestartSec=5
|
||
|
||
[Install]
|
||
WantedBy=multi-user.target
|
||
```
|
||
|
||
Log-Verzeichnis anlegen und Dienst aktivieren:
|
||
|
||
```bash
|
||
sudo mkdir -p /var/log/faktenkompass
|
||
sudo chown www-data:www-data /var/log/faktenkompass
|
||
sudo systemctl daemon-reload
|
||
sudo systemctl enable --now faktenkompass
|
||
sudo systemctl status faktenkompass
|
||
```
|
||
|
||
`--proxy-headers` setzt voraus, dass Nginx die Header `X-Forwarded-For`, `X-Forwarded-Proto` und `Host` korrekt weitergibt.
|
||
|
||
### 5. Nginx-Konfiguration
|
||
|
||
Datei `/etc/nginx/sites-available/faktenkompass`:
|
||
|
||
```nginx
|
||
upstream faktenkompass {
|
||
server 127.0.0.1:8001;
|
||
}
|
||
|
||
server {
|
||
listen 80;
|
||
server_name faktenkompass.example.com;
|
||
|
||
client_max_body_size 25M;
|
||
|
||
location /static/ {
|
||
alias /pfad/zu/ArgumentAtlas/staticfiles/;
|
||
expires 30d;
|
||
access_log off;
|
||
}
|
||
|
||
location /media/ {
|
||
alias /pfad/zu/ArgumentAtlas/media/;
|
||
expires 7d;
|
||
access_log off;
|
||
}
|
||
|
||
location / {
|
||
proxy_pass http://faktenkompass;
|
||
proxy_http_version 1.1;
|
||
proxy_set_header Host $host;
|
||
proxy_set_header X-Real-IP $remote_addr;
|
||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||
proxy_set_header X-Forwarded-Proto $scheme;
|
||
proxy_redirect off;
|
||
}
|
||
}
|
||
```
|
||
|
||
Aktivieren und testen:
|
||
|
||
```bash
|
||
sudo ln -s /etc/nginx/sites-available/faktenkompass /etc/nginx/sites-enabled/
|
||
sudo nginx -t
|
||
sudo systemctl reload nginx
|
||
```
|
||
|
||
Für HTTPS: Certbot/Let's Encrypt verwenden (`certbot --nginx`).
|
||
|
||
### 6. Updates einspielen
|
||
|
||
```bash
|
||
cd /pfad/zu/ArgumentAtlas
|
||
source .venv/bin/activate
|
||
git pull
|
||
pip install -r requirements.txt
|
||
python manage.py migrate
|
||
python manage.py collectstatic --noinput
|
||
sudo systemctl restart faktenkompass
|
||
```
|
||
|
||
## Projektstruktur
|
||
|
||
```
|
||
ArgumentAtlas/
|
||
├── faktenkompass/ # Django-Projektkonfiguration
|
||
│ ├── settings.py
|
||
│ └── urls.py
|
||
├── claims/ # Haupt-App
|
||
│ ├── models.py # Category, Claim, Source, EvidenceFile, CounterArgument, Tag
|
||
│ ├── views.py
|
||
│ ├── urls.py
|
||
│ ├── admin.py
|
||
│ └── management/commands/load_sample_data.py
|
||
├── templates/ # Django-Templates (Bootstrap 5)
|
||
├── static/css/custom.css # Minimales Custom-Styling
|
||
├── requirements.txt
|
||
└── manage.py
|
||
```
|
||
|
||
## Funktionen
|
||
|
||
- **Startseite:** Kategorien als Karten mit Behauptungsanzahl
|
||
- **Kategorieseite:** Behauptungen filtern und durchsuchen
|
||
- **Behauptungsdetail:** Status, Kurzantwort, Nachweise (Bilder/PDFs), Quellen, Gegenargumente, Tags
|
||
- **Globale Suche:** Behauptungen über alle Kategorien hinweg
|
||
- **Admin:** Alle Inhalte über Django Admin pflegen
|
||
- **SEO:** Sprechende URLs (`/kategorie/klimawandel/`, `/behauptung/...`)
|
||
|
||
## Inhalte verwalten
|
||
|
||
Melden Sie sich im Django-Admin an, um Kategorien, Behauptungen, Quellen, Gegenargumente und Schlagwörter anzulegen oder zu bearbeiten. Slugs werden automatisch aus Titeln generiert.
|
||
|
||
### Nachweise hochladen
|
||
|
||
Bei jeder Behauptung können im Admin unter **Nachweise** Dateien hochgeladen werden:
|
||
|
||
- **Bilder:** JPG, PNG, GIF, WebP, SVG (z. B. Grafiken, Screenshots, Diagramme)
|
||
- **PDFs:** Studien, Berichte, Faktenblätter
|
||
|
||
Optional: Titel, Bildunterschrift und Reihenfolge. Hochgeladene Dateien erscheinen auf der Behauptungsdetailseite im Abschnitt „Nachweise“.
|
||
|
||
Dateien werden unter `media/evidence/` gespeichert. In der Produktion muss der Webserver Medien-Dateien ausliefern (z. B. über Nginx).
|
||
|
||
### Fakten-Assistent (KI im Admin)
|
||
|
||
Der Assistent hilft beim Anlegen neuer Behauptungen per ChatGPT. **Nichts wird automatisch veröffentlicht** – jeder Entwurf muss zuerst geprüft werden.
|
||
|
||
**Einrichtung:**
|
||
|
||
```bash
|
||
export OPENAI_API_KEY=sk-...
|
||
# optional: OPENAI_MODEL=gpt-4o-mini, OPENAI_MODEL_VISION=gpt-4o
|
||
```
|
||
|
||
**Nutzung:**
|
||
|
||
1. Admin öffnen → **Fakten-Assistent** (Startseite oder unter Fakten-Entwürfe)
|
||
2. Artikel-URL, Beschreibung und/oder Bild/PDF eingeben
|
||
3. **Entwurf generieren** – die KI schlägt Kategorie, Behauptung, Quellen und Gegenargumente vor
|
||
4. Entwurf prüfen, bearbeiten, ggf. **KI erneut fragen**
|
||
5. Erst mit **Veröffentlichen** wird der Eintrag live geschaltet
|
||
|
||
**Sicherheit:**
|
||
|
||
- Nur für eingeloggte Staff-Nutzer
|
||
- Artikel-URLs: SSRF-Schutz (keine internen/privaten Adressen)
|
||
- API-Schlüssel nur serverseitig (Umgebungsvariable), nie im Frontend
|
||
- Hochgeladene Dateien werden erst nach Freigabe als Nachweis verknüpft
|
||
|
||
## Lizenz
|
||
|
||
Projekt für den internen Gebrauch / Bildungszwecke.
|