4.7 KiB
Export & Utility
Health Check
GET /health → { "status": "ok" }
Public, no auth. Also available at /api/v1/health.
Export
Convert markdown to PDF or DOCX via pandoc:
POST /export
{
"content": "# My Document\n\nBody text...",
"format": "pdf|docx",
"filename": "my-document"
}
Returns the binary file with appropriate Content-Type. Requires
pandoc in the container (available in the unified and backend
Docker images).
17b. Files & Storage
All binary content in Chat Switchboard flows through a single
ObjectStore abstraction backed by PVC (filesystem) or S3. All
file metadata lives in one files table. The old attachments
table is dropped.
Storage Backend
| Operation | Description |
|---|---|
Put(key, reader, size, contentType) |
Store a blob |
Get(key) → reader, size, contentType |
Retrieve a blob |
Delete(key) |
Remove a blob |
DeletePrefix(prefix) |
Bulk remove (channel deletion) |
Exists(key) |
Check without reading |
Healthy() |
Backend health check |
Stats() |
Aggregate metrics |
Backends: pvc (STORAGE_PATH=/data/storage) or s3
(S3_ENDPOINT, S3_BUCKET, S3_ACCESS_KEY, S3_SECRET_KEY).
Key Namespacing
| Prefix | Pattern | What |
|---|---|---|
attachments/ |
attachments/{channel_id}/{file_id}_{filename} |
User uploads + AI outputs (legacy prefix retained for existing blobs) |
kb/ |
kb/{kb_id}/{doc_id}_{filename} |
Knowledge base documents |
exports/ |
exports/{user_id}/{export_id}_{filename} |
Chat/data exports |
workspace/ |
workspace/{workspace_id}/{path} |
Workspace files |
File Object
CREATE TABLE files (
id UUID PRIMARY KEY,
channel_id UUID REFERENCES channels(id) ON DELETE CASCADE,
message_id UUID REFERENCES messages(id) ON DELETE SET NULL,
user_id UUID REFERENCES users(id) ON DELETE SET NULL,
project_id UUID REFERENCES projects(id) ON DELETE SET NULL,
origin TEXT NOT NULL DEFAULT 'user_upload'
CHECK (origin IN ('user_upload','tool_output','system')),
filename TEXT NOT NULL,
content_type TEXT NOT NULL DEFAULT 'application/octet-stream',
size_bytes BIGINT NOT NULL DEFAULT 0,
storage_key TEXT NOT NULL,
display_hint TEXT NOT NULL DEFAULT 'download'
CHECK (display_hint IN ('inline','download','thumbnail')),
extracted_text TEXT,
metadata JSONB DEFAULT '{}',
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
Origin:
| Value | Who creates | Examples |
|---|---|---|
user_upload |
User via upload UI | PDF, image, doc attached to message |
tool_output |
Tool execution during completion | DALL-E image, video gen, code artifact |
system |
Platform | Export, avatar stored as file |
Display hint:
| Value | Frontend behavior |
|---|---|
inline |
Render in message stream (images, video, audio, HTML) |
download |
Filename + size + download button |
thumbnail |
Thumbnail preview, click to expand |
Tool Output Flow
- Tool executes (image gen, video render, etc.)
- Tool writes blob via
ObjectStore.Put - Tool creates file record:
POST /fileswithorigin: "tool_output",message_id= current assistant message - Tool result includes
file_idreference - WebSocket emits
file.createdevent:
{
"event": "file.created",
"channel_id": "uuid",
"message_id": "uuid",
"file": { ...file object... }
}
- Frontend renders inline based on
display_hint+content_type
The event fires during streaming so the user sees the artifact before the completion finishes.
Content Type → Display Hint Defaults
| Content Type | Default Hint | Rendering |
|---|---|---|
image/* |
inline |
<img> in message, lightbox on click |
video/* |
inline |
<video> player |
audio/* |
inline |
<audio> player |
text/html |
inline |
Sandboxed iframe |
application/pdf |
thumbnail |
Thumb + PDF viewer on click |
text/*, application/json |
inline |
Syntax-highlighted code block |
| Everything else | download |
Filename + download button |
Tools can override the default hint explicitly.
File Manager (Future Surface)
A user-scoped file browser backed by GET /files?page=1&per_page=50.
Displays all files owned by the user across all channels, grouped by
channel or date. Supports download and delete. Deleting a file that
is referenced by a message replaces the inline render with a
"file deleted" placeholder.