feat: implement StaySense MVP backend, frontend, imports, and deployment docs

This commit is contained in:
Oliver 2026-02-15 13:08:56 +01:00
commit 902988276c
No known key found for this signature in database
24 changed files with 2536 additions and 0 deletions

102
docs/DEPLOYMENT.md Normal file
View file

@ -0,0 +1,102 @@
# StaySense Deployment Guide (Linux + Nginx)
## 1. Voraussetzungen
- Ubuntu/Debian Server mit sudo
- Domain (optional, empfohlen)
- Python 3.10+
- Nginx
- systemd
Install:
```bash
sudo apt update
sudo apt install -y python3 nginx
```
## 2. Code bereitstellen
```bash
sudo mkdir -p /opt/staysense
sudo chown -R $USER:$USER /opt/staysense
git clone <REPO_URL> /opt/staysense
```
## 3. Initialisierung
```bash
cd /opt/staysense/backend
python3 -c "from db import init_db; init_db()"
python3 import_osm_overpass.py
python3 run_import_jobs.py --config ../docs/open_data_sources.json --prune-legacy
```
## 4. API als Service starten
1. Service-Datei kopieren:
```bash
sudo cp /opt/staysense/deploy/systemd/staysense-api.service /etc/systemd/system/
```
2. Secret setzen (Datei anpassen):
```bash
sudo nano /etc/systemd/system/staysense-api.service
# STAYSENSE_SERVER_SALT=... setzen
```
3. Aktivieren:
```bash
sudo systemctl daemon-reload
sudo systemctl enable --now staysense-api.service
sudo systemctl status staysense-api.service
```
## 5. Import-Timer aktivieren
```bash
sudo cp /opt/staysense/deploy/systemd/staysense-import.service /etc/systemd/system/
sudo cp /opt/staysense/deploy/systemd/staysense-import.timer /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now staysense-import.timer
sudo systemctl list-timers | grep staysense
```
## 6. Nginx konfigurieren
```bash
sudo cp /opt/staysense/deploy/nginx/staysense.conf /etc/nginx/sites-available/staysense
sudo ln -s /etc/nginx/sites-available/staysense /etc/nginx/sites-enabled/staysense
sudo nginx -t
sudo systemctl reload nginx
```
## 7. API-Route im Frontend anpassen
Fuer Reverse Proxy `/api` kann in `src/index.html` vor `app.js` gesetzt werden:
```html
<script>
window.STAYSENSE_API_BASE = "/api";
</script>
```
Danach Nginx reloaden.
## 8. HTTPS (empfohlen)
```bash
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d staysense.example.com
```
## 9. Betrieb / Checks
```bash
curl -s http://127.0.0.1:8787/health
sudo journalctl -u staysense-api.service -f
sudo journalctl -u staysense-import.service -n 100
```

27
docs/GITHUB_PUBLISH.md Normal file
View file

@ -0,0 +1,27 @@
# GitHub Publish Guide
## 1. Repository erstellen
- Neues GitHub Repo erstellen, z. B. `staysense-mvp`
- Private oder Public nach Bedarf
## 2. Remote setzen
```bash
cd StaySense
git remote add origin git@github.com:<ORG_OR_USER>/<REPO>.git
# alternativ HTTPS:
# git remote add origin https://github.com/<ORG_OR_USER>/<REPO>.git
```
## 3. Push
```bash
git push -u origin main
```
## 4. Empfohlene Repo-Settings
- Branch Protection fuer `main`
- Issues/Projects aktivieren
- Secrets fuer Deployment (falls CI/CD)

View file

@ -0,0 +1,79 @@
# StaySense Umsetzungsplan (MVP NRW)
## Ziel
Entscheidung in <10 Sekunden: Ist ein Spot heute Nacht (22-06) voraussichtlich ruhig?
## Scope
- Region: NRW, Pilot Kreis Mettmann
- Plattform im MVP: Web-App mit iOS-tauglichem Verhalten (Offline-Queue/Cache)
- Kein Account-System
## Architektur
- Frontend: Vanilla HTML/CSS/JS (`src/`)
- Backend: Python Standardbibliothek + SQLite (`backend/`)
- Daten: `data/staysense.db`
## API (MVP)
- `GET /spot/score?lat=..&lon=..&at=ISO8601`
- liefert `score`, `ampel`, `reasons`, `night_window`, `meta`
- `POST /spot/signal`
- Body: `spot_id`, `signal_type`, `device_token`, `timestamp`
- erzwingt 1 Signal pro `(spot, device)` in 24h
## Datenpipeline
- OSM Import (Overpass):
- Tabellen: `osm_poi`, `osm_zone`, `osm_road`
- Script: `backend/import_osm_overpass.py`
- OpenData Connector Layer:
- Script: `backend/open_data_connector.py`
- Konfig: `docs/open_data_sources.json`
- Formate: CSV + JSON
- Job Runner:
- Script: `backend/run_import_jobs.py`
- Modi: einmalig (`once`) oder periodisch (`daemon`)
- Optionales Legacy-Pruning: `--prune-legacy`
## Datenmodell
- `spot`
- Standortmetadaten inkl. OSM-Typ und Distanzmetriken
- `community_signal`
- Signale mit `hashed_device`, ohne PII
- `open_data_event`
- lokale Risiko-Ereignisse mit Zeitfenster
- `data_source_state`
- Importstand/Frische je Datenquelle
## Score Engine v0.1
- Startwert: `100`
- Modifikatoren:
- Umgebungstyp (z. B. residential -10, industrial +10)
- Distanz zu Polizei/Krankenhaus
- Zeitlogik (Wochenende/Feiertag -10, Werktagnacht +5)
- lokale Events (z. B. Muellabfuhr -20)
- Community-Signale mit Zeit-Decay (`calm`, `noise`, `knock`, `police`)
- Ausgabe:
- Score 0-100
- Ampel
- Top-2 bis Top-4 Gruende
- Source-Health in `meta.health` (Freshness/Fallback-Info)
## Datenschutz / Sicherheit
- Local device token (UUIDv4) nur auf Client
- Backend speichert nur HMAC-Hash
- Kein Fingerprinting
- Kein Login
- HTTPS-only fuer Produktion
## Naechste Schritte
1. Reale NRW/Kommunal-URLs in `open_data_sources.json` aktivieren
2. Health-Checks + Alerting fuer fehlgeschlagene Importjobs
3. Postgres + PostGIS Migration

41
docs/OPERATIONS.md Normal file
View file

@ -0,0 +1,41 @@
# Operations Runbook
## Wichtige Befehle
API neu starten:
```bash
sudo systemctl restart staysense-api.service
```
Import manuell ausfuehren:
```bash
sudo systemctl start staysense-import.service
```
Service-Logs:
```bash
sudo journalctl -u staysense-api.service -f
sudo journalctl -u staysense-import.service -f
```
Health check:
```bash
curl -s http://127.0.0.1:8787/health
```
## Backup
```bash
cp /opt/staysense/data/staysense.db /opt/staysense/data/staysense.db.bak
```
## Restore
```bash
cp /opt/staysense/data/staysense.db.bak /opt/staysense/data/staysense.db
sudo systemctl restart staysense-api.service
```

View file

@ -0,0 +1,3 @@
lat,lon,event_type,start_datetime,end_datetime,risk_modifier,source
51.2502,6.9735,waste,2026-02-16T06:00:00Z,2026-02-16T08:00:00Z,-20,stadt_mettmann_abfall
51.2960,6.8500,market,2026-02-16T05:30:00Z,2026-02-16T10:30:00Z,-12,stadt_ratingen_markt
1 lat lon event_type start_datetime end_datetime risk_modifier source
2 51.2502 6.9735 waste 2026-02-16T06:00:00Z 2026-02-16T08:00:00Z -20 stadt_mettmann_abfall
3 51.2960 6.8500 market 2026-02-16T05:30:00Z 2026-02-16T10:30:00Z -12 stadt_ratingen_markt

View file

@ -0,0 +1,42 @@
{
"sources": [
{
"id": "local_template_csv",
"enabled": true,
"format": "csv",
"file": "open_data_events_template.csv",
"source_name": "stadt_mettmann_template",
"field_map": {
"lat": "lat",
"lon": "lon",
"event_type": "event_type",
"start_datetime": "start_datetime",
"end_datetime": "end_datetime",
"risk_modifier": "risk_modifier"
}
},
{
"id": "nrw_portal_placeholder_json",
"enabled": false,
"format": "json",
"url": "https://example-opendata.nrw.example/api/events.json",
"json_path": "items",
"source_name": "open_data_nrw",
"field_map": {
"external_id": "id",
"lat": "latitude",
"lon": "longitude",
"event_type": "category",
"start_datetime": "start",
"end_datetime": "end",
"risk_modifier": "risk"
},
"event_type_map": {
"abfall": "waste",
"markt": "market",
"veranstaltung": "event",
"baustelle": "construction"
}
}
]
}