openapi: 3.0.3
info:
  title: Simplinion Tasks API
  description: >
    A professional task management API for the "Simplinion Tasks" ecosystem. 
    It features a robust ABCDE priority matrix, hierarchical task structures (Goals/Tasks/Subtasks), 
    multi-customer association, and comprehensive work-log tracking for performance analysis.
  version: 1.1.2
servers:
  # Added by API Auto Mocking Plugin
  - description: SwaggerHub API Auto Mocking
    url: http://localhost:3050/v1
  - url: https://tasks-api.simplinion.com/
    description: Production Environment

tags:
  - name: Tasks
    description: Management of the primary work items, including goals and standard tasks.
  - name: Goals
    description: Management of top-level goals (tasks without a parent goal).
  - name: Subtasks
    description: Management of subtasks and their checklist items, nested under a parent task.
  - name: Customers
    description: Operations to manage the directory of customers that can be linked to tasks.
  - name: Time Tracking
    description: Logging and auditing actual time spent on specific tasks.
  - name: Groups
    description: Logical categorization of tasks (e.g., by department or project phase).

security:
  - bearerAuth: []

paths:
  /tasks:
    get:
      tags: [Tasks]
      summary: Retrieve tasks with advanced filtering
      description: >
        Returns a list of tasks. Supports a universal 'filter' parameter, 
        sorting by any field, and pagination via limit/offset.
      parameters:
        - name: filter
          in: query
          description: >
            Universal filter string. Format: 'field:operator:value'. 
            Supports multiple filters separated by commas.
            Operators: eq (equal), neq (not equal), contains, gt, lt.
          schema:
            type: string
          example: "status:eq:In Progress,priority.main:eq:A"
        - name: sortBy
          in: query
          description: Field and direction for sorting.
          schema:
            type: string
          example: "deadline:asc"
        - name: limit
          in: query
          description: Maximum number of records to return.
          schema:
            type: integer
            default: 20
          example: 50
        - name: offset
          in: query
          description: Number of records to skip for pagination.
          schema:
            type: integer
            default: 0
          example: 0
      responses:
        '200':
          description: Successful retrieval of task list.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Task'
    post:
      tags: [Tasks]
      summary: Create a new task
      description: Initializes a new task or goal with the provided configuration.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TaskCreate'
      responses:
        '201':
          description: Task created successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Task'

  /tasks/{taskId}:
    parameters:
      - name: taskId
        in: path
        required: true
        description: Unique UUID of the task.
        schema:
          type: string
          format: uuid
        example: "550e8400-e29b-41d4-a716-446655440000"
    get:
      tags: [Tasks]
      summary: Fetch task by ID
      responses:
        '200':
          description: Detailed task object.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Task'
        '404':
          description: Task not found.
    put:
      tags: [Tasks]
      summary: Update task details
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TaskUpdate'
      responses:
        '200':
          description: Task updated.
        '404':
          description: Task not found.
    patch:
      tags: [Tasks]
      summary: Partially update task details
      description: Updates only the provided fields of a task, leaving all other fields unchanged.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TaskUpdate'
      responses:
        '200':
          description: Task updated.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Task'
        '404':
          description: Task not found.
    delete:
      tags: [Tasks]
      summary: Delete task
      responses:
        '204':
          description: Task removed.
        '404':
          description: Task not found.

  /tasks/unestimated:
    get:
      tags: [Tasks]
      summary: Identify unestimated tasks
      description: Returns tasks where 'estimation' has not been defined yet.
      responses:
        '200':
          description: List of unestimated tasks.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Task'

  /tasks/{taskId}/log-time:
    post:
      tags: [Time Tracking]
      summary: Log work session
      parameters:
        - name: taskId
          in: path
          required: true
          schema:
            type: string
            format: uuid
          example: "550e8400-e29b-41d4-a716-446655440000"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TimeLogEntry'
      responses:
        '201':
          description: Time logged.
        '404':
          description: Task not found.

  /goals:
    get:
      tags: [Goals]
      summary: List all goals
      description: >
        Returns a list of top-level goals (tasks with no parent goal).
        Supports sorting and pagination via limit/offset.
      parameters:
        - name: sortBy
          in: query
          description: Field and direction for sorting.
          schema:
            type: string
          example: "deadline:asc"
        - name: limit
          in: query
          description: Maximum number of records to return.
          schema:
            type: integer
            default: 20
          example: 50
        - name: offset
          in: query
          description: Number of records to skip for pagination.
          schema:
            type: integer
            default: 0
          example: 0
      responses:
        '200':
          description: Successful retrieval of goal list.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Task'
    post:
      tags: [Goals]
      summary: Create a new goal
      description: Initializes a new top-level goal. The goalId field is ignored – goals never have a parent.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GoalCreate'
      responses:
        '201':
          description: Goal created successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Task'
        '422':
          description: Validation error.

  /goals/{goalId}:
    parameters:
      - name: goalId
        in: path
        required: true
        description: Unique UUID of the goal.
        schema:
          type: string
          format: uuid
        example: "f47ac10b-58cc-4372-a567-0e02b2c3d479"
    get:
      tags: [Goals]
      summary: Fetch goal by ID
      responses:
        '200':
          description: Detailed goal object.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Task'
        '404':
          description: Goal not found.
    put:
      tags: [Goals]
      summary: Update goal details
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GoalCreate'
      responses:
        '200':
          description: Goal updated.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Task'
        '404':
          description: Goal not found.
    patch:
      tags: [Goals]
      summary: Partially update goal details
      description: Updates only the provided fields of a goal, leaving all other fields unchanged.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GoalCreate'
      responses:
        '200':
          description: Goal updated.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Task'
        '404':
          description: Goal not found.
    delete:
      tags: [Goals]
      summary: Delete goal
      responses:
        '204':
          description: Goal removed.
        '404':
          description: Goal not found.

  /tasks/{taskId}/subtasks:
    parameters:
      - name: taskId
        in: path
        required: true
        description: Unique UUID of the parent task.
        schema:
          type: string
          format: uuid
        example: "550e8400-e29b-41d4-a716-446655440000"
    get:
      tags: [Subtasks]
      summary: List subtasks for a task
      responses:
        '200':
          description: Array of subtasks belonging to the given task.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SubtaskDetail'
        '404':
          description: Task not found.
    post:
      tags: [Subtasks]
      summary: Create a subtask
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SubtaskCreate'
      responses:
        '201':
          description: Subtask created successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubtaskDetail'
        '404':
          description: Task not found.
        '422':
          description: Validation error.

  /tasks/{taskId}/subtasks/{subtaskId}:
    parameters:
      - name: taskId
        in: path
        required: true
        description: Unique UUID of the parent task.
        schema:
          type: string
          format: uuid
        example: "550e8400-e29b-41d4-a716-446655440000"
      - name: subtaskId
        in: path
        required: true
        description: Unique UUID of the subtask.
        schema:
          type: string
          format: uuid
        example: "7b43a91c-1234-4567-890a-bcdef1234567"
    get:
      tags: [Subtasks]
      summary: Fetch subtask by ID
      responses:
        '200':
          description: Detailed subtask object including checklist items.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubtaskDetail'
        '404':
          description: Subtask not found.
    put:
      tags: [Subtasks]
      summary: Update a subtask
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SubtaskCreate'
      responses:
        '200':
          description: Subtask updated.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubtaskDetail'
        '404':
          description: Subtask not found.
    patch:
      tags: [Subtasks]
      summary: Partially update a subtask
      description: Updates only the provided fields of a subtask, leaving all other fields unchanged.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SubtaskCreate'
      responses:
        '200':
          description: Subtask updated.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubtaskDetail'
        '404':
          description: Subtask not found.
    delete:
      tags: [Subtasks]
      summary: Delete a subtask
      responses:
        '204':
          description: Subtask removed.
        '404':
          description: Subtask not found.

  /customers:
    get:
      tags: [Customers]
      summary: List all customers
      responses:
        '200':
          description: Array of customers.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Customer'
    post:
      tags: [Customers]
      summary: Register a new customer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CustomerCreate'
      responses:
        '201':
          description: Customer registered.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Customer'

  /customers/{customerId}:
    parameters:
      - name: customerId
        in: path
        required: true
        description: Unique UUID of the customer.
        schema:
          type: string
          format: uuid
        example: "a39b4612-4291-49e3-827c-367f33d42012"
    get:
      tags: [Customers]
      summary: Get customer info
      responses:
        '200':
          description: Successful retrieval of customer details.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Customer'
        '404':
          description: Customer not found.
    put:
      tags: [Customers]
      summary: Update customer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CustomerCreate'
      responses:
        '200':
          description: Customer updated successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Customer'
        '404':
          description: Customer not found.
    patch:
      tags: [Customers]
      summary: Partially update customer
      description: Updates only the provided fields of a customer, leaving all other fields unchanged.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CustomerCreate'
      responses:
        '200':
          description: Customer updated successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Customer'
        '404':
          description: Customer not found.
    delete:
      tags: [Customers]
      summary: Remove customer
      responses:
        '204':
          description: Customer removed successfully.
        '404':
          description: Customer not found.

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: Authentication via JWT Bearer token.

  schemas:
    Task:
      type: object
      properties:
        id:
          type: string
          format: uuid
          example: "550e8400-e29b-41d4-a716-446655440000"
        title:
          type: string
          example: "Implement OAuth2 Authentication"
        description:
          type: string
          example: "Create a secure login flow using Google and GitHub providers."
        status:
          type: string
          example: "In Progress"
        priority:
          $ref: '#/components/schemas/Priority'
        goalId:
          type: string
          format: uuid
          nullable: true
          example: "f47ac10b-58cc-4372-a567-0e02b2c3d479"
        deadline:
          type: string
          format: date-time
          example: "2024-12-31T23:59:59Z"
        estimation:
          $ref: '#/components/schemas/Estimation'
        plannedTimeline:
          $ref: '#/components/schemas/Timeline'
        actualTimeline:
          type: object
          properties:
            startedAt:
              type: string
              format: date-time
              example: "2024-11-01T09:00:00Z"
            totalTimeLoggedMinutes:
              type: integer
              example: 180
        assigneeId:
          type: string
          example: "user_77"
        groups:
          type: array
          items:
            type: string
          example: ["Backend", "Security"]
        customerIds:
          type: array
          items:
            type: string
            format: uuid
          example: ["a39b4612-4291-49e3-827c-367f33d42012"]
        subtasks:
          type: array
          items:
            $ref: '#/components/schemas/Subtask'
        createdAt:
          type: string
          format: date-time
          example: "2024-10-25T14:30:00Z"
        updatedAt:
          type: string
          format: date-time
          example: "2024-11-01T12:00:00Z"

    TaskCreate:
      type: object
      required: [title, priority, status]
      properties:
        title:
          type: string
          example: "Design New Dashboard Layout"
        description:
          type: string
          example: "Prepare wireframes and high-fidelity mockups for the user homepage."
        status:
          type: string
          example: "New"
        priority:
          $ref: '#/components/schemas/Priority'
        goalId:
          type: string
          format: uuid
          nullable: true
          example: null
        deadline:
          type: string
          format: date-time
          example: "2024-11-15T17:00:00Z"
        estimation:
          $ref: '#/components/schemas/Estimation'
        plannedTimeline:
          $ref: '#/components/schemas/Timeline'
        groups:
          type: array
          items:
            type: string
          example: ["UI/UX"]
        customerIds:
          type: array
          items:
            type: string
            format: uuid
          example: ["a39b4612-4291-49e3-827c-367f33d42012"]
        assigneeId:
          type: string
          example: "designer_01"

    TaskUpdate:
      $ref: '#/components/schemas/TaskCreate'

    Customer:
      type: object
      properties:
        id:
          type: string
          format: uuid
          example: "a39b4612-4291-49e3-827c-367f33d42012"
        name:
          type: string
          example: "John Doe"
        email:
          type: string
          format: email
          example: "john.doe@acme-corp.com"
        companyName:
          type: string
          example: "Acme Corporation"
        createdAt:
          type: string
          format: date-time
          example: "2024-01-15T10:00:00Z"

    CustomerCreate:
      type: object
      required: [name]
      properties:
        name:
          type: string
          example: "Jane Smith"
        email:
          type: string
          format: email
          example: "jane.smith@globaltech.io"
        companyName:
          type: string
          example: "Global Tech Solutions"

    GoalCreate:
      type: object
      required: [title, priority, status]
      properties:
        title:
          type: string
          example: "Launch new product line"
        description:
          type: string
          example: "Full rollout plan for Q1 product launch."
        status:
          type: string
          example: "New"
        priority:
          $ref: '#/components/schemas/Priority'
        deadline:
          type: string
          format: date-time
          example: "2024-12-31T23:59:59Z"
        estimation:
          $ref: '#/components/schemas/Estimation'
        plannedTimeline:
          $ref: '#/components/schemas/Timeline'
        groups:
          type: array
          items:
            type: string
          example: ["Strategy"]
        customerIds:
          type: array
          items:
            type: string
            format: uuid
          example: ["a39b4612-4291-49e3-827c-367f33d42012"]
        assigneeId:
          type: string
          example: "manager_01"

    SubtaskDetail:
      type: object
      properties:
        id:
          type: string
          format: uuid
          example: "7b43a91c-1234-4567-890a-bcdef1234567"
        taskId:
          type: string
          format: uuid
          example: "550e8400-e29b-41d4-a716-446655440000"
        title:
          type: string
          example: "Database migration for user profiles"
        isCompleted:
          type: boolean
          example: false
        checklist:
          type: array
          items:
            $ref: '#/components/schemas/ChecklistItem'

    SubtaskCreate:
      type: object
      required: [title]
      properties:
        title:
          type: string
          example: "Write migration script"
        isCompleted:
          type: boolean
          example: false
        checklist:
          type: array
          items:
            $ref: '#/components/schemas/ChecklistItem'

    Subtask:
      type: object
      properties:
        id:
          type: string
          format: uuid
          example: "7b43a91c-1234-4567-890a-bcdef1234567"
        title:
          type: string
          example: "Database migration for user profiles"
        isCompleted:
          type: boolean
          example: false
        checklist:
          type: array
          items:
            $ref: '#/components/schemas/ChecklistItem'

    ChecklistItem:
      type: object
      properties:
        id:
          type: string
          example: "item_01"
        text:
          type: string
          example: "Write migration script"
        isDone:
          type: boolean
          example: true

    Priority:
      type: object
      required: [main, sub]
      properties:
        main:
          type: string
          enum: [A, B, C, D, E]
          description: >
            A: Very important, high consequences.
            B: Important, minor consequences.
            C: Optional, no consequences.
            D: Delegatable.
            E: Eliminate (waste of time).
          example: "A"
        sub:
          type: integer
          minimum: 1
          example: 1

    Estimation:
      type: object
      properties:
        value:
          type: number
          example: 5
        unit:
          type: string
          enum: [hours, days, months, story_points]
          example: "story_points"

    Timeline:
      type: object
      properties:
        plannedStartDate:
          type: string
          format: date
          example: "2024-11-01"
        plannedEndDate:
          type: string
          format: date
          example: "2024-11-07"

    TimeLogEntry:
      type: object
      required: [durationMinutes]
      properties:
        durationMinutes:
          type: integer
          example: 45
        note:
          type: string
          example: "Finished setting up the staging environment."
        loggedAt:
          type: string
          format: date-time
          example: "2024-11-02T16:45:00Z"