{"title":"Agent Task Manager API","version":"1.0.0","description":"API for managing agent tasks with task hierarchy support and JWT authentication","base_url":"https://task.agent.lisacorp.com","authentication":{"type":"Bearer Token (JWT)","description":"JWT token in Authorization header is required for protected endpoints","example":"Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."},"endpoints":{"Authentication":[{"method":"POST","path":"/generate-jwt","description":"Generate JWT token for authentication (Rate limit: 5 requests per minute per IP)","requires_auth":false,"request":{"body":{"expires_in":"Token lifetime in hours (optional, default 8760)","secret":"Service secret key (required)","user_id":"User ID (optional, default 'anonymous')"},"example":{"expires_in":24,"secret":"your-secret-key","user_id":"user123"}},"response":{"expires_at":1735689600,"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...","user_id":"user123"},"possible_errors":[{"code":400,"description":"Invalid JSON format or missing required field 'secret'"},{"code":401,"description":"Invalid secret"},{"code":429,"description":"Rate limit exceeded"}]},{"method":"GET","path":"/me","description":"Get current user information","requires_auth":true,"response":{"expires_at":1735689600,"user_id":"user123"},"possible_errors":[{"code":401,"description":"Missing or invalid token"}]}],"Business Logic":[{"method":"INFO","path":"","description":"Main rules for working with tasks","requires_auth":false,"response":{"rules":["1. When creating a subtask, parent task is automatically moved to 'waiting' status","2. Subtasks can only be created for tasks in statuses: waiting, working, submitted","3. When all subtasks are completed or canceled, parent task is automatically moved to 'submitted' status","4. When completing or canceling a task, all its active subtasks (submitted, working, waiting) are recursively canceled","5. Only assignee can take task for work, complete or fail it","6. Assignee or task creator can cancel task","7. Tasks are automatically deleted after 3 months (can be changed during creation)","8. Each task has root_task_id for hierarchy tracking","9. When getting task (GET /task), response includes completed first-level subtasks","10. Only root task creator can view all tasks in its hierarchy (GET /root-task/:id/tasks)","11. In-memory cache is used to store list of users with active tasks","12. Cache is synchronized with database on application startup","13. Cache is automatically synchronized with DB every 10 minutes (configurable via CACHE_SYNC_INTERVAL)","14. Automatic cleanup of tasks with expired DeleteAt runs every hour (configurable via CLEANUP_INTERVAL)"]}}],"Health":[{"method":"GET","path":"/health","description":"Service health check","requires_auth":false,"response":{"status":"healthy"}},{"method":"GET","path":"/ready","description":"Service readiness check (including DB)","requires_auth":false,"response":{"status":"ready"}}],"In-Memory Cache":[{"method":"INFO","path":"","description":"In-memory caching of users with active tasks","requires_auth":false,"response":{"benefits":["Instant access to users list","No dependency on external services","Automatic synchronization on startup","Periodic synchronization for data freshness","Thread-safe implementation"],"data_structure":"Thread-safe map for storing unique user_id","operations":["1. Add user when creating task in 'submitted' status","2. Add user when parent task returns to 'submitted'","3. Remove user when they have no active tasks left (on complete/cancel)","4. Get list of all users with active tasks via GET /users-with-tasks","5. Automatic full synchronization with DB on schedule"],"periodic_sync":"Periodic synchronization every 10 minutes (configurable via CACHE_SYNC_INTERVAL)","purpose":"Fast storage of users list with active tasks","sync_on_startup":"Automatic synchronization with DB on application startup"}}],"Security":[{"method":"INFO","path":"","description":"Security mechanisms","requires_auth":false,"response":{"environment_variables":{"BLACKLISTED_USERS":"Comma-separated list of blacklisted users (optional)","CACHE_SYNC_INTERVAL":"Cache synchronization interval with DB (optional, default 10m)","SECRET_KEY":"Secret key for JWT token signing (required)"},"features":["1. JWT tokens for authentication with configurable lifetime","2. Rate limiting on /generate-jwt endpoint (5 requests per minute per IP)","3. User blacklist via BLACKLISTED_USERS environment variable (comma-separated)","4. Secret key passed through POST body, not URL","5. JWT signature algorithm verification to protect against algorithm confusion attacks","6. All tokens of blacklisted user are automatically blocked"]}}],"Statistics":[{"method":"GET","path":"/stat","description":"Get user task statistics for specified period","requires_auth":true,"request":{"query_params":{"period":"Statistics period (optional, default 'all-time'). Possible values: today, yesterday, week, month, year, all-time"}},"response":{"_note":"pending_tasks and in_progress show current state, new_tasks and failed_tasks are counted for specified period","failed_tasks":2,"in_progress":3,"new_tasks":25,"pending_tasks":15,"period":"week"},"possible_errors":[{"code":400,"description":"Invalid period parameter"},{"code":401,"description":"Authorization required"},{"code":500,"description":"Error calculating statistics"}]}],"Task Statuses":[{"method":"INFO","path":"","description":"Possible task statuses","requires_auth":false,"response":{"canceled":"Task canceled","completed":"Task successfully completed","failed":"Task completed with error","input-required":"Additional input required","rejected":"Task rejected","submitted":"Task created and waiting to be taken for work","waiting":"Task waiting for subtasks completion","working":"Task in progress"}}],"Tasks":[{"method":"POST","path":"/task","description":"Create new task","requires_auth":true,"request":{"assignee":"Assignee ID (optional)","credentials":{"example":{"postgres":{"DB_HOST":"localhost","DB_PASSWORD":"secret123"},"redis":{"REDIS_URL":"redis://localhost:6379"}},"service_name":{"ENV_VAR":"value"}},"delete_at":"Task deletion date ISO 8601 (optional, default +3 months)","description":"Task description (required)","parent_task_id":"Parent task UUID (optional)"},"response":{"assignee":"agent456","created_at":"2024-01-20T10:30:00Z","created_by":"user123","credentials":"{}","delete_at":"2024-04-20T10:30:00Z","description":"Analyze sales data","id":"123e4567-e89b-12d3-a456-426614174000","parent_task_id":null,"result":"","root_task_id":"123e4567-e89b-12d3-a456-426614174000","status":"submitted"},"possible_errors":[{"code":400,"description":"Invalid data format or parent task in invalid status"},{"code":401,"description":"Authorization required"}]},{"method":"GET","path":"/task","description":"Get task for work (takes first available task where assignee = current user and status = submitted)","requires_auth":true,"response":{"_note":"Status automatically changes to 'working'","completed_subtasks":[{"description":"Subtask 1","id":"456e7890-e89b-12d3-a456-426614174001","result":"Subtask completed successfully","status":"completed"}],"description":"Analyze data","id":"123e4567-e89b-12d3-a456-426614174000","status":"working"},"possible_errors":[{"code":404,"description":"No available tasks for this user"},{"code":401,"description":"Authorization required"}]},{"method":"POST","path":"/task/:id/complete","description":"Complete task (only assignee can complete task)","requires_auth":true,"request":{"delete_at":"New deletion date ISO 8601 (optional)","description":"Task execution result (required)"},"response":{"_note":"When completing a task, all active subtasks (submitted, working, waiting) are automatically canceled. If all subtasks are completed or canceled, parent task is moved to status = submitted","id":"123e4567-e89b-12d3-a456-426614174000","result":"Analysis completed. Sales growth is 15%","status":"completed"},"possible_errors":[{"code":400,"description":"Task not in 'working' status or invalid data format"},{"code":403,"description":"Only assignee can complete task"},{"code":404,"description":"Task not found"},{"code":401,"description":"Authorization required"}]},{"method":"POST","path":"/task/:id/cancel","description":"Cancel task and all its subtasks (can be performed by assignee or creator)","requires_auth":true,"request":{"_note":"Request body not required"},"response":{"_note":"When canceling a task, all active subtasks (submitted, working, waiting) are recursively canceled. If all parent's subtasks are now completed or canceled, parent is moved to status = submitted","id":"123e4567-e89b-12d3-a456-426614174000","status":"canceled"},"possible_errors":[{"code":400,"description":"Cannot cancel task with status completed, canceled or failed"},{"code":403,"description":"Only assignee or creator can cancel task"},{"code":404,"description":"Task not found"},{"code":401,"description":"Authorization required"}]},{"method":"POST","path":"/tasks/:id/fail","description":"Mark task as failed (only assignee can fail task)","requires_auth":true,"request":{"reason":"Failure reason (required)"},"response":{"_note":"Parent task remains in waiting status and waits for completion of other subtasks","id":"123e4567-e89b-12d3-a456-426614174000","result":"FAILURE REASON: Could not connect to database","status":"failed"},"possible_errors":[{"code":400,"description":"Task not in 'working' status or invalid data format"},{"code":403,"description":"Only assignee can fail task"},{"code":404,"description":"Task not found"},{"code":401,"description":"Authorization required"}]},{"method":"GET","path":"/root-task/:id/tasks","description":"Get all tasks by root_task_id (available only to root task creator)","requires_auth":true,"response":[{"_note":"Credentials field excluded from output","assignee":"agent1","created_at":"2024-01-20T10:30:00Z","created_by":"user123","description":"Main task","id":"123e4567-e89b-12d3-a456-426614174000","parent_task_id":null,"result":"","root_task_id":"123e4567-e89b-12d3-a456-426614174000","status":"submitted"},{"assignee":"agent2","created_at":"2024-01-20T10:35:00Z","created_by":"user123","description":"Subtask","id":"456e7890-e89b-12d3-a456-426614174001","parent_task_id":"123e4567-e89b-12d3-a456-426614174000","result":"","root_task_id":"123e4567-e89b-12d3-a456-426614174000","status":"working"}],"possible_errors":[{"code":400,"description":"Invalid ID format"},{"code":403,"description":"Access denied: you are not the creator of the root task"},{"code":404,"description":"Root task not found"},{"code":401,"description":"Authorization required"}]},{"method":"GET","path":"/root-task","description":"Get list of current user's root tasks (where id == root_task_id and created_by == current user)","requires_auth":true,"response":[{"assignee":"agent1","created_at":"2024-01-20T10:30:00Z","delete_at":"2024-04-20T10:30:00Z","description":"Main task 1","root_task_id":"123e4567-e89b-12d3-a456-426614174000","status":"submitted"},{"assignee":"agent2","created_at":"2024-01-21T14:00:00Z","delete_at":null,"description":"Main task 2","root_task_id":"789a0123-e89b-12d3-a456-426614174002","status":"completed"}],"possible_errors":[{"code":401,"description":"Authorization required"},{"code":500,"description":"Error retrieving tasks from database"}]}],"Users":[{"method":"GET","path":"/users-with-tasks","description":"Get list of users with active tasks (from in-memory cache)","requires_auth":true,"request":{"query_params":{"filter":"Comma-separated list of users for filtering (optional). Example: user1,user2,user3"}},"response":{"_note":"If filter parameter is specified, only users from the list who have active tasks are returned","count":3,"users":["user1","user2","user3"]},"possible_errors":[{"code":401,"description":"Authorization required"}]}]}}