106 lines
3.5 KiB
Markdown
106 lines
3.5 KiB
Markdown
|
|
# Delivery Desk upload contract
|
||
|
|
|
||
|
|
## Current hierarchy and identity
|
||
|
|
|
||
|
|
`operation group -> project -> work -> review round`
|
||
|
|
|
||
|
|
- A project belongs to exactly one operation group.
|
||
|
|
- A work belongs to exactly one project.
|
||
|
|
- A review round belongs to exactly one work and contains exactly one proposal.
|
||
|
|
- `externalId` is unique within a project and is the only supported idempotency key for agent-created works.
|
||
|
|
- Product-facing operations do not accept a collection/delivery-set ID.
|
||
|
|
|
||
|
|
## Authentication and scope
|
||
|
|
|
||
|
|
Send `Authorization: Bearer <DELIVERY_DESK_API_KEY>`.
|
||
|
|
|
||
|
|
| Key scope | Readable projects | Create work | Create round |
|
||
|
|
|---|---|---|---|
|
||
|
|
| `project` | Its bound active project | Only in that project | Only for works in that project |
|
||
|
|
| `platform` | All non-archived projects | Any active project | Any work in an active project |
|
||
|
|
|
||
|
|
Prefer `project`. Do not store the token in a plan file.
|
||
|
|
|
||
|
|
## Discovery endpoints
|
||
|
|
|
||
|
|
### `GET /api/projects`
|
||
|
|
|
||
|
|
Returns accessible projects. Relevant fields:
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"id": 12,
|
||
|
|
"group_id": 3,
|
||
|
|
"group_name": "示例运营组",
|
||
|
|
"name": "光影内容计划",
|
||
|
|
"slug": "light-notes",
|
||
|
|
"status": "active",
|
||
|
|
"review_status": "reviewing"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### `GET /api/projects/:projectId/works`
|
||
|
|
|
||
|
|
Returns works in the exact project. Use `?externalId=<value>` for exact external-ID lookup.
|
||
|
|
|
||
|
|
### `GET /api/works/:workId`
|
||
|
|
|
||
|
|
Returns current work content, project identity, images, and rounds. Use `?round=N` only when inspecting a historical round.
|
||
|
|
|
||
|
|
## Mutation endpoints
|
||
|
|
|
||
|
|
### `POST /api/projects/:projectId/works`
|
||
|
|
|
||
|
|
JSON body:
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"externalId": "client-2026-001",
|
||
|
|
"title": "作品标题",
|
||
|
|
"description": "正文",
|
||
|
|
"tags": ["#夏日"],
|
||
|
|
"images": ["https://cdn.example.com/01.jpg"]
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
Constraints:
|
||
|
|
|
||
|
|
- `title` is required.
|
||
|
|
- `images` contains 1-30 public HTTP/HTTPS URLs.
|
||
|
|
- Array order is display order; item 1 is the cover.
|
||
|
|
- An active Tencent COS configuration is required. URLs on its configured public/CDN origin are reused; other public images are downloaded, validated, and stored in that COS before the work is created.
|
||
|
|
- Cross-origin images must be supported image responses no larger than 20 MB. Local, private, reserved, and non-standard-port targets are rejected.
|
||
|
|
- Repeating the same `projectId + externalId` returns the existing work with `idempotent: true`.
|
||
|
|
|
||
|
|
### `POST /api/works/:workId/rounds`
|
||
|
|
|
||
|
|
JSON body:
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"title": "修改后的标题",
|
||
|
|
"description": "修改后的正文",
|
||
|
|
"tags": ["#第二轮"],
|
||
|
|
"images": ["https://cdn.example.com/round-2.jpg"]
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
This endpoint is not idempotent. One successful call creates exactly one new round. Never blindly retry after a timeout.
|
||
|
|
It applies the same COS reuse/import rules as work creation.
|
||
|
|
|
||
|
|
## State guards
|
||
|
|
|
||
|
|
- Only `active` projects accept new works or rounds.
|
||
|
|
- Closed or archived projects are read-only.
|
||
|
|
- A completed project may require an authorized administrator to reopen the relevant workflow before another round can be created.
|
||
|
|
- `400`: malformed or incomplete input.
|
||
|
|
- `401`: missing/invalid authentication.
|
||
|
|
- `403`: key or account cannot access the target project.
|
||
|
|
- `404`: target does not exist.
|
||
|
|
- `409`: target state disallows mutation or a uniqueness conflict occurred.
|
||
|
|
- `413`: a remote image exceeds 20 MB.
|
||
|
|
- `422`: a remote image cannot be downloaded or is not a supported image response.
|
||
|
|
- `502`: Delivery Desk could not store an imported image in Tencent COS.
|
||
|
|
|
||
|
|
Do not work around `403` or `409` by selecting a different project. Report the exact target and ask the operator or administrator to resolve access/state.
|