feat: add TechLog feature contracts
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
import type { components } from "./generated.ts";
|
||||
|
||||
type Schemas = components["schemas"];
|
||||
export type RecordKind = Schemas["RecordKind"];
|
||||
export type WorkingCopy = Schemas["WorkingCopy"];
|
||||
export type WorkingCopyInput = Schemas["WorkingCopyInput"];
|
||||
export type WorkingCopyDetail = Schemas["WorkingCopyDetail"];
|
||||
export type StudioDashboard = Schemas["StudioDashboard"];
|
||||
export type DocumentPage = Schemas["DocumentPage"];
|
||||
export type CreateDocumentInput = Schemas["CreateDocumentInput"];
|
||||
export type SaveDocumentCommand = Schemas["SaveDocumentCommand"];
|
||||
export type ValidateDocumentCommand = Schemas["ValidateDocumentCommand"];
|
||||
export type ValidationReport = Schemas["ValidationReport"];
|
||||
export type CreatePreviewCommand = Schemas["CreatePreviewCommand"];
|
||||
export type PublicPreview = Schemas["PublicPreview"];
|
||||
export type PreviewDetail = Schemas["PreviewDetail"];
|
||||
export type PublishDocumentCommand = Schemas["PublishDocumentCommand"];
|
||||
export type PublishResult = Schemas["PublishResult"];
|
||||
export type UnpublishCommand = Schemas["UnpublishCommand"];
|
||||
export type PublicationAggregate = Schemas["PublicationAggregate"];
|
||||
export type PublicationEvent = Schemas["PublicationEvent"];
|
||||
export type PublicationListItem = Schemas["PublicationListItem"];
|
||||
export type PublicationPage = Schemas["PublicationPage"];
|
||||
export type PublicationSnapshot = Schemas["PublicationSnapshot"];
|
||||
export type CatalogPage = Schemas["CatalogPage"];
|
||||
export type ProblemDetails = Schemas["ProblemDetails"];
|
||||
export type PublicRenderModel = Schemas["PublicRenderModel"];
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,984 @@
|
||||
openapi: 3.1.0
|
||||
info:
|
||||
title: TechLog Studio API
|
||||
version: 1.0.0
|
||||
description: Transport contract for the TechLog Studio authoring frontend.
|
||||
license: { name: Proprietary, identifier: LicenseRef-Proprietary }
|
||||
servers:
|
||||
- url: /
|
||||
security: []
|
||||
paths:
|
||||
/api/v1/studio/dashboard:
|
||||
get:
|
||||
operationId: getStudioDashboard
|
||||
summary: Get the Studio dashboard
|
||||
responses:
|
||||
"200": { description: Dashboard lists and totals, content: { application/json: { schema: { $ref: "#/components/schemas/StudioDashboard" } } } }
|
||||
"401": { $ref: "#/components/responses/AuthenticationRequired" }
|
||||
"403": { $ref: "#/components/responses/AccessDenied" }
|
||||
"503": { $ref: "#/components/responses/StudioUnavailable" }
|
||||
/api/v1/studio/documents:
|
||||
get:
|
||||
operationId: listStudioDocuments
|
||||
summary: List working copies
|
||||
parameters:
|
||||
- { $ref: "#/components/parameters/Query" }
|
||||
- { $ref: "#/components/parameters/DocumentKind" }
|
||||
- { $ref: "#/components/parameters/PublicationStatus" }
|
||||
- { $ref: "#/components/parameters/NextAction" }
|
||||
- { $ref: "#/components/parameters/ProjectId" }
|
||||
- { $ref: "#/components/parameters/DocumentSort" }
|
||||
- { $ref: "#/components/parameters/Cursor" }
|
||||
- { $ref: "#/components/parameters/Limit" }
|
||||
responses:
|
||||
"200": { description: Working-copy cursor page, content: { application/json: { schema: { $ref: "#/components/schemas/DocumentPage" } } } }
|
||||
"401": { $ref: "#/components/responses/AuthenticationRequired" }
|
||||
"403": { $ref: "#/components/responses/AccessDenied" }
|
||||
"422": { $ref: "#/components/responses/RequestValidationFailed" }
|
||||
"503": { $ref: "#/components/responses/StudioUnavailable" }
|
||||
post:
|
||||
operationId: createStudioDocument
|
||||
summary: Create a working copy
|
||||
parameters: [{ $ref: "#/components/parameters/IdempotencyKey" }]
|
||||
requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/CreateDocumentInput" } } } }
|
||||
responses:
|
||||
"201":
|
||||
description: Created working copy
|
||||
headers: { Idempotency-Replayed: { $ref: "#/components/headers/IdempotencyReplayed" } }
|
||||
content: { application/json: { schema: { $ref: "#/components/schemas/WorkingCopy" } } }
|
||||
"401": { $ref: "#/components/responses/AuthenticationRequired" }
|
||||
"403": { $ref: "#/components/responses/AccessDenied" }
|
||||
"409": { $ref: "#/components/responses/CommandConflict" }
|
||||
"422": { $ref: "#/components/responses/RequestValidationFailed" }
|
||||
"503": { $ref: "#/components/responses/StudioUnavailable" }
|
||||
/api/v1/studio/documents/{documentId}:
|
||||
parameters: [{ $ref: "#/components/parameters/DocumentId" }]
|
||||
get:
|
||||
operationId: getStudioDocument
|
||||
summary: Get a working copy and its current state
|
||||
responses:
|
||||
"200": { description: Working-copy detail, content: { application/json: { schema: { $ref: "#/components/schemas/WorkingCopyDetail" } } } }
|
||||
"401": { $ref: "#/components/responses/AuthenticationRequired" }
|
||||
"403": { $ref: "#/components/responses/AccessDenied" }
|
||||
"404": { $ref: "#/components/responses/DocumentNotFound" }
|
||||
"503": { $ref: "#/components/responses/StudioUnavailable" }
|
||||
put:
|
||||
operationId: saveStudioDocument
|
||||
summary: Save a full working copy
|
||||
parameters: [{ $ref: "#/components/parameters/IdempotencyKey" }]
|
||||
requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/SaveDocumentCommand" } } } }
|
||||
responses:
|
||||
"200":
|
||||
description: Saved working-copy detail
|
||||
headers: { Idempotency-Replayed: { $ref: "#/components/headers/IdempotencyReplayed" } }
|
||||
content: { application/json: { schema: { $ref: "#/components/schemas/WorkingCopyDetail" } } }
|
||||
"401": { $ref: "#/components/responses/AuthenticationRequired" }
|
||||
"403": { $ref: "#/components/responses/AccessDenied" }
|
||||
"404": { $ref: "#/components/responses/DocumentNotFound" }
|
||||
"409": { $ref: "#/components/responses/CommandConflict" }
|
||||
"422": { $ref: "#/components/responses/RequestValidationFailed" }
|
||||
"503": { $ref: "#/components/responses/StudioUnavailable" }
|
||||
/api/v1/studio/documents/{documentId}/validate:
|
||||
parameters: [{ $ref: "#/components/parameters/DocumentId" }]
|
||||
post:
|
||||
operationId: validateStudioDocument
|
||||
summary: Validate a saved working copy
|
||||
parameters: [{ $ref: "#/components/parameters/IdempotencyKey" }]
|
||||
requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/ValidateDocumentCommand" } } } }
|
||||
responses:
|
||||
"200":
|
||||
description: Validation report
|
||||
headers: { Idempotency-Replayed: { $ref: "#/components/headers/IdempotencyReplayed" } }
|
||||
content: { application/json: { schema: { $ref: "#/components/schemas/ValidationReport" } } }
|
||||
"401": { $ref: "#/components/responses/AuthenticationRequired" }
|
||||
"403": { $ref: "#/components/responses/AccessDenied" }
|
||||
"404": { $ref: "#/components/responses/DocumentNotFound" }
|
||||
"409": { $ref: "#/components/responses/CommandConflict" }
|
||||
"422": { $ref: "#/components/responses/RequestValidationFailed" }
|
||||
"503": { $ref: "#/components/responses/StudioUnavailable" }
|
||||
/api/v1/studio/documents/{documentId}/preview:
|
||||
parameters: [{ $ref: "#/components/parameters/DocumentId" }]
|
||||
get:
|
||||
operationId: getCurrentStudioPreview
|
||||
summary: Get the latest preview and its computed state
|
||||
responses:
|
||||
"200": { description: Preview detail, content: { application/json: { schema: { $ref: "#/components/schemas/PreviewDetail" } } } }
|
||||
"401": { $ref: "#/components/responses/AuthenticationRequired" }
|
||||
"403": { $ref: "#/components/responses/AccessDenied" }
|
||||
"404": { $ref: "#/components/responses/PreviewNotFound" }
|
||||
"503": { $ref: "#/components/responses/StudioUnavailable" }
|
||||
post:
|
||||
operationId: createStudioPreview
|
||||
summary: Create a public-layout preview
|
||||
parameters: [{ $ref: "#/components/parameters/IdempotencyKey" }]
|
||||
requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/CreatePreviewCommand" } } } }
|
||||
responses:
|
||||
"201":
|
||||
description: Created preview
|
||||
headers: { Idempotency-Replayed: { $ref: "#/components/headers/IdempotencyReplayed" } }
|
||||
content: { application/json: { schema: { $ref: "#/components/schemas/PublicPreview" } } }
|
||||
"401": { $ref: "#/components/responses/AuthenticationRequired" }
|
||||
"403": { $ref: "#/components/responses/AccessDenied" }
|
||||
"404": { $ref: "#/components/responses/DocumentNotFound" }
|
||||
"409": { $ref: "#/components/responses/CommandConflict" }
|
||||
"422": { $ref: "#/components/responses/RequestValidationFailed" }
|
||||
"503": { $ref: "#/components/responses/StudioUnavailable" }
|
||||
/api/v1/studio/documents/{documentId}/publish:
|
||||
parameters: [{ $ref: "#/components/parameters/DocumentId" }]
|
||||
post:
|
||||
operationId: publishStudioDocument
|
||||
summary: Publish or republish a validated preview
|
||||
parameters: [{ $ref: "#/components/parameters/IdempotencyKey" }]
|
||||
requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/PublishDocumentCommand" } } } }
|
||||
responses:
|
||||
"200":
|
||||
description: Publication aggregate and immutable event
|
||||
headers: { Idempotency-Replayed: { $ref: "#/components/headers/IdempotencyReplayed" } }
|
||||
content: { application/json: { schema: { $ref: "#/components/schemas/PublishResult" } } }
|
||||
"401": { $ref: "#/components/responses/AuthenticationRequired" }
|
||||
"403": { $ref: "#/components/responses/AccessDenied" }
|
||||
"404": { $ref: "#/components/responses/DocumentNotFound" }
|
||||
"409": { $ref: "#/components/responses/CommandConflict" }
|
||||
"422": { $ref: "#/components/responses/RequestValidationFailed" }
|
||||
"503": { $ref: "#/components/responses/StudioUnavailable" }
|
||||
/api/v1/studio/publications/{publicationId}/unpublish:
|
||||
parameters: [{ $ref: "#/components/parameters/PublicationId" }]
|
||||
post:
|
||||
operationId: unpublishStudioPublication
|
||||
summary: Unpublish the current publication
|
||||
parameters: [{ $ref: "#/components/parameters/IdempotencyKey" }]
|
||||
requestBody: { required: true, content: { application/json: { schema: { $ref: "#/components/schemas/UnpublishCommand" } } } }
|
||||
responses:
|
||||
"200":
|
||||
description: Updated publication aggregate and event
|
||||
headers: { Idempotency-Replayed: { $ref: "#/components/headers/IdempotencyReplayed" } }
|
||||
content: { application/json: { schema: { $ref: "#/components/schemas/PublishResult" } } }
|
||||
"401": { $ref: "#/components/responses/AuthenticationRequired" }
|
||||
"403": { $ref: "#/components/responses/AccessDenied" }
|
||||
"404": { $ref: "#/components/responses/PublicationNotFound" }
|
||||
"409": { $ref: "#/components/responses/CommandConflict" }
|
||||
"422": { $ref: "#/components/responses/RequestValidationFailed" }
|
||||
"503": { $ref: "#/components/responses/StudioUnavailable" }
|
||||
/api/v1/studio/publications:
|
||||
get:
|
||||
operationId: listStudioPublications
|
||||
summary: List immutable publication events
|
||||
description: Events are ordered by occurredAt DESC, then publicationEventId.
|
||||
parameters:
|
||||
- { $ref: "#/components/parameters/Query" }
|
||||
- { $ref: "#/components/parameters/PublicationEventType" }
|
||||
- { $ref: "#/components/parameters/Cursor" }
|
||||
- { $ref: "#/components/parameters/Limit" }
|
||||
responses:
|
||||
"200": { description: Publication cursor page, content: { application/json: { schema: { $ref: "#/components/schemas/PublicationPage" } } } }
|
||||
"401": { $ref: "#/components/responses/AuthenticationRequired" }
|
||||
"403": { $ref: "#/components/responses/AccessDenied" }
|
||||
"422": { $ref: "#/components/responses/RequestValidationFailed" }
|
||||
"503": { $ref: "#/components/responses/StudioUnavailable" }
|
||||
/api/v1/studio/publications/{publicationEventId}/preview:
|
||||
parameters: [{ $ref: "#/components/parameters/PublicationEventId" }]
|
||||
get:
|
||||
operationId: getStudioPublicationSnapshot
|
||||
summary: Get an immutable publication snapshot
|
||||
responses:
|
||||
"200": { description: Publication snapshot, content: { application/json: { schema: { $ref: "#/components/schemas/PublicationSnapshot" } } } }
|
||||
"401": { $ref: "#/components/responses/AuthenticationRequired" }
|
||||
"403": { $ref: "#/components/responses/AccessDenied" }
|
||||
"404": { $ref: "#/components/responses/PublicationSnapshotNotFound" }
|
||||
"503": { $ref: "#/components/responses/StudioUnavailable" }
|
||||
/api/v1/studio/catalog:
|
||||
get:
|
||||
operationId: listStudioCatalog
|
||||
summary: List catalog entries for editor pickers
|
||||
parameters:
|
||||
- { $ref: "#/components/parameters/CatalogType" }
|
||||
- { $ref: "#/components/parameters/Query" }
|
||||
- { $ref: "#/components/parameters/Cursor" }
|
||||
- { $ref: "#/components/parameters/Limit" }
|
||||
responses:
|
||||
"200": { description: Catalog cursor page, content: { application/json: { schema: { $ref: "#/components/schemas/CatalogPage" } } } }
|
||||
"401": { $ref: "#/components/responses/AuthenticationRequired" }
|
||||
"403": { $ref: "#/components/responses/AccessDenied" }
|
||||
"422": { $ref: "#/components/responses/RequestValidationFailed" }
|
||||
"503": { $ref: "#/components/responses/StudioUnavailable" }
|
||||
components:
|
||||
parameters:
|
||||
DocumentId: { name: documentId, in: path, required: true, schema: { type: string, format: uuid } }
|
||||
PublicationId: { name: publicationId, in: path, required: true, schema: { type: string, format: uuid } }
|
||||
PublicationEventId: { name: publicationEventId, in: path, required: true, schema: { type: string, format: uuid } }
|
||||
IdempotencyKey: { name: Idempotency-Key, in: header, required: true, schema: { type: string, minLength: 1, maxLength: 200 } }
|
||||
Query: { name: q, in: query, description: Free-text query normalized as part of the opaque cursor, schema: { type: string, maxLength: 100 } }
|
||||
Cursor: { name: cursor, in: query, description: Opaque cursor bound to normalized filters and sort, schema: { type: string, minLength: 1, maxLength: 2000 } }
|
||||
Limit: { name: limit, in: query, schema: { type: integer, minimum: 1, maximum: 100, default: 20 } }
|
||||
DocumentKind: { name: kind, in: query, schema: { $ref: "#/components/schemas/RecordKind" } }
|
||||
PublicationStatus: { name: publicationStatus, in: query, schema: { $ref: "#/components/schemas/PublicationStatus" } }
|
||||
NextAction: { name: nextAction, in: query, schema: { $ref: "#/components/schemas/NextAction" } }
|
||||
ProjectId: { name: projectId, in: query, schema: { type: string, format: uuid } }
|
||||
DocumentSort: { name: sort, in: query, schema: { type: string, enum: [UPDATED_DESC, UPDATED_ASC, TITLE_ASC], default: UPDATED_DESC } }
|
||||
PublicationEventType: { name: type, in: query, schema: { $ref: "#/components/schemas/PublicationEventType" } }
|
||||
CatalogType: { name: type, in: query, required: true, schema: { $ref: "#/components/schemas/CatalogEntryType" } }
|
||||
headers:
|
||||
IdempotencyReplayed: { description: True when the original result was replayed, schema: { type: boolean } }
|
||||
responses:
|
||||
AuthenticationRequired: { description: Authentication required, x-error-codes: [AUTHENTICATION_REQUIRED], content: { application/problem+json: { schema: { $ref: "#/components/schemas/ProblemDetails" } } } }
|
||||
AccessDenied: { description: Studio access denied, x-error-codes: [STUDIO_ACCESS_DENIED], content: { application/problem+json: { schema: { $ref: "#/components/schemas/ProblemDetails" } } } }
|
||||
DocumentNotFound: { description: Document not found, x-error-codes: [DOCUMENT_NOT_FOUND], content: { application/problem+json: { schema: { $ref: "#/components/schemas/ProblemDetails" } } } }
|
||||
PreviewNotFound: { description: Document or preview not found, x-error-codes: [DOCUMENT_NOT_FOUND, PREVIEW_NOT_FOUND], content: { application/problem+json: { schema: { $ref: "#/components/schemas/ProblemDetails" } } } }
|
||||
PublicationNotFound: { description: Publication not found, x-error-codes: [PUBLICATION_NOT_FOUND], content: { application/problem+json: { schema: { $ref: "#/components/schemas/ProblemDetails" } } } }
|
||||
PublicationSnapshotNotFound: { description: Publication event or snapshot not found, x-error-codes: [PUBLICATION_EVENT_NOT_FOUND, PUBLICATION_SNAPSHOT_NOT_FOUND], content: { application/problem+json: { schema: { $ref: "#/components/schemas/ProblemDetails" } } } }
|
||||
CommandConflict:
|
||||
description: Command conflicts with current state, freshness, or idempotency
|
||||
x-error-codes: [VERSION_CONFLICT, PUBLICATION_CONFLICT, VALIDATION_STALE, PREVIEW_STALE, PREVIEW_EXPIRED, IDEMPOTENCY_KEY_REUSED]
|
||||
content: { application/problem+json: { schema: { $ref: "#/components/schemas/ProblemDetails" } } }
|
||||
RequestValidationFailed: { description: Request validation failed, x-error-codes: [REQUEST_VALIDATION_FAILED], content: { application/problem+json: { schema: { $ref: "#/components/schemas/ProblemDetails" } } } }
|
||||
StudioUnavailable: { description: Studio unavailable, x-error-codes: [STUDIO_UNAVAILABLE], content: { application/problem+json: { schema: { $ref: "#/components/schemas/ProblemDetails" } } } }
|
||||
schemas:
|
||||
RecordKind: { type: string, enum: [CASE, REFERENCE, QUESTION] }
|
||||
PublicationStatus: { type: string, enum: [NEVER_PUBLISHED, PUBLISHED, UNPUBLISHED] }
|
||||
NextAction: { type: string, enum: [CONTINUE_EDITING, VALIDATE, FIX_VALIDATION, CREATE_PREVIEW, PUBLISH, NONE] }
|
||||
RelationInput:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [id, targetId, reason, order]
|
||||
properties:
|
||||
id: { type: [string, "null"], format: uuid }
|
||||
targetId: { type: [string, "null"], format: uuid }
|
||||
reason: { type: string, maxLength: 100000 }
|
||||
order: { type: integer, minimum: 0 }
|
||||
Relation:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [id, targetId, reason, order]
|
||||
properties:
|
||||
id: { type: string, format: uuid }
|
||||
targetId: { type: string, format: uuid }
|
||||
reason: { type: string, maxLength: 100000 }
|
||||
order: { type: integer, minimum: 0 }
|
||||
OrderedText:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [id, text, order]
|
||||
properties:
|
||||
id: { type: string, format: uuid }
|
||||
text: { type: string, minLength: 1, maxLength: 100000 }
|
||||
order: { type: integer, minimum: 0 }
|
||||
ReferenceRule:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [id, title, body, order]
|
||||
properties:
|
||||
id: { type: string, format: uuid }
|
||||
title: { type: string, minLength: 1, maxLength: 120 }
|
||||
body: { type: string, minLength: 1, maxLength: 100000 }
|
||||
order: { type: integer, minimum: 0 }
|
||||
QuestionOption:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [id, title, description, order]
|
||||
properties:
|
||||
id: { type: string, format: uuid }
|
||||
title: { type: string, minLength: 1, maxLength: 120 }
|
||||
description: { type: string, maxLength: 100000 }
|
||||
order: { type: integer, minimum: 0 }
|
||||
QuestionResolution:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [summary, evidenceTargetId, linkLabel]
|
||||
properties:
|
||||
summary: { type: string, maxLength: 100000 }
|
||||
evidenceTargetId: { type: [string, "null"], format: uuid }
|
||||
linkLabel: { type: string, maxLength: 120 }
|
||||
WorkingCopyInputBase:
|
||||
type: object
|
||||
required: [kind, title, slug, summary, topicId, projectId, relations]
|
||||
properties:
|
||||
kind: { $ref: "#/components/schemas/RecordKind" }
|
||||
title: { type: string, maxLength: 120 }
|
||||
slug:
|
||||
oneOf:
|
||||
- { type: string, const: "" }
|
||||
- { type: string, minLength: 3, maxLength: 100, pattern: "^[a-z0-9]+(?:-[a-z0-9]+)*$" }
|
||||
summary: { type: string, maxLength: 300 }
|
||||
topicId: { type: [string, "null"], format: uuid }
|
||||
projectId: { type: [string, "null"], format: uuid }
|
||||
relations: { type: array, maxItems: 20, items: { $ref: "#/components/schemas/RelationInput" } }
|
||||
CaseInput:
|
||||
unevaluatedProperties: false
|
||||
allOf:
|
||||
- { $ref: "#/components/schemas/WorkingCopyInputBase" }
|
||||
- type: object
|
||||
required: [kind, problem, conclusion, environment, reproduction, lastVerifiedOn, bodyMarkdown]
|
||||
properties:
|
||||
kind: { type: string, const: CASE }
|
||||
problem: { type: string, maxLength: 100000 }
|
||||
conclusion: { type: string, maxLength: 100000 }
|
||||
environment: { type: string, maxLength: 100000 }
|
||||
reproduction: { type: string, maxLength: 100000 }
|
||||
lastVerifiedOn: { type: [string, "null"], format: date }
|
||||
bodyMarkdown: { type: string, maxLength: 100000 }
|
||||
ReferenceInput:
|
||||
unevaluatedProperties: false
|
||||
allOf:
|
||||
- { $ref: "#/components/schemas/WorkingCopyInputBase" }
|
||||
- type: object
|
||||
required: [kind, purpose, rules, applyWhen, exceptions, examples, verifiedOn]
|
||||
properties:
|
||||
kind: { type: string, const: REFERENCE }
|
||||
purpose: { type: string, maxLength: 100000 }
|
||||
rules: { type: array, maxItems: 50, items: { $ref: "#/components/schemas/ReferenceRule" } }
|
||||
applyWhen: { type: array, maxItems: 50, items: { $ref: "#/components/schemas/OrderedText" } }
|
||||
exceptions: { type: array, maxItems: 50, items: { $ref: "#/components/schemas/OrderedText" } }
|
||||
examples: { type: array, maxItems: 50, items: { $ref: "#/components/schemas/OrderedText" } }
|
||||
verifiedOn: { type: [string, "null"], format: date }
|
||||
QuestionInput:
|
||||
unevaluatedProperties: false
|
||||
allOf:
|
||||
- { $ref: "#/components/schemas/WorkingCopyInputBase" }
|
||||
- type: object
|
||||
required: [kind, questionStatus, facts, assumptions, unknowns, constraints, options, nextValidation, resolution]
|
||||
properties:
|
||||
kind: { type: string, const: QUESTION }
|
||||
questionStatus: { type: [string, "null"], enum: [OPEN, RESOLVED, null] }
|
||||
facts: { type: array, maxItems: 50, items: { $ref: "#/components/schemas/OrderedText" } }
|
||||
assumptions: { type: array, maxItems: 50, items: { $ref: "#/components/schemas/OrderedText" } }
|
||||
unknowns: { type: array, maxItems: 50, items: { $ref: "#/components/schemas/OrderedText" } }
|
||||
constraints: { type: array, maxItems: 50, items: { $ref: "#/components/schemas/OrderedText" } }
|
||||
options: { type: array, maxItems: 50, items: { $ref: "#/components/schemas/QuestionOption" } }
|
||||
nextValidation: { type: string, maxLength: 100000 }
|
||||
resolution:
|
||||
oneOf:
|
||||
- { $ref: "#/components/schemas/QuestionResolution" }
|
||||
- { type: "null" }
|
||||
WorkingCopyInput:
|
||||
oneOf:
|
||||
- { $ref: "#/components/schemas/CaseInput" }
|
||||
- { $ref: "#/components/schemas/ReferenceInput" }
|
||||
- { $ref: "#/components/schemas/QuestionInput" }
|
||||
discriminator:
|
||||
propertyName: kind
|
||||
mapping:
|
||||
CASE: "#/components/schemas/CaseInput"
|
||||
REFERENCE: "#/components/schemas/ReferenceInput"
|
||||
QUESTION: "#/components/schemas/QuestionInput"
|
||||
WorkingCopyBase:
|
||||
allOf:
|
||||
- { $ref: "#/components/schemas/WorkingCopyInputBase" }
|
||||
- type: object
|
||||
required: [id, version, relations, updatedAt]
|
||||
properties:
|
||||
id: { type: string, format: uuid }
|
||||
version: { type: integer, minimum: 1 }
|
||||
relations: { type: array, maxItems: 20, items: { $ref: "#/components/schemas/Relation" } }
|
||||
updatedAt: { type: string, format: date-time }
|
||||
CaseWorkingCopy:
|
||||
unevaluatedProperties: false
|
||||
allOf:
|
||||
- { $ref: "#/components/schemas/WorkingCopyBase" }
|
||||
- type: object
|
||||
required: [kind, problem, conclusion, environment, reproduction, lastVerifiedOn, bodyMarkdown]
|
||||
properties:
|
||||
kind: { type: string, const: CASE }
|
||||
problem: { type: string, maxLength: 100000 }
|
||||
conclusion: { type: string, maxLength: 100000 }
|
||||
environment: { type: string, maxLength: 100000 }
|
||||
reproduction: { type: string, maxLength: 100000 }
|
||||
lastVerifiedOn: { type: [string, "null"], format: date }
|
||||
bodyMarkdown: { type: string, maxLength: 100000 }
|
||||
ReferenceWorkingCopy:
|
||||
unevaluatedProperties: false
|
||||
allOf:
|
||||
- { $ref: "#/components/schemas/WorkingCopyBase" }
|
||||
- type: object
|
||||
required: [kind, purpose, rules, applyWhen, exceptions, examples, verifiedOn]
|
||||
properties:
|
||||
kind: { type: string, const: REFERENCE }
|
||||
purpose: { type: string, maxLength: 100000 }
|
||||
rules: { type: array, maxItems: 50, items: { $ref: "#/components/schemas/ReferenceRule" } }
|
||||
applyWhen: { type: array, maxItems: 50, items: { $ref: "#/components/schemas/OrderedText" } }
|
||||
exceptions: { type: array, maxItems: 50, items: { $ref: "#/components/schemas/OrderedText" } }
|
||||
examples: { type: array, maxItems: 50, items: { $ref: "#/components/schemas/OrderedText" } }
|
||||
verifiedOn: { type: [string, "null"], format: date }
|
||||
QuestionWorkingCopy:
|
||||
unevaluatedProperties: false
|
||||
allOf:
|
||||
- { $ref: "#/components/schemas/WorkingCopyBase" }
|
||||
- type: object
|
||||
required: [kind, questionStatus, facts, assumptions, unknowns, constraints, options, nextValidation, resolution]
|
||||
properties:
|
||||
kind: { type: string, const: QUESTION }
|
||||
questionStatus: { type: [string, "null"], enum: [OPEN, RESOLVED, null] }
|
||||
facts: { type: array, maxItems: 50, items: { $ref: "#/components/schemas/OrderedText" } }
|
||||
assumptions: { type: array, maxItems: 50, items: { $ref: "#/components/schemas/OrderedText" } }
|
||||
unknowns: { type: array, maxItems: 50, items: { $ref: "#/components/schemas/OrderedText" } }
|
||||
constraints: { type: array, maxItems: 50, items: { $ref: "#/components/schemas/OrderedText" } }
|
||||
options: { type: array, maxItems: 50, items: { $ref: "#/components/schemas/QuestionOption" } }
|
||||
nextValidation: { type: string, maxLength: 100000 }
|
||||
resolution:
|
||||
oneOf:
|
||||
- { $ref: "#/components/schemas/QuestionResolution" }
|
||||
- { type: "null" }
|
||||
WorkingCopy:
|
||||
oneOf:
|
||||
- { $ref: "#/components/schemas/CaseWorkingCopy" }
|
||||
- { $ref: "#/components/schemas/ReferenceWorkingCopy" }
|
||||
- { $ref: "#/components/schemas/QuestionWorkingCopy" }
|
||||
discriminator:
|
||||
propertyName: kind
|
||||
mapping:
|
||||
CASE: "#/components/schemas/CaseWorkingCopy"
|
||||
REFERENCE: "#/components/schemas/ReferenceWorkingCopy"
|
||||
QUESTION: "#/components/schemas/QuestionWorkingCopy"
|
||||
CreateDocumentInput: { $ref: "#/components/schemas/WorkingCopyInput" }
|
||||
SaveDocumentCommand:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [expectedVersion, document]
|
||||
properties:
|
||||
expectedVersion: { type: integer, minimum: 1 }
|
||||
document: { $ref: "#/components/schemas/WorkingCopyInput" }
|
||||
ValidateDocumentCommand:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [expectedVersion]
|
||||
properties: { expectedVersion: { type: integer, minimum: 1 } }
|
||||
ValidationIssue:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [code, severity, path, message]
|
||||
properties:
|
||||
code: { type: string, minLength: 1, maxLength: 100 }
|
||||
severity: { type: string, enum: [ERROR, WARNING] }
|
||||
path:
|
||||
type: string
|
||||
pattern: "^(?:/(?:[^~/]|~0|~1)*)*$"
|
||||
description: JSON Pointer to the affected field
|
||||
message: { type: string, minLength: 1, maxLength: 1000 }
|
||||
ValidationReport:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [validationId, documentId, validatedVersion, status, issues, validatedAt, validUntil, dependencyRevision]
|
||||
properties:
|
||||
validationId: { type: string, format: uuid }
|
||||
documentId: { type: string, format: uuid }
|
||||
validatedVersion: { type: integer, minimum: 1 }
|
||||
status: { type: string, enum: [INVALID, WARNINGS, VALID] }
|
||||
issues: { type: array, maxItems: 200, items: { $ref: "#/components/schemas/ValidationIssue" } }
|
||||
validatedAt: { type: string, format: date-time }
|
||||
validUntil: { type: string, format: date-time }
|
||||
dependencyRevision: { type: string, minLength: 1, maxLength: 200 }
|
||||
CreatePreviewCommand:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [expectedVersion, validationId]
|
||||
properties:
|
||||
expectedVersion: { type: integer, minimum: 1 }
|
||||
validationId: { type: string, format: uuid }
|
||||
PublishDocumentCommand:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [expectedVersion, validationId, previewId, acknowledgedWarningCodes]
|
||||
properties:
|
||||
expectedVersion: { type: integer, minimum: 1 }
|
||||
validationId: { type: string, format: uuid }
|
||||
previewId: { type: string, format: uuid }
|
||||
acknowledgedWarningCodes: { type: array, uniqueItems: true, maxItems: 200, items: { type: string, minLength: 1, maxLength: 100 } }
|
||||
UnpublishCommand:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [expectedPublicationRevision]
|
||||
properties: { expectedPublicationRevision: { type: integer, minimum: 1 } }
|
||||
DisplayTarget:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [id, label, publicPath]
|
||||
properties:
|
||||
id: { type: string, format: uuid }
|
||||
label: { type: string, minLength: 1, maxLength: 200 }
|
||||
publicPath: { type: [string, "null"], maxLength: 500 }
|
||||
ResolvedRelation:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [id, targetId, targetKind, title, publicPath, reason, order]
|
||||
properties:
|
||||
id: { type: string, format: uuid }
|
||||
targetId: { type: string, format: uuid }
|
||||
targetKind: { type: string, enum: [CASE, REFERENCE, QUESTION, PROJECT, PROJECT_DECISION] }
|
||||
title: { type: string, minLength: 1, maxLength: 200 }
|
||||
publicPath: { type: [string, "null"], maxLength: 500 }
|
||||
reason: { type: string, maxLength: 100000 }
|
||||
order: { type: integer, minimum: 0 }
|
||||
RenderContext:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [generatedAt, dependencyRevision]
|
||||
properties:
|
||||
generatedAt: { type: string, format: date-time }
|
||||
dependencyRevision: { type: string, minLength: 1, maxLength: 200 }
|
||||
PublicRenderModelBase:
|
||||
type: object
|
||||
required: [kind, slug, title, summary, publicPath, topic, project, relations, renderContext]
|
||||
properties:
|
||||
kind: { $ref: "#/components/schemas/RecordKind" }
|
||||
slug: { type: string, minLength: 3, maxLength: 100, pattern: "^[a-z0-9]+(?:-[a-z0-9]+)*$" }
|
||||
title: { type: string, minLength: 1, maxLength: 120 }
|
||||
summary: { type: string, minLength: 1, maxLength: 300 }
|
||||
publicPath: { type: string, minLength: 1, maxLength: 500 }
|
||||
topic: { $ref: "#/components/schemas/DisplayTarget" }
|
||||
project:
|
||||
oneOf:
|
||||
- { $ref: "#/components/schemas/DisplayTarget" }
|
||||
- { type: "null" }
|
||||
relations: { type: array, maxItems: 20, items: { $ref: "#/components/schemas/ResolvedRelation" } }
|
||||
renderContext: { $ref: "#/components/schemas/RenderContext" }
|
||||
InlineText:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [type, text]
|
||||
properties:
|
||||
type: { type: string, const: TEXT }
|
||||
text: { type: string, minLength: 1, maxLength: 100000 }
|
||||
InlineContainer:
|
||||
type: object
|
||||
required: [type, children]
|
||||
properties:
|
||||
type: { type: string, enum: [EMPHASIS, STRONG] }
|
||||
children: { type: array, maxItems: 1000, items: { $ref: "#/components/schemas/Inline" } }
|
||||
InlineCode:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [type, code]
|
||||
properties:
|
||||
type: { type: string, const: INLINE_CODE }
|
||||
code: { type: string, minLength: 1, maxLength: 100000 }
|
||||
InlineLink:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [type, label, href]
|
||||
properties:
|
||||
type: { type: string, const: LINK }
|
||||
label: { type: string, minLength: 1, maxLength: 100000 }
|
||||
href: { type: string, format: uri, maxLength: 2000 }
|
||||
InlineStatus:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [type, label, tone]
|
||||
properties:
|
||||
type: { type: string, const: STATUS }
|
||||
label: { type: string, minLength: 1, maxLength: 120 }
|
||||
tone: { type: string, enum: [warning, evidence, neutral] }
|
||||
Inline:
|
||||
oneOf:
|
||||
- { $ref: "#/components/schemas/InlineText" }
|
||||
- { $ref: "#/components/schemas/InlineEmphasis" }
|
||||
- { $ref: "#/components/schemas/InlineStrong" }
|
||||
- { $ref: "#/components/schemas/InlineCode" }
|
||||
- { $ref: "#/components/schemas/InlineLink" }
|
||||
- { $ref: "#/components/schemas/InlineStatus" }
|
||||
discriminator:
|
||||
propertyName: type
|
||||
mapping:
|
||||
TEXT: "#/components/schemas/InlineText"
|
||||
EMPHASIS: "#/components/schemas/InlineEmphasis"
|
||||
STRONG: "#/components/schemas/InlineStrong"
|
||||
INLINE_CODE: "#/components/schemas/InlineCode"
|
||||
LINK: "#/components/schemas/InlineLink"
|
||||
STATUS: "#/components/schemas/InlineStatus"
|
||||
InlineEmphasis:
|
||||
unevaluatedProperties: false
|
||||
allOf:
|
||||
- { $ref: "#/components/schemas/InlineContainer" }
|
||||
- { type: object, properties: { type: { type: string, const: EMPHASIS } } }
|
||||
InlineStrong:
|
||||
unevaluatedProperties: false
|
||||
allOf:
|
||||
- { $ref: "#/components/schemas/InlineContainer" }
|
||||
- { type: object, properties: { type: { type: string, const: STRONG } } }
|
||||
HeadingBlock:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [type, id, level, content]
|
||||
properties:
|
||||
type: { type: string, const: HEADING }
|
||||
id: { type: string, minLength: 1, maxLength: 200 }
|
||||
level: { type: integer, minimum: 2, maximum: 4 }
|
||||
content: { type: array, maxItems: 1000, items: { $ref: "#/components/schemas/Inline" } }
|
||||
ParagraphBlock:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [type, content]
|
||||
properties:
|
||||
type: { type: string, const: PARAGRAPH }
|
||||
content: { type: array, maxItems: 1000, items: { $ref: "#/components/schemas/Inline" } }
|
||||
BlockquoteBlock:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [type, content]
|
||||
properties:
|
||||
type: { type: string, const: BLOCKQUOTE }
|
||||
content: { type: array, maxItems: 1000, items: { $ref: "#/components/schemas/Inline" } }
|
||||
ListItem:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [id, content]
|
||||
properties:
|
||||
id: { type: string, minLength: 1, maxLength: 200 }
|
||||
content: { type: array, maxItems: 1000, items: { $ref: "#/components/schemas/Inline" } }
|
||||
ListBlockBase:
|
||||
type: object
|
||||
required: [type, items]
|
||||
properties:
|
||||
type: { type: string, enum: [UNORDERED_LIST, ORDERED_LIST] }
|
||||
items: { type: array, maxItems: 1000, items: { $ref: "#/components/schemas/ListItem" } }
|
||||
UnorderedListBlock:
|
||||
unevaluatedProperties: false
|
||||
allOf:
|
||||
- { $ref: "#/components/schemas/ListBlockBase" }
|
||||
- { type: object, properties: { type: { type: string, const: UNORDERED_LIST } } }
|
||||
OrderedListBlock:
|
||||
unevaluatedProperties: false
|
||||
allOf:
|
||||
- { $ref: "#/components/schemas/ListBlockBase" }
|
||||
- { type: object, properties: { type: { type: string, const: ORDERED_LIST } } }
|
||||
CodeBlock:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [type, code, language, label]
|
||||
properties:
|
||||
type: { type: string, const: CODE_BLOCK }
|
||||
code: { type: string, maxLength: 100000 }
|
||||
language: { type: [string, "null"], maxLength: 100 }
|
||||
label: { type: [string, "null"], maxLength: 200 }
|
||||
DataTableColumn:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [id, label, alignment]
|
||||
properties:
|
||||
id: { type: string, minLength: 1, maxLength: 200 }
|
||||
label: { type: string, minLength: 1, maxLength: 500 }
|
||||
alignment: { type: string, enum: [LEFT, CENTER, RIGHT] }
|
||||
DataTableCell:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [columnId, content]
|
||||
properties:
|
||||
columnId: { type: string, minLength: 1, maxLength: 200 }
|
||||
content: { type: array, maxItems: 1000, items: { $ref: "#/components/schemas/Inline" } }
|
||||
DataTableRow:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [id, cells]
|
||||
properties:
|
||||
id: { type: string, minLength: 1, maxLength: 200 }
|
||||
cells: { type: array, maxItems: 100, items: { $ref: "#/components/schemas/DataTableCell" } }
|
||||
DataTableBlock:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [type, id, caption, rowHeaderColumn, columns, rows]
|
||||
properties:
|
||||
type: { type: string, const: DATA_TABLE }
|
||||
id: { type: string, minLength: 1, maxLength: 200 }
|
||||
caption: { type: string, maxLength: 1000 }
|
||||
rowHeaderColumn: { type: [integer, "null"], minimum: 1 }
|
||||
columns: { type: array, minItems: 1, maxItems: 100, items: { $ref: "#/components/schemas/DataTableColumn" } }
|
||||
rows: { type: array, maxItems: 1000, items: { $ref: "#/components/schemas/DataTableRow" } }
|
||||
CalloutBlock:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [type, tone, label, content]
|
||||
properties:
|
||||
type: { type: string, const: CALLOUT }
|
||||
tone: { type: string, enum: [warning, info] }
|
||||
label: { type: string, maxLength: 200 }
|
||||
content: { type: array, maxItems: 1000, items: { $ref: "#/components/schemas/Inline" } }
|
||||
EvidenceFigureBlock:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [type, key, alt, caption, zoom]
|
||||
properties:
|
||||
type: { type: string, const: EVIDENCE_FIGURE }
|
||||
key: { type: string, minLength: 1, maxLength: 200 }
|
||||
alt: { type: string, minLength: 1, maxLength: 1000 }
|
||||
caption: { type: string, maxLength: 1000 }
|
||||
zoom: { type: boolean }
|
||||
CaseRenderBlock:
|
||||
oneOf:
|
||||
- { $ref: "#/components/schemas/HeadingBlock" }
|
||||
- { $ref: "#/components/schemas/ParagraphBlock" }
|
||||
- { $ref: "#/components/schemas/BlockquoteBlock" }
|
||||
- { $ref: "#/components/schemas/UnorderedListBlock" }
|
||||
- { $ref: "#/components/schemas/OrderedListBlock" }
|
||||
- { $ref: "#/components/schemas/CodeBlock" }
|
||||
- { $ref: "#/components/schemas/DataTableBlock" }
|
||||
- { $ref: "#/components/schemas/CalloutBlock" }
|
||||
- { $ref: "#/components/schemas/EvidenceFigureBlock" }
|
||||
discriminator:
|
||||
propertyName: type
|
||||
mapping:
|
||||
HEADING: "#/components/schemas/HeadingBlock"
|
||||
PARAGRAPH: "#/components/schemas/ParagraphBlock"
|
||||
BLOCKQUOTE: "#/components/schemas/BlockquoteBlock"
|
||||
UNORDERED_LIST: "#/components/schemas/UnorderedListBlock"
|
||||
ORDERED_LIST: "#/components/schemas/OrderedListBlock"
|
||||
CODE_BLOCK: "#/components/schemas/CodeBlock"
|
||||
DATA_TABLE: "#/components/schemas/DataTableBlock"
|
||||
CALLOUT: "#/components/schemas/CalloutBlock"
|
||||
EVIDENCE_FIGURE: "#/components/schemas/EvidenceFigureBlock"
|
||||
CasePublicRenderModel:
|
||||
unevaluatedProperties: false
|
||||
allOf:
|
||||
- { $ref: "#/components/schemas/PublicRenderModelBase" }
|
||||
- type: object
|
||||
required: [kind, problem, conclusion, environment, reproduction, lastVerifiedOn, bodyBlocks]
|
||||
properties:
|
||||
kind: { type: string, const: CASE }
|
||||
problem: { type: string, minLength: 1, maxLength: 100000 }
|
||||
conclusion: { type: string, minLength: 1, maxLength: 100000 }
|
||||
environment: { type: string, maxLength: 100000 }
|
||||
reproduction: { type: string, maxLength: 100000 }
|
||||
lastVerifiedOn: { type: string, format: date }
|
||||
bodyBlocks: { type: array, maxItems: 10000, items: { $ref: "#/components/schemas/CaseRenderBlock" } }
|
||||
ReferencePublicRenderModel:
|
||||
unevaluatedProperties: false
|
||||
allOf:
|
||||
- { $ref: "#/components/schemas/PublicRenderModelBase" }
|
||||
- type: object
|
||||
required: [kind, purpose, rules, applyWhen, exceptions, examples, verifiedOn]
|
||||
properties:
|
||||
kind: { type: string, const: REFERENCE }
|
||||
purpose: { type: string, minLength: 1, maxLength: 100000 }
|
||||
rules: { type: array, minItems: 1, maxItems: 50, items: { $ref: "#/components/schemas/ReferenceRule" } }
|
||||
applyWhen: { type: array, minItems: 1, maxItems: 50, items: { $ref: "#/components/schemas/OrderedText" } }
|
||||
exceptions: { type: array, maxItems: 50, items: { $ref: "#/components/schemas/OrderedText" } }
|
||||
examples: { type: array, maxItems: 50, items: { $ref: "#/components/schemas/OrderedText" } }
|
||||
verifiedOn: { type: string, format: date }
|
||||
ResolvedQuestionResolution:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [summary, evidenceTarget, linkLabel]
|
||||
properties:
|
||||
summary: { type: string, minLength: 1, maxLength: 100000 }
|
||||
evidenceTarget: { $ref: "#/components/schemas/DisplayTarget" }
|
||||
linkLabel: { type: string, minLength: 1, maxLength: 120 }
|
||||
QuestionPublicRenderModel:
|
||||
unevaluatedProperties: false
|
||||
allOf:
|
||||
- { $ref: "#/components/schemas/PublicRenderModelBase" }
|
||||
- type: object
|
||||
required: [kind, status, facts, assumptions, unknowns, constraints, options, nextValidation, resolution]
|
||||
properties:
|
||||
kind: { type: string, const: QUESTION }
|
||||
status: { type: string, enum: [OPEN, RESOLVED] }
|
||||
facts: { type: array, minItems: 1, maxItems: 50, items: { $ref: "#/components/schemas/OrderedText" } }
|
||||
assumptions: { type: array, maxItems: 50, items: { $ref: "#/components/schemas/OrderedText" } }
|
||||
unknowns: { type: array, maxItems: 50, items: { $ref: "#/components/schemas/OrderedText" } }
|
||||
constraints: { type: array, maxItems: 50, items: { $ref: "#/components/schemas/OrderedText" } }
|
||||
options: { type: array, maxItems: 50, items: { $ref: "#/components/schemas/QuestionOption" } }
|
||||
nextValidation: { type: string, minLength: 1, maxLength: 100000 }
|
||||
resolution:
|
||||
oneOf:
|
||||
- { $ref: "#/components/schemas/ResolvedQuestionResolution" }
|
||||
- { type: "null" }
|
||||
PublicRenderModel:
|
||||
oneOf:
|
||||
- { $ref: "#/components/schemas/CasePublicRenderModel" }
|
||||
- { $ref: "#/components/schemas/ReferencePublicRenderModel" }
|
||||
- { $ref: "#/components/schemas/QuestionPublicRenderModel" }
|
||||
discriminator:
|
||||
propertyName: kind
|
||||
mapping:
|
||||
CASE: "#/components/schemas/CasePublicRenderModel"
|
||||
REFERENCE: "#/components/schemas/ReferencePublicRenderModel"
|
||||
QUESTION: "#/components/schemas/QuestionPublicRenderModel"
|
||||
PublicPreview:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [previewId, documentId, previewVersion, validationId, createdAt, expiresAt, renderModel]
|
||||
properties:
|
||||
previewId: { type: string, format: uuid }
|
||||
documentId: { type: string, format: uuid }
|
||||
previewVersion: { type: integer, minimum: 1 }
|
||||
validationId: { type: string, format: uuid }
|
||||
createdAt: { type: string, format: date-time }
|
||||
expiresAt: { type: string, format: date-time }
|
||||
renderModel: { $ref: "#/components/schemas/PublicRenderModel" }
|
||||
PreviewDetail:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [preview, state, currentDocumentVersion, currentValidationId]
|
||||
properties:
|
||||
preview: { $ref: "#/components/schemas/PublicPreview" }
|
||||
state: { type: string, enum: [CURRENT, STALE, EXPIRED] }
|
||||
currentDocumentVersion: { type: integer, minimum: 1 }
|
||||
currentValidationId: { type: [string, "null"], format: uuid }
|
||||
PublicationAggregate:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [publicationId, documentId, status, publishedVersion, publicationRevision, latestEventId, publicPath, updatedAt]
|
||||
properties:
|
||||
publicationId: { type: string, format: uuid }
|
||||
documentId: { type: string, format: uuid }
|
||||
status: { type: string, enum: [PUBLISHED, UNPUBLISHED] }
|
||||
publishedVersion: { type: integer, minimum: 1 }
|
||||
publicationRevision: { type: integer, minimum: 1 }
|
||||
latestEventId: { type: string, format: uuid }
|
||||
publicPath: { type: string, minLength: 1, maxLength: 500 }
|
||||
updatedAt: { type: string, format: date-time }
|
||||
PublicationEventType: { type: string, enum: [PUBLISHED, REPUBLISHED, UNPUBLISHED] }
|
||||
PublicationEvent:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [publicationEventId, publicationId, documentId, type, occurredAt, publishedVersion, sourcePublishedEventId, snapshotAvailable]
|
||||
properties:
|
||||
publicationEventId: { type: string, format: uuid }
|
||||
publicationId: { type: string, format: uuid }
|
||||
documentId: { type: string, format: uuid }
|
||||
type: { $ref: "#/components/schemas/PublicationEventType" }
|
||||
occurredAt: { type: string, format: date-time }
|
||||
publishedVersion: { type: integer, minimum: 1 }
|
||||
sourcePublishedEventId: { type: [string, "null"], format: uuid }
|
||||
snapshotAvailable: { type: boolean }
|
||||
PublicationSnapshot:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [event, renderModel]
|
||||
properties:
|
||||
event: { $ref: "#/components/schemas/PublicationEvent" }
|
||||
renderModel: { $ref: "#/components/schemas/PublicRenderModel" }
|
||||
PublishResult:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [publication, event]
|
||||
properties:
|
||||
publication: { $ref: "#/components/schemas/PublicationAggregate" }
|
||||
event: { $ref: "#/components/schemas/PublicationEvent" }
|
||||
DocumentSummary:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [id, title, kind, project, updatedAt, publicationStatus, publishedVersion, hasUnpublishedChanges, nextAction]
|
||||
properties:
|
||||
id: { type: string, format: uuid }
|
||||
title: { type: string, maxLength: 120 }
|
||||
kind: { $ref: "#/components/schemas/RecordKind" }
|
||||
project:
|
||||
oneOf:
|
||||
- { $ref: "#/components/schemas/DisplayTarget" }
|
||||
- { type: "null" }
|
||||
updatedAt: { type: string, format: date-time }
|
||||
publicationStatus: { $ref: "#/components/schemas/PublicationStatus" }
|
||||
publishedVersion: { type: [integer, "null"], minimum: 1 }
|
||||
hasUnpublishedChanges: { type: boolean }
|
||||
nextAction: { $ref: "#/components/schemas/NextAction" }
|
||||
PublicationAction: { type: string, enum: [VIEW_SNAPSHOT, VIEW_SOURCE_SNAPSHOT, UNPUBLISH] }
|
||||
PublicationListItem:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [event, publication, document, availableActions]
|
||||
properties:
|
||||
event: { $ref: "#/components/schemas/PublicationEvent" }
|
||||
publication: { $ref: "#/components/schemas/PublicationAggregate" }
|
||||
document: { $ref: "#/components/schemas/DocumentSummary" }
|
||||
availableActions: { type: array, uniqueItems: true, maxItems: 3, items: { $ref: "#/components/schemas/PublicationAction" } }
|
||||
WorkingCopyDetail:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [document, currentValidation, latestPreview, currentPublication, dependencyRevision]
|
||||
properties:
|
||||
document: { $ref: "#/components/schemas/WorkingCopy" }
|
||||
currentValidation:
|
||||
oneOf:
|
||||
- { $ref: "#/components/schemas/ValidationReport" }
|
||||
- { type: "null" }
|
||||
latestPreview:
|
||||
oneOf:
|
||||
- { $ref: "#/components/schemas/PublicPreview" }
|
||||
- { type: "null" }
|
||||
currentPublication:
|
||||
oneOf:
|
||||
- { $ref: "#/components/schemas/PublicationAggregate" }
|
||||
- { type: "null" }
|
||||
dependencyRevision: { type: string, minLength: 1, maxLength: 200 }
|
||||
StudioDashboard:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [continueWriting, readyToPublish, recentPublications, totals]
|
||||
properties:
|
||||
continueWriting: { type: array, maxItems: 5, items: { $ref: "#/components/schemas/DocumentSummary" } }
|
||||
readyToPublish: { type: array, maxItems: 5, items: { $ref: "#/components/schemas/DocumentSummary" } }
|
||||
recentPublications: { type: array, maxItems: 5, items: { $ref: "#/components/schemas/PublicationListItem" } }
|
||||
totals: { $ref: "#/components/schemas/DashboardTotals" }
|
||||
DashboardTotals:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [documents, readyToPublish, publications]
|
||||
properties:
|
||||
documents: { type: integer, minimum: 0 }
|
||||
readyToPublish: { type: integer, minimum: 0 }
|
||||
publications: { type: integer, minimum: 0 }
|
||||
DocumentPage:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [items, nextCursor]
|
||||
properties:
|
||||
items: { type: array, maxItems: 100, items: { $ref: "#/components/schemas/DocumentSummary" } }
|
||||
nextCursor: { type: [string, "null"], maxLength: 2000 }
|
||||
PublicationPage:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [items, nextCursor]
|
||||
properties:
|
||||
items: { type: array, maxItems: 100, items: { $ref: "#/components/schemas/PublicationListItem" } }
|
||||
nextCursor: { type: [string, "null"], maxLength: 2000 }
|
||||
CatalogEntryType: { type: string, enum: [TOPIC, PROJECT, RELATION, EVIDENCE] }
|
||||
CatalogEntry:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [id, type, label, dependencyRevision]
|
||||
properties:
|
||||
id: { type: string, format: uuid }
|
||||
type: { $ref: "#/components/schemas/CatalogEntryType" }
|
||||
label: { type: string, minLength: 1, maxLength: 200 }
|
||||
kind: { type: string, enum: [CASE, REFERENCE, QUESTION, PROJECT, PROJECT_DECISION] }
|
||||
publicPath: { type: string, minLength: 1, maxLength: 500 }
|
||||
dependencyRevision: { type: string, minLength: 1, maxLength: 200 }
|
||||
CatalogPage:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [items, nextCursor]
|
||||
properties:
|
||||
items: { type: array, maxItems: 100, items: { $ref: "#/components/schemas/CatalogEntry" } }
|
||||
nextCursor: { type: [string, "null"], maxLength: 2000 }
|
||||
FieldError:
|
||||
type: object
|
||||
additionalProperties: false
|
||||
required: [path, message]
|
||||
properties:
|
||||
path:
|
||||
type: string
|
||||
pattern: "^(?:/(?:[^~/]|~0|~1)*)*$"
|
||||
description: JSON Pointer to the invalid field
|
||||
message: { type: string, minLength: 1, maxLength: 1000 }
|
||||
ProblemDetails:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
required: [type, title, status, detail, code]
|
||||
properties:
|
||||
type: { type: string, format: uri-reference }
|
||||
title: { type: string, minLength: 1, maxLength: 200 }
|
||||
status: { type: integer, minimum: 400, maximum: 599 }
|
||||
detail: { type: string, minLength: 1, maxLength: 5000 }
|
||||
code:
|
||||
type: string
|
||||
enum: [AUTHENTICATION_REQUIRED, STUDIO_ACCESS_DENIED, DOCUMENT_NOT_FOUND, PREVIEW_NOT_FOUND, PUBLICATION_NOT_FOUND, PUBLICATION_EVENT_NOT_FOUND, PUBLICATION_SNAPSHOT_NOT_FOUND, VERSION_CONFLICT, PUBLICATION_CONFLICT, VALIDATION_STALE, PREVIEW_STALE, PREVIEW_EXPIRED, IDEMPOTENCY_KEY_REUSED, REQUEST_VALIDATION_FAILED, STUDIO_UNAVAILABLE]
|
||||
instance: { type: string, format: uri-reference }
|
||||
traceId: { type: string, maxLength: 200 }
|
||||
fieldErrors: { type: array, maxItems: 200, items: { $ref: "#/components/schemas/FieldError" } }
|
||||
latestDocument: { $ref: "#/components/schemas/WorkingCopyDetail" }
|
||||
latestPublication: { $ref: "#/components/schemas/PublicationAggregate" }
|
||||
conflictingFields:
|
||||
type: array
|
||||
uniqueItems: true
|
||||
maxItems: 200
|
||||
items:
|
||||
type: string
|
||||
pattern: "^(?:/(?:[^~/]|~0|~1)*)*$"
|
||||
retryable: { type: boolean }
|
||||
Reference in New Issue
Block a user