* plumb for firestore * chore: cleanup orion api to only include essentials * setup boilerplate for data and rendering This includes zod types creation for API response validation, and exploration of path based resolution of rendering particles. * chore: structure container particles for rendering children * wire firestore crud for particles * integrate visibility to particles * docs: explain particle view resolver
310 lines
7.3 KiB
Markdown
310 lines
7.3 KiB
Markdown
# API Documentation
|
|
|
|
All protected endpoints require a `Bearer` token in the `Authorization` header.
|
|
|
|
## Authentication
|
|
|
|
### Request Sign-In Code
|
|
`POST /auth/request-code`
|
|
|
|
Sends a 4-digit sign-in code to the provided email. Creates user if not exists.
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"email": "[email protected]"
|
|
}
|
|
```
|
|
|
|
**Response:** `204 No Content`
|
|
|
|
### Sign In
|
|
`POST /auth/sign-in`
|
|
|
|
Verifies the code and returns a session token.
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"email": "[email protected]",
|
|
"code": "1234"
|
|
}
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"human": { "id": "...", "email": "...", "email_prefix": "...", "created_at": "..." },
|
|
"token": "session_token"
|
|
}
|
|
```
|
|
|
|
### Sign Out
|
|
`POST /auth/sign-out` (Protected)
|
|
|
|
Invalidates the current session. Returns `204 No Content`.
|
|
|
|
### Get Current User
|
|
`GET /auth/me` (Protected)
|
|
|
|
Returns the authenticated user.
|
|
|
|
---
|
|
|
|
## Networks
|
|
|
|
### Create Network
|
|
`POST /networks` (Protected)
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"name": "My Network"
|
|
}
|
|
```
|
|
|
|
### List Networks
|
|
`GET /networks` (Protected)
|
|
|
|
Returns all networks the user is a member of.
|
|
|
|
### Get Network
|
|
`GET /networks/{id}` (Protected)
|
|
|
|
Returns a specific network by ID.
|
|
|
|
### Add Members to Network
|
|
`POST /networks/{id}/members` (Protected)
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"email_addresses": ["[email protected]", "[email protected]"]
|
|
}
|
|
```
|
|
|
|
### Remove Member from Network
|
|
`DELETE /networks/{id}/members/{email}` (Protected)
|
|
|
|
Removes a member by email from the network.
|
|
|
|
---
|
|
|
|
### Download Particle Object
|
|
`GET /particles/{id}/download` (Protected)
|
|
|
|
For now, the `{id}` should be an object id. Not the particle id.
|
|
|
|
Returns a `302` redirect to a signed download URL. Only works for `media` and `file` particles.
|
|
|
|
---
|
|
|
|
## Depot (File Storage)
|
|
|
|
### Prepare Upload
|
|
`POST /depot/upload` (Protected)
|
|
|
|
Prepares a signed URL for direct upload to GCS.
|
|
|
|
**Request Body:**
|
|
```json
|
|
{
|
|
"network_id": "network_uuid",
|
|
"name": "filename.png",
|
|
"content_type": "image/png",
|
|
"content_length": 12345
|
|
}
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"object_id": "uuid",
|
|
"upload_url": "https://storage.googleapis.com/...",
|
|
"upload_headers": { "Content-Type": "image/png" }
|
|
}
|
|
```
|
|
|
|
### Confirm Upload
|
|
`POST /depot/objects/{id}/confirm` (Protected)
|
|
|
|
Confirms that an upload has been completed.
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"id": "uuid",
|
|
"name": "filename.png",
|
|
"content_type": "image/png",
|
|
"content_length": 12345,
|
|
"contains_content": true,
|
|
"created_at": "..."
|
|
}
|
|
```
|
|
|
|
### Upload Flow
|
|
|
|
1. `POST /depot/upload` — get signed URL and `object_id`
|
|
2. Upload file directly to GCS using the signed URL
|
|
3. `POST /depot/objects/{id}/confirm` — mark upload complete
|
|
4. Create a `media` or `file` particle with the `object_id` in its data
|
|
|
|
---
|
|
|
|
## Object Reference
|
|
|
|
### Human
|
|
|
|
| Field | Type | Description |
|
|
|-------|------|-------------|
|
|
| `id` | `string \| null` | Unique identifier. Null if not yet registered. |
|
|
| `email` | `string` | Email address (stable identifier). |
|
|
| `email_prefix` | `string` | The local part of the email (before `@`). |
|
|
| `created_at` | `string \| null` | ISO 8601 timestamp. Null if not registered. |
|
|
|
|
```json
|
|
{
|
|
"id": "abc-123",
|
|
"email": "[email protected]",
|
|
"email_prefix": "alice",
|
|
"created_at": "2025-01-15T10:30:00Z"
|
|
}
|
|
```
|
|
|
|
### Network
|
|
|
|
| Field | Type | Description |
|
|
|-------|------|-------------|
|
|
| `id` | `string` | Unique identifier. |
|
|
| `name` | `string` | Display name of the network. |
|
|
| `admin_human` | `Human` | The network administrator. |
|
|
| `humans` | `Human[]` | All members of the network (including admin). |
|
|
| `created_at` | `string` | ISO 8601 timestamp. |
|
|
|
|
```json
|
|
{
|
|
"id": "net-456",
|
|
"name": "My Team",
|
|
"admin_human": { "id": "abc-123", "email": "[email protected]", "email_prefix": "alice", "created_at": "..." },
|
|
"humans": [
|
|
{ "id": "abc-123", "email": "[email protected]", "email_prefix": "alice", "created_at": "..." }
|
|
],
|
|
"created_at": "2025-01-15T10:30:00Z"
|
|
}
|
|
```
|
|
|
|
### DepotObject
|
|
|
|
Returned by `POST /depot/objects/{id}/confirm`.
|
|
|
|
| Field | Type | Description |
|
|
|-------|------|-------------|
|
|
| `id` | `string` | Unique object identifier. |
|
|
| `name` | `string` | Original filename. |
|
|
| `content_type` | `string` | MIME type (e.g. `image/png`). |
|
|
| `content_length` | `integer` | Size in bytes. |
|
|
| `contains_content` | `boolean` | Whether the object has been uploaded successfully. |
|
|
| `created_at` | `string` | ISO 8601 timestamp. |
|
|
|
|
---
|
|
|
|
## Particle Data by Type
|
|
|
|
The `data` field on a Particle is a JSON object whose schema depends on the particle's `type`.
|
|
|
|
### `stream`
|
|
|
|
| Field | Type | Description |
|
|
|-------|------|-------------|
|
|
| `name` | `string` | Stream name (required). |
|
|
| `status` | `string` | `"open"` or `"closed"` (required). |
|
|
| `description` | `string \| null` | Stream description (optional). |
|
|
|
|
```json
|
|
{ "name": "Sprint Planning", "status": "open", "description": "Weekly sync" }
|
|
```
|
|
|
|
### `folder`
|
|
|
|
| Field | Type | Description |
|
|
|-------|------|-------------|
|
|
| `name` | `string` | Folder name (required). |
|
|
| `color` | `string \| null` | Display color (optional). |
|
|
|
|
```json
|
|
{ "name": "Design Assets", "color": "#FF5733" }
|
|
```
|
|
|
|
### `media`
|
|
|
|
| Field | Type | Description |
|
|
|-------|------|-------------|
|
|
| `object_id` | `string` | Reference to depot storage object (required). |
|
|
| `mime_type` | `string` | MIME type of the media (required). |
|
|
| `duration_ms` | `integer` | Duration in milliseconds, must be > 0 (required). |
|
|
|
|
```json
|
|
{ "object_id": "obj-123", "mime_type": "image/jpeg", "duration_ms": 5000 }
|
|
```
|
|
|
|
### `file`
|
|
|
|
| Field | Type | Description |
|
|
|-------|------|-------------|
|
|
| `object_id` | `string` | Reference to depot storage object (required). |
|
|
| `filename` | `string` | Original filename (required). |
|
|
| `mime_type` | `string` | MIME type (required). |
|
|
| `size` | `integer` | File size in bytes, must be > 0 (required). |
|
|
|
|
```json
|
|
{ "object_id": "obj-456", "filename": "report.pdf", "mime_type": "application/pdf", "size": 204800 }
|
|
```
|
|
|
|
### `text`
|
|
|
|
| Field | Type | Description |
|
|
|-------|------|-------------|
|
|
| `content` | `string` | Text content (required). |
|
|
|
|
```json
|
|
{ "content": "Hello world" }
|
|
```
|
|
|
|
### `quest`
|
|
|
|
| Field | Type | Description |
|
|
|-------|------|-------------|
|
|
| `title` | `string` | Quest/task title (required). |
|
|
| `description` | `string` | Details about the quest (required). |
|
|
| `status` | `string \| null` | Current status (optional, e.g. `"todo"`, `"in_progress"`, `"done"`). |
|
|
| `assigned_to` | `string \| null` | Email of the assigned user (optional). |
|
|
| `due_date` | `string \| null` | ISO date string (optional, e.g. `"2025-03-01"`). |
|
|
|
|
```json
|
|
{ "title": "Fix login bug", "description": "Login fails on Safari", "status": "todo", "assigned_to": "[email protected]" }
|
|
```
|
|
|
|
### `paper`
|
|
|
|
| Field | Type | Description |
|
|
|-------|------|-------------|
|
|
| `title` | `string` | Document title (required). |
|
|
| `content` | `string` | Document body in markdown (required). |
|
|
|
|
```json
|
|
{ "title": "Architecture RFC", "content": "## Overview\n..." }
|
|
```
|
|
|
|
---
|
|
|
|
## Error Responses
|
|
|
|
All endpoints return standard HTTP status codes with plain text error bodies:
|
|
|
|
- **400** Bad Request — invalid input or missing required fields
|
|
- **401** Unauthorized — missing or invalid auth token
|
|
- **403** Forbidden — user lacks permission (not a member, not creator, not admin)
|
|
- **404** Not Found — resource doesn't exist
|
|
- **409** Conflict — state conflict (stream already open/closed, capacity exceeded)
|
|
- **500** Internal Server Error
|