Reimplements the Flask app as a Go HTTP API (chi + modernc sqlite) with a minimal vanilla-JS frontend in web/. Endpoints mirror the original Flask routes but return JSON instead of HTML. - auth: login/logout/register/sessioninfo/headerbar with crypto/rand tokens - entry: paginated feed (single JOIN), create with image scaling - user: profile, userinfo; delete still a stub - requireAuth middleware passes uid via context - notes/api.md documents the API and schema Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
4.2 KiB
kver API Definition
Abgeleitet aus dem bestehenden Flask-Code. Basis für die Go-Reimplementierung.
Authentifizierung
Sessions werden als Cookie (session) übertragen. Alle geschützten Endpunkte erwarten diesen Cookie.
Auth
POST /auth/login
Einloggen.
Request (form-encoded):
| Feld | Typ | Beschreibung |
|---|---|---|
user |
string | Nutzername |
pass |
string | Passwort |
timeout |
int | Session-Dauer in Sekunden |
Response:
200+ setztsession-Cookie → Redirect auf/200+ Fehlertext bei falschen Credentials
GET /auth/login
Login-Seite anzeigen (wird in der Go-API nicht benötigt, Frontend übernimmt das).
POST /auth/newuser
Neuen Account registrieren.
Request (form-encoded):
| Feld | Typ | Beschreibung |
|---|---|---|
user |
string | Nutzername (3–32 Zeichen, [a-zA-Z0-9._\s-]) |
pass1 |
string | Passwort (min. 10 Zeichen) |
pass2 |
string | Passwort-Bestätigung |
Response:
200bei Erfolg200+ Fehlerliste bei Validierungsfehler
GET /auth/logout
Session beenden und Cookie löschen.
Response: Redirect auf /
GET /auth/headerbar
Gibt zurück ob der Nutzer eingeloggt ist (für die UI-Headerleiste).
Response: HTML-Partial (in Go-API: JSON)
GET /auth/sessioninfo
Infos zur aktuellen Session.
Auth: erforderlich
Response:
{
"uid": 123456,
"created_at": 1700000000,
"expires": 1700086400,
"description": ""
}
Entries (Beiträge)
GET /entry/feed/:page
Paginierter Feed aller Beiträge, neueste zuerst.
Parameter:
| Name | Typ | Beschreibung |
|---|---|---|
page |
int | Seite (0–100), 20 Einträge pro Seite |
Response:
[
{
"pid": 123456789,
"created_at": 1700000000,
"uid": 42,
"content": "...",
"filepath": "static/media/...",
"username": "max"
}
]
Leeres Array [] wenn keine weiteren Einträge vorhanden.
POST /entry/create
Neuen Beitrag erstellen.
Auth: erforderlich
Request (multipart/form-data):
| Feld | Typ | Beschreibung |
|---|---|---|
content |
string | Text (max. 1000 Zeichen) |
file |
file (optional) | Bild (JPG oder GIF, wird auf max. 1024px skaliert) |
Mindestens content oder file muss vorhanden sein.
Response:
201bei Erfolg400bei leerem Beitrag401wenn nicht eingeloggt
GET /entry/:pid/interactions/:mode
Abstimmung auf einen Beitrag. (Aktuell nicht implementiert.)
Parameter:
| Name | Typ | Beschreibung |
|---|---|---|
pid |
int | Post-ID |
mode |
string | left oder right |
User
GET /u/:username
Öffentliche Profilseite eines Nutzers.
Response: Nutzerprofil + Beiträge (Details noch offen)
GET /user/info
Eigene Account-Informationen.
Auth: erforderlich
Response:
{
"uid": 42,
"username": "max",
"created_at": 1700000000
}
GET /user/delete
Account löschen. (Noch nicht implementiert.)
Datenbankschema (SQLite)
CREATE TABLE user (
id INTEGER PRIMARY KEY AUTOINCREMENT,
uid INTEGER UNIQUE,
username TEXT UNIQUE,
password BLOB,
created_at INTEGER,
last_login INTEGER
);
CREATE TABLE session (
id INTEGER PRIMARY KEY AUTOINCREMENT,
uid INTEGER,
value TEXT UNIQUE,
created_at INTEGER,
expires INTEGER,
description TEXT
);
CREATE TABLE entry (
id INTEGER PRIMARY KEY AUTOINCREMENT,
pid INTEGER UNIQUE,
uid INTEGER,
created_at INTEGER,
content TEXT,
filepath TEXT
);
CREATE TABLE vote (
id INTEGER PRIMARY KEY AUTOINCREMENT,
uid INTEGER,
pid INTEGER,
mode TEXT -- 'left' | 'right'
);
Offene Punkte
/entry/:pid/interactions/:modeist auskommentiert — Voting-Logik muss neu designed werden/user/deleteist noch ein Stub- Kein Rate-Limiting außer dem zufälligen
sleepbeim Login session-Token ist nurrandbelow(999999999) + timestamp— sollte aufcrypto/randumgestellt werden- Fehler-Responses sind aktuell Plaintext/HTML — in der Go-API einheitlich JSON