5.0 KiB
5.0 KiB
Editor Backend API Spec (/api/editor)
Purpose
Provide a backend contract for storing and syncing editor project state (timeline, scenes, settings, metadata).
Scope
- Persist editor state as JSON snapshots.
- Support optimistic concurrency for autosave sync.
- Support project listing and retrieval across devices.
Out of Scope (v1)
- Real-time collaborative editing.
- Server-side timeline merge.
- Asset transcoding.
Auth and Tenancy
- All endpoints require
Authorization: Bearer <JWT>. - All reads/writes are scoped to the authenticated user and workspace context.
- Return
401when JWT/context is invalid. - Return
404when project does not exist in the caller workspace.
Data Model
editor_projects
idUUID PKworkspace_idstring not nullowner_idbigint/int not nullnamestring(255) not nullstate_jsonJSONB not nullversionbigint not null default1created_attimestamptz not nullupdated_attimestamptz not nulldeleted_attimestamptz nullable
Indexes:
(workspace_id, updated_at desc)(workspace_id, owner_id, updated_at desc)- Optional GIN on
state_jsonif querying inside JSON is needed later.
Project State Envelope (stored in state_json)
Use a versioned envelope so backend can validate shape at a high level while keeping timeline details client-owned.
{
"schemaVersion": 3,
"currentSceneId": "scene_main",
"metadata": {
"id": "proj_123",
"name": "My Project",
"duration": 42.5,
"updatedAt": "2026-02-09T16:00:00.000Z"
},
"settings": {},
"scenes": []
}
Validation (v1):
schemaVersionrequired integer.scenesrequired array.- JSON payload size limit: recommend
<= 5 MB(return413if exceeded). - Backend should not mutate timeline internals except metadata timestamps/version fields it owns.
API Contract
Base path: /api/editor
1) List Projects
GET /api/editor/projects?offset=0&limit=20&search=my
Query:
offsetoptional int>= 0, default0limitoptional int1..100, default20searchoptional string (name contains)
Response 200:
{
"items": [
{
"id": "uuid",
"workspaceId": "ws_123",
"ownerId": 1,
"name": "My Project",
"version": 8,
"updatedAt": "2026-02-09T16:00:00.000Z",
"createdAt": "2026-02-08T16:00:00.000Z"
}
],
"total": 1
}
2) Get Project
GET /api/editor/projects/:id
Response 200:
{
"id": "uuid",
"workspaceId": "ws_123",
"ownerId": 1,
"name": "My Project",
"version": 8,
"state": {},
"updatedAt": "2026-02-09T16:00:00.000Z",
"createdAt": "2026-02-08T16:00:00.000Z"
}
Errors:
404project not found in workspace
3) Upsert Project State (Optimistic Concurrency)
PUT /api/editor/projects/:id
Request:
{
"name": "My Project",
"baseVersion": 8,
"state": {},
"clientRequestId": "optional-idempotency-key"
}
Rules:
- If project does not exist, allow create when caller has write access. New record starts at
version = 1. - If project exists,
baseVersionmust equal currentversion. - On success, increment version by 1 (or set to 1 for create), set
updated_at = now(). - If
baseVersionmismatch, return conflict.
Success 200:
{
"id": "uuid",
"version": 9,
"updatedAt": "2026-02-09T16:00:00.000Z"
}
Conflict 409:
{
"error": "VERSION_CONFLICT",
"message": "Project has a newer version on server",
"serverVersion": 10,
"serverUpdatedAt": "2026-02-09T16:02:00.000Z"
}
Validation errors:
400invalid payload413payload too large
Sync and Conflict Behavior (Client Contract)
- Client reads project
versionfromGET /api/editor/projects/:id. - Autosave sends
PUTwithbaseVersion. - On
409, client fetches latest server project and prompts user: keep local or server (v1 policy). - Do not silently overwrite newer server versions.
Security and Limits
- Enforce workspace isolation on every query.
- Validate project ownership or workspace role before writes.
- Rate limit write endpoint (
PUT) to protect autosave storms. - Sanitize/validate
namelength and UTF-8 validity.
Observability
- Log structured fields:
workspaceId,projectId,userId,version,status, latency. - Emit metrics:
editor_api_put_success_totaleditor_api_put_conflict_totaleditor_api_put_validation_error_totaleditor_api_payload_bytes
Suggested Backend Tasks
- Add DB migration for
editor_projects. - Implement
GET /api/editor/projects. - Implement
GET /api/editor/projects/:id. - Implement
PUT /api/editor/projects/:idwith optimistic concurrency transaction. - Add request/response validation schema and shared error format.
- Add integration tests for auth, tenancy, conflict, payload size, and create/update flows.
Acceptance Criteria
- Project created on device A appears in list on device B.
- Autosave updates increase
versionmonotonically. - Concurrent writes produce deterministic
409conflict responses. - Unauthorized cross-workspace access is blocked.