{
  "openapi": "3.0.3",
  "info": {
    "title": "Master Vendor API",
    "version": "1.0.0",
    "description": "Public API reference for Master Vendor SSO and app user synchronization."
  },
  "servers": [
    {
      "url": "https://vendor.ilectraev.com"
    }
  ],
  "paths": {
    "/healthz": {
      "get": {
        "summary": "Health check",
        "responses": {
          "200": {
            "description": "Service is healthy",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HealthResponse"
                }
              }
            }
          }
        }
      }
    },
    "/.well-known/openid-configuration": {
      "get": {
        "summary": "OpenID configuration",
        "responses": {
          "200": {
            "description": "OIDC discovery metadata"
          }
        }
      }
    },
    "/oauth/authorize": {
      "get": {
        "summary": "Start OAuth authorization",
        "parameters": [
          {
            "name": "response_type",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "enum": ["code"]
            }
          },
          {
            "name": "client_id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "redirect_uri",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uri"
            }
          },
          {
            "name": "scope",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "example": "openid email profile"
            }
          },
          {
            "name": "state",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "code_challenge",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "code_challenge_method",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": ["S256"],
              "default": "S256"
            }
          }
        ],
        "responses": {
          "302": {
            "description": "Redirects to login or back to the app callback"
          },
          "400": {
            "description": "Invalid authorize request, client, or redirect_uri"
          }
        }
      }
    },
    "/oauth/token": {
      "post": {
        "summary": "Exchange authorization code for access token",
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "$ref": "#/components/schemas/TokenRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Access token response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TokenResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid grant, code, redirect_uri, or PKCE verifier"
          },
          "401": {
            "description": "Invalid client"
          }
        }
      }
    },
    "/oauth/userinfo": {
      "get": {
        "summary": "Current logged-in user info",
        "responses": {
          "200": {
            "description": "User info",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserInfoResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        }
      }
    },
    "/oauth/jwks": {
      "get": {
        "summary": "JSON Web Key Set",
        "responses": {
          "200": {
            "description": "JWKS used to verify RS256 access tokens"
          }
        }
      }
    },
    "/api/apps/{app_id}/users/sync": {
      "post": {
        "summary": "Create or update a mapped app user",
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "app_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SyncUserRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "User synchronized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SyncUserResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid JSON"
          },
          "401": {
            "description": "Invalid app credential"
          }
        }
      }
    },
    "/api/apps/{app_id}/users/disable": {
      "post": {
        "summary": "Disable a mapped app user",
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "app_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DisableUserRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "User disabled",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DisableUserResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid JSON"
          },
          "401": {
            "description": "Invalid app credential"
          },
          "404": {
            "description": "Mapped user not found"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "basicAuth": {
        "type": "http",
        "scheme": "basic"
      }
    },
    "schemas": {
      "HealthResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "example": "ok"
          }
        }
      },
      "TokenRequest": {
        "type": "object",
        "required": ["grant_type", "client_id", "client_secret", "code", "redirect_uri", "code_verifier"],
        "properties": {
          "grant_type": {
            "type": "string",
            "enum": ["authorization_code"]
          },
          "client_id": {
            "type": "string"
          },
          "client_secret": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "redirect_uri": {
            "type": "string",
            "format": "uri"
          },
          "code_verifier": {
            "type": "string"
          }
        }
      },
      "TokenResponse": {
        "type": "object",
        "properties": {
          "access_token": {
            "type": "string"
          },
          "token_type": {
            "type": "string",
            "example": "Bearer"
          },
          "expires_in": {
            "type": "integer",
            "example": 900
          }
        }
      },
      "UserInfoResponse": {
        "type": "object",
        "properties": {
          "sub": {
            "type": "string",
            "example": "1"
          },
          "email": {
            "type": "string",
            "format": "email"
          }
        }
      },
      "SyncUserRequest": {
        "type": "object",
        "required": ["email", "password", "external_user_id"],
        "properties": {
          "email": {
            "type": "string",
            "format": "email"
          },
          "password": {
            "type": "string"
          },
          "external_user_id": {
            "type": "string"
          }
        }
      },
      "SyncUserResponse": {
        "type": "object",
        "properties": {
          "identity_id": {
            "type": "integer"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "app_id": {
            "type": "string"
          },
          "external_user_id": {
            "type": "string"
          }
        }
      },
      "DisableUserRequest": {
        "type": "object",
        "required": ["external_user_id"],
        "properties": {
          "external_user_id": {
            "type": "string"
          }
        }
      },
      "DisableUserResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "example": "disabled"
          }
        }
      }
    }
  }
}
