- frontend.go: Seitenrouten liefern die index.html (no-cache), gehashte
Assets unter /assets dauerhaft cachebar, sonst echtes 404
- /stats als Seite, /stats.html leitet per 301 weiter
- Containerfile: Node-Stage baut das Frontend nach web/
- Vite baut nach ../web (gitignored); web/ (Vanilla-JS) gelöscht
- notes/frontend.md, deploy.md angepasst
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TiXsPUqw7oeomZ8wZrQW5q
- Moderationsseite und Melde-Funktion (report) komplett ausgebaut; folgt
als eigenständiges Projekt
- alle API-Endpunkte unter /api, dort ausschließlich JSON: auch 404, 405,
Rate-Limit (429) und Panics (500)
- Fehler nur über HTTP-Status; stille DB-Fehler in stats, logout und
Vote-Zählern liefern jetzt 500 statt Nullen
- /auth/headerbar entfernt (Frontend nutzt /api/user/info)
- Frontend auf /api und statusbasierte Auswertung umgestellt
- notes/api.md neu als Referenz der aktuellen API
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TiXsPUqw7oeomZ8wZrQW5q
Das anonymisierte /16 (bzw. /32 bei IPv6) gehört oft nicht einem
einzigen AS -- gerade im APNIC-Raum ist es in viele kleine Bloecke
zerstueckelt. Der bisherige Lookup auf die Basisadresse lieferte dann
nur den zufaelligen Inhaber von Offset 0 (z.B. faelschlich "Rakuten
Mobile" fuer einen Besucher, der irgendwo im selben /16 sitzt).
Jetzt: per NetworksWithin alle ASNs im Netz zaehlen, das mit der
groessten Adress-Abdeckung waehlen und bei weiteren "(n weitere
Treffer)" anhaengen. Homogene Netze stehen sauber mit Betreibername,
zersplitterte tragen den dominanten plus ehrlichen Unsicherheits-Marker.
Arbeitet weiter ausschliesslich auf dem maskierten Netz, nie auf der
vollen IP.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Der Seitenaufruf wartete bisher synchron auf den DB-Upsert. Mit
synchronous=FULL (WAL) macht SQLite pro Commit ein fsync -> spuerbare
Latenz pro Seitenaufruf. Die Erfassung laeuft jetzt in einer Goroutine,
die Auslieferung blockiert nicht mehr darauf. Der GeoIP-Lookup war nie
das Problem (mmap, einmal beim Start geoeffnet).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Seitenaufrufe werden serverseitig pro (Tag, anonymisiertes Netz, Pfad)
gezaehlt -- nur auf den HTML-Seiten-Routen, nicht auf API/Assets. Die
Client-IP wird sofort maskiert (IPv4 /16, IPv6 /32); die vollstaendige
IP wird nie gespeichert oder weiterverwendet.
Optional loest eine lokale GeoLite2-ASN-DB (Env KVER_GEOIP_ASN) den
Netzbetreiber aus dem bereits anonymisierten Netz auf -- auch dafuer wird
nicht die volle IP herangezogen. Fehlt die DB, bleibt das Feld leer.
Neuer Endpunkt GET /stats/detail liefert die Aggregate; die Tabelle
impression speichert nur Zaehlwerte (kein Eventlog).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>