Files
Kontrollverlust/notes/api.md
T
irrlicht cb237c248e Rewrite backend in Go with JSON API and JS frontend
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>
2026-06-01 10:17:02 +02:00

4.2 KiB
Raw Blame History

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 + setzt session-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 (332 Zeichen, [a-zA-Z0-9._\s-])
pass1 string Passwort (min. 10 Zeichen)
pass2 string Passwort-Bestätigung

Response:

  • 200 bei Erfolg
  • 200 + 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 (0100), 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:

  • 201 bei Erfolg
  • 400 bei leerem Beitrag
  • 401 wenn 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/:mode ist auskommentiert — Voting-Logik muss neu designed werden
  • /user/delete ist noch ein Stub
  • Kein Rate-Limiting außer dem zufälligen sleep beim Login
  • session-Token ist nur randbelow(999999999) + timestamp — sollte auf crypto/rand umgestellt werden
  • Fehler-Responses sind aktuell Plaintext/HTML — in der Go-API einheitlich JSON