mirror of
https://github.com/Sosokker/go-chi-oapi-codegen-todolist.git
synced 2025-12-19 05:54:07 +01:00
1018 lines
32 KiB
YAML
1018 lines
32 KiB
YAML
openapi: 3.0.3
|
|
info:
|
|
title: Todolist API
|
|
version: 1.3.0 # Incremented version
|
|
description: |
|
|
API for managing Todo items, including CRUD operations, subtasks, deadlines, attachments (stored in GCS), and user-defined Tags.
|
|
Supports user authentication via email/password (JWT) and Google OAuth.
|
|
Designed for use with oapi-codegen and Chi.
|
|
|
|
**Note on Notifications:** Real-time notifications (e.g., via SSE or WebSockets) are planned but not fully described in this OpenAPI specification due to limitations in representing asynchronous APIs. These will be documented separately.
|
|
|
|
**Note on Tag Deletion:** Deleting a Tag will typically remove its association from any Todo items currently using it.
|
|
servers:
|
|
- url: /api/v1
|
|
description: API version 1
|
|
|
|
components:
|
|
securitySchemes:
|
|
BearerAuth:
|
|
type: http
|
|
scheme: bearer
|
|
bearerFormat: JWT
|
|
description: JWT authentication token provided in the Authorization header.
|
|
CookieAuth:
|
|
type: apiKey
|
|
in: cookie
|
|
name: jwt_token
|
|
description: JWT authentication token provided via an HTTP-only cookie.
|
|
|
|
schemas:
|
|
# --- User Schemas ---
|
|
User:
|
|
type: object
|
|
description: Represents a registered user.
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
readOnly: true
|
|
username:
|
|
type: string
|
|
email:
|
|
type: string
|
|
format: email
|
|
emailVerified:
|
|
type: boolean
|
|
readOnly: true
|
|
description: Indicates if the user's email has been verified (e.g., via OAuth or email confirmation).
|
|
createdAt:
|
|
type: string
|
|
format: date-time
|
|
readOnly: true
|
|
updatedAt:
|
|
type: string
|
|
format: date-time
|
|
readOnly: true
|
|
required:
|
|
- id
|
|
- username
|
|
- email
|
|
- emailVerified
|
|
- createdAt
|
|
- updatedAt
|
|
|
|
SignupRequest:
|
|
type: object
|
|
description: Data required for signing up a new user via email/password.
|
|
properties:
|
|
username:
|
|
type: string
|
|
minLength: 3
|
|
maxLength: 50
|
|
email:
|
|
type: string
|
|
format: email
|
|
password:
|
|
type: string
|
|
minLength: 6
|
|
writeOnly: true
|
|
required:
|
|
- username
|
|
- email
|
|
- password
|
|
|
|
LoginRequest:
|
|
type: object
|
|
description: Data required for logging in via email/password.
|
|
properties:
|
|
email:
|
|
type: string
|
|
format: email
|
|
password:
|
|
type: string
|
|
writeOnly: true
|
|
required:
|
|
- email
|
|
- password
|
|
|
|
LoginResponse:
|
|
type: object
|
|
description: Response containing the JWT access token for API clients. For browser clients, a cookie is typically set instead.
|
|
properties:
|
|
accessToken:
|
|
type: string
|
|
description: JWT access token.
|
|
tokenType:
|
|
type: string
|
|
default: "Bearer"
|
|
description: Type of the token (always Bearer).
|
|
required:
|
|
- accessToken
|
|
- tokenType
|
|
|
|
UpdateUserRequest:
|
|
type: object
|
|
description: Data for updating user details.
|
|
properties:
|
|
username:
|
|
type: string
|
|
minLength: 3
|
|
maxLength: 50
|
|
|
|
# --- Tag Schemas ---
|
|
Tag:
|
|
type: object
|
|
description: Represents a user-defined tag for organizing Todos.
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
readOnly: true
|
|
userId:
|
|
type: string
|
|
format: uuid
|
|
readOnly: true
|
|
description: The ID of the user who owns this Tag.
|
|
name:
|
|
type: string
|
|
description: Name of the tag (e.g., "Work", "Personal"). Must be unique per user.
|
|
color:
|
|
type: string
|
|
format: hexcolor
|
|
nullable: true
|
|
description: Optional color associated with the tag.
|
|
icon:
|
|
type: string
|
|
nullable: true
|
|
description: Optional identifier for an icon associated with the tag (e.g., 'briefcase', 'home'). Frontend maps this to actual icon display.
|
|
createdAt:
|
|
type: string
|
|
format: date-time
|
|
readOnly: true
|
|
updatedAt:
|
|
type: string
|
|
format: date-time
|
|
readOnly: true
|
|
required:
|
|
- id
|
|
- userId
|
|
- name
|
|
- createdAt
|
|
- updatedAt
|
|
|
|
CreateTagRequest:
|
|
type: object
|
|
description: Data required to create a new Tag.
|
|
properties:
|
|
name:
|
|
type: string
|
|
minLength: 1
|
|
maxLength: 50
|
|
description: Name of the tag. Must be unique for the user.
|
|
color:
|
|
type: string
|
|
format: hexcolor
|
|
nullable: true
|
|
description: Optional color code (e.g., #FF5733).
|
|
icon:
|
|
type: string
|
|
nullable: true
|
|
maxLength: 30
|
|
description: Optional icon identifier.
|
|
required:
|
|
- name
|
|
|
|
UpdateTagRequest:
|
|
type: object
|
|
description: Data for updating an existing Tag. All fields are optional.
|
|
properties:
|
|
name:
|
|
type: string
|
|
minLength: 1
|
|
maxLength: 50
|
|
description: New name for the tag. Must be unique for the user.
|
|
color:
|
|
type: string
|
|
format: hexcolor
|
|
nullable: true
|
|
description: New color code.
|
|
icon:
|
|
type: string
|
|
nullable: true
|
|
maxLength: 30
|
|
description: New icon identifier.
|
|
|
|
# --- Attachment Info Schema ---
|
|
AttachmentInfo:
|
|
type: object
|
|
description: Metadata about an uploaded attachment.
|
|
properties:
|
|
fileId:
|
|
type: string
|
|
description: Unique storage identifier/path for the file (used for deletion).
|
|
fileName:
|
|
type: string
|
|
description: Original name of the uploaded file.
|
|
fileUrl:
|
|
type: string
|
|
format: url
|
|
description: URL to access the uploaded file (e.g., a signed GCS URL).
|
|
contentType:
|
|
type: string
|
|
description: MIME type of the uploaded file.
|
|
size:
|
|
type: integer
|
|
format: int64
|
|
description: Size of the uploaded file in bytes.
|
|
required:
|
|
- fileId
|
|
- fileName
|
|
- fileUrl
|
|
- contentType
|
|
- size
|
|
|
|
# --- Todo Schemas ---
|
|
Todo:
|
|
type: object
|
|
description: Represents a Todo item.
|
|
properties:
|
|
id: { type: string, format: uuid, readOnly: true }
|
|
userId: { type: string, format: uuid, readOnly: true }
|
|
title: { type: string }
|
|
description: { type: string, nullable: true }
|
|
status: { type: string, enum: [pending, in-progress, completed], default: pending }
|
|
deadline: { type: string, format: date-time, nullable: true }
|
|
tagIds:
|
|
type: array
|
|
items: { type: string, format: uuid }
|
|
default: []
|
|
attachmentUrl: # <-- Changed from attachments array
|
|
type: string
|
|
format: url
|
|
nullable: true
|
|
description: Publicly accessible URL of the attached image, if any.
|
|
subtasks:
|
|
type: array
|
|
items: { $ref: '#/components/schemas/Subtask' }
|
|
readOnly: true
|
|
default: []
|
|
createdAt: { type: string, format: date-time, readOnly: true }
|
|
updatedAt: { type: string, format: date-time, readOnly: true }
|
|
required:
|
|
- id
|
|
- userId
|
|
- title
|
|
- status
|
|
- tagIds
|
|
- createdAt
|
|
- updatedAt
|
|
|
|
CreateTodoRequest:
|
|
type: object
|
|
description: Data required to create a new Todo item.
|
|
properties:
|
|
title:
|
|
type: string
|
|
minLength: 1
|
|
description:
|
|
type: string
|
|
nullable: true
|
|
status:
|
|
type: string
|
|
enum: [pending, in-progress, completed]
|
|
default: pending
|
|
deadline:
|
|
type: string
|
|
format: date-time
|
|
nullable: true
|
|
tagIds:
|
|
type: array
|
|
items:
|
|
type: string
|
|
format: uuid
|
|
description: Optional list of existing Tag IDs to associate with the new Todo. IDs must belong to the user.
|
|
default: []
|
|
required:
|
|
- title
|
|
|
|
UpdateTodoRequest:
|
|
type: object
|
|
description: Data for updating an existing Todo item. Attachment is managed via dedicated endpoints.
|
|
properties:
|
|
title: { type: string, minLength: 1 }
|
|
description: { type: string, nullable: true }
|
|
status: { type: string, enum: [pending, in-progress, completed] }
|
|
deadline: { type: string, format: date-time, nullable: true }
|
|
tagIds:
|
|
type: array
|
|
items: { type: string, format: uuid }
|
|
|
|
# --- Subtask Schemas ---
|
|
Subtask:
|
|
type: object
|
|
description: Represents a subtask associated with a Todo item.
|
|
properties:
|
|
id:
|
|
type: string
|
|
format: uuid
|
|
readOnly: true
|
|
todoId:
|
|
type: string
|
|
format: uuid
|
|
readOnly: true
|
|
description: The ID of the parent Todo item.
|
|
description:
|
|
type: string
|
|
description: Description of the subtask.
|
|
completed:
|
|
type: boolean
|
|
default: false
|
|
description: Whether the subtask is completed.
|
|
createdAt:
|
|
type: string
|
|
format: date-time
|
|
readOnly: true
|
|
updatedAt:
|
|
type: string
|
|
format: date-time
|
|
readOnly: true
|
|
required:
|
|
- id
|
|
- todoId
|
|
- description
|
|
- completed
|
|
- createdAt
|
|
- updatedAt
|
|
|
|
CreateSubtaskRequest:
|
|
type: object
|
|
description: Data required to create a new Subtask.
|
|
properties:
|
|
description:
|
|
type: string
|
|
minLength: 1
|
|
required:
|
|
- description
|
|
|
|
UpdateSubtaskRequest:
|
|
type: object
|
|
description: Data for updating an existing Subtask. Both fields are optional.
|
|
properties:
|
|
description:
|
|
type: string
|
|
minLength: 1
|
|
completed:
|
|
type: boolean
|
|
|
|
# --- File Upload Response Schema ---
|
|
FileUploadResponse: # This is the same as AttachmentInfo, could reuse definition with $ref
|
|
$ref: '#/components/schemas/AttachmentInfo'
|
|
|
|
# --- Error Schema ---
|
|
Error:
|
|
type: object
|
|
description: Standard error response format.
|
|
properties:
|
|
code:
|
|
type: integer
|
|
format: int32
|
|
description: HTTP status code or application-specific code.
|
|
message:
|
|
type: string
|
|
description: Detailed error message.
|
|
required:
|
|
- code
|
|
- message
|
|
|
|
responses:
|
|
BadRequest:
|
|
description: Invalid input (e.g., validation error, missing fields, invalid tag ID).
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Error"
|
|
Unauthorized:
|
|
description: Authentication failed (e.g., invalid credentials, invalid/expired token/cookie, missing authentication).
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Error"
|
|
Forbidden:
|
|
description: Authorization failed (e.g., user does not have permission to access or modify the resource, such as another user's tag).
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Error"
|
|
NotFound:
|
|
description: The requested resource (e.g., Todo, Tag, Subtask, Attachment) was not found.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Error"
|
|
Conflict:
|
|
description: Conflict (e.g., username or email already exists, tag name already exists for the user, resource state conflict).
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Error"
|
|
InternalServerError:
|
|
description: Internal server error.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Error"
|
|
|
|
security:
|
|
- BearerAuth: []
|
|
- CookieAuth: []
|
|
|
|
paths:
|
|
# --- Authentication Endpoints ---
|
|
/auth/signup:
|
|
post:
|
|
summary: Register a new user via email/password (API).
|
|
operationId: signupUserApi
|
|
tags: [Auth]
|
|
security: []
|
|
requestBody:
|
|
required: true
|
|
description: User details for registration.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/SignupRequest"
|
|
responses:
|
|
"201":
|
|
description: User created successfully. Returns the new user object.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/User"
|
|
"400":
|
|
$ref: "#/components/responses/BadRequest"
|
|
"409":
|
|
$ref: "#/components/responses/Conflict"
|
|
"500":
|
|
$ref: "#/components/responses/InternalServerError"
|
|
|
|
/auth/login:
|
|
post:
|
|
summary: Log in a user via email/password (API).
|
|
description: Authenticates a user and returns a JWT access token in the response body for API clients. For browser clients, this endpoint typically also sets an HTTP-only cookie containing the JWT.
|
|
operationId: loginUserApi
|
|
tags: [Auth]
|
|
security: []
|
|
requestBody:
|
|
required: true
|
|
description: User credentials for login.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/LoginRequest"
|
|
responses:
|
|
"200":
|
|
description: Login successful. Returns JWT token for API clients. Sets auth cookie for browsers.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/LoginResponse"
|
|
headers:
|
|
Set-Cookie:
|
|
schema:
|
|
type: string
|
|
description: Contains the JWT authentication cookie (e.g., `jwt_token=...; HttpOnly; Secure; Path=/; SameSite=Lax`)
|
|
"400":
|
|
$ref: "#/components/responses/BadRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"500":
|
|
$ref: "#/components/responses/InternalServerError"
|
|
|
|
/auth/logout:
|
|
post:
|
|
summary: Log out the current user.
|
|
description: Invalidates the current session (e.g., clears the authentication cookie).
|
|
operationId: logoutUser
|
|
tags: [Auth]
|
|
security:
|
|
- BearerAuth: []
|
|
- CookieAuth: []
|
|
responses:
|
|
"204":
|
|
description: Logout successful. No content returned.
|
|
headers:
|
|
Set-Cookie:
|
|
schema:
|
|
type: string
|
|
description: Clears the JWT authentication cookie (e.g., `jwt_token=; HttpOnly; Secure; Path=/; Max-Age=0; SameSite=Lax`)
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"500":
|
|
$ref: "#/components/responses/InternalServerError"
|
|
|
|
/auth/google/login:
|
|
get:
|
|
summary: Initiate Google OAuth login flow.
|
|
description: Redirects the user's browser to Google's authentication page. Not a typical REST endpoint, part of the web flow.
|
|
operationId: initiateGoogleLogin
|
|
tags: [Auth]
|
|
security: []
|
|
responses:
|
|
"302":
|
|
description: Redirect to Google's OAuth consent screen. The 'Location' header contains the redirect URL.
|
|
headers:
|
|
Location:
|
|
schema:
|
|
type: string
|
|
format: url
|
|
description: URL to Google's OAuth endpoint.
|
|
"500":
|
|
description: Server error during redirect URL generation.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Error"
|
|
|
|
/auth/google/callback:
|
|
get:
|
|
summary: Callback endpoint for Google OAuth flow.
|
|
description: Google redirects the user here after authentication. The server exchanges the received code for tokens, finds/creates the user, generates a JWT, sets the auth cookie, and redirects the user (e.g., to the web app dashboard).
|
|
operationId: handleGoogleCallback
|
|
tags: [Auth]
|
|
security: []
|
|
responses:
|
|
"302":
|
|
description: Authentication successful. Redirects the user to the frontend application (e.g., '/dashboard'). Sets auth cookie.
|
|
headers:
|
|
Location:
|
|
schema:
|
|
type: string
|
|
description: Redirect URL within the application after successful login.
|
|
Set-Cookie:
|
|
schema:
|
|
type: string
|
|
description: Contains the JWT authentication cookie.
|
|
"401":
|
|
description: Authentication failed with Google or failed to process callback. Redirects to a login/error page.
|
|
headers:
|
|
Location:
|
|
schema:
|
|
type: string
|
|
description: Redirect URL to an error or login page.
|
|
"500":
|
|
description: Internal server error during callback processing. Redirects to an error page.
|
|
headers:
|
|
Location:
|
|
schema:
|
|
type: string
|
|
description: Redirect URL to an error page.
|
|
|
|
# --- User Endpoints ---
|
|
/users/me:
|
|
get:
|
|
summary: Get current authenticated user's details.
|
|
operationId: getCurrentUser
|
|
tags: [Users]
|
|
security:
|
|
- BearerAuth: []
|
|
- CookieAuth: []
|
|
responses:
|
|
"200":
|
|
description: Current user details.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/User"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"500":
|
|
$ref: "#/components/responses/InternalServerError"
|
|
patch:
|
|
summary: Update current authenticated user's details.
|
|
operationId: updateCurrentUser
|
|
tags: [Users]
|
|
security:
|
|
- BearerAuth: []
|
|
- CookieAuth: []
|
|
requestBody:
|
|
required: true
|
|
description: User details to update. Only fields provided will be updated.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/UpdateUserRequest'
|
|
responses:
|
|
"200":
|
|
description: User updated successfully. Returns the updated user object.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/User"
|
|
"400":
|
|
$ref: "#/components/responses/BadRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"409":
|
|
$ref: "#/components/responses/Conflict"
|
|
"500":
|
|
$ref: "#/components/responses/InternalServerError"
|
|
|
|
# --- Tag Endpoints ---
|
|
/tags:
|
|
get:
|
|
summary: List all tags created by the current user.
|
|
operationId: listUserTags
|
|
tags: [Tags]
|
|
security:
|
|
- BearerAuth: []
|
|
- CookieAuth: []
|
|
responses:
|
|
"200":
|
|
description: A list of the user's tags.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/Tag'
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"500":
|
|
$ref: "#/components/responses/InternalServerError"
|
|
post:
|
|
summary: Create a new tag.
|
|
operationId: createTag
|
|
tags: [Tags]
|
|
security:
|
|
- BearerAuth: []
|
|
- CookieAuth: []
|
|
requestBody:
|
|
required: true
|
|
description: Details of the tag to create.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/CreateTagRequest'
|
|
responses:
|
|
"201":
|
|
description: Tag created successfully. Returns the new tag.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Tag'
|
|
"400":
|
|
$ref: "#/components/responses/BadRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"409":
|
|
$ref: "#/components/responses/Conflict"
|
|
"500":
|
|
$ref: "#/components/responses/InternalServerError"
|
|
|
|
/tags/{tagId}:
|
|
parameters:
|
|
- name: tagId
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
description: ID of the Tag.
|
|
get:
|
|
summary: Get a specific tag by ID.
|
|
operationId: getTagById
|
|
tags: [Tags]
|
|
security:
|
|
- BearerAuth: []
|
|
- CookieAuth: []
|
|
responses:
|
|
"200":
|
|
description: The requested Tag details.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Tag'
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"500":
|
|
$ref: "#/components/responses/InternalServerError"
|
|
patch:
|
|
summary: Update a specific tag by ID.
|
|
operationId: updateTagById
|
|
tags: [Tags]
|
|
security:
|
|
- BearerAuth: []
|
|
- CookieAuth: []
|
|
requestBody:
|
|
required: true
|
|
description: Fields of the tag to update.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/UpdateTagRequest'
|
|
responses:
|
|
"200":
|
|
description: Tag updated successfully. Returns the updated tag.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Tag'
|
|
"400":
|
|
$ref: "#/components/responses/BadRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"409":
|
|
$ref: "#/components/responses/Conflict"
|
|
"500":
|
|
$ref: "#/components/responses/InternalServerError"
|
|
delete:
|
|
summary: Delete a specific tag by ID.
|
|
description: Deletes a tag owned by the user. This will typically remove the tag's ID from any Todos currently associated with it.
|
|
operationId: deleteTagById
|
|
tags: [Tags]
|
|
security:
|
|
- BearerAuth: []
|
|
- CookieAuth: []
|
|
responses:
|
|
"204":
|
|
description: Tag deleted successfully. No content.
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"500":
|
|
$ref: "#/components/responses/InternalServerError"
|
|
|
|
# --- Todo Endpoints ---
|
|
/todos:
|
|
get:
|
|
summary: List Todo items for the current user.
|
|
operationId: listTodos
|
|
tags: [Todos]
|
|
security:
|
|
- BearerAuth: []
|
|
- CookieAuth: []
|
|
parameters:
|
|
- { name: status, in: query, required: false, schema: { type: string, enum: [pending, in-progress, completed] } }
|
|
- { name: tagId, in: query, required: false, schema: { type: string, format: uuid } }
|
|
- { name: limit, in: query, required: false, schema: { type: integer, minimum: 1, default: 20 } }
|
|
- { name: offset, in: query, required: false, schema: { type: integer, minimum: 0, default: 0 } }
|
|
responses:
|
|
"200":
|
|
description: A list of Todo items.
|
|
content: { application/json: { schema: { type: array, items: { $ref: "#/components/schemas/Todo" } } } }
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"500":
|
|
$ref: "#/components/responses/InternalServerError"
|
|
post:
|
|
summary: Create a new Todo item.
|
|
operationId: createTodo
|
|
tags: [Todos]
|
|
requestBody:
|
|
required: true
|
|
content: { application/json: { schema: { $ref: "#/components/schemas/CreateTodoRequest" } } }
|
|
responses:
|
|
"201":
|
|
description: Todo item created successfully.
|
|
content: { application/json: { schema: { $ref: "#/components/schemas/Todo" } } }
|
|
"400":
|
|
$ref: "#/components/responses/BadRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"500":
|
|
$ref: "#/components/responses/InternalServerError"
|
|
|
|
/todos/{todoId}:
|
|
parameters:
|
|
- { name: todoId, in: path, required: true, schema: { type: string, format: uuid } }
|
|
get:
|
|
summary: Get a specific Todo item by ID.
|
|
operationId: getTodoById
|
|
tags: [Todos]
|
|
responses:
|
|
"200":
|
|
description: The requested Todo item.
|
|
content: { application/json: { schema: { $ref: "#/components/schemas/Todo" } } }
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"500":
|
|
$ref: "#/components/responses/InternalServerError"
|
|
patch:
|
|
summary: Update a specific Todo item by ID.
|
|
operationId: updateTodoById
|
|
tags: [Todos]
|
|
requestBody:
|
|
required: true
|
|
content: { application/json: { schema: { $ref: "#/components/schemas/UpdateTodoRequest" } } }
|
|
responses:
|
|
"200":
|
|
description: Todo item updated successfully.
|
|
content: { application/json: { schema: { $ref: "#/components/schemas/Todo" } } }
|
|
"400":
|
|
$ref: "#/components/responses/BadRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"500":
|
|
$ref: "#/components/responses/InternalServerError"
|
|
delete:
|
|
summary: Delete a specific Todo item by ID.
|
|
operationId: deleteTodoById
|
|
tags: [Todos]
|
|
security:
|
|
- BearerAuth: []
|
|
- CookieAuth: []
|
|
responses:
|
|
"204":
|
|
description: Todo item deleted successfully. No content.
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"500":
|
|
$ref: "#/components/responses/InternalServerError"
|
|
|
|
# --- Attachment Endpoints ---
|
|
/todos/{todoId}/attachments:
|
|
parameters:
|
|
- { name: todoId, in: path, required: true, schema: { type: string, format: uuid } }
|
|
post:
|
|
summary: Upload or replace the image attachment for a Todo item.
|
|
operationId: uploadOrReplaceTodoAttachment # Renamed for clarity
|
|
tags: [Attachments, Todos]
|
|
requestBody:
|
|
required: true
|
|
description: The image file to upload.
|
|
content:
|
|
multipart/form-data:
|
|
schema:
|
|
type: object
|
|
properties: { file: { type: string, format: binary } }
|
|
required: [file]
|
|
responses:
|
|
"201": # Use 201 Created (or 200 OK if replacing)
|
|
description: Image uploaded/replaced successfully. Returns file details.
|
|
content: { application/json: { schema: { $ref: '#/components/schemas/FileUploadResponse' } } } # Reusing this schema
|
|
"400": { $ref: "#/components/responses/BadRequest" } # Invalid file type, size limit etc.
|
|
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
"403": { $ref: "#/components/responses/Forbidden" }
|
|
"404": { $ref: "#/components/responses/NotFound" } # Todo not found
|
|
"500": { $ref: "#/components/responses/InternalServerError" }
|
|
delete:
|
|
summary: Delete the image attachment from a Todo item.
|
|
operationId: deleteTodoAttachment # Reused name is fine
|
|
tags: [Attachments, Todos]
|
|
responses:
|
|
"204": { description: Attachment deleted successfully. }
|
|
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
"403": { $ref: "#/components/responses/Forbidden" }
|
|
"404": { $ref: "#/components/responses/NotFound" } # Todo or attachment not found
|
|
"500": { $ref: "#/components/responses/InternalServerError" }
|
|
|
|
# --- Subtask Endpoints ---
|
|
/todos/{todoId}/subtasks:
|
|
parameters:
|
|
- { name: todoId, in: path, required: true, schema: { type: string, format: uuid } }
|
|
get:
|
|
summary: List all subtasks for a specific Todo item.
|
|
operationId: listSubtasksForTodo
|
|
tags: [Subtasks, Todos]
|
|
security:
|
|
- BearerAuth: []
|
|
- CookieAuth: []
|
|
responses:
|
|
"200":
|
|
description: A list of subtasks for the specified Todo.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/Subtask'
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"500":
|
|
$ref: "#/components/responses/InternalServerError"
|
|
post:
|
|
summary: Create a new subtask for a specific Todo item.
|
|
operationId: createSubtaskForTodo
|
|
tags: [Subtasks, Todos]
|
|
security:
|
|
- BearerAuth: []
|
|
- CookieAuth: []
|
|
requestBody:
|
|
required: true
|
|
description: Details of the subtask to create.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/CreateSubtaskRequest'
|
|
responses:
|
|
"201":
|
|
description: Subtask created successfully. Returns the new subtask.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Subtask'
|
|
"400":
|
|
$ref: "#/components/responses/BadRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"500":
|
|
$ref: "#/components/responses/InternalServerError"
|
|
|
|
/todos/{todoId}/subtasks/{subtaskId}:
|
|
parameters:
|
|
- name: todoId
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
description: ID of the parent Todo item.
|
|
- name: subtaskId
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
format: uuid
|
|
description: ID of the Subtask item.
|
|
patch:
|
|
summary: Update a specific subtask.
|
|
operationId: updateSubtaskById
|
|
tags: [Subtasks, Todos]
|
|
security:
|
|
- BearerAuth: []
|
|
- CookieAuth: []
|
|
requestBody:
|
|
required: true
|
|
description: Fields of the subtask to update.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/UpdateSubtaskRequest'
|
|
responses:
|
|
"200":
|
|
description: Subtask updated successfully. Returns the updated subtask.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Subtask'
|
|
"400":
|
|
$ref: "#/components/responses/BadRequest"
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"500":
|
|
$ref: "#/components/responses/InternalServerError"
|
|
delete:
|
|
summary: Delete a specific subtask.
|
|
operationId: deleteSubtaskById
|
|
tags: [Subtasks, Todos]
|
|
security:
|
|
- BearerAuth: []
|
|
- CookieAuth: []
|
|
responses:
|
|
"204":
|
|
description: Subtask deleted successfully. No content.
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
"403":
|
|
$ref: "#/components/responses/Forbidden"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"500":
|
|
$ref: "#/components/responses/InternalServerError"
|