- Invite flow: admin issue/revoke on join requests, public single-use claim links (hash-only tokens, 7-day expiry, no state reveal), claim creates the Member account and marks the request accepted - Gallery: admin status page plus resync endpoint; sync refreshes thumbnails whose content changed; tools/gallery contract and checker - Docs: public content page, admin-only operator runbook, api.md invite/gallery sections, all routes in the live API docs, docs reachability gate test - Screenshots cover the new pages; version 1.0.18
57 lines
6.2 KiB
Python
57 lines
6.2 KiB
Python
# retoor <retoor@molodetz.nl>
|
|
from molodetz.docs_api.registry import endpoint, field
|
|
|
|
GROUP = {
|
|
"slug": "admin",
|
|
"title": "Admin",
|
|
"description": "Administrators only. Writing and publishing posts, join requests, services, trash, settings.",
|
|
"endpoints": [
|
|
endpoint("GET", "/admin", "Overview", auth="admin", sample={"post_count": 5, "open_joins": 0, "user_count": 1, "deleted_count": 0, "flyer_count": 4, "meme_count": 38}),
|
|
endpoint("GET", "/admin/posts", "Posts", auth="admin", sample={"posts": []}),
|
|
endpoint("GET", "/admin/posts/new", "New post", auth="admin", sample={}),
|
|
endpoint(
|
|
"POST",
|
|
"/admin/posts",
|
|
"Post creation",
|
|
"Adds a markdown post; status draft or published.",
|
|
auth="admin",
|
|
fields=[
|
|
field("title", required=True, example="A title"),
|
|
field("body", required=True, example="Text in **markdown**."),
|
|
field("topic", enum=["roll", "standard"], example="roll"),
|
|
field("status", enum=["draft", "published"], example="draft"),
|
|
field("is_placeholder", type="boolean"),
|
|
],
|
|
sample={"ok": True, "redirect": "/admin/posts", "data": {"uid": "..."}},
|
|
probe_body={"title": "x"},
|
|
),
|
|
endpoint("GET", "/admin/posts/{uid}/edit", "Edit post", auth="admin", fields=[field("uid", required=True, location="path")], probe_path="/admin/posts/unknown/edit"),
|
|
endpoint("POST", "/admin/posts/{uid}", "Save post", auth="admin", fields=[field("uid", required=True, location="path")], probe_path="/admin/posts/unknown", probe_body={"title": "x"}),
|
|
endpoint("POST", "/admin/posts/{uid}/publish", "Publish", auth="admin", fields=[field("uid", required=True, location="path")], probe_path="/admin/posts/unknown/publish"),
|
|
endpoint("POST", "/admin/posts/{uid}/delete", "Post removal", "Soft delete; restore from the trash.", auth="admin", destructive=True, fields=[field("uid", required=True, location="path")], probe_path="/admin/posts/unknown/delete"),
|
|
endpoint("GET", "/admin/joins", "Join requests", auth="admin", sample={"requests": []}),
|
|
endpoint("POST", "/admin/joins/{uid}/status", "Join request status", auth="admin", fields=[field("uid", required=True, location="path"), field("status", enum=["open", "contacted", "accepted", "declined"])], probe_path="/admin/joins/unknown/status", probe_body={"status": "open"}),
|
|
endpoint("POST", "/admin/joins/{uid}/check", "Check repo link", "Fetches the title through the guarded outbound client.", auth="admin", fields=[field("uid", required=True, location="path")], probe_path="/admin/joins/unknown/check"),
|
|
endpoint("POST", "/admin/joins/{uid}/invite", "Issue invite", "Issues a single-use claim link, shown once. Revokes the previous open invite.", auth="admin", fields=[field("uid", required=True, location="path")], sample={"ok": True, "redirect": "/admin/joins", "data": {"claim_url": "https://example.com/invite/...", "expires_at": "..."}}, probe_path="/admin/joins/unknown/invite"),
|
|
endpoint("POST", "/admin/joins/{uid}/invite/revoke", "Revoke invite", "Revokes the open invite without touching the request.", auth="admin", fields=[field("uid", required=True, location="path")], sample={"ok": True, "redirect": "/admin/joins", "data": {"revoked": 1}}, probe_path="/admin/joins/unknown/invite/revoke"),
|
|
endpoint("GET", "/admin/gallery", "Gallery status", "Live flyer and meme counts plus catalogued files missing from disk.", auth="admin", sample={"flyers": 4, "memes": 38, "missing": []}),
|
|
endpoint("POST", "/admin/gallery/resync", "Resync gallery", "Re-reads sources, refreshes changed thumbnails, retires removed entries.", auth="admin", sample={"ok": True, "redirect": "/admin/gallery", "data": {"synced": 42, "flyers": 4, "memes": 38, "missing": []}}),
|
|
endpoint("GET", "/admin/services", "Services", auth="admin", sample={"services": []}),
|
|
endpoint("GET", "/admin/services/{name}", "Service", auth="admin", fields=[field("name", required=True, location="path", example="backup")], probe_path="/admin/services/backup"),
|
|
endpoint("POST", "/admin/services/{name}/command", "Service command", auth="admin", fields=[field("name", required=True, location="path"), field("verb", enum=["start", "stop", "run", "clear"])], probe_path="/admin/services/backup/command", probe_body={"verb": "noop"}),
|
|
endpoint("POST", "/admin/services/{name}/config", "Service configuration", auth="admin", fields=[field("name", required=True, location="path")], probe_path="/admin/services/backup/config", probe_body={}),
|
|
endpoint("GET", "/admin/trash", "Trash", auth="admin", sample={"items": []}),
|
|
endpoint("POST", "/admin/trash/restore", "Restore", auth="admin", fields=[field("stamp", required=True)], probe_body={"stamp": "none"}),
|
|
endpoint("POST", "/admin/trash/purge", "Permanent purge", auth="admin", destructive=True, fields=[field("stamp", required=True)], probe_body={"stamp": "none"}),
|
|
endpoint("GET", "/admin/settings", "Settings", auth="admin", sample={"settings": {}}),
|
|
endpoint("POST", "/admin/settings", "Save settings", auth="admin", probe_body={}),
|
|
endpoint("GET", "/admin/users", "Accounts", auth="admin", sample={"users": []}),
|
|
endpoint("POST", "/admin/users/{uid}/role", "Change role", auth="admin", fields=[field("uid", required=True, location="path"), field("role", enum=["Admin", "Member"])], probe_path="/admin/users/unknown/role", probe_body={"role": "Member"}),
|
|
endpoint("GET", "/admin/audit", "Audit log", auth="admin", sample={"rows": []}),
|
|
endpoint("GET", "/admin/backups", "Backups", auth="admin", sample={"backups": []}),
|
|
endpoint("POST", "/admin/backups", "Schedule backup", auth="admin", fields=[field("target", enum=["database", "uploads", "keys", "full"])], probe_body={"target": "nope"}),
|
|
endpoint("GET", "/admin/backups/{uid}/download", "Download backup", "Primary administrator only.", auth="admin", negotiation="none", interactive=False, probe_path="/admin/backups/unknown/download"),
|
|
endpoint("GET", "/admin/stats", "Statistics", auth="admin", sample={"top_paths": [], "daily": []}),
|
|
],
|
|
}
|