Files
CalendarApi/internal/api/openapi/specs/projects.json
Michilis bd24545b7b Fix BASE_URL config loading, add tasks/projects; robust .env path resolution
- Config: try ENV_FILE, .env, ../.env for loading; trim trailing slash from BaseURL
- Log BASE_URL at server startup for verification
- .env.example: document BASE_URL
- Tasks, projects, tags, migrations and related API/handlers

Made-with: Cursor
2026-03-09 18:57:51 +00:00

230 lines
10 KiB
JSON

{
"paths": {
"/projects": {
"get": {
"tags": ["Projects"],
"summary": "List projects",
"description": "Returns the authenticated user's projects (owned and shared). Requires `tasks:read` scope.",
"operationId": "listProjects",
"parameters": [
{ "name": "limit", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 200, "default": 50 } },
{ "name": "cursor", "in": "query", "schema": { "type": "string" }, "description": "Pagination cursor" }
],
"responses": {
"200": {
"description": "List of projects",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["items", "page"],
"properties": {
"items": { "type": "array", "items": { "$ref": "#/components/schemas/Project" } },
"page": { "$ref": "#/components/schemas/PageInfo" }
}
}
}
}
},
"401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
"403": { "description": "Insufficient scope", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
}
},
"post": {
"tags": ["Projects"],
"summary": "Create a project",
"description": "Creates a new project for the authenticated user. Requires `tasks:write` scope.",
"operationId": "createProject",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["name"],
"properties": {
"name": { "type": "string", "minLength": 1, "maxLength": 100 },
"color": { "type": "string", "pattern": "^#[0-9A-Fa-f]{6}$", "example": "#3B82F6" },
"deadline": { "type": "string", "format": "date-time" },
"sort_order": { "type": "integer" }
}
}
}
}
},
"responses": {
"200": {
"description": "Project created",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["project"],
"properties": {
"project": { "$ref": "#/components/schemas/Project" }
}
}
}
}
},
"400": { "description": "Validation error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
"401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
"403": { "description": "Insufficient scope", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
}
}
},
"/projects/{id}": {
"get": {
"tags": ["Projects"],
"summary": "Get a project",
"description": "Returns a single project by ID. User must be owner or member. Requires `tasks:read` scope.",
"operationId": "getProject",
"parameters": [
{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }
],
"responses": {
"200": {
"description": "Project details",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["project"],
"properties": {
"project": { "$ref": "#/components/schemas/Project" }
}
}
}
}
},
"401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
"403": { "description": "Insufficient scope", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
"404": { "description": "Project not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
}
},
"put": {
"tags": ["Projects"],
"summary": "Update a project",
"description": "Updates a project. Requires `tasks:write` scope and owner/editor role.",
"operationId": "updateProject",
"parameters": [
{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"name": { "type": "string", "minLength": 1, "maxLength": 100 },
"color": { "type": "string", "pattern": "^#[0-9A-Fa-f]{6}$" },
"deadline": { "type": "string", "format": "date-time", "nullable": true },
"sort_order": { "type": "integer" }
}
}
}
}
},
"responses": {
"200": {
"description": "Project updated",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["project"],
"properties": {
"project": { "$ref": "#/components/schemas/Project" }
}
}
}
}
},
"400": { "description": "Validation error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
"401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
"403": { "description": "Insufficient scope", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
"404": { "description": "Project not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
}
},
"delete": {
"tags": ["Projects"],
"summary": "Delete a project",
"description": "Deletes a project. Requires `tasks:write` scope and owner role.",
"operationId": "deleteProject",
"parameters": [
{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }
],
"responses": {
"200": { "description": "Project deleted", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OkResponse" } } } },
"401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
"403": { "description": "Insufficient scope", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
"404": { "description": "Project not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
}
}
},
"/projects/{id}/share": {
"post": {
"tags": ["Projects"],
"summary": "Share project",
"description": "Shares a project with a user by email. Requires `tasks:write` scope and owner/editor role.",
"operationId": "shareProject",
"parameters": [
{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["email", "role"],
"properties": {
"email": { "type": "string", "format": "email" },
"role": { "type": "string", "enum": ["editor", "viewer"] }
}
}
}
}
},
"responses": {
"200": { "description": "Project shared", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OkResponse" } } } },
"400": { "description": "Validation error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
"401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
"403": { "description": "Insufficient scope", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
"404": { "description": "Project not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
}
}
},
"/projects/{id}/members": {
"get": {
"tags": ["Projects"],
"summary": "List project members",
"description": "Returns members of a project. Requires `tasks:read` scope.",
"operationId": "listProjectMembers",
"parameters": [
{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }
],
"responses": {
"200": {
"description": "List of project members",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["items"],
"properties": {
"items": { "type": "array", "items": { "$ref": "#/components/schemas/ProjectMember" } }
}
}
}
}
},
"401": { "description": "Not authenticated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
"403": { "description": "Insufficient scope", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
"404": { "description": "Project not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
}
}
}
}
}