mirror of
https://github.com/narrrl/narl-workspace.git
synced 2026-11-03 16:41:27 +01:00
A document now lists the cards about it: the ones whose notes it is and
the ones whose description links to it. GET /nodes/{id}/cards answers
that, and the node itself carries it as `cards`. A line under the
document's meta line says what is still open and when it is first due;
it and `gc` open a new cards part of the info sheet, where j/k picks a
card, Space, H/L, D, a and `:` act on it, and Enter turns it over on its
board. `c` while reading a document makes a card about it.
Card verbs act on the card in focus wherever it is looked at: the
board's cursor, the card turned over, the agenda's highlight, the card
picked in the info sheet, or a document's only open card. patchCard,
sendCard and toggleDone take that card, so patchAgendaCard,
sendAgendaCard and finishCard are gone, and :due, :repeat, :label and
:done no longer refuse to run away from the board.
Migration 0027 adds card_links, links for a card's description: indexed
on every write, backfilled on start, followed and rewritten on a rename
or move like a document's, and claimed when a title they named appears.
It also adds cards_fts over title, description and checklist steps;
GET /cards?q= searches it, and / lists the cards found after the nodes,
Enter turning one over on its board.
67 lines
6.1 KiB
Markdown
67 lines
6.1 KiB
Markdown
<!-- Generated by scripts/wiki.ts from the API section of README.md. Edit that, then run `make wiki`. -->
|
|
|
|
# API
|
|
|
|
Everything except the login, the health check and the two share routes
|
|
requires the session cookie; `/api/capture` takes a token instead. Media answers `Range` requests, so a video seeks,
|
|
sealed or not.
|
|
|
|
| method | path | purpose |
|
|
| --- | --- | --- |
|
|
| `GET` | `/api/health` | public: up, and the database answers — for a supervisor |
|
|
| `POST` | `/api/login`, `/api/logout` | session; `/api/logout?everywhere=true` ends every one |
|
|
| `GET` | `/api/me` | current user |
|
|
| `GET` | `/api/sessions` | every signed-in browser, the one seen last first |
|
|
| `DELETE` | `/api/sessions/{id}` | sign another browser out, and lock the vault |
|
|
| `GET`/`POST` | `/api/spaces` | the spaces / create one |
|
|
| `GET`/`POST` | `/api/nodes` | children (`?parent=`) or search (`?q=`, `?space=`; a file matched by its text has `in_text` and the words around the match as `excerpt`, each matched word between U+0002 and U+0003) / create, from a template with `template_id` |
|
|
| `GET`/`PUT`/`DELETE` | `/api/nodes/{id}` | read / update only the fields sent — `name`, `body`, `created_at`, `has_board`; with `base_updated_at`, refused with `409` once it was saved since / delete into the trash, subtree and all — or for good, for something already in it |
|
|
| `GET`/`DELETE` | `/api/trash` | what was deleted, the last first / empty it |
|
|
| `DELETE` | `/api/trash/{id}` | delete one thing in the trash for good |
|
|
| `POST` | `/api/trash/{id}/restore` | back where it was deleted from, or to its space when that folder is gone |
|
|
| `GET` | `/api/spaces/{id}/board` | the lists and cards of one space |
|
|
| `GET` | `/api/agenda` | open cards due within a week or in hand, on every board, whether the diary has today, its entries `on_this_day` in earlier years, and `today` in `WORKSPACE_TIMEZONE`, with its bounds |
|
|
| `GET` | `/api/diary/days?month=2026-10` | the diary's entries in a month, each with its local `day` |
|
|
| `POST` | `/api/diary/day` | `{ day? }`: the entry of `2026-10-22`, or of today in `WORKSPACE_TIMEZONE`, started from `templates/day` when there is none; answers `{ id, created }` |
|
|
| `GET` | `/api/diary/around/{id}` | the entries before and after a diary entry, by date |
|
|
| `GET` | `/api/nodes/{id}/templates` | the templates of the space the node is in |
|
|
| `POST` | `/api/capture` | `{ text, to: "card" \| "diary", space? }`, with a session or `Authorization: Bearer` a token |
|
|
| `GET`/`POST` | `/api/tokens` | the capture tokens / make one, `{ name }`, answered with the token this once |
|
|
| `DELETE` | `/api/tokens/{id}` | remove a capture token |
|
|
| `POST` | `/api/spaces/{id}/lists` | add a list |
|
|
| `PUT`/`DELETE` | `/api/lists/{id}` | rename / delete a list and its cards |
|
|
| `POST` | `/api/lists/{id}/cards` | add a card |
|
|
| `PUT`/`DELETE` | `/api/cards/{id}` | update (title, body, due, repeat, checklist, labels, done, link) / delete; finishing a repeating card answers its copy as `again` |
|
|
| `POST` | `/api/cards/{id}/move` | to another list and place in it; `again` as above |
|
|
| `GET` | `/api/cards?q=…` | cards whose title, summary or a checklist step matches, open ones first; `space` keeps it to one board |
|
|
| `GET`/`POST` | `/api/scratch` | the scratchpad's notes, the one touched last first / a new note `{ body }` |
|
|
| `PUT`/`DELETE` | `/api/scratch/{id}` | rewrite a note `{ body }` / drop it |
|
|
| `POST` | `/api/nodes/{id}/move` | reparent, and place among the new siblings |
|
|
| `POST` | `/api/nodes/move` | `{ ids, parent_id }`: several into one folder, all or none |
|
|
| `POST` | `/api/nodes/{id}/import` | import a folder or zip (multipart) under this node |
|
|
| `POST` | `/api/import` | import an export at the root: directories become spaces |
|
|
| `GET` | `/api/resolve?path=` | the node behind a slug path, `work/notes/monday` |
|
|
| `GET` | `/api/nodes/{id}/revisions` | a document's earlier versions, the newest first |
|
|
| `GET` | `/api/nodes/{id}/revisions/{rev}` | one earlier version, with its text |
|
|
| `GET` | `/api/nodes/{id}/backlinks` | the documents that link to this one, with the line each does it on |
|
|
| `GET` | `/api/nodes/{id}/cards` | the cards about this document: its own (`node_id`) and the ones whose summary links here — also in the node itself as `cards` |
|
|
| `POST`/`DELETE` | `/api/nodes/{id}/share` | mint or rotate / revoke a share link |
|
|
| `GET` | `/api/export` | the whole workspace, boards and dates included, as a zip |
|
|
| `GET`/`POST` | `/api/backup` | Proton Drive mirror: status / run now |
|
|
| `POST`/`DELETE` | `/api/backup/login` | log the mirror in to Proton, body `{"username","password"}` / forget its session |
|
|
| `POST` | `/api/backup/login/totp`, `/api/backup/login/captcha` | the two-factor code `{"code"}`, or the solved human check `{"token"}`, a waiting login asked for |
|
|
| `GET`/`POST` | `/api/media` | list / upload (multipart) |
|
|
| `GET`/`DELETE` | `/api/media/{id}` | serve (with `Range`) / delete a file nothing in the tree owns |
|
|
| `POST` | `/api/typst` | `{source}` of a ` ```typst ` block → `{svg}`, or `{error}` as typst words it |
|
|
| `GET` | `/api/spaces/overview` | every space with what was last written in it |
|
|
| `POST` | `/api/nodes/{id}/files` | upload files into this folder as file nodes (`?encrypt=true` seals them) |
|
|
| `POST` | `/api/nodes/{id}/inspect` | what a certificate, key or keystore file holds (`{password}` opens a protected one) |
|
|
| `POST` | `/api/nodes/{id}/encrypt`, `/decrypt` | seal a file, or a folder for good — what is in it and what lands later — or take it out |
|
|
| `GET`/`POST`/`PUT` | `/api/vault` | status / set the password once / change it |
|
|
| `POST` | `/api/vault/unlock`, `/api/vault/lock` | open / close the vault |
|
|
| `GET`/`POST` | `/api/ssh-keys` | the keys that may mount over SFTP / add one |
|
|
| `DELETE` | `/api/ssh-keys/{id}` | remove a key, which ends its mounts |
|
|
| `POST` | `/api/share/{token}` | public: read a shared document, body `{"key"}`; sets the share's media cookie |
|
|
| `GET` | `/api/share/{token}/media/{id}` | public: media inside a shared document, with that cookie |
|
|
| `POST` | `/api/share/{token}/typst` | public: a typst block the shared document holds, with that cookie |
|