Document the guides API, and move Guides beside Slides
The repo already enforces that every served route appears in docs/api-inventory.json, and the guides endpoints did not - so the parity test was failing. They are now listed with auth, params and a working example each, beside knowledgebase because the two get read for the same reason. docs/GUIDES.md covers what the inventory cannot: the block schema and why it is blocks rather than HTML, the id rule that makes a tick rememberable, what the server refuses and why validation happens at the door, the working-copy / revision / published-pointer split that stops a live procedure changing under somebody following it, and a worked example of creating and publishing a guide from a script. It also states plainly what does not exist yet - no importer, orphaned images never pruned - and what converting existing documents will actually be like: structured HTML and Markdown map onto block types nearly one for one, while a plain-text runbook lands as paragraphs and needs marking up by hand afterwards. Generated ids have to stay stable across re-imports, or every re-import resets readers' progress. Guides moves to position 8 in the sidebar, beside Slides, rather than down among the reference lists in Information. A guide is something somebody goes and does something with, not a catalogue they look things up in.
This commit is contained in:
@@ -3442,5 +3442,122 @@
|
||||
"example": "curl -H \"Authorization: Bearer $TOKEN\" -X POST http://localhost:5001/api/mappositions/snapshots/7/restore"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"surface": "guides",
|
||||
"endpoints": [
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/api/guides",
|
||||
"auth": "jwt + guides.view",
|
||||
"params": "query: q (searches title, summary, tags and body), tag",
|
||||
"purpose": "List guides. Published guides plus the caller's own drafts; someone with guides.edit sees every draft",
|
||||
"example": "curl 'http://localhost:5001/api/guides?tag=partmarker' -H \"Authorization: Bearer $TOK\""
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/api/guides/tags",
|
||||
"auth": "jwt + guides.view",
|
||||
"params": "none",
|
||||
"purpose": "Every tag in use with a count, for filter chips",
|
||||
"example": "curl http://localhost:5001/api/guides/tags -H \"Authorization: Bearer $TOK\""
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/api/guides/<slug>",
|
||||
"auth": "jwt + guides.view",
|
||||
"params": "none",
|
||||
"purpose": "Read a guide as a READER: returns the PUBLISHED revision, not the working copy, so an edit in progress does not change what somebody following the procedure sees. 404 (not 403) for an unpublished guide the caller cannot edit",
|
||||
"example": "curl http://localhost:5001/api/guides/replace-a-marker -H \"Authorization: Bearer $TOK\""
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/api/guides/<guideid>/working",
|
||||
"auth": "jwt + guides.view (+ edit rights)",
|
||||
"params": "none",
|
||||
"purpose": "The working copy, for the editor. Requires guides.edit, or guides.create while the guide is your own and unpublished",
|
||||
"example": "curl http://localhost:5001/api/guides/12/working -H \"Authorization: Bearer $TOK\""
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/api/guides/<guideid>/revisions",
|
||||
"auth": "jwt + guides.view",
|
||||
"params": "none",
|
||||
"purpose": "Version history, newest first, flagging which revision is published",
|
||||
"example": "curl http://localhost:5001/api/guides/12/revisions -H \"Authorization: Bearer $TOK\""
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/api/guides/revisions/<revisionid>",
|
||||
"auth": "jwt + guides.view",
|
||||
"params": "none",
|
||||
"purpose": "One revision including its blocks, for viewing or comparing an old version",
|
||||
"example": "curl http://localhost:5001/api/guides/revisions/34 -H \"Authorization: Bearer $TOK\""
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/api/guides",
|
||||
"auth": "jwt + guides.create",
|
||||
"params": "body: title (required), summary, tags (comma separated), blocks (array), note",
|
||||
"purpose": "Create a guide as a draft. Every block needs a unique, stable id: the id is what a reader's tick is remembered against, and a save without one is refused",
|
||||
"example": "curl -X POST http://localhost:5001/api/guides -H \"Authorization: Bearer $TOK\" -H 'Content-Type: application/json' -d '{\"title\":\"Swap a controller\",\"tags\":\"partmarker\",\"blocks\":[{\"id\":\"b1\",\"type\":\"paragraph\",\"text\":\"Power it off.\"}]}'"
|
||||
},
|
||||
{
|
||||
"method": "PUT",
|
||||
"path": "/api/guides/<guideid>",
|
||||
"auth": "jwt + guides.view (+ edit rights)",
|
||||
"params": "body: any of title, summary, tags, blocks, note",
|
||||
"purpose": "Save the working copy. Writes a new revision ONLY when the content hash changes, so an autosave that changed nothing records nothing; the response carries saved=false in that case",
|
||||
"example": "curl -X PUT http://localhost:5001/api/guides/12 -H \"Authorization: Bearer $TOK\" -H 'Content-Type: application/json' -d '{\"blocks\":[]}'"
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/api/guides/<guideid>/publish",
|
||||
"auth": "jwt + guides.publish",
|
||||
"params": "none",
|
||||
"purpose": "Point readers at the latest saved revision. Promotes an existing revision rather than snapshotting, so a publish cannot ship unsaved edits nobody reviewed",
|
||||
"example": "curl -X POST http://localhost:5001/api/guides/12/publish -H \"Authorization: Bearer $TOK\""
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/api/guides/<guideid>/unpublish",
|
||||
"auth": "jwt + guides.publish",
|
||||
"params": "none",
|
||||
"purpose": "Withdraw from readers without deleting anything; revisions survive so the guide can be corrected and published again",
|
||||
"example": "curl -X POST http://localhost:5001/api/guides/12/unpublish -H \"Authorization: Bearer $TOK\""
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/api/guides/<guideid>/restore/<revisionid>",
|
||||
"auth": "jwt + guides.view (+ edit rights)",
|
||||
"params": "none",
|
||||
"purpose": "Bring an old revision back as a NEW revision. History is never rewritten, so what was published in between stays on record",
|
||||
"example": "curl -X POST http://localhost:5001/api/guides/12/restore/34 -H \"Authorization: Bearer $TOK\""
|
||||
},
|
||||
{
|
||||
"method": "DELETE",
|
||||
"path": "/api/guides/<guideid>",
|
||||
"auth": "jwt + guides.delete",
|
||||
"params": "none",
|
||||
"purpose": "Delete a guide and its revisions and images",
|
||||
"example": "curl -X DELETE http://localhost:5001/api/guides/12 -H \"Authorization: Bearer $TOK\""
|
||||
},
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/api/guides/images",
|
||||
"auth": "jwt + guides.create",
|
||||
"params": "multipart: file (png/jpeg/gif/webp, max 8 MB), guideid (optional)",
|
||||
"purpose": "Upload an image for a guide. guideid is optional because an image is pasted before a new guide has an id; the editor attaches it on save",
|
||||
"example": "curl -X POST http://localhost:5001/api/guides/images -H \"Authorization: Bearer $TOK\" -F file=@screenshot.png -F guideid=12"
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/api/guides/images/<imageid>",
|
||||
"auth": "jwt + guides.view",
|
||||
"params": "none",
|
||||
"purpose": "Serve an uploaded image; cached immutably since an image is replaced rather than edited",
|
||||
"example": "curl http://localhost:5001/api/guides/images/5 -H \"Authorization: Bearer $TOK\" --output shot.png"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user