OSM-Beiträge: dog=yes-Erfassung mit GPS/Zeit-Anti-Fraud + Gamification-Zähler

- Tabelle osm_contributions (status pending→submitted→confirmed/rejected).
- Router /api/osm-contrib: POST /dog-friendly (Anti-Fraud: GPS-Beleg über
  kürzliche eigene Tour ≤50m + Verweil-Proxy, Tour-Recency 48h, Tages-Cap,
  Dedup, Positions-Sanity), GET /status (Zähler).
- Settings-UI: Zähler "X Orte eingetragen · noch Y bis Badge/Pro".
- OSM-Changeset-Upload + Pro-Freischaltung + Geräte-Attestierung folgen separat.
This commit is contained in:
rene 2026-06-03 21:20:32 +02:00
parent 46caa05020
commit 1cfaa0264f
4 changed files with 186 additions and 0 deletions

View file

@ -368,6 +368,30 @@ def init_db():
linked_at TEXT NOT NULL DEFAULT (datetime('now'))
);
-- OSM-Beiträge ("Hund war willkommen" dog=yes). Anti-Fraud: GPS-Beleg
-- über eine kürzliche eigene Tour (route_id) + Zeit/Rate-Limits.
-- status: pending submitted (an OSM) confirmed (Revert-überlebt) | rejected.
CREATE TABLE IF NOT EXISTS osm_contributions (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
osm_id INTEGER NOT NULL,
osm_type TEXT NOT NULL DEFAULT 'node', -- node | way
poi_type TEXT,
tag_key TEXT NOT NULL DEFAULT 'dog',
tag_value TEXT NOT NULL DEFAULT 'yes',
lat REAL,
lon REAL,
route_id INTEGER REFERENCES routes(id) ON DELETE SET NULL,
gps_distance_m REAL,
gps_points_near INTEGER,
status TEXT NOT NULL DEFAULT 'pending',
created_at TEXT NOT NULL DEFAULT (datetime('now')),
submitted_at TEXT,
changeset_id INTEGER,
UNIQUE(user_id, osm_id, tag_key)
);
CREATE INDEX IF NOT EXISTS idx_osm_contrib_user ON osm_contributions(user_id, status);
-- VERLORENE HUNDE
CREATE TABLE IF NOT EXISTS lost_dogs (
id INTEGER PRIMARY KEY AUTOINCREMENT,