Adressen: Slug und Version im Pfad statt Parameter

Seite: /<slug>[/v<N>][/lauf|/buch|/lesen][/<Abschnitt>], Zurück-Taste je
Abschnitt. API: /api/themen/<slug>/v<N>/… mit Version als Pflichtteil des
Pfads; /api/topics entfällt. Slugs stehen in thema.json und werden beim
Start nachgetragen. Unbekannte API-Pfade liefern 404 statt der Seite.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
team3
2026-10-05 17:12:42 +02:00
parent 1b6899638b
commit d15ec49714
8 changed files with 284 additions and 191 deletions

View File

@@ -13,20 +13,22 @@ async function req(pfad, opts = {}) {
return ct.includes('json') ? r.json() : r.text()
}
// Pfade: /api/themen/<slug>/v<N>/… – die Version ist immer Teil der Adresse
const e = encodeURIComponent
const q = (v) => (v ? `?v=${v}` : '') // Version; ohne Angabe die neueste
const v = (slug, n) => `/themen/${e(slug)}/v${n}`
export const api = {
topics: () => req('/topics'),
anlegen: (name, hinweise = '') => req('/topics', { method: 'POST', body: { name, hinweise } }),
versionAnlegen: (t) => req(`/topics/${e(t)}/version`, { method: 'POST' }),
loeschen: (t, v) => req(`/topics/${e(t)}${q(v)}`, { method: 'DELETE' }),
start: (t, v) => req(`/topics/${e(t)}/start${q(v)}`, { method: 'POST' }),
pause: (t, v) => req(`/topics/${e(t)}/pause${q(v)}`, { method: 'POST' }),
reset: (t, v) => req(`/topics/${e(t)}/reset${q(v)}`, { method: 'POST' }),
state: (t, v) => req(`/topics/${e(t)}/state${q(v)}`),
guide: (t, v) => req(`/topics/${e(t)}/guide${q(v)}`),
position: (t, v) => req(`/topics/${e(t)}/position${q(v)}`),
positionSetzen: (t, daten, v) => req(`/topics/${e(t)}/position${q(v)}`, { method: 'PUT', body: daten }),
guideMdUrl: (t, v) => `/api/topics/${e(t)}/guide.md${q(v)}`,
pdfUrl: (t, v) => `/api/topics/${e(t)}/buch.pdf${q(v)}`,
themen: () => req('/themen'),
anlegen: (name, hinweise = '') => req('/themen', { method: 'POST', body: { name, hinweise } }),
loeschen: (slug) => req(`/themen/${e(slug)}`, { method: 'DELETE' }),
versionAnlegen: (slug) => req(`/themen/${e(slug)}/versionen`, { method: 'POST' }),
versionLoeschen: (slug, n) => req(v(slug, n), { method: 'DELETE' }),
state: (slug, n) => req(v(slug, n)),
start: (slug, n) => req(v(slug, n) + '/start', { method: 'POST' }),
pause: (slug, n) => req(v(slug, n) + '/pause', { method: 'POST' }),
reset: (slug, n) => req(v(slug, n) + '/reset', { method: 'POST' }),
buch: (slug, n) => req(v(slug, n) + '/buch'),
position: (slug, n) => req(v(slug, n) + '/position'),
positionSetzen: (slug, n, daten) => req(v(slug, n) + '/position', { method: 'PUT', body: daten }),
buchMdUrl: (slug, n) => '/api' + v(slug, n) + '/buch.md',
pdfUrl: (slug, n) => '/api' + v(slug, n) + '/buch.pdf',
}