{
  "openapi": "3.1.0",
  "info": {
    "title": "GeneXus.Programs API",
    "version": "0.1.0",
    "description": "REST contract for the AjaxSample business app: Countries, Cities, Clients, Products and Invoices. CRUD plus paginated grids. Write operations return { success, messages }."
  },
  "servers": [{ "url": "/api" }],
  "paths": {
    "/wwcountry/grid": {
      "get": {
        "summary": "List countries (paginated)",
        "tags": ["Country"],
        "parameters": [
          { "$ref": "#/components/parameters/firstRecord" },
          { "$ref": "#/components/parameters/pageSize" }
        ],
        "responses": { "200": { "description": "Page of countries", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CountryGrid" } } } } }
      }
    },
    "/country": {
      "post": {
        "summary": "Create a country",
        "tags": ["Country"],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Country" } } } },
        "responses": { "200": { "$ref": "#/components/responses/Event" } }
      }
    },
    "/country/{countryId}": {
      "parameters": [{ "name": "countryId", "in": "path", "required": true, "schema": { "type": "integer" } }],
      "get": { "summary": "Get a country", "tags": ["Country"], "responses": { "200": { "description": "Country", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Country" } } } } } },
      "put": { "summary": "Update a country", "tags": ["Country"], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Country" } } } }, "responses": { "200": { "$ref": "#/components/responses/Event" } } },
      "delete": { "summary": "Delete a country", "tags": ["Country"], "responses": { "200": { "$ref": "#/components/responses/Event" } } }
    },

    "/wwcity/grid": {
      "get": {
        "summary": "List cities (paginated)",
        "tags": ["City"],
        "parameters": [
          { "$ref": "#/components/parameters/firstRecord" },
          { "$ref": "#/components/parameters/pageSize" }
        ],
        "responses": { "200": { "description": "Page of cities", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CityGrid" } } } } }
      }
    },
    "/city": {
      "post": {
        "summary": "Create a city",
        "tags": ["City"],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/City" } } } },
        "responses": { "200": { "$ref": "#/components/responses/Event" } }
      }
    },
    "/city/{countryId}/{cityId}": {
      "parameters": [
        { "name": "countryId", "in": "path", "required": true, "schema": { "type": "integer" } },
        { "name": "cityId", "in": "path", "required": true, "schema": { "type": "integer" } }
      ],
      "get": { "summary": "Get a city", "tags": ["City"], "responses": { "200": { "description": "City", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/City" } } } } } },
      "put": { "summary": "Update a city", "tags": ["City"], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/City" } } } }, "responses": { "200": { "$ref": "#/components/responses/Event" } } },
      "delete": { "summary": "Delete a city", "tags": ["City"], "responses": { "200": { "$ref": "#/components/responses/Event" } } }
    },

    "/wwclient/grid": {
      "get": {
        "summary": "List clients (paginated)",
        "tags": ["Client"],
        "parameters": [
          { "$ref": "#/components/parameters/firstRecord" },
          { "$ref": "#/components/parameters/pageSize" }
        ],
        "responses": { "200": { "description": "Page of clients", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ClientGrid" } } } } }
      }
    },
    "/client": {
      "post": {
        "summary": "Create a client",
        "tags": ["Client"],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Client" } } } },
        "responses": { "200": { "$ref": "#/components/responses/Event" } }
      }
    },
    "/client/{clientId}": {
      "parameters": [{ "name": "clientId", "in": "path", "required": true, "schema": { "type": "integer" } }],
      "get": { "summary": "Get a client", "tags": ["Client"], "responses": { "200": { "description": "Client", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Client" } } } } } },
      "put": { "summary": "Update a client", "tags": ["Client"], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Client" } } } }, "responses": { "200": { "$ref": "#/components/responses/Event" } } },
      "delete": { "summary": "Delete a client", "tags": ["Client"], "responses": { "200": { "$ref": "#/components/responses/Event" } } }
    },

    "/wwproduct/grid": {
      "get": {
        "summary": "List products (paginated)",
        "tags": ["Product"],
        "parameters": [
          { "$ref": "#/components/parameters/firstRecord" },
          { "$ref": "#/components/parameters/pageSize" }
        ],
        "responses": { "200": { "description": "Page of products", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProductGrid" } } } } }
      }
    },
    "/product": {
      "post": {
        "summary": "Create a product",
        "tags": ["Product"],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Product" } } } },
        "responses": { "200": { "$ref": "#/components/responses/Event" } }
      }
    },
    "/product/{productId}": {
      "parameters": [{ "name": "productId", "in": "path", "required": true, "schema": { "type": "integer" } }],
      "get": { "summary": "Get a product", "tags": ["Product"], "responses": { "200": { "description": "Product", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Product" } } } } } },
      "put": { "summary": "Update a product", "tags": ["Product"], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Product" } } } }, "responses": { "200": { "$ref": "#/components/responses/Event" } } },
      "delete": { "summary": "Delete a product", "tags": ["Product"], "responses": { "200": { "$ref": "#/components/responses/Event" } } }
    },

    "/wwinvoice/grid": {
      "get": {
        "summary": "List invoices (paginated)",
        "tags": ["Invoice"],
        "parameters": [
          { "$ref": "#/components/parameters/firstRecord" },
          { "$ref": "#/components/parameters/pageSize" }
        ],
        "responses": { "200": { "description": "Page of invoices", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/InvoiceGrid" } } } } }
      }
    },
    "/invoice": {
      "post": {
        "summary": "Create an invoice",
        "tags": ["Invoice"],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Invoice" } } } },
        "responses": { "200": { "$ref": "#/components/responses/Event" } }
      }
    },
    "/invoice/{invoiceId}": {
      "parameters": [{ "name": "invoiceId", "in": "path", "required": true, "schema": { "type": "integer" } }],
      "get": { "summary": "Get an invoice", "tags": ["Invoice"], "responses": { "200": { "description": "Invoice", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Invoice" } } } } } },
      "put": { "summary": "Update an invoice", "tags": ["Invoice"], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Invoice" } } } }, "responses": { "200": { "$ref": "#/components/responses/Event" } } },
      "delete": { "summary": "Delete an invoice", "tags": ["Invoice"], "responses": { "200": { "$ref": "#/components/responses/Event" } } }
    }
  },
  "components": {
    "parameters": {
      "firstRecord": { "name": "firstRecord", "in": "query", "schema": { "type": "integer", "default": 0 }, "description": "Zero-based offset of the first row" },
      "pageSize": { "name": "pageSize", "in": "query", "schema": { "type": "integer", "default": 20 }, "description": "Rows per page" }
    },
    "responses": {
      "Event": { "description": "Result of a write operation", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EventResponse" } } } }
    },
    "schemas": {
      "EventResponse": {
        "type": "object",
        "properties": {
          "success": { "type": "boolean" },
          "messages": { "type": "array", "items": { "type": "string" } }
        },
        "required": ["success"]
      },
      "GridEnvelope": {
        "type": "object",
        "properties": {
          "eof": { "type": "integer" },
          "firstRecord": { "type": "integer" },
          "pageSize": { "type": "integer" }
        }
      },
      "Country": {
        "type": "object",
        "properties": {
          "countryId": { "type": "integer" },
          "countryName": { "type": "string" }
        },
        "required": ["countryId", "countryName"]
      },
      "City": {
        "type": "object",
        "properties": {
          "countryId": { "type": "integer" },
          "cityId": { "type": "integer" },
          "countryName": { "type": "string" },
          "cityName": { "type": "string" }
        },
        "required": ["countryId", "cityId", "cityName"]
      },
      "Client": {
        "type": "object",
        "properties": {
          "clientId": { "type": "integer" },
          "clientFirstName": { "type": "string" },
          "clientLastName": { "type": "string" },
          "countryId": { "type": "integer" },
          "countryName": { "type": "string" },
          "cityId": { "type": "integer" },
          "cityName": { "type": "string" },
          "clientAddress": { "type": "string" },
          "clientBalance": { "type": "number" },
          "clientLogo": { "type": "string" }
        },
        "required": ["clientId", "clientFirstName", "clientLastName"]
      },
      "Product": {
        "type": "object",
        "properties": {
          "productId": { "type": "integer" },
          "productName": { "type": "string" },
          "productPrice": { "type": "number" },
          "productStock": { "type": "integer" }
        },
        "required": ["productId", "productName"]
      },
      "InvoiceLine": {
        "type": "object",
        "properties": {
          "invoiceLineId": { "type": "integer" },
          "productId": { "type": "integer" },
          "productName": { "type": "string" },
          "productStock": { "type": "number" },
          "productPrice": { "type": "number" },
          "invoiceLineQty": { "type": "number" },
          "invoiceLineAmount": { "type": "number" }
        }
      },
      "Invoice": {
        "type": "object",
        "properties": {
          "invoiceId": { "type": "integer" },
          "invoiceDate": { "type": "string", "format": "date" },
          "invoiceDescription": { "type": "string" },
          "clientId": { "type": "integer" },
          "clientFirstName": { "type": "string" },
          "clientBalance": { "type": "number" },
          "clientAddress": { "type": "string" },
          "invoiceLatestLine": { "type": "number" },
          "invoiceSubTotal": { "type": "number" },
          "invoiceTaxes": { "type": "number" },
          "invoiceTotal": { "type": "number" },
          "lines": { "type": "array", "items": { "$ref": "#/components/schemas/InvoiceLine" } }
        },
        "required": ["invoiceId", "clientId"]
      },
      "CountryGrid": {
        "allOf": [
          { "$ref": "#/components/schemas/GridEnvelope" },
          { "type": "object", "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/Country" } } } }
        ]
      },
      "CityGrid": {
        "allOf": [
          { "$ref": "#/components/schemas/GridEnvelope" },
          { "type": "object", "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/City" } } } }
        ]
      },
      "ClientGrid": {
        "allOf": [
          { "$ref": "#/components/schemas/GridEnvelope" },
          { "type": "object", "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/Client" } } } }
        ]
      },
      "ProductGrid": {
        "allOf": [
          { "$ref": "#/components/schemas/GridEnvelope" },
          { "type": "object", "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/Product" } } } }
        ]
      },
      "InvoiceGrid": {
        "allOf": [
          { "$ref": "#/components/schemas/GridEnvelope" },
          { "type": "object", "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/Invoice" } } } }
        ]
      }
    }
  }
}
