{
  "openapi": "3.0.3",
  "info": {
    "title": "Sovelis Enterprise Data Movement Platform API",
    "description": "Production-ready REST API specification for Sovelis Enterprise Data Movement Platform. Includes multi-tenant isolation, 3-role RBAC, idempotent mutations, async job queues, and standardized SVL error codes.",
    "version": "1.0.0",
    "contact": {
      "name": "Sovelis Engineering & Architecture Team",
      "url": "https://sovelis.io"
    }
  },
  "servers": [
    {
      "url": "/api/v1",
      "description": "Sovelis API v1 Gateway"
    }
  ],
  "components": {
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "Token",
        "description": "Provide personal access token prefixed with 'Bearer '"
      }
    },
    "schemas": {
      "StandardResponseEnvelope": {
        "type": "object",
        "properties": {
          "success": { "type": "boolean", "example": true },
          "data": { "type": "object" },
          "request_id": { "type": "string", "format": "uuid", "example": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d" },
          "timestamp": { "type": "string", "format": "date-time", "example": "2026-08-10T10:00:00Z" }
        }
      },
      "StandardErrorEnvelope": {
        "type": "object",
        "properties": {
          "success": { "type": "boolean", "example": false },
          "error": {
            "type": "object",
            "properties": {
              "code": { "type": "string", "example": "SVL-4001" },
              "message": { "type": "string", "example": "Permission denied." },
              "details": { "type": "object" }
            }
          },
          "request_id": { "type": "string", "format": "uuid", "example": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d" },
          "timestamp": { "type": "string", "format": "date-time", "example": "2026-08-10T10:00:00Z" }
        }
      },
      "Project": {
        "type": "object",
        "properties": {
          "id": { "type": "integer", "example": 1 },
          "organization_id": { "type": "integer", "example": 1 },
          "name": { "type": "string", "example": "Zendesk to Freshdesk Migration" },
          "slug": { "type": "string", "example": "zendesk-to-freshdesk" },
          "description": { "type": "string", "example": "Production migration of support tickets" },
          "status": { "type": "string", "enum": ["active", "archived", "completed"], "example": "active" },
          "is_pinned": { "type": "boolean", "example": true },
          "connections_count": { "type": "integer", "example": 2 },
          "migration_jobs_count": { "type": "integer", "example": 1 },
          "created_at": { "type": "string", "format": "date-time" },
          "updated_at": { "type": "string", "format": "date-time" }
        }
      },
      "Connection": {
        "type": "object",
        "properties": {
          "id": { "type": "integer", "example": 1 },
          "name": { "type": "string", "example": "Production Zendesk Source" },
          "connector_id": { "type": "string", "example": "zendesk" },
          "type": { "type": "string", "enum": ["source", "destination", "bidirectional"], "example": "source" },
          "auth_type": { "type": "string", "enum": ["api_key", "oauth2", "basic"], "example": "api_key" },
          "masked_credentials": {
            "type": "object",
            "properties": {
              "api_key": { "type": "string", "example": "adm********9f2" }
            }
          },
          "status": { "type": "string", "enum": ["connected", "disconnected", "error", "untested"], "example": "connected" },
          "last_tested_at": { "type": "string", "format": "date-time" }
        }
      },
      "MigrationJob": {
        "type": "object",
        "properties": {
          "id": { "type": "integer", "example": 1 },
          "name": { "type": "string", "example": "Zendesk Support History 2025" },
          "status": { "type": "string", "enum": ["pending", "analyzing", "queued", "running", "paused", "completed", "failed", "cancelled"], "example": "running" },
          "progress_percentage": { "type": "number", "format": "float", "example": 64.5 },
          "total_records": { "type": "integer", "example": 10000 },
          "processed_records": { "type": "integer", "example": 6450 },
          "successful_records": { "type": "integer", "example": 6400 },
          "failed_records": { "type": "integer", "example": 50 },
          "health_score": { "type": "integer", "example": 98 }
        }
      },
      "CreditWallet": {
        "type": "object",
        "properties": {
          "id": { "type": "integer", "example": 1 },
          "organization_id": { "type": "integer", "example": 1 },
          "balance": { "type": "integer", "example": 25000 },
          "allocated_credits": { "type": "integer", "example": 30000 },
          "consumed_credits": { "type": "integer", "example": 5000 },
          "is_locked": { "type": "boolean", "example": false }
        }
      }
    }
  },
  "paths": {
    "/auth/login": {
      "post": {
        "summary": "Authenticate User & Issue API Token",
        "tags": ["Authentication"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["email", "password"],
                "properties": {
                  "email": { "type": "string", "format": "email", "example": "admin@acme.com" },
                  "password": { "type": "string", "format": "password", "example": "Secret123!" }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Authenticated successfully" },
          "401": { "description": "Invalid credentials (SVL-1002)" }
        }
      }
    },
    "/auth/register": {
      "post": {
        "summary": "Register Organization & Admin Account",
        "tags": ["Authentication"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["organization_name", "name", "email", "password"],
                "properties": {
                  "organization_name": { "type": "string", "example": "Acme Corp" },
                  "name": { "type": "string", "example": "John Doe" },
                  "email": { "type": "string", "format": "email", "example": "john@acme.com" },
                  "password": { "type": "string", "min": 8, "example": "StrongPass123!" }
                }
              }
            }
          }
        },
        "responses": {
          "201": { "description": "Organization created" },
          "422": { "description": "Validation error (SVL-3002)" }
        }
      }
    },
    "/projects": {
      "get": {
        "summary": "List Organization Projects",
        "security": [{ "BearerAuth": [] }],
        "tags": ["Projects"],
        "responses": {
          "200": { "description": "Paginated list of projects" }
        }
      },
      "post": {
        "summary": "Create Project",
        "security": [{ "BearerAuth": [] }],
        "tags": ["Projects"],
        "parameters": [
          { "name": "Idempotency-Key", "in": "header", "schema": { "type": "string" } }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["name"],
                "properties": {
                  "name": { "type": "string", "example": "Zendesk to Freshdesk" },
                  "description": { "type": "string", "example": "Production migration" },
                  "is_pinned": { "type": "boolean", "example": true }
                }
              }
            }
          }
        },
        "responses": {
          "201": { "description": "Project created" }
        }
      }
    },
    "/connections": {
      "get": {
        "summary": "List SaaS Connections",
        "security": [{ "BearerAuth": [] }],
        "tags": ["Connections"],
        "responses": { "200": { "description": "Paginated connections" } }
      },
      "post": {
        "summary": "Create SaaS Connection",
        "security": [{ "BearerAuth": [] }],
        "tags": ["Connections"],
        "parameters": [
          { "name": "Idempotency-Key", "in": "header", "schema": { "type": "string" } }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["name", "connector_id", "credentials"],
                "properties": {
                  "name": { "type": "string", "example": "Source Zendesk" },
                  "connector_id": { "type": "string", "example": "zendesk" },
                  "type": { "type": "string", "enum": ["source", "destination"], "example": "source" },
                  "credentials": { "type": "object", "example": { "subdomain": "acme", "api_key": "secret123" } }
                }
              }
            }
          }
        },
        "responses": { "201": { "description": "Connection created" } }
      }
    },
    "/connections/{id}/test": {
      "post": {
        "summary": "Test Connection Connectivity",
        "security": [{ "BearerAuth": [] }],
        "tags": ["Connections"],
        "parameters": [
          { "name": "id", "in": "path", "required": true, "schema": { "type": "integer" } }
        ],
        "responses": {
          "200": { "description": "Connection test completed" },
          "422": { "description": "Connection failed (SVL-1001)" }
        }
      }
    },
    "/migrations": {
      "get": {
        "summary": "List Migration Jobs",
        "security": [{ "BearerAuth": [] }],
        "tags": ["Migrations"],
        "responses": { "200": { "description": "Paginated migrations" } }
      },
      "post": {
        "summary": "Create Migration Job",
        "security": [{ "BearerAuth": [] }],
        "tags": ["Migrations"],
        "parameters": [
          { "name": "Idempotency-Key", "in": "header", "schema": { "type": "string" } }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["project_id", "source_connection_id", "destination_connection_id", "name"],
                "properties": {
                  "project_id": { "type": "integer", "example": 1 },
                  "source_connection_id": { "type": "integer", "example": 1 },
                  "destination_connection_id": { "type": "integer", "example": 2 },
                  "name": { "type": "string", "example": "Full Ticket History 2025" }
                }
              }
            }
          }
        },
        "responses": { "201": { "description": "Migration created" } }
      }
    },
    "/migrations/{id}/start": {
      "post": {
        "summary": "Start Migration (Dispatches Async Queue Job)",
        "security": [{ "BearerAuth": [] }],
        "tags": ["Migrations"],
        "parameters": [
          { "name": "id", "in": "path", "required": true, "schema": { "type": "integer" } },
          { "name": "Idempotency-Key", "in": "header", "schema": { "type": "string" } }
        ],
        "responses": {
          "202": { "description": "Migration dispatched to Horizon queue" },
          "402": { "description": "Insufficient credits (SVL-7001)" },
          "409": { "description": "Invalid state transition (SVL-4005)" }
        }
      }
    },
    "/migrations/{id}/progress": {
      "get": {
        "summary": "Get Real-Time Migration Progress & Throughput",
        "security": [{ "BearerAuth": [] }],
        "tags": ["Migrations"],
        "parameters": [
          { "name": "id", "in": "path", "required": true, "schema": { "type": "integer" } }
        ],
        "responses": { "200": { "description": "Progress telemetry" } }
      }
    },
    "/migrations/{id}/health": {
      "get": {
        "summary": "Get Migration Health Score & Failure Metrics",
        "security": [{ "BearerAuth": [] }],
        "tags": ["Migrations"],
        "parameters": [
          { "name": "id", "in": "path", "required": true, "schema": { "type": "integer" } }
        ],
        "responses": { "200": { "description": "Health score & recommendations" } }
      }
    },
    "/credits/balance": {
      "get": {
        "summary": "Get Credit Wallet Balance",
        "security": [{ "BearerAuth": [] }],
        "tags": ["Credit Wallet"],
        "responses": { "200": { "description": "Credit balance & stats" } }
      }
    },
    "/credits/transactions": {
      "get": {
        "summary": "List Credit Ledger Transactions",
        "security": [{ "BearerAuth": [] }],
        "tags": ["Credit Wallet"],
        "responses": { "200": { "description": "Paginated credit transactions" } }
      }
    },
    "/connectors": {
      "get": {
        "summary": "List Approved SaaS Connectors",
        "security": [{ "BearerAuth": [] }],
        "tags": ["Connectors"],
        "responses": { "200": { "description": "Available connectors catalog" } }
      }
    }
  }
}
