{ "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" } } } } } } } } }