forked from mirror/crumbs-original
docs: add public sharing to features, architecture, and API docs
- FEATURES.md: add public link sharing feature details - ARCHITECTURE.md: add shared_notes table to schema section - openapi.yaml: add share create/revoke, public note, and public attachment endpoints with SharedNoteData schema - Regenerate API.md Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
committed by
Fred Cabassut
co-authored by
Claude Opus 4.6
parent
44570c5205
commit
ec5f2a321f
+109
@@ -410,6 +410,115 @@ Owner can remove anyone. Collaborator can only remove self (leave). Use `userId=
|
||||
|
||||
---
|
||||
|
||||
## Sharing
|
||||
|
||||
### `POST /api/notes/{id}/share`
|
||||
|
||||
Create a public share link
|
||||
|
||||
Owner-only. Creates a public share URL for the note. Idempotent — returns existing token if already shared.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
| Name | In | Type | Required | Description |
|
||||
|------|----|------|----------|-------------|
|
||||
| `id` | path | string | yes | |
|
||||
|
||||
**Response:** `201`
|
||||
|
||||
```json
|
||||
{
|
||||
"token": "token",
|
||||
"url": "url"
|
||||
}
|
||||
```
|
||||
|
||||
**Errors:** `404` Note not found or not owner
|
||||
|
||||
---
|
||||
|
||||
### `DELETE /api/notes/{id}/share`
|
||||
|
||||
Revoke a public share link
|
||||
|
||||
Owner-only. Removes the public share link for the note.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
| Name | In | Type | Required | Description |
|
||||
|------|----|------|----------|-------------|
|
||||
| `id` | path | string | yes | |
|
||||
|
||||
**Response:** `204`
|
||||
|
||||
**Errors:** `404` Note not found or not owner
|
||||
|
||||
---
|
||||
|
||||
### `GET /api/shared/{token}`
|
||||
|
||||
Get a shared note (public)
|
||||
|
||||
No authentication required. Returns the note content for a valid share token. Rate limited to 60 requests per minute per IP.
|
||||
|
||||
> No authentication required.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
| Name | In | Type | Required | Description |
|
||||
|------|----|------|----------|-------------|
|
||||
| `token` | path | string | yes | |
|
||||
|
||||
**Response:** `200`
|
||||
|
||||
```json
|
||||
{
|
||||
"title": "title",
|
||||
"content": "content",
|
||||
"checklistMode": true,
|
||||
"color": "default",
|
||||
"attachments": [
|
||||
{
|
||||
"id": "id",
|
||||
"noteId": "noteId",
|
||||
"filename": "filename",
|
||||
"mimeType": "mimeType",
|
||||
"size": 1,
|
||||
"thumbnailPath": "thumbnailPath",
|
||||
"createdAt": "2025-01-01T00:00:00.000Z"
|
||||
}
|
||||
],
|
||||
"createdAt": "2025-01-01T00:00:00.000Z",
|
||||
"updatedAt": "2025-01-01T00:00:00.000Z"
|
||||
}
|
||||
```
|
||||
|
||||
**Errors:** `404` Invalid token or note is trashed, `429` Rate limit exceeded
|
||||
|
||||
---
|
||||
|
||||
### `GET /api/shared/{token}/attachment/{attachmentId}`
|
||||
|
||||
Get an attachment from a shared note (public)
|
||||
|
||||
No authentication required. Serves image binary for an attachment belonging to the shared note. Rate limited.
|
||||
|
||||
> No authentication required.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
| Name | In | Type | Required | Description |
|
||||
|------|----|------|----------|-------------|
|
||||
| `token` | path | string | yes | |
|
||||
| `attachmentId` | path | string | yes | |
|
||||
| `thumb` | query | string | no | Set to '1' to get the thumbnail version (1) |
|
||||
|
||||
**Response:** `200`
|
||||
|
||||
**Errors:** `404` Invalid token, note trashed, or attachment not found, `429` Rate limit exceeded
|
||||
|
||||
---
|
||||
|
||||
## Users
|
||||
|
||||
### `GET /api/users/search`
|
||||
|
||||
@@ -100,6 +100,7 @@ Key tables:
|
||||
- `api_keys` - MCP API keys (SHA-256 hashed, prefix for display)
|
||||
- `note_collaborators` - Sharing relationships (noteId + userId + addedBy)
|
||||
- `note_user_state` - Per-user pin/archive/sortOrder for shared notes
|
||||
- `shared_notes` - Public share links (noteId → token, 1:1 with cascade delete)
|
||||
- `sync_log` - Sync operation history
|
||||
|
||||
### Collaboration Access Control
|
||||
|
||||
+9
-2
@@ -81,13 +81,20 @@
|
||||
- Permanently delete from trash
|
||||
|
||||
### Note Sharing / Collaboration
|
||||
- **Public link sharing**: share any note via a public URL — no login required for viewers
|
||||
- Toggle public link on/off from the share dialog
|
||||
- Copy shareable URL with one click
|
||||
- Read-only public page with full markdown/checklist/image rendering
|
||||
- Public links are automatically invalidated when a note is trashed
|
||||
- Rate-limited public endpoints (60 req/min per IP)
|
||||
- Globe icon on note cards indicates a public link is active
|
||||
- Share notes with other users on the same instance
|
||||
- User search autocomplete for adding collaborators
|
||||
- Full collaboration: both owner and collaborators can edit content, color, and checklist mode
|
||||
- Per-user state: pin, archive, and sort order are independent per user
|
||||
- Owner-only actions: trash, delete, share/unshare
|
||||
- Collaborator indicator (Users icon) on shared note cards
|
||||
- Hover popover showing collaborator names
|
||||
- Sharing indicator on note cards (Globe for public, Users for collaborators-only)
|
||||
- Hover popover showing sharing status and collaborator names
|
||||
- Share dialog accessible from editor toolbar
|
||||
- Collaborators can leave shared notes
|
||||
- Shared notes appear mixed in main list alongside owned notes
|
||||
|
||||
@@ -237,6 +237,104 @@ paths:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Success'
|
||||
|
||||
/api/notes/{id}/share:
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
post:
|
||||
summary: Create a public share link
|
||||
description: Owner-only. Creates a public share URL for the note. Idempotent — returns existing token if already shared.
|
||||
tags: [Sharing]
|
||||
responses:
|
||||
'201':
|
||||
description: Share link created
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
token:
|
||||
type: string
|
||||
url:
|
||||
type: string
|
||||
format: uri
|
||||
'404':
|
||||
description: Note not found or not owner
|
||||
delete:
|
||||
summary: Revoke a public share link
|
||||
description: Owner-only. Removes the public share link for the note.
|
||||
tags: [Sharing]
|
||||
responses:
|
||||
'204':
|
||||
description: Share link revoked
|
||||
'404':
|
||||
description: Note not found or not owner
|
||||
|
||||
/api/shared/{token}:
|
||||
parameters:
|
||||
- name: token
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
get:
|
||||
summary: Get a shared note (public)
|
||||
description: No authentication required. Returns the note content for a valid share token. Rate limited to 60 requests per minute per IP.
|
||||
tags: [Sharing]
|
||||
security: []
|
||||
responses:
|
||||
'200':
|
||||
description: Shared note data
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SharedNoteData'
|
||||
'404':
|
||||
description: Invalid token or note is trashed
|
||||
'429':
|
||||
description: Rate limit exceeded
|
||||
|
||||
/api/shared/{token}/attachment/{attachmentId}:
|
||||
parameters:
|
||||
- name: token
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
- name: attachmentId
|
||||
in: path
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
get:
|
||||
summary: Get an attachment from a shared note (public)
|
||||
description: No authentication required. Serves image binary for an attachment belonging to the shared note. Rate limited.
|
||||
tags: [Sharing]
|
||||
security: []
|
||||
parameters:
|
||||
- name: thumb
|
||||
in: query
|
||||
schema:
|
||||
type: string
|
||||
enum: ['1']
|
||||
description: Set to '1' to get the thumbnail version
|
||||
responses:
|
||||
'200':
|
||||
description: Image binary
|
||||
content:
|
||||
image/*:
|
||||
schema:
|
||||
type: string
|
||||
format: binary
|
||||
'404':
|
||||
description: Invalid token, note trashed, or attachment not found
|
||||
'429':
|
||||
description: Rate limit exceeded
|
||||
|
||||
/api/users/search:
|
||||
get:
|
||||
summary: Search users
|
||||
@@ -520,6 +618,29 @@ components:
|
||||
description: API key (crumbs_...)
|
||||
|
||||
schemas:
|
||||
SharedNoteData:
|
||||
type: object
|
||||
properties:
|
||||
title:
|
||||
type: string
|
||||
content:
|
||||
type: string
|
||||
checklistMode:
|
||||
type: boolean
|
||||
color:
|
||||
type: string
|
||||
enum: [default, coral, peach, sand, mint, sage, fog, storm, dusk, blossom, clay, chalk]
|
||||
attachments:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Attachment'
|
||||
createdAt:
|
||||
type: string
|
||||
format: date-time
|
||||
updatedAt:
|
||||
type: string
|
||||
format: date-time
|
||||
|
||||
Success:
|
||||
type: object
|
||||
properties:
|
||||
|
||||
Reference in New Issue
Block a user