Add connected pages: hierarchy, backlinks, and live embeds
release gate / check (push) Failing after 7m7s
release gate / check (push) Failing after 7m7s
Implement Notion-like upgrade phase 3: owner-scoped nested pages with cycle rejection and child promotion on delete; Markdown-derived internal links and backlinks; live collection embeds resolved in the content-save transaction. Add migration 008, API/docs, integration coverage, and page/sidebar UI.
This commit is contained in:
@@ -111,14 +111,34 @@ test-only). CardDAV keeps the configured HTTPS port.
|
||||
| PATCH | `/api/kanban/columns/{id}` | Updated column; body `{label?,color?}` |
|
||||
| DELETE | `/api/kanban/columns/{id}` | `{ok:true,movedTo,moved}`; moves cards, never deletes bookmarks; refuses last column |
|
||||
| PUT | `/api/kanban/cards/{id}` | Moved bookmark; body `{columnId,position,version}`. Reorders the target column (0-based position, clamped at the end) and normalizes every card's `kanbanPosition`. Owner only. `version` is REQUIRED: 400 when missing/invalid, 409 when stale; success bumps the moved card's `version` |
|
||||
| GET | `/api/pages?search=...` | Pages, pinned first, with `_count.bookmarks`; title/content substring search treats `%` and `_` literally and uses trigram indexes |
|
||||
| POST | `/api/pages` | 201 page; body `{title?,content?}` |
|
||||
| GET | `/api/pages?search=...` | Pages, pinned first, with `parentId` and `_count.{bookmarks,children}`; title/content substring search treats `%` and `_` literally and uses trigram indexes |
|
||||
| POST | `/api/pages` | 201 page; body `{title?,content?,parentId?}`. `parentId` must be an owned page; a missing/foreign parent is 400 |
|
||||
| PUT | `/api/pages` | `{ok:true}`; complete `{order:[id,...]}` |
|
||||
| GET | `/api/pages/{id}` | Page plus ordered `bookmarks:[{bookmark}]` |
|
||||
| PATCH | `/api/pages/{id}` | Updated page; `{title?,content?,pinned?,icon?,version?,addBookmarkId?,removeBookmarkId?}`. `version` (the base revision from GET) is REQUIRED with `content`: 400 when missing, 409 when stale. Metadata-only patches stay version-free and do not bump the revision |
|
||||
| DELETE | `/api/pages/{id}` | `{ok:true}`; keeps bookmarks |
|
||||
| GET | `/api/pages/{id}` | Page plus ordered `bookmarks:[{bookmark}]`, owner-scoped `backlinks:[{id,title,updatedAt}]`, resolved outgoing `links:[{id,title}]`, and `embeds:[{collectionId,viewId,position,collection,view}]` |
|
||||
| PATCH | `/api/pages/{id}` | Updated page; `{title?,content?,pinned?,icon?,parentId?,version?,addBookmarkId?,removeBookmarkId?}`. `version` (the base revision from GET) is REQUIRED with `content`: 400 when missing, 409 when stale. Metadata-only patches (including moving a page) stay version-free and do not bump the revision. Moving under itself or a descendant is rejected 400 (no cycles) |
|
||||
| DELETE | `/api/pages/{id}` | `{ok:true}`; keeps bookmarks and promotes child pages to the top level |
|
||||
| GET | `/api/pages/{id}/backlinks` | Owner-scoped `[{id,title,updatedAt}]` from `PageLink` — the pages whose Markdown links here |
|
||||
| GET | `/api/pages/{id}/markdown` | Markdown attachment |
|
||||
|
||||
### Connected pages (phase 3)
|
||||
|
||||
Page hierarchy, internal links and live collection embeds are ordinary
|
||||
Markdown contained in the page body; the server rebuilds the resolved graph
|
||||
in the same transaction as every content save:
|
||||
|
||||
- `[label](computer:page/<pageId>)` links to another page. `/pages?id=<id>`
|
||||
and `page/<id>` are accepted as hand-written aliases. Only owned targets
|
||||
are stored, so a backlink can never reveal another account's page title;
|
||||
self-links are ignored.
|
||||
- `{{collection:<collectionId>}}` embeds the collection's live default view;
|
||||
`{{collection:<collectionId>|view=<viewId>}}` pins a saved view's
|
||||
filters/sorts. Only owned collections are stored, and item reads still go
|
||||
through the normal collection endpoint, so an embed displays data without
|
||||
publishing it or widening bookmark access.
|
||||
- Deleting a page removes its links/embeds, promotes its children, and keeps
|
||||
its bookmarks. Deleting a collection removes its embeds; deleting a view
|
||||
falls the embed back to the collection's default view.
|
||||
|
||||
## Collections
|
||||
|
||||
Contextual workflows over existing bookmarks (phase 2 of the Notion-like
|
||||
|
||||
Reference in New Issue
Block a user