mirror of
https://github.com/Dvorinka/Productier.git
synced 2026-06-03 20:13:01 +00:00
1942 lines
47 KiB
YAML
1942 lines
47 KiB
YAML
openapi: 3.1.0
|
|
info:
|
|
title: Productier API
|
|
version: 0.1.0
|
|
description: Core API contract for Productier workspaces, planning, notes, and focus sessions.
|
|
servers:
|
|
- url: http://localhost:8080
|
|
paths:
|
|
/v1/health:
|
|
get:
|
|
operationId: getHealth
|
|
tags: [system]
|
|
responses:
|
|
"200":
|
|
description: Health check
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/HealthResponse"
|
|
"503":
|
|
description: Dependency health check failed
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/HealthResponse"
|
|
/v1/metrics:
|
|
get:
|
|
operationId: getMetrics
|
|
tags: [system]
|
|
responses:
|
|
"200":
|
|
description: Runtime request metrics snapshot
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/MetricsResponse"
|
|
"401":
|
|
description: Metrics token missing or invalid
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorResponse"
|
|
/v1/metrics/prometheus:
|
|
get:
|
|
operationId: getMetricsPrometheus
|
|
tags: [system]
|
|
responses:
|
|
"200":
|
|
description: Runtime request metrics in Prometheus text format
|
|
content:
|
|
text/plain:
|
|
schema:
|
|
type: string
|
|
"401":
|
|
description: Metrics token missing or invalid
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorResponse"
|
|
/v1/workspaces:
|
|
get:
|
|
operationId: listWorkspaces
|
|
tags: [workspaces]
|
|
responses:
|
|
"200":
|
|
description: Workspace list
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [data]
|
|
properties:
|
|
data:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/Workspace"
|
|
/v1/members:
|
|
get:
|
|
operationId: listMembers
|
|
tags: [workspaces]
|
|
parameters:
|
|
- name: workspaceSlug
|
|
in: query
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
"200":
|
|
description: Workspace members
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [data]
|
|
properties:
|
|
data:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/Member"
|
|
/v1/members/{memberId}:
|
|
patch:
|
|
operationId: updateMember
|
|
tags: [workspaces]
|
|
parameters:
|
|
- name: memberId
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/UpdateMemberInput"
|
|
responses:
|
|
"200":
|
|
description: Updated member
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [data]
|
|
properties:
|
|
data:
|
|
$ref: "#/components/schemas/Member"
|
|
"400":
|
|
description: Invalid input
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorResponse"
|
|
"403":
|
|
description: Forbidden
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorResponse"
|
|
"404":
|
|
description: Member not found
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorResponse"
|
|
"409":
|
|
description: Business rule conflict
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorResponse"
|
|
/v1/invites:
|
|
get:
|
|
operationId: listInvites
|
|
tags: [workspaces]
|
|
parameters:
|
|
- name: workspaceSlug
|
|
in: query
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
"200":
|
|
description: Workspace invites
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [data]
|
|
properties:
|
|
data:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/Invite"
|
|
post:
|
|
operationId: createInvite
|
|
tags: [workspaces]
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/CreateInviteInput"
|
|
responses:
|
|
"201":
|
|
description: Created invite
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [data]
|
|
properties:
|
|
data:
|
|
$ref: "#/components/schemas/Invite"
|
|
"400":
|
|
description: Invalid input
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorResponse"
|
|
"403":
|
|
description: Forbidden
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorResponse"
|
|
/v1/invites/{token}:
|
|
get:
|
|
operationId: getInviteByToken
|
|
tags: [workspaces]
|
|
parameters:
|
|
- name: token
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
"200":
|
|
description: Invite detail
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [data]
|
|
properties:
|
|
data:
|
|
$ref: "#/components/schemas/Invite"
|
|
"404":
|
|
description: Invite not found
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorResponse"
|
|
/v1/invites/{token}/accept:
|
|
post:
|
|
operationId: acceptInvite
|
|
tags: [workspaces]
|
|
parameters:
|
|
- name: token
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/AcceptInviteInput"
|
|
responses:
|
|
"200":
|
|
description: Accepted invite
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [data]
|
|
properties:
|
|
data:
|
|
$ref: "#/components/schemas/Invite"
|
|
"400":
|
|
description: Invalid input
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorResponse"
|
|
"404":
|
|
description: Invite not found
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorResponse"
|
|
/v1/invites/{inviteId}/revoke:
|
|
post:
|
|
operationId: revokeInvite
|
|
tags: [workspaces]
|
|
parameters:
|
|
- name: inviteId
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
"204":
|
|
description: Invite revoked
|
|
"403":
|
|
description: Forbidden
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorResponse"
|
|
"404":
|
|
description: Invite not found
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorResponse"
|
|
"409":
|
|
description: Invite state conflict
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorResponse"
|
|
/v1/activity:
|
|
get:
|
|
operationId: listActivity
|
|
tags: [workspaces]
|
|
parameters:
|
|
- name: workspaceSlug
|
|
in: query
|
|
required: true
|
|
schema:
|
|
type: string
|
|
- name: limit
|
|
in: query
|
|
required: false
|
|
description: Max entries to return (1-40, default 8)
|
|
schema:
|
|
type: integer
|
|
minimum: 1
|
|
maximum: 40
|
|
- name: type
|
|
in: query
|
|
required: false
|
|
description: Optional inferred activity category filter
|
|
schema:
|
|
type: string
|
|
enum: [task, board, calendar, note, focus, mail, invite, system]
|
|
- name: q
|
|
in: query
|
|
required: false
|
|
description: Case-insensitive text search over title and detail
|
|
schema:
|
|
type: string
|
|
responses:
|
|
"200":
|
|
description: Workspace activity feed
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [data]
|
|
properties:
|
|
data:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/ActivityEntry"
|
|
"400":
|
|
description: Invalid activity query parameters
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorResponse"
|
|
/v1/board-groups:
|
|
get:
|
|
operationId: listBoardGroups
|
|
tags: [board]
|
|
parameters:
|
|
- name: workspaceSlug
|
|
in: query
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
"200":
|
|
description: Board groups
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [data]
|
|
properties:
|
|
data:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/BoardGroup"
|
|
post:
|
|
operationId: createBoardGroup
|
|
tags: [board]
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/CreateBoardGroupInput"
|
|
responses:
|
|
"201":
|
|
description: Created board group
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [data]
|
|
properties:
|
|
data:
|
|
$ref: "#/components/schemas/BoardGroup"
|
|
/v1/board-groups/{groupId}:
|
|
patch:
|
|
operationId: updateBoardGroup
|
|
tags: [board]
|
|
parameters:
|
|
- name: groupId
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/UpdateBoardGroupInput"
|
|
responses:
|
|
"200":
|
|
description: Updated board group
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [data]
|
|
properties:
|
|
data:
|
|
$ref: "#/components/schemas/BoardGroup"
|
|
/v1/labels:
|
|
get:
|
|
operationId: listLabels
|
|
tags: [labels]
|
|
parameters:
|
|
- name: workspaceSlug
|
|
in: query
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
"200":
|
|
description: Label list
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [data]
|
|
properties:
|
|
data:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/Label"
|
|
post:
|
|
operationId: createLabel
|
|
tags: [labels]
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/CreateLabelInput"
|
|
responses:
|
|
"201":
|
|
description: Created label
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [data]
|
|
properties:
|
|
data:
|
|
$ref: "#/components/schemas/Label"
|
|
/v1/tasks:
|
|
get:
|
|
operationId: listTasks
|
|
tags: [tasks]
|
|
parameters:
|
|
- name: workspaceSlug
|
|
in: query
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
"200":
|
|
description: Task list
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [data]
|
|
properties:
|
|
data:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/Task"
|
|
post:
|
|
operationId: createTask
|
|
tags: [tasks]
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/CreateTaskInput"
|
|
responses:
|
|
"201":
|
|
description: Created task
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [data]
|
|
properties:
|
|
data:
|
|
$ref: "#/components/schemas/Task"
|
|
/v1/calendar/events:
|
|
get:
|
|
operationId: listCalendarEvents
|
|
tags: [calendar]
|
|
parameters:
|
|
- name: workspaceSlug
|
|
in: query
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
"200":
|
|
description: Calendar events
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [data]
|
|
properties:
|
|
data:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/CalendarEvent"
|
|
post:
|
|
operationId: createCalendarEvent
|
|
tags: [calendar]
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/CreateCalendarEventInput"
|
|
responses:
|
|
"201":
|
|
description: Created event
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [data]
|
|
properties:
|
|
data:
|
|
$ref: "#/components/schemas/CalendarEvent"
|
|
/v1/tasks/{taskId}:
|
|
patch:
|
|
operationId: updateTask
|
|
tags: [tasks]
|
|
parameters:
|
|
- name: taskId
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/UpdateTaskInput"
|
|
responses:
|
|
"200":
|
|
description: Updated task
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [data]
|
|
properties:
|
|
data:
|
|
$ref: "#/components/schemas/Task"
|
|
/v1/tasks/{taskId}/attachments:
|
|
post:
|
|
operationId: uploadTaskAttachment
|
|
tags: [tasks]
|
|
parameters:
|
|
- name: taskId
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
multipart/form-data:
|
|
schema:
|
|
type: object
|
|
required: [file]
|
|
properties:
|
|
file:
|
|
type: string
|
|
format: binary
|
|
responses:
|
|
"201":
|
|
description: Uploaded task attachment
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [data]
|
|
properties:
|
|
data:
|
|
$ref: "#/components/schemas/Attachment"
|
|
"400":
|
|
description: Invalid upload
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorResponse"
|
|
"404":
|
|
description: Task not found
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorResponse"
|
|
"500":
|
|
description: Attachment storage or update failure
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorResponse"
|
|
/v1/tasks/{taskId}/attachments/{attachmentId}:
|
|
delete:
|
|
operationId: deleteTaskAttachment
|
|
tags: [tasks]
|
|
parameters:
|
|
- name: taskId
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
- name: attachmentId
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
"204":
|
|
description: Deleted attachment
|
|
"404":
|
|
description: Task or attachment not found
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorResponse"
|
|
"500":
|
|
description: Attachment delete failure
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorResponse"
|
|
/v1/tasks/{taskId}/attachments/{attachmentId}/download:
|
|
get:
|
|
operationId: downloadTaskAttachment
|
|
tags: [tasks]
|
|
parameters:
|
|
- name: taskId
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
- name: attachmentId
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
"200":
|
|
description: Attachment file stream
|
|
content:
|
|
application/octet-stream:
|
|
schema:
|
|
type: string
|
|
format: binary
|
|
"404":
|
|
description: Task or attachment not found
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorResponse"
|
|
"500":
|
|
description: Attachment read failure
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorResponse"
|
|
/v1/calendar/events/{eventId}:
|
|
patch:
|
|
operationId: updateCalendarEvent
|
|
tags: [calendar]
|
|
parameters:
|
|
- name: eventId
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/UpdateCalendarEventInput"
|
|
responses:
|
|
"200":
|
|
description: Updated event
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [data]
|
|
properties:
|
|
data:
|
|
$ref: "#/components/schemas/CalendarEvent"
|
|
/v1/notes:
|
|
get:
|
|
operationId: listNotes
|
|
tags: [notes]
|
|
parameters:
|
|
- name: workspaceSlug
|
|
in: query
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
"200":
|
|
description: Notes list
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [data]
|
|
properties:
|
|
data:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/Note"
|
|
post:
|
|
operationId: createNote
|
|
tags: [notes]
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/CreateNoteInput"
|
|
responses:
|
|
"201":
|
|
description: Created note
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [data]
|
|
properties:
|
|
data:
|
|
$ref: "#/components/schemas/Note"
|
|
/v1/notes/{noteId}:
|
|
patch:
|
|
operationId: updateNote
|
|
tags: [notes]
|
|
parameters:
|
|
- name: noteId
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/UpdateNoteInput"
|
|
responses:
|
|
"200":
|
|
description: Updated note
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [data]
|
|
properties:
|
|
data:
|
|
$ref: "#/components/schemas/Note"
|
|
/v1/focus/sessions:
|
|
get:
|
|
operationId: listFocusSessions
|
|
tags: [focus]
|
|
parameters:
|
|
- name: workspaceSlug
|
|
in: query
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
"200":
|
|
description: Focus sessions
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [data]
|
|
properties:
|
|
data:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/FocusSession"
|
|
post:
|
|
operationId: createFocusSession
|
|
tags: [focus]
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/CreateFocusSessionInput"
|
|
responses:
|
|
"201":
|
|
description: Created focus session
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [data]
|
|
properties:
|
|
data:
|
|
$ref: "#/components/schemas/FocusSession"
|
|
/v1/focus/sessions/{sessionId}:
|
|
patch:
|
|
operationId: updateFocusSession
|
|
tags: [focus]
|
|
parameters:
|
|
- name: sessionId
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/UpdateFocusSessionInput"
|
|
responses:
|
|
"200":
|
|
description: Updated focus session
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [data]
|
|
properties:
|
|
data:
|
|
$ref: "#/components/schemas/FocusSession"
|
|
/v1/mailboxes:
|
|
get:
|
|
operationId: listMailboxes
|
|
tags: [mail]
|
|
parameters:
|
|
- name: workspaceSlug
|
|
in: query
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
"200":
|
|
description: Connected mailboxes
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [data]
|
|
properties:
|
|
data:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/Mailbox"
|
|
post:
|
|
operationId: connectMailbox
|
|
tags: [mail]
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ConnectMailboxInput"
|
|
responses:
|
|
"201":
|
|
description: Connected mailbox
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [data]
|
|
properties:
|
|
data:
|
|
$ref: "#/components/schemas/Mailbox"
|
|
"400":
|
|
description: Invalid mailbox configuration
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorResponse"
|
|
/v1/mailboxes/{mailboxId}/sync:
|
|
post:
|
|
operationId: syncMailbox
|
|
tags: [mail]
|
|
parameters:
|
|
- name: mailboxId
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
"200":
|
|
description: Synced mailbox
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [data]
|
|
properties:
|
|
data:
|
|
$ref: "#/components/schemas/Mailbox"
|
|
"404":
|
|
description: Mailbox not found
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorResponse"
|
|
"502":
|
|
description: Mail provider sync failure
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorResponse"
|
|
/v1/mail/messages:
|
|
get:
|
|
operationId: listMailMessages
|
|
tags: [mail]
|
|
parameters:
|
|
- name: workspaceSlug
|
|
in: query
|
|
required: true
|
|
schema:
|
|
type: string
|
|
- name: mailboxId
|
|
in: query
|
|
required: false
|
|
schema:
|
|
type: string
|
|
responses:
|
|
"200":
|
|
description: Mail messages
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [data]
|
|
properties:
|
|
data:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/MailMessage"
|
|
/v1/mail/messages/{messageId}/create-task:
|
|
post:
|
|
operationId: createTaskFromMail
|
|
tags: [mail]
|
|
parameters:
|
|
- name: messageId
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/CreateTaskFromMailInput"
|
|
responses:
|
|
"201":
|
|
description: Created task from mail
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [data]
|
|
properties:
|
|
data:
|
|
$ref: "#/components/schemas/Task"
|
|
"400":
|
|
description: Invalid request
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorResponse"
|
|
"404":
|
|
description: Message not found
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorResponse"
|
|
"409":
|
|
description: Message already linked
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorResponse"
|
|
"500":
|
|
description: Link operation failure
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorResponse"
|
|
/v1/mail/outgoing:
|
|
get:
|
|
operationId: listOutgoingMails
|
|
tags: [mail]
|
|
parameters:
|
|
- name: workspaceSlug
|
|
in: query
|
|
required: true
|
|
schema:
|
|
type: string
|
|
- name: mailboxId
|
|
in: query
|
|
required: false
|
|
schema:
|
|
type: string
|
|
responses:
|
|
"200":
|
|
description: Outgoing mail queue
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [data]
|
|
properties:
|
|
data:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/OutgoingMail"
|
|
post:
|
|
operationId: createOutgoingMail
|
|
tags: [mail]
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/CreateOutgoingMailInput"
|
|
responses:
|
|
"201":
|
|
description: Queued outgoing mail
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
required: [data]
|
|
properties:
|
|
data:
|
|
$ref: "#/components/schemas/OutgoingMail"
|
|
"400":
|
|
description: Invalid input
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorResponse"
|
|
"403":
|
|
description: Mailbox does not belong to workspace
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorResponse"
|
|
"404":
|
|
description: Mailbox not found
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorResponse"
|
|
"502":
|
|
description: Queue delivery upstream failure
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorResponse"
|
|
components:
|
|
schemas:
|
|
HealthResponse:
|
|
type: object
|
|
required: [ok, mode, timestamp, storage]
|
|
properties:
|
|
ok:
|
|
type: boolean
|
|
mode:
|
|
type: string
|
|
timestamp:
|
|
type: string
|
|
format: date-time
|
|
storage:
|
|
$ref: "#/components/schemas/HealthStorageStatus"
|
|
HealthStorageStatus:
|
|
type: object
|
|
required: [provider, ok]
|
|
properties:
|
|
provider:
|
|
type: string
|
|
ok:
|
|
type: boolean
|
|
error:
|
|
type: string
|
|
MetricsResponse:
|
|
type: object
|
|
required: [generatedAt, uptimeSeconds, requestsTotal, statusClassTotals, routes]
|
|
properties:
|
|
generatedAt:
|
|
type: string
|
|
format: date-time
|
|
uptimeSeconds:
|
|
type: integer
|
|
format: int64
|
|
requestsTotal:
|
|
type: integer
|
|
format: int64
|
|
statusClassTotals:
|
|
type: object
|
|
additionalProperties:
|
|
type: integer
|
|
format: int64
|
|
routes:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/MetricsRouteStat"
|
|
MetricsRouteStat:
|
|
type: object
|
|
required: [method, path, status, count, avgLatencyMs, maxLatencyMs, lastSeenAt]
|
|
properties:
|
|
method:
|
|
type: string
|
|
path:
|
|
type: string
|
|
status:
|
|
type: integer
|
|
count:
|
|
type: integer
|
|
format: int64
|
|
avgLatencyMs:
|
|
type: number
|
|
format: double
|
|
maxLatencyMs:
|
|
type: number
|
|
format: double
|
|
lastSeenAt:
|
|
type: string
|
|
format: date-time
|
|
ErrorResponse:
|
|
type: object
|
|
required: [error]
|
|
properties:
|
|
error:
|
|
$ref: "#/components/schemas/ErrorDetail"
|
|
ErrorDetail:
|
|
type: object
|
|
required: [code, message, requestId]
|
|
properties:
|
|
code:
|
|
type: string
|
|
message:
|
|
type: string
|
|
requestId:
|
|
type: string
|
|
BoardGroup:
|
|
type: object
|
|
required: [id, workspaceSlug, name, color, order]
|
|
properties:
|
|
id:
|
|
type: string
|
|
workspaceSlug:
|
|
type: string
|
|
name:
|
|
type: string
|
|
color:
|
|
type: string
|
|
order:
|
|
type: integer
|
|
Workspace:
|
|
type: object
|
|
required:
|
|
- id
|
|
- slug
|
|
- name
|
|
- role
|
|
- createdAt
|
|
properties:
|
|
id:
|
|
type: string
|
|
slug:
|
|
type: string
|
|
name:
|
|
type: string
|
|
role:
|
|
type: string
|
|
enum: [owner, admin, member]
|
|
createdAt:
|
|
type: string
|
|
format: date-time
|
|
Member:
|
|
type: object
|
|
required:
|
|
- id
|
|
- workspaceSlug
|
|
- name
|
|
- email
|
|
- role
|
|
- status
|
|
properties:
|
|
id:
|
|
type: string
|
|
workspaceSlug:
|
|
type: string
|
|
name:
|
|
type: string
|
|
email:
|
|
type: string
|
|
role:
|
|
type: string
|
|
enum: [owner, admin, member]
|
|
status:
|
|
type: string
|
|
enum: [active, invited, removed]
|
|
Invite:
|
|
type: object
|
|
required:
|
|
- id
|
|
- workspaceSlug
|
|
- email
|
|
- role
|
|
- token
|
|
- createdAt
|
|
- status
|
|
properties:
|
|
id:
|
|
type: string
|
|
workspaceSlug:
|
|
type: string
|
|
email:
|
|
type: string
|
|
format: email
|
|
role:
|
|
type: string
|
|
enum: [owner, admin, member]
|
|
token:
|
|
type: string
|
|
createdAt:
|
|
type: string
|
|
format: date-time
|
|
status:
|
|
type: string
|
|
enum: [pending, accepted]
|
|
ActivityEntry:
|
|
type: object
|
|
required:
|
|
- id
|
|
- workspaceSlug
|
|
- title
|
|
- detail
|
|
- createdAt
|
|
properties:
|
|
id:
|
|
type: string
|
|
workspaceSlug:
|
|
type: string
|
|
title:
|
|
type: string
|
|
detail:
|
|
type: string
|
|
createdAt:
|
|
type: string
|
|
format: date-time
|
|
Label:
|
|
type: object
|
|
required: [id, workspaceSlug, name, color]
|
|
properties:
|
|
id:
|
|
type: string
|
|
workspaceSlug:
|
|
type: string
|
|
name:
|
|
type: string
|
|
color:
|
|
type: string
|
|
Attachment:
|
|
type: object
|
|
required: [id, name, mimeType, size]
|
|
properties:
|
|
id:
|
|
type: string
|
|
name:
|
|
type: string
|
|
mimeType:
|
|
type: string
|
|
size:
|
|
type: integer
|
|
dataUrl:
|
|
type: string
|
|
TaskComment:
|
|
type: object
|
|
required: [id, taskId, author, content, createdAt]
|
|
properties:
|
|
id:
|
|
type: string
|
|
taskId:
|
|
type: string
|
|
author:
|
|
type: string
|
|
content:
|
|
type: string
|
|
createdAt:
|
|
type: string
|
|
format: date-time
|
|
Task:
|
|
type: object
|
|
required:
|
|
- id
|
|
- workspaceSlug
|
|
- boardGroupId
|
|
- title
|
|
- status
|
|
- color
|
|
- labelIds
|
|
- attachments
|
|
- comments
|
|
- createdAt
|
|
- updatedAt
|
|
properties:
|
|
id:
|
|
type: string
|
|
workspaceSlug:
|
|
type: string
|
|
boardGroupId:
|
|
type: string
|
|
title:
|
|
type: string
|
|
description:
|
|
type: string
|
|
status:
|
|
type: string
|
|
enum: [todo, in_progress, done]
|
|
color:
|
|
type: string
|
|
dueAt:
|
|
type: string
|
|
format: date-time
|
|
scheduledStart:
|
|
type: string
|
|
format: date-time
|
|
scheduledEnd:
|
|
type: string
|
|
format: date-time
|
|
assigneeId:
|
|
type: string
|
|
labelIds:
|
|
type: array
|
|
items:
|
|
type: string
|
|
attachments:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/Attachment"
|
|
comments:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/TaskComment"
|
|
createdAt:
|
|
type: string
|
|
format: date-time
|
|
updatedAt:
|
|
type: string
|
|
format: date-time
|
|
CreateTaskInput:
|
|
type: object
|
|
required: [workspaceSlug, boardGroupId, title]
|
|
properties:
|
|
workspaceSlug:
|
|
type: string
|
|
boardGroupId:
|
|
type: string
|
|
title:
|
|
type: string
|
|
description:
|
|
type: string
|
|
dueAt:
|
|
type: string
|
|
format: date-time
|
|
color:
|
|
type: string
|
|
UpdateTaskInput:
|
|
type: object
|
|
properties:
|
|
title:
|
|
type: string
|
|
description:
|
|
type: string
|
|
status:
|
|
type: string
|
|
enum: [todo, in_progress, done]
|
|
boardGroupId:
|
|
type: string
|
|
color:
|
|
type: string
|
|
dueAt:
|
|
type: string
|
|
format: date-time
|
|
scheduledStart:
|
|
type: string
|
|
format: date-time
|
|
scheduledEnd:
|
|
type: string
|
|
format: date-time
|
|
assigneeId:
|
|
type: string
|
|
labelIds:
|
|
type: array
|
|
items:
|
|
type: string
|
|
attachments:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/Attachment"
|
|
comments:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/TaskComment"
|
|
CalendarEvent:
|
|
type: object
|
|
required:
|
|
- id
|
|
- workspaceSlug
|
|
- title
|
|
- startsAt
|
|
- endsAt
|
|
- color
|
|
- attachments
|
|
properties:
|
|
id:
|
|
type: string
|
|
workspaceSlug:
|
|
type: string
|
|
title:
|
|
type: string
|
|
description:
|
|
type: string
|
|
startsAt:
|
|
type: string
|
|
format: date-time
|
|
endsAt:
|
|
type: string
|
|
format: date-time
|
|
color:
|
|
type: string
|
|
linkedTaskId:
|
|
type: string
|
|
attachments:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/Attachment"
|
|
CreateCalendarEventInput:
|
|
type: object
|
|
required: [workspaceSlug, title, startsAt, endsAt]
|
|
properties:
|
|
workspaceSlug:
|
|
type: string
|
|
title:
|
|
type: string
|
|
description:
|
|
type: string
|
|
startsAt:
|
|
type: string
|
|
format: date-time
|
|
endsAt:
|
|
type: string
|
|
format: date-time
|
|
linkedTaskId:
|
|
type: string
|
|
color:
|
|
type: string
|
|
attachments:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/Attachment"
|
|
UpdateCalendarEventInput:
|
|
type: object
|
|
properties:
|
|
title:
|
|
type: string
|
|
description:
|
|
type: string
|
|
startsAt:
|
|
type: string
|
|
format: date-time
|
|
endsAt:
|
|
type: string
|
|
format: date-time
|
|
linkedTaskId:
|
|
type: string
|
|
color:
|
|
type: string
|
|
attachments:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/Attachment"
|
|
Note:
|
|
type: object
|
|
required:
|
|
- id
|
|
- workspaceSlug
|
|
- title
|
|
- content
|
|
- updatedAt
|
|
properties:
|
|
id:
|
|
type: string
|
|
workspaceSlug:
|
|
type: string
|
|
title:
|
|
type: string
|
|
content:
|
|
type: string
|
|
updatedAt:
|
|
type: string
|
|
format: date-time
|
|
CreateNoteInput:
|
|
type: object
|
|
required: [workspaceSlug, title, content]
|
|
properties:
|
|
workspaceSlug:
|
|
type: string
|
|
title:
|
|
type: string
|
|
content:
|
|
type: string
|
|
UpdateNoteInput:
|
|
type: object
|
|
properties:
|
|
title:
|
|
type: string
|
|
content:
|
|
type: string
|
|
FocusSession:
|
|
type: object
|
|
required:
|
|
- id
|
|
- workspaceSlug
|
|
- mode
|
|
- startedAt
|
|
- pausedTotalSeconds
|
|
- durationSeconds
|
|
properties:
|
|
id:
|
|
type: string
|
|
workspaceSlug:
|
|
type: string
|
|
taskId:
|
|
type: string
|
|
mode:
|
|
type: string
|
|
enum: [focus, short_break, long_break]
|
|
startedAt:
|
|
type: string
|
|
format: date-time
|
|
completedAt:
|
|
type: string
|
|
format: date-time
|
|
pausedAt:
|
|
type: string
|
|
format: date-time
|
|
pausedTotalSeconds:
|
|
type: integer
|
|
durationSeconds:
|
|
type: integer
|
|
CreateFocusSessionInput:
|
|
type: object
|
|
required: [workspaceSlug, mode, durationSeconds]
|
|
properties:
|
|
workspaceSlug:
|
|
type: string
|
|
taskId:
|
|
type: string
|
|
mode:
|
|
type: string
|
|
enum: [focus, short_break, long_break]
|
|
durationSeconds:
|
|
type: integer
|
|
UpdateFocusSessionInput:
|
|
type: object
|
|
properties:
|
|
completedAt:
|
|
type: string
|
|
format: date-time
|
|
pausedAt:
|
|
type: string
|
|
format: date-time
|
|
pausedTotalSeconds:
|
|
type: integer
|
|
MailAddress:
|
|
type: object
|
|
required: [name, email]
|
|
properties:
|
|
name:
|
|
type: string
|
|
email:
|
|
type: string
|
|
format: email
|
|
Mailbox:
|
|
type: object
|
|
required:
|
|
- id
|
|
- workspaceSlug
|
|
- label
|
|
- email
|
|
- displayName
|
|
- imapHost
|
|
- imapPort
|
|
- imapUsername
|
|
- imapUseTls
|
|
- smtpHost
|
|
- smtpPort
|
|
- smtpUsername
|
|
- smtpUseTls
|
|
- createdAt
|
|
- updatedAt
|
|
- syncStatus
|
|
properties:
|
|
id:
|
|
type: string
|
|
workspaceSlug:
|
|
type: string
|
|
label:
|
|
type: string
|
|
email:
|
|
type: string
|
|
format: email
|
|
displayName:
|
|
type: string
|
|
imapHost:
|
|
type: string
|
|
imapPort:
|
|
type: integer
|
|
imapUsername:
|
|
type: string
|
|
imapUseTls:
|
|
type: boolean
|
|
smtpHost:
|
|
type: string
|
|
smtpPort:
|
|
type: integer
|
|
smtpUsername:
|
|
type: string
|
|
smtpUseTls:
|
|
type: boolean
|
|
createdAt:
|
|
type: string
|
|
format: date-time
|
|
updatedAt:
|
|
type: string
|
|
format: date-time
|
|
lastSyncedAt:
|
|
type: string
|
|
format: date-time
|
|
syncStatus:
|
|
type: string
|
|
enum: [idle, syncing, ready, error]
|
|
syncError:
|
|
type: string
|
|
MailMessage:
|
|
type: object
|
|
required:
|
|
- id
|
|
- workspaceSlug
|
|
- mailboxId
|
|
- remoteUid
|
|
- messageId
|
|
- folder
|
|
- from
|
|
- to
|
|
- cc
|
|
- subject
|
|
- snippet
|
|
- textBody
|
|
- htmlBody
|
|
- receivedAt
|
|
- isRead
|
|
- createdAt
|
|
- updatedAt
|
|
properties:
|
|
id:
|
|
type: string
|
|
workspaceSlug:
|
|
type: string
|
|
mailboxId:
|
|
type: string
|
|
remoteUid:
|
|
type: integer
|
|
messageId:
|
|
type: string
|
|
folder:
|
|
type: string
|
|
from:
|
|
$ref: "#/components/schemas/MailAddress"
|
|
to:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/MailAddress"
|
|
cc:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/MailAddress"
|
|
subject:
|
|
type: string
|
|
snippet:
|
|
type: string
|
|
textBody:
|
|
type: string
|
|
htmlBody:
|
|
type: string
|
|
receivedAt:
|
|
type: string
|
|
format: date-time
|
|
isRead:
|
|
type: boolean
|
|
linkedTaskId:
|
|
type: string
|
|
createdAt:
|
|
type: string
|
|
format: date-time
|
|
updatedAt:
|
|
type: string
|
|
format: date-time
|
|
OutgoingMail:
|
|
type: object
|
|
required:
|
|
- id
|
|
- workspaceSlug
|
|
- mailboxId
|
|
- to
|
|
- cc
|
|
- bcc
|
|
- subject
|
|
- textBody
|
|
- htmlBody
|
|
- status
|
|
- createdAt
|
|
- updatedAt
|
|
properties:
|
|
id:
|
|
type: string
|
|
workspaceSlug:
|
|
type: string
|
|
mailboxId:
|
|
type: string
|
|
to:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/MailAddress"
|
|
cc:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/MailAddress"
|
|
bcc:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/MailAddress"
|
|
subject:
|
|
type: string
|
|
textBody:
|
|
type: string
|
|
htmlBody:
|
|
type: string
|
|
status:
|
|
type: string
|
|
enum: [queued, scheduled, sent, failed]
|
|
scheduledFor:
|
|
type: string
|
|
format: date-time
|
|
sentAt:
|
|
type: string
|
|
format: date-time
|
|
error:
|
|
type: string
|
|
createdAt:
|
|
type: string
|
|
format: date-time
|
|
updatedAt:
|
|
type: string
|
|
format: date-time
|
|
ConnectMailboxInput:
|
|
type: object
|
|
required:
|
|
- workspaceSlug
|
|
- email
|
|
- imapHost
|
|
- imapPassword
|
|
- smtpHost
|
|
properties:
|
|
workspaceSlug:
|
|
type: string
|
|
label:
|
|
type: string
|
|
email:
|
|
type: string
|
|
format: email
|
|
displayName:
|
|
type: string
|
|
imapHost:
|
|
type: string
|
|
imapPort:
|
|
type: integer
|
|
imapUsername:
|
|
type: string
|
|
imapPassword:
|
|
type: string
|
|
imapUseTls:
|
|
type: boolean
|
|
smtpHost:
|
|
type: string
|
|
smtpPort:
|
|
type: integer
|
|
smtpUsername:
|
|
type: string
|
|
smtpPassword:
|
|
type: string
|
|
smtpUseTls:
|
|
type: boolean
|
|
CreateOutgoingMailInput:
|
|
type: object
|
|
required: [workspaceSlug, mailboxId, to]
|
|
properties:
|
|
workspaceSlug:
|
|
type: string
|
|
mailboxId:
|
|
type: string
|
|
to:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/MailAddress"
|
|
cc:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/MailAddress"
|
|
bcc:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/MailAddress"
|
|
subject:
|
|
type: string
|
|
textBody:
|
|
type: string
|
|
htmlBody:
|
|
type: string
|
|
scheduledFor:
|
|
type: string
|
|
format: date-time
|
|
CreateTaskFromMailInput:
|
|
type: object
|
|
required: [boardGroupId]
|
|
properties:
|
|
boardGroupId:
|
|
type: string
|
|
title:
|
|
type: string
|
|
dueAt:
|
|
type: string
|
|
format: date-time
|
|
color:
|
|
type: string
|
|
CreateBoardGroupInput:
|
|
type: object
|
|
required: [workspaceSlug, name]
|
|
properties:
|
|
workspaceSlug:
|
|
type: string
|
|
name:
|
|
type: string
|
|
color:
|
|
type: string
|
|
UpdateBoardGroupInput:
|
|
type: object
|
|
properties:
|
|
name:
|
|
type: string
|
|
color:
|
|
type: string
|
|
order:
|
|
type: integer
|
|
CreateLabelInput:
|
|
type: object
|
|
required: [workspaceSlug, name, color]
|
|
properties:
|
|
workspaceSlug:
|
|
type: string
|
|
name:
|
|
type: string
|
|
color:
|
|
type: string
|
|
CreateInviteInput:
|
|
type: object
|
|
required: [workspaceSlug, email, role]
|
|
properties:
|
|
workspaceSlug:
|
|
type: string
|
|
email:
|
|
type: string
|
|
format: email
|
|
role:
|
|
type: string
|
|
enum: [owner, admin, member]
|
|
AcceptInviteInput:
|
|
type: object
|
|
required: [name, email]
|
|
properties:
|
|
name:
|
|
type: string
|
|
email:
|
|
type: string
|
|
format: email
|
|
UpdateMemberInput:
|
|
type: object
|
|
properties:
|
|
role:
|
|
type: string
|
|
enum: [owner, admin, member]
|
|
status:
|
|
type: string
|
|
enum: [active, removed]
|