{
  "openapi": "3.1.1",
  "info": {
    "title": "ITLab.Template.Next.Api | v1",
    "version": "1.0.0"
  },
  "servers": [
    {
      "url": "http://localhost/"
    }
  ],
  "paths": {
    "/v1/orders": {
      "post": {
        "tags": [
          "Orders"
        ],
        "summary": "Creates a new order in Pending status.",
        "operationId": "CreateOrder",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateOrderCommand"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateOrderResponse"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Orders"
        ],
        "summary": "Lists paginated orders, with optional DSL filter.",
        "operationId": "ListOrders",
        "parameters": [
          {
            "name": "pageNumber",
            "in": "query",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "pageSize",
            "in": "query",
            "schema": {
              "pattern": "^-?(?:0|[1-9]\\d*)$",
              "type": [
                "integer",
                "string"
              ],
              "format": "int32"
            }
          },
          {
            "name": "orderBy",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "order",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/EOrderDirection"
            }
          },
          {
            "name": "filter",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "paginated",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaginatedListOfOrderSummaryResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/orders/{id}": {
      "get": {
        "tags": [
          "Orders"
        ],
        "summary": "Returns the order with the given identifier.",
        "operationId": "GetOrderById",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/orders/{id}/approve": {
      "patch": {
        "tags": [
          "Orders"
        ],
        "summary": "Transitions the order from Pending to Approved.",
        "operationId": "ApproveOrder",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          }
        }
      }
    },
    "/v1/auth/session": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Validates credentials and starts a BFF session (HttpOnly cookie).",
        "operationId": "LoginSession",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LoginSessionCommand"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthenticatedUser"
                }
              }
            }
          }
        }
      }
    },
    "/v1/auth/session/refresh": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Re-issues the session cookie with the user's current roles.",
        "operationId": "RefreshSession",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthenticatedUser"
                }
              }
            }
          }
        }
      }
    },
    "/v1/auth/session/logout": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Clears the BFF session cookie.",
        "operationId": "LogoutSession",
        "responses": {
          "204": {
            "description": "No Content"
          }
        }
      }
    },
    "/v1/auth/me": {
      "get": {
        "tags": [
          "Authentication"
        ],
        "summary": "Returns the current authenticated user (id, name, roles) for the SPA to gate UI.",
        "operationId": "CurrentUser",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CurrentUserResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/auth/csrf": {
      "get": {
        "tags": [
          "Authentication"
        ],
        "summary": "Issues an antiforgery token; echo it in the X-XSRF-TOKEN header on cookie writes.",
        "operationId": "Antiforgery",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CsrfTokenResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/auth/token": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Validates credentials and issues a Bearer access + refresh token (mobile/native).",
        "operationId": "IssueToken",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TokenLoginCommand"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TokenPair"
                }
              }
            }
          }
        }
      }
    },
    "/v1/auth/token/refresh": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Rotates a refresh token, returning a new Bearer token pair.",
        "operationId": "RefreshToken",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RefreshTokenCommand"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TokenPair"
                }
              }
            }
          }
        }
      }
    },
    "/v1/auth/clients/token": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "summary": "Client-credentials grant: exchanges client id/secret for a service access token.",
        "operationId": "IssueClientToken",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ClientTokenCommand"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServiceAccessToken"
                }
              }
            }
          }
        }
      }
    },
    "/.well-known/jwks.json": {
      "get": {
        "tags": [
          "ITLab.Template.Next.Api"
        ],
        "summary": "JSON Web Key Set",
        "operationId": "Jwks",
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "AuthenticatedUser": {
        "required": [
          "id",
          "userName",
          "email",
          "roles"
        ],
        "type": "object",
        "properties": {
          "id": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "userName": {
            "type": "string"
          },
          "email": {
            "type": "string"
          },
          "roles": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "ClientTokenCommand": {
        "required": [
          "clientId",
          "clientSecret"
        ],
        "type": "object",
        "properties": {
          "clientId": {
            "type": "string"
          },
          "clientSecret": {
            "type": "string"
          }
        }
      },
      "CreateOrderCommand": {
        "required": [
          "customer",
          "total"
        ],
        "type": "object",
        "properties": {
          "customer": {
            "type": "string"
          },
          "total": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          }
        }
      },
      "CreateOrderResponse": {
        "required": [
          "id"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          }
        }
      },
      "CsrfTokenResponse": {
        "required": [
          "token"
        ],
        "type": "object",
        "properties": {
          "token": {
            "type": "string"
          }
        }
      },
      "CurrentUserResponse": {
        "required": [
          "id",
          "userName",
          "roles"
        ],
        "type": "object",
        "properties": {
          "id": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "userName": {
            "type": "string"
          },
          "roles": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "EOrderDirection": {
        "type": "integer"
      },
      "EOrderStatus": {
        "type": "integer"
      },
      "LoginSessionCommand": {
        "required": [
          "email",
          "password"
        ],
        "type": "object",
        "properties": {
          "email": {
            "type": "string"
          },
          "password": {
            "type": "string"
          }
        }
      },
      "OrderResponse": {
        "required": [
          "id",
          "customer",
          "total",
          "status",
          "createdAtUtc",
          "createdAtTimeZone",
          "updatedAtUtc",
          "updatedAtTimeZone",
          "createdBy",
          "modifiedBy"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "customer": {
            "type": "string"
          },
          "total": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          },
          "status": {
            "$ref": "#/components/schemas/EOrderStatus"
          },
          "createdAtUtc": {
            "type": "string",
            "format": "date-time"
          },
          "createdAtTimeZone": {
            "type": [
              "null",
              "string"
            ]
          },
          "updatedAtUtc": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "updatedAtTimeZone": {
            "type": [
              "null",
              "string"
            ]
          },
          "createdBy": {
            "type": [
              "null",
              "string"
            ]
          },
          "modifiedBy": {
            "type": [
              "null",
              "string"
            ]
          }
        }
      },
      "OrderSummaryResponse": {
        "required": [
          "id",
          "customer",
          "total",
          "status",
          "createdAtUtc"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "customer": {
            "type": "string"
          },
          "total": {
            "pattern": "^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$",
            "type": [
              "number",
              "string"
            ],
            "format": "double"
          },
          "status": {
            "$ref": "#/components/schemas/EOrderStatus"
          },
          "createdAtUtc": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "PaginatedListOfOrderSummaryResponse": {
        "required": [
          "items",
          "pageNumber",
          "totalPages"
        ],
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OrderSummaryResponse"
            }
          },
          "pageNumber": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "totalPages": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "totalCount": {
            "pattern": "^-?(?:0|[1-9]\\d*)$",
            "type": [
              "integer",
              "string"
            ],
            "format": "int32"
          },
          "hasPreviousPage": {
            "type": "boolean"
          },
          "hasNextPage": {
            "type": "boolean"
          }
        }
      },
      "RefreshTokenCommand": {
        "required": [
          "refreshToken"
        ],
        "type": "object",
        "properties": {
          "refreshToken": {
            "type": "string"
          }
        }
      },
      "ServiceAccessToken": {
        "required": [
          "accessToken",
          "expiresAt"
        ],
        "type": "object",
        "properties": {
          "accessToken": {
            "type": "string"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "TokenLoginCommand": {
        "required": [
          "email",
          "password"
        ],
        "type": "object",
        "properties": {
          "email": {
            "type": "string"
          },
          "password": {
            "type": "string"
          }
        }
      },
      "TokenPair": {
        "required": [
          "accessToken",
          "accessTokenExpiresAt",
          "refreshToken"
        ],
        "type": "object",
        "properties": {
          "accessToken": {
            "type": "string"
          },
          "accessTokenExpiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "refreshToken": {
            "type": "string"
          }
        }
      }
    },
    "securitySchemes": {
      "Bearer": {
        "type": "http",
        "description": "Bearer token issued by the IdP configured in Authentication:Jwt:Authority. Click Authorize and paste the raw token (no 'Bearer ' prefix).",
        "scheme": "bearer",
        "bearerFormat": "JWT"
      }
    }
  },
  "security": [
    {
      "Bearer": [ ]
    }
  ],
  "tags": [
    {
      "name": "Orders"
    },
    {
      "name": "Authentication"
    },
    {
      "name": "ITLab.Template.Next.Api"
    }
  ]
}