openapi: 3.0.3
info:
  title: Feature MVC Template API
  version: 1.0.0
  description: API contract for the modular feature-based MVC template.
servers:
  - url: /api/v1
paths:
  /auth/me:
    get:
      summary: Return the current authenticated user
      tags: [Auth]
      responses:
        "200":
          description: Current user payload
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiResponse"
  /modules:
    get:
      summary: List registered modules
      tags: [System]
      responses:
        "200":
          description: Module list
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiResponse"
        "401":
          description: Unauthenticated
        "403":
          description: Forbidden
  /module-toggle:
    post:
      summary: Enable or disable a module
      tags: [System]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [module, enabled]
              properties:
                module:
                  type: string
                enabled:
                  type: boolean
      responses:
        "200":
          description: Module status updated
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiResponse"
        "401":
          description: Unauthenticated
        "403":
          description: Forbidden
  /modules/migrate:
    post:
      summary: Run pending migrations for one module
      tags: [System]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [module]
              properties:
                module:
                  type: string
      responses:
        "200":
          description: Migration result
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiResponse"
        "401":
          description: Unauthenticated
        "403":
          description: Forbidden
  /system/events:
    get:
      summary: Inspect registered EventBus listeners
      tags: [System]
      responses:
        "200":
          description: Event listener counts by event name
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiResponse"
        "401":
          description: Unauthenticated
        "403":
          description: Forbidden
  /tasks:
    get:
      summary: List tasks
      tags: [Tasks]
      responses:
        "200":
          description: Task list
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiResponse"
    post:
      summary: Create a task
      tags: [Tasks]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [title]
              properties:
                title:
                  type: string
      responses:
        "201":
          description: Task created
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiResponse"
  /tasks/toggle:
    post:
      summary: Toggle task completion
      tags: [Tasks]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [id]
              properties:
                id:
                  type: integer
      responses:
        "200":
          description: Task updated
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiResponse"
  /tasks/delete:
    post:
      summary: Delete a task
      tags: [Tasks]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [id]
              properties:
                id:
                  type: integer
      responses:
        "200":
          description: Task deleted
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiResponse"
  /files/tree:
    get:
      summary: List files in a safe project directory
      tags: [Files]
      parameters:
        - in: query
          name: path
          schema:
            type: string
      responses:
        "200":
          description: File tree
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiResponse"
  /files/read:
    get:
      summary: Read an editable text file
      tags: [Files]
      parameters:
        - in: query
          name: path
          schema:
            type: string
      responses:
        "200":
          description: File content
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiResponse"
  /files/save:
    post:
      summary: Save an editable text file
      tags: [Files]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [path, content]
              properties:
                path:
                  type: string
                content:
                  type: string
      responses:
        "200":
          description: File saved
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiResponse"
  /files/create-file:
    post:
      summary: Create an editable file in a safe project directory
      tags: [Files]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/FileCreateRequest"
      responses:
        "200":
          description: File created
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiResponse"
  /files/create-directory:
    post:
      summary: Create a directory in a safe project directory
      tags: [Files]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/FileCreateRequest"
      responses:
        "200":
          description: Directory created
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiResponse"
  /files/delete:
    post:
      summary: Delete a file or directory inside the project root
      tags: [Files]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/FilePathRequest"
      responses:
        "200":
          description: Path deleted
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiResponse"
  /files/rename:
    post:
      summary: Rename a file or directory inside the project root
      tags: [Files]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              allOf:
                - $ref: "#/components/schemas/FilePathRequest"
                - type: object
                  required: [name]
                  properties:
                    name:
                      type: string
      responses:
        "200":
          description: Path renamed
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiResponse"
  /files/move:
    post:
      summary: Move a file or directory inside the project root
      tags: [Files]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/FileTransferRequest"
      responses:
        "200":
          description: Path moved
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiResponse"
  /files/copy:
    post:
      summary: Copy a file or directory inside the project root
      tags: [Files]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/FileTransferRequest"
      responses:
        "200":
          description: Path copied
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiResponse"
  /files/upload:
    post:
      summary: Upload one or more files into a safe project directory
      tags: [Files]
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required: [directory, files]
              properties:
                directory:
                  type: string
                files:
                  type: array
                  items:
                    type: string
                    format: binary
      responses:
        "200":
          description: Files uploaded
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiResponse"
  /buyer-stats/summary:
    get:
      summary: Return buyer statistics summary
      tags: [BuyerStats]
      responses:
        "200":
          description: Buyer statistics summary
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiResponse"
        "401":
          description: Unauthenticated
        "403":
          description: Forbidden
  /buyer-stats/products:
    get:
      summary: List buyer statistics products
      tags: [BuyerStats]
      responses:
        "200":
          description: Product list
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiResponse"
    post:
      summary: Create a buyer statistics product
      tags: [BuyerStats]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [title]
              properties:
                crm_id:
                  type: string
                  nullable: true
                title:
                  type: string
                status:
                  type: string
                  enum: [draft, active, archived]
      responses:
        "201":
          description: Product created
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiResponse"
  /buyer-stats/products/delete:
    post:
      summary: Delete a buyer statistics product
      tags: [BuyerStats]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [id]
              properties:
                id:
                  type: integer
      responses:
        "200":
          description: Product deleted
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiResponse"
  /buyer-stats/settings:
    get:
      summary: Return buyer statistics settings and sources
      tags: [BuyerStats]
      responses:
        "200":
          description: Settings and configured sources
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiResponse"
components:
  schemas:
    FileCreateRequest:
      type: object
      required: [directory, name]
      properties:
        directory:
          type: string
        name:
          type: string
    FilePathRequest:
      type: object
      required: [path]
      properties:
        path:
          type: string
    FileTransferRequest:
      allOf:
        - $ref: "#/components/schemas/FilePathRequest"
        - type: object
          required: [directory]
          properties:
            directory:
              type: string
    ApiResponse:
      type: object
      required: [success, data, error]
      properties:
        success:
          type: boolean
        data:
          nullable: true
        error:
          nullable: true
          type: object
          properties:
            code:
              type: string
            message:
              type: string
