feat(task-013): add draft assembly API, immutable versioning, and editor preview

This commit is contained in:
2026-05-21 23:33:15 +03:00
parent 8ebb5ad623
commit c3914bf8be
19 changed files with 2416 additions and 16 deletions
+500
View File
@@ -238,6 +238,11 @@
"default": null,
"title": "Parent Job Id"
},
"payload": {
"additionalProperties": true,
"title": "Payload",
"type": "object"
},
"queued_at": {
"format": "date-time",
"title": "Queued At",
@@ -999,6 +1004,67 @@
"title": "CurrentUserResponse",
"type": "object"
},
"DraftAssembleResponse": {
"additionalProperties": false,
"properties": {
"draft": {
"$ref": "#/components/schemas/DraftSummary"
}
},
"required": [
"draft"
],
"title": "DraftAssembleResponse",
"type": "object"
},
"DraftFaqItem": {
"additionalProperties": false,
"properties": {
"answer": {
"minLength": 1,
"title": "Answer",
"type": "string"
},
"question": {
"minLength": 1,
"title": "Question",
"type": "string"
}
},
"required": [
"question",
"answer"
],
"title": "DraftFaqItem",
"type": "object"
},
"DraftListResponse": {
"additionalProperties": false,
"properties": {
"drafts": {
"items": {
"$ref": "#/components/schemas/DraftSummary"
},
"title": "Drafts",
"type": "array"
}
},
"title": "DraftListResponse",
"type": "object"
},
"DraftResponse": {
"additionalProperties": false,
"properties": {
"draft": {
"$ref": "#/components/schemas/DraftSummary"
}
},
"required": [
"draft"
],
"title": "DraftResponse",
"type": "object"
},
"DraftSummary": {
"additionalProperties": false,
"properties": {
@@ -1007,6 +1073,24 @@
"title": "Article Id",
"type": "string"
},
"based_on_draft_id": {
"anyOf": [
{
"format": "uuid",
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Based On Draft Id"
},
"body_markdown": {
"default": "",
"title": "Body Markdown",
"type": "string"
},
"body_object_key": {
"anyOf": [
{
@@ -1019,6 +1103,26 @@
"default": null,
"title": "Body Object Key"
},
"created_at": {
"format": "date-time",
"title": "Created At",
"type": "string"
},
"evidence_references": {
"items": {
"format": "uuid",
"type": "string"
},
"title": "Evidence References",
"type": "array"
},
"faq_items": {
"items": {
"$ref": "#/components/schemas/DraftFaqItem"
},
"title": "Faq Items",
"type": "array"
},
"id": {
"format": "uuid",
"title": "Id",
@@ -1061,6 +1165,13 @@
"title": "Title",
"type": "string"
},
"unsupported_claim_warnings": {
"items": {
"type": "string"
},
"title": "Unsupported Claim Warnings",
"type": "array"
},
"updated_at": {
"format": "date-time",
"title": "Updated At",
@@ -1070,6 +1181,13 @@
"minimum": 1,
"title": "Version",
"type": "integer"
},
"visual_placeholders": {
"items": {
"type": "string"
},
"title": "Visual Placeholders",
"type": "array"
}
},
"required": [
@@ -1079,11 +1197,129 @@
"title",
"slug",
"status",
"created_at",
"updated_at"
],
"title": "DraftSummary",
"type": "object"
},
"DraftUpdateRequest": {
"additionalProperties": false,
"properties": {
"body_markdown": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Body Markdown"
},
"evidence_references": {
"anyOf": [
{
"items": {
"format": "uuid",
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"title": "Evidence References"
},
"faq_items": {
"anyOf": [
{
"items": {
"$ref": "#/components/schemas/DraftFaqItem"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"title": "Faq Items"
},
"meta_description": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Meta Description"
},
"meta_title": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Meta Title"
},
"title": {
"anyOf": [
{
"minLength": 1,
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Title"
},
"unsupported_claim_warnings": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"title": "Unsupported Claim Warnings"
},
"visual_placeholders": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"title": "Visual Placeholders"
}
},
"title": "DraftUpdateRequest",
"type": "object"
},
"EvidenceCreateRequest": {
"additionalProperties": false,
"properties": {
@@ -3668,6 +3904,65 @@
]
}
},
"/api/articles/{article_id}/draft/assemble": {
"post": {
"operationId": "post_assemble_draft_api_articles__article_id__draft_assemble_post",
"parameters": [
{
"in": "path",
"name": "article_id",
"required": true,
"schema": {
"format": "uuid",
"title": "Article Id",
"type": "string"
}
},
{
"in": "header",
"name": "X-Demo-User-Email",
"required": false,
"schema": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "X-Demo-User-Email"
}
}
],
"responses": {
"201": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/DraftAssembleResponse"
}
}
},
"description": "Successful Response"
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
},
"description": "Validation Error"
}
},
"summary": "Post Assemble Draft",
"tags": [
"drafts"
]
}
},
"/api/articles/{article_id}/draft/start": {
"post": {
"operationId": "post_start_draft_api_articles__article_id__draft_start_post",
@@ -3727,6 +4022,211 @@
]
}
},
"/api/articles/{article_id}/drafts": {
"get": {
"operationId": "get_article_drafts_api_articles__article_id__drafts_get",
"parameters": [
{
"in": "path",
"name": "article_id",
"required": true,
"schema": {
"format": "uuid",
"title": "Article Id",
"type": "string"
}
},
{
"in": "header",
"name": "X-Demo-User-Email",
"required": false,
"schema": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "X-Demo-User-Email"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/DraftListResponse"
}
}
},
"description": "Successful Response"
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
},
"description": "Validation Error"
}
},
"summary": "Get Article Drafts",
"tags": [
"drafts"
]
}
},
"/api/articles/{article_id}/drafts/{draft_id}": {
"get": {
"operationId": "get_article_draft_api_articles__article_id__drafts__draft_id__get",
"parameters": [
{
"in": "path",
"name": "article_id",
"required": true,
"schema": {
"format": "uuid",
"title": "Article Id",
"type": "string"
}
},
{
"in": "path",
"name": "draft_id",
"required": true,
"schema": {
"format": "uuid",
"title": "Draft Id",
"type": "string"
}
},
{
"in": "header",
"name": "X-Demo-User-Email",
"required": false,
"schema": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "X-Demo-User-Email"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/DraftResponse"
}
}
},
"description": "Successful Response"
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
},
"description": "Validation Error"
}
},
"summary": "Get Article Draft",
"tags": [
"drafts"
]
},
"patch": {
"operationId": "patch_article_draft_api_articles__article_id__drafts__draft_id__patch",
"parameters": [
{
"in": "path",
"name": "article_id",
"required": true,
"schema": {
"format": "uuid",
"title": "Article Id",
"type": "string"
}
},
{
"in": "path",
"name": "draft_id",
"required": true,
"schema": {
"format": "uuid",
"title": "Draft Id",
"type": "string"
}
},
{
"in": "header",
"name": "X-Demo-User-Email",
"required": false,
"schema": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "X-Demo-User-Email"
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/DraftUpdateRequest"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/DraftResponse"
}
}
},
"description": "Successful Response"
},
"422": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HTTPValidationError"
}
}
},
"description": "Validation Error"
}
},
"summary": "Patch Article Draft",
"tags": [
"drafts"
]
}
},
"/api/articles/{article_id}/evidence": {
"get": {
"operationId": "get_article_evidence_api_articles__article_id__evidence_get",
+36 -1
View File
@@ -35,8 +35,8 @@ export type AgentJobSummary = {
input_files?: RunnerFileRef[];
job_type: AgentJobType;
output_files?: RunnerFileRef[];
payload?: Record<string, unknown>;
parent_job_id?: string | null;
payload?: Record<string, unknown>;
queued_at: string;
started_at?: string | null;
status: AgentJobStatus;
@@ -168,17 +168,52 @@ export type CurrentUserResponse = {
user: CurrentUser;
};
export type DraftAssembleResponse = {
draft: DraftSummary;
};
export type DraftFaqItem = {
answer: string;
question: string;
};
export type DraftListResponse = {
drafts?: DraftSummary[];
};
export type DraftResponse = {
draft: DraftSummary;
};
export type DraftSummary = {
article_id: string;
based_on_draft_id?: string | null;
body_markdown?: string;
body_object_key?: string | null;
created_at: string;
evidence_references?: string[];
faq_items?: DraftFaqItem[];
id: string;
meta_description?: string | null;
meta_title?: string | null;
slug: string;
status: ArticleWorkflowStatus;
title: string;
unsupported_claim_warnings?: string[];
updated_at: string;
version: number;
visual_placeholders?: string[];
};
export type DraftUpdateRequest = {
body_markdown?: string | null;
evidence_references?: string[] | null;
faq_items?: DraftFaqItem[] | null;
meta_description?: string | null;
meta_title?: string | null;
title?: string | null;
unsupported_claim_warnings?: string[] | null;
visual_placeholders?: string[] | null;
};
export type EvidenceCreateRequest = {