{
  "openapi": "3.1.0",
  "info": {
    "title": "Recruit API",
    "version": "2.0.0",
    "description": "REST API for the Eu Nerd IT Services platform. Provides programmatic access to talent management, CRM, ticketing, contracts, invoicing, content, and messaging. All endpoints require Bearer token authentication.",
    "contact": {
      "name": "Eu Nerd Tech",
      "email": "tech@eunerd.com.br",
      "url": "https://encontreumnerd.com.br"
    },
    "license": {
      "name": "Proprietary"
    }
  },
  "servers": [
    {
      "url": "https://wzcftlekhxlsavsjgfhb.supabase.co/functions/v1/openclaw-api",
      "description": "Production"
    }
  ],
  "security": [
    { "bearerAuth": [] }
  ],
  "tags": [
    { "name": "Candidates", "description": "Technician/provider profiles with geolocation, certifications, KYC status" },
    { "name": "Vacancies", "description": "Job postings, applications, and vacancy requests" },
    { "name": "Operations", "description": "Service orders, allocations, and scheduling" },
    { "name": "Support", "description": "Helpdesk ticketing system" },
    { "name": "CRM", "description": "Deal pipelines, deals, activities, and company management" },
    { "name": "Sales", "description": "Proposals with tracking and versioning" },
    { "name": "Contracts", "description": "Digital contract lifecycle management" },
    { "name": "Documents", "description": "Document signature requests and management" },
    { "name": "Finance", "description": "Invoice batches, employee invoices, provider invoices, and payments" },
    { "name": "Content", "description": "Blog articles with SEO optimization" },
    { "name": "Messaging", "description": "WhatsApp messaging via Meta Cloud API" },
    { "name": "Email", "description": "Transactional email sending via Resend" },
    { "name": "Analytics", "description": "Platform metrics and dashboards" }
  ],
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "API key provided as Bearer token. Obtain from Eu Nerd admin."
      }
    },
    "schemas": {
      "PaginatedResponse": {
        "type": "object",
        "properties": {
          "data": { "type": "array", "description": "Array of resource objects" },
          "total": { "type": "integer", "description": "Total matching records" },
          "limit": { "type": "integer", "description": "Records per page" },
          "offset": { "type": "integer", "description": "Current offset" }
        }
      },
      "DetailResponse": {
        "type": "object",
        "properties": {
          "data": { "type": "object", "description": "Single resource object" }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "error": { "type": "string", "description": "Error description" }
        }
      },
      "Candidate": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "nome": { "type": "string" },
          "email": { "type": "string", "format": "email" },
          "telefone": { "type": "string" },
          "cpf": { "type": "string", "nullable": true },
          "cnpj": { "type": "string", "nullable": true },
          "cidade": { "type": "string" },
          "estado": { "type": "string" },
          "bairro": { "type": "string" },
          "nivel_senioridade": { "type": "string", "nullable": true },
          "nivel_ingles": { "type": "string", "nullable": true },
          "certificacoes": { "type": "array", "items": { "type": "string" }, "nullable": true },
          "etapa": { "type": "string", "enum": ["triagem", "entrevista", "proposta", "contratado", "arquivado"] },
          "status": { "type": "string", "enum": ["adequado", "talvez", "nao_adequado"], "nullable": true },
          "tech_profile": { "type": "object", "nullable": true },
          "job_categories": { "type": "object", "nullable": true },
          "total_jobs_completed": { "type": "integer", "nullable": true },
          "total_jobs_all": { "type": "integer", "nullable": true },
          "service_radius_km": { "type": "number", "nullable": true },
          "schedule_availability": { "type": "object", "nullable": true },
          "disponibilidade_inicio": { "type": "string", "nullable": true },
          "curriculo_url": { "type": "string", "format": "uri", "nullable": true, "description": "URL of the candidate's resume file" },
          "curriculo_mime_type": { "type": "string", "nullable": true, "description": "MIME type of the resume (e.g. application/pdf)" },
          "created_at": { "type": "string", "format": "date-time" }
        }
      },
      "CandidateCreate": {
        "type": "object",
        "required": ["nome", "email", "telefone", "cidade", "estado"],
        "properties": {
          "nome": { "type": "string" },
          "email": { "type": "string", "format": "email" },
          "telefone": { "type": "string" },
          "cidade": { "type": "string" },
          "estado": { "type": "string", "description": "2-letter state code (e.g. SP, RJ)" },
          "bairro": { "type": "string" },
          "cep": { "type": "string" },
          "endereco_linha": { "type": "string" },
          "curriculo_url": { "type": "string", "format": "uri" },
          "curriculo_mime_type": { "type": "string", "default": "application/pdf" },
          "certificacoes": { "type": "array", "items": { "type": "string" } },
          "nivel_senioridade": { "type": "string" },
          "nivel_ingles": { "type": "string" },
          "observacoes": { "type": "string" }
        }
      },
      "CandidateUpdate": {
        "type": "object",
        "properties": {
          "nome": { "type": "string" },
          "email": { "type": "string" },
          "telefone": { "type": "string" },
          "cidade": { "type": "string" },
          "estado": { "type": "string" },
          "bairro": { "type": "string" },
          "etapa": { "type": "string", "enum": ["triagem", "entrevista", "proposta", "contratado", "arquivado"] },
          "status": { "type": "string", "enum": ["adequado", "talvez", "nao_adequado"] },
          "certificacoes": { "type": "array", "items": { "type": "string" } },
          "nivel_senioridade": { "type": "string" },
          "nivel_ingles": { "type": "string" },
          "observacoes": { "type": "string" },
          "cnpj": { "type": "string" },
          "cpf": { "type": "string" },
          "disponibilidade_inicio": { "type": "string" },
          "service_radius_km": { "type": "number" }
        }
      },
      "Vacancy": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "title": { "type": "string" },
          "client_name": { "type": "string", "nullable": true },
          "description": { "type": "string", "nullable": true },
          "location": { "type": "string", "nullable": true },
          "status": { "type": "string", "enum": ["open", "closed", "draft"] },
          "work_mode": { "type": "string", "nullable": true },
          "contract_type": { "type": "string", "nullable": true },
          "job_area": { "type": "string", "nullable": true },
          "requirements": { "type": "string", "nullable": true },
          "salary_range_min": { "type": "number", "nullable": true },
          "salary_range_max": { "type": "number", "nullable": true },
          "published_at": { "type": "string", "format": "date-time", "nullable": true },
          "created_at": { "type": "string", "format": "date-time" }
        }
      },
      "VacancyCreate": {
        "type": "object",
        "required": ["title"],
        "properties": {
          "title": { "type": "string" },
          "client_name": { "type": "string" },
          "description": { "type": "string" },
          "location": { "type": "string" },
          "work_mode": { "type": "string" },
          "contract_type": { "type": "string" },
          "job_area": { "type": "string" },
          "requirements": { "type": "string" },
          "salary_range_min": { "type": "number" },
          "salary_range_max": { "type": "number" }
        }
      },
      "VacancyUpdate": {
        "type": "object",
        "properties": {
          "title": { "type": "string" },
          "description": { "type": "string" },
          "client_name": { "type": "string" },
          "location": { "type": "string" },
          "status": { "type": "string", "enum": ["open", "closed", "draft"] },
          "work_mode": { "type": "string" },
          "contract_type": { "type": "string" },
          "job_area": { "type": "string" },
          "requirements": { "type": "string" },
          "salary_range_min": { "type": "number" },
          "salary_range_max": { "type": "number" },
          "published_at": { "type": "string", "format": "date-time" }
        }
      },
      "Deal": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "title": { "type": "string" },
          "pipeline_id": { "type": "string", "format": "uuid" },
          "company_id": { "type": "string", "format": "uuid", "nullable": true },
          "company_name": { "type": "string", "nullable": true, "description": "Resolved from companies table on detail" },
          "contact_name": { "type": "string", "nullable": true },
          "contact_email": { "type": "string", "nullable": true },
          "contact_phone": { "type": "string", "nullable": true },
          "stage": { "type": "string" },
          "value": { "type": "number", "nullable": true },
          "priority": { "type": "string", "nullable": true },
          "source": { "type": "string", "nullable": true },
          "notes": { "type": "string", "nullable": true },
          "owner_id": { "type": "string", "format": "uuid", "nullable": true },
          "stage_entered_at": { "type": "string", "format": "date-time", "nullable": true },
          "created_at": { "type": "string", "format": "date-time" },
          "updated_at": { "type": "string", "format": "date-time" }
        }
      },
      "DealCreate": {
        "type": "object",
        "required": ["pipeline_id"],
        "properties": {
          "pipeline_id": { "type": "string", "format": "uuid" },
          "company_name": { "type": "string", "description": "Auto-resolves company_id from name" },
          "contact_name": { "type": "string" },
          "contact_email": { "type": "string" },
          "contact_phone": { "type": "string" },
          "description": { "type": "string" },
          "stage": { "type": "string", "default": "lead" },
          "source": { "type": "string" }
        }
      },
      "DealUpdate": {
        "type": "object",
        "properties": {
          "stage": { "type": "string", "description": "Stage changes auto-log deal_activities and update stage_entered_at" },
          "value": { "type": "number" },
          "priority": { "type": "string" },
          "contact_name": { "type": "string" },
          "contact_email": { "type": "string" },
          "contact_phone": { "type": "string" },
          "notes": { "type": "string" },
          "owner_id": { "type": "string", "format": "uuid" }
        }
      },
      "Ticket": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "ticket_number": { "type": "string", "description": "Auto-generated: TK-YYYYMMDD-XXXX" },
          "subject": { "type": "string" },
          "status": { "type": "string", "enum": ["open", "in_progress", "resolved", "closed"] },
          "priority": { "type": "string" },
          "client_name": { "type": "string", "nullable": true },
          "category": { "type": "string", "nullable": true },
          "sender_email": { "type": "string" },
          "sender_name": { "type": "string", "nullable": true },
          "source": { "type": "string", "nullable": true },
          "assigned_to": { "type": "string", "nullable": true },
          "resolution_notes": { "type": "string", "nullable": true },
          "resolved_at": { "type": "string", "format": "date-time", "nullable": true },
          "created_at": { "type": "string", "format": "date-time" }
        }
      },
      "TicketCreate": {
        "type": "object",
        "required": ["subject", "sender_email"],
        "properties": {
          "subject": { "type": "string" },
          "sender_email": { "type": "string", "format": "email" },
          "client_name": { "type": "string" },
          "category": { "type": "string" },
          "priority": { "type": "string", "default": "medium" },
          "sender_name": { "type": "string" },
          "source": { "type": "string", "default": "api" },
          "parsed_data": { "type": "object" }
        }
      },
      "TicketUpdate": {
        "type": "object",
        "properties": {
          "status": { "type": "string", "enum": ["open", "in_progress", "resolved", "closed"], "description": "Auto-fills resolved_at on resolved|closed" },
          "priority": { "type": "string" },
          "category": { "type": "string" },
          "assigned_to": { "type": "string" },
          "resolution_notes": { "type": "string" }
        }
      },
      "ServiceOrder": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "code": { "type": "string", "description": "Auto-generated: OS-YYYY-XXXXX" },
          "company_name": { "type": "string" },
          "description": { "type": "string" },
          "status": { "type": "string" },
          "priority": { "type": "string" },
          "category": { "type": "string", "nullable": true },
          "candidate_id": { "type": "string", "format": "uuid", "nullable": true },
          "scheduled_date": { "type": "string", "format": "date-time", "nullable": true },
          "completed_at": { "type": "string", "format": "date-time", "nullable": true },
          "created_at": { "type": "string", "format": "date-time" }
        }
      },
      "ServiceOrderCreate": {
        "type": "object",
        "required": ["company_name", "description"],
        "properties": {
          "company_name": { "type": "string" },
          "description": { "type": "string" },
          "category": { "type": "string" },
          "priority": { "type": "string", "default": "medium" },
          "scheduled_date": { "type": "string", "format": "date-time" },
          "candidate_id": { "type": "string", "format": "uuid" },
          "contact_name": { "type": "string" },
          "contact_phone": { "type": "string" },
          "city": { "type": "string" },
          "state": { "type": "string" },
          "address": { "type": "string" }
        }
      },
      "ServiceOrderUpdate": {
        "type": "object",
        "properties": {
          "status": { "type": "string", "description": "Auto-fills completed_at on status=completed" },
          "priority": { "type": "string" },
          "category": { "type": "string" },
          "candidate_id": { "type": "string", "format": "uuid" },
          "scheduled_date": { "type": "string", "format": "date-time" },
          "completion_notes": { "type": "string" },
          "rating": { "type": "number" },
          "description": { "type": "string" }
        }
      },
      "Company": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "name": { "type": "string" },
          "cnpj": { "type": "string", "nullable": true },
          "email": { "type": "string", "nullable": true },
          "phone": { "type": "string", "nullable": true },
          "city": { "type": "string", "nullable": true },
          "state": { "type": "string", "nullable": true },
          "segment": { "type": "string", "nullable": true },
          "is_active": { "type": "boolean" },
          "contract_type": { "type": "string", "nullable": true },
          "monthly_value": { "type": "number", "nullable": true },
          "status": { "type": "string", "nullable": true },
          "created_at": { "type": "string", "format": "date-time" }
        }
      },
      "CompanyCreate": {
        "type": "object",
        "required": ["name"],
        "properties": {
          "name": { "type": "string" },
          "cnpj": { "type": "string" },
          "email": { "type": "string" },
          "phone": { "type": "string" },
          "city": { "type": "string" },
          "state": { "type": "string" },
          "segment": { "type": "string" }
        }
      },
      "CompanyUpdate": {
        "type": "object",
        "properties": {
          "name": { "type": "string" },
          "cnpj": { "type": "string" },
          "email": { "type": "string" },
          "phone": { "type": "string" },
          "city": { "type": "string" },
          "state": { "type": "string" },
          "segment": { "type": "string" },
          "is_active": { "type": "boolean" },
          "contract_type": { "type": "string" },
          "monthly_value": { "type": "number" },
          "status": { "type": "string" }
        }
      },
      "Proposal": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "title": { "type": "string" },
          "client_name": { "type": "string" },
          "proposal_type": { "type": "string", "description": "E.g. custom, field_service, outsourcing, projeto" },
          "status": { "type": "string", "enum": ["rascunho", "ativa", "aceita", "expirada"] },
          "recipient_name": { "type": "string", "nullable": true },
          "recipient_email": { "type": "string", "nullable": true },
          "slug": { "type": "string", "description": "URL-safe identifier, auto-generated if not provided" },
          "signing_token": { "type": "string", "format": "uuid", "description": "Token for the public proposal acceptance URL (/proposta/{signing_token})" },
          "content": { "type": "object", "nullable": true, "description": "Proposal body — { sections: [{ title, html, order }] }" },
          "metadata": { "type": "object", "nullable": true, "description": "Free-form metadata (investment, scope details, brief answers)" },
          "original_content": { "type": "object", "nullable": true, "description": "Snapshot of content at first generation, preserved for diff/versioning" },
          "client_logo_url": { "type": "string", "nullable": true, "description": "URL of the client logo to display on the proposal" },
          "source_file_url": { "type": "string", "nullable": true, "description": "URL of the source file (PDF/DOCX) used to generate the proposal" },
          "vacancy_request_id": { "type": "string", "format": "uuid", "nullable": true, "description": "Link to a vacancy request if the proposal originated from one" },
          "created_by": { "type": "string", "format": "uuid", "nullable": true, "description": "User ID of the creator" },
          "sent_at": { "type": "string", "format": "date-time", "nullable": true, "description": "Auto-set when status transitions to ativa" },
          "accepted_at": { "type": "string", "format": "date-time", "nullable": true, "description": "Auto-set when status transitions to aceita" },
          "accepted_by": { "type": "string", "nullable": true, "description": "Name/email of who accepted" },
          "expires_at": { "type": "string", "format": "date-time", "nullable": true },
          "created_at": { "type": "string", "format": "date-time" },
          "updated_at": { "type": "string", "format": "date-time" }
        }
      },
      "ProposalCreate": {
        "type": "object",
        "required": ["title", "client_name"],
        "properties": {
          "title": { "type": "string", "description": "Proposal title" },
          "client_name": { "type": "string", "description": "Client/company name" },
          "proposal_type": { "type": "string", "description": "E.g. custom, field_service, outsourcing, projeto. Default: custom" },
          "recipient_name": { "type": "string", "description": "Name of the recipient" },
          "recipient_email": { "type": "string", "format": "email", "description": "Email of the recipient" },
          "content": { "type": "object", "description": "Proposal body — { sections: [{ title, html, order }] }" },
          "metadata": { "type": "object", "description": "Free-form metadata (investment, scope, brief answers)" },
          "expires_at": { "type": "string", "format": "date-time", "description": "Expiration date" },
          "slug": { "type": "string", "description": "Custom slug. Auto-generated from client_name if omitted" }
        }
      },
      "ProposalUpdate": {
        "type": "object",
        "properties": {
          "status": { "type": "string", "enum": ["rascunho", "ativa", "aceita", "expirada"], "description": "Auto-fills sent_at on →ativa, accepted_at on →aceita" },
          "title": { "type": "string" },
          "client_name": { "type": "string" },
          "content": { "type": "object", "description": "Replace proposal body sections" },
          "metadata": { "type": "object" },
          "expires_at": { "type": "string", "format": "date-time" },
          "recipient_name": { "type": "string" },
          "recipient_email": { "type": "string" },
          "proposal_type": { "type": "string" },
          "client_logo_url": { "type": "string", "description": "URL of the client logo" },
          "source_file_url": { "type": "string", "description": "URL of the source file" }
        }
      },
      "Article": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "format": "uuid" },
          "slug": { "type": "string" },
          "title": { "type": "string" },
          "subtitle": { "type": "string", "nullable": true },
          "content_html": { "type": "string" },
          "content_markdown": { "type": "string", "nullable": true },
          "excerpt": { "type": "string", "nullable": true },
          "category": { "type": "string", "nullable": true },
          "status": { "type": "string", "enum": ["draft", "published", "archived"] },
          "tags": { "type": "array", "items": { "type": "string" }, "nullable": true },
          "meta_title": { "type": "string", "nullable": true },
          "meta_description": { "type": "string", "nullable": true },
          "meta_keywords": { "type": "string", "nullable": true },
          "featured_image_url": { "type": "string", "nullable": true },
          "featured_image_alt": { "type": "string", "nullable": true },
          "author_name": { "type": "string", "nullable": true },
          "reading_time_minutes": { "type": "integer", "nullable": true },
          "word_count": { "type": "integer", "nullable": true },
          "view_count": { "type": "integer" },
          "og_title": { "type": "string", "nullable": true },
          "og_description": { "type": "string", "nullable": true },
          "og_image": { "type": "string", "nullable": true },
          "canonical_url": { "type": "string", "nullable": true },
          "schema_markup": { "type": "object", "nullable": true },
          "structured_data": { "type": "object", "nullable": true },
          "published_at": { "type": "string", "format": "date-time", "nullable": true },
          "created_at": { "type": "string", "format": "date-time" },
          "updated_at": { "type": "string", "format": "date-time" }
        }
      },
      "ArticleCreate": {
        "type": "object",
        "required": ["title"],
        "properties": {
          "title": { "type": "string" },
          "slug": { "type": "string", "description": "Auto-generated from title if not provided" },
          "content_html": { "type": "string" },
          "content_markdown": { "type": "string" },
          "category": { "type": "string" },
          "status": { "type": "string", "enum": ["draft", "published", "archived"], "default": "draft", "description": "Auto-fills published_at when set to published" },
          "excerpt": { "type": "string" },
          "tags": { "type": "array", "items": { "type": "string" } },
          "meta_title": { "type": "string" },
          "meta_description": { "type": "string" },
          "meta_keywords": { "type": "string" },
          "featured_image_url": { "type": "string" },
          "featured_image_alt": { "type": "string" },
          "author_name": { "type": "string" },
          "subtitle": { "type": "string" },
          "reading_time_minutes": { "type": "integer" },
          "word_count": { "type": "integer" },
          "og_title": { "type": "string" },
          "og_description": { "type": "string" },
          "og_image": { "type": "string" },
          "canonical_url": { "type": "string" },
          "schema_markup": { "type": "object" },
          "structured_data": { "type": "object" }
        }
      },
      "WhatsAppSend": {
        "type": "object",
        "required": ["template_id", "phone"],
        "properties": {
          "template_id": { "type": "string", "format": "uuid", "description": "UUID of a whatsapp_templates record" },
          "phone": { "type": "string", "description": "Brazilian phone number. Auto-normalized to E.164. Accepts: 11999999999, 5511999999999, +5511999999999" },
          "variables": { "type": "object", "description": "Key-value pairs matching template variables_schema labels" }
        }
      },
      "DocumentSignatureCreate": {
        "type": "object",
        "required": ["title", "file_url", "file_name", "recipients"],
        "properties": {
          "title": { "type": "string" },
          "file_url": { "type": "string", "description": "Direct download URL or storage path. External URLs are downloaded and stored automatically." },
          "file_name": { "type": "string" },
          "file_type": { "type": "string", "enum": ["pdf", "docx"], "default": "pdf" },
          "message": { "type": "string", "description": "Custom message for signing email" },
          "created_by": { "type": "string", "format": "uuid", "description": "User ID. Falls back to master_admin if not provided." },
          "recipients": {
            "type": "array",
            "items": {
              "type": "object",
              "required": ["name", "email"],
              "properties": {
                "name": { "type": "string" },
                "email": { "type": "string", "format": "email" },
                "role": { "type": "string", "default": "signer" }
              }
            }
          }
        }
      },
      "VacancyRequestCreate": {
        "type": "object",
        "required": ["client_name", "client_user_id"],
        "properties": {
          "client_name": { "type": "string" },
          "client_user_id": { "type": "string", "format": "uuid" },
          "job_title": { "type": "string" },
          "job_description": { "type": "string" },
          "request_type": { "type": "string", "default": "outsourcing" },
          "work_mode": { "type": "string" },
          "contract_type": { "type": "string" },
          "positions_count": { "type": "integer", "default": 1 },
          "location_city": { "type": "string" },
          "location_state": { "type": "string" },
          "start_date": { "type": "string", "format": "date" },
          "end_date": { "type": "string", "format": "date" },
          "request_data": { "type": "object" }
        }
      },
      "VacancyRequestUpdate": {
        "type": "object",
        "properties": {
          "status": { "type": "string", "enum": ["pending", "approved", "rejected"], "description": "Auto-fills reviewed_at on approved" },
          "admin_notes": { "type": "string" },
          "reviewed_by": { "type": "string" },
          "reviewed_at": { "type": "string", "format": "date-time" },
          "converted_vacancy_id": { "type": "string", "format": "uuid" },
          "job_title": { "type": "string" },
          "job_description": { "type": "string" },
          "work_mode": { "type": "string" },
          "contract_type": { "type": "string" },
          "positions_count": { "type": "integer" }
        }
      },
      "DealActivityCreate": {
        "type": "object",
        "required": ["deal_id", "type", "content"],
        "properties": {
          "deal_id": { "type": "string", "format": "uuid" },
          "type": { "type": "string", "enum": ["note", "stage_change", "email", "call", "meeting"] },
          "content": { "type": "string" },
          "metadata": { "type": "object" }
        }
      },
      "ProviderInvoiceUpdate": {
        "type": "object",
        "properties": {
          "status": { "type": "string", "description": "Auto-fills reviewed_at on approved, paid_at on paid" },
          "notes": { "type": "string" },
          "rejection_reason": { "type": "string" },
          "estimated_payment_date": { "type": "string", "format": "date" },
          "paid_at": { "type": "string", "format": "date-time" }
        }
      },
      "SchedulingLinkCreate": {
        "type": "object",
        "required": ["candidate_id", "created_by"],
        "properties": {
          "candidate_id": { "type": "string", "format": "uuid" },
          "vacancy_id": { "type": "string", "format": "uuid" },
          "created_by": { "type": "string", "format": "uuid" }
        }
      },
      "EmployeeInvoiceUpdate": {
        "type": "object",
        "properties": {
          "status": { "type": "string", "description": "Auto-fills paid_at on status=paid" },
          "paid_at": { "type": "string", "format": "date-time" },
          "notes": { "type": "string" },
          "final_value": { "type": "number" },
          "rejection_reason": { "type": "string" }
        }
      }
    },
    "parameters": {
      "limit": {
        "name": "limit",
        "in": "query",
        "schema": { "type": "integer", "default": 50, "maximum": 500 },
        "description": "Records per page (max 500)"
      },
      "offset": {
        "name": "offset",
        "in": "query",
        "schema": { "type": "integer", "default": 0 },
        "description": "Pagination offset"
      },
      "search": {
        "name": "search",
        "in": "query",
        "schema": { "type": "string" },
        "description": "Text search across relevant fields per resource"
      },
      "idPath": {
        "name": "id",
        "in": "path",
        "required": true,
        "schema": { "type": "string", "format": "uuid" }
      }
    }
  },
  "paths": {
    "/candidates": {
      "get": {
        "summary": "List candidates",
        "description": "Returns paginated list of technician/provider candidates. Searchable by nome, email, cidade.",
        "tags": ["Candidates"],
        "parameters": [
          { "$ref": "#/components/parameters/limit" },
          { "$ref": "#/components/parameters/offset" },
          { "$ref": "#/components/parameters/search" },
          { "name": "etapa", "in": "query", "schema": { "type": "string", "enum": ["triagem", "entrevista", "proposta", "contratado", "arquivado"] }, "description": "Filter by pipeline stage" },
          { "name": "cidade", "in": "query", "schema": { "type": "string" }, "description": "Filter by city (partial match)" }
        ],
        "responses": {
          "200": { "description": "Paginated list of candidates", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PaginatedResponse" } } } },
          "401": { "description": "Unauthorized", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } },
          "429": { "description": "Rate limit exceeded" }
        }
      },
      "post": {
        "summary": "Create candidate",
        "description": "Creates a new candidate in triagem stage.",
        "tags": ["Candidates"],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CandidateCreate" } } } },
        "responses": { "201": { "description": "Candidate created" }, "400": { "description": "Missing required fields" } }
      }
    },
    "/candidates/{id}": {
      "get": {
        "summary": "Get candidate detail",
        "description": "Returns full candidate profile including tech_profile, job_categories, schedule_availability.",
        "tags": ["Candidates"],
        "parameters": [{ "$ref": "#/components/parameters/idPath" }],
        "responses": { "200": { "description": "Candidate detail" }, "404": { "description": "Not found" } }
      },
      "patch": {
        "summary": "Update candidate",
        "description": "Update candidate data, stage, or status.",
        "tags": ["Candidates"],
        "parameters": [{ "$ref": "#/components/parameters/idPath" }],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CandidateUpdate" } } } },
        "responses": { "200": { "description": "Updated candidate" }, "404": { "description": "Not found" } }
      }
    },
    "/vacancies": {
      "get": {
        "summary": "List vacancies",
        "description": "Returns paginated list of job vacancies. Searchable by title, client_name.",
        "tags": ["Vacancies"],
        "parameters": [
          { "$ref": "#/components/parameters/limit" },
          { "$ref": "#/components/parameters/offset" },
          { "$ref": "#/components/parameters/search" },
          { "name": "status", "in": "query", "schema": { "type": "string", "enum": ["open", "closed", "draft"] } }
        ],
        "responses": { "200": { "description": "Paginated list" } }
      },
      "post": {
        "summary": "Create vacancy",
        "description": "Creates a new vacancy in draft status.",
        "tags": ["Vacancies"],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/VacancyCreate" } } } },
        "responses": { "201": { "description": "Vacancy created" } }
      }
    },
    "/vacancies/{id}": {
      "get": {
        "summary": "Get vacancy detail",
        "tags": ["Vacancies"],
        "parameters": [{ "$ref": "#/components/parameters/idPath" }],
        "responses": { "200": { "description": "Full vacancy detail" }, "404": { "description": "Not found" } }
      },
      "patch": {
        "summary": "Update vacancy",
        "tags": ["Vacancies"],
        "parameters": [{ "$ref": "#/components/parameters/idPath" }],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/VacancyUpdate" } } } },
        "responses": { "200": { "description": "Updated vacancy" } }
      }
    },
    "/vacancy-applications/{vacancy_id}": {
      "get": {
        "summary": "List applications for a vacancy",
        "description": "Returns applications with inline candidate data (nome, email, telefone, cidade, estado).",
        "tags": ["Vacancies"],
        "parameters": [
          { "name": "vacancy_id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } },
          { "$ref": "#/components/parameters/limit" },
          { "$ref": "#/components/parameters/offset" },
          { "name": "status", "in": "query", "schema": { "type": "string" } }
        ],
        "responses": { "200": { "description": "Applications with vacancy info" }, "404": { "description": "Vacancy not found" } }
      }
    },
    "/vacancy-requests": {
      "get": {
        "summary": "List vacancy requests",
        "description": "Client-submitted vacancy requests. Searchable by client_name, job_title.",
        "tags": ["Vacancies"],
        "parameters": [
          { "$ref": "#/components/parameters/limit" },
          { "$ref": "#/components/parameters/offset" },
          { "$ref": "#/components/parameters/search" },
          { "name": "status", "in": "query", "schema": { "type": "string", "enum": ["pending", "approved", "rejected"] } },
          { "name": "client_name", "in": "query", "schema": { "type": "string" } }
        ],
        "responses": { "200": { "description": "Paginated list" } }
      },
      "post": {
        "summary": "Create vacancy request",
        "description": "Creates a new vacancy request in pending status.",
        "tags": ["Vacancies"],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/VacancyRequestCreate" } } } },
        "responses": { "201": { "description": "Request created" } }
      }
    },
    "/vacancy-requests/{id}": {
      "get": {
        "summary": "Get vacancy request detail",
        "tags": ["Vacancies"],
        "parameters": [{ "$ref": "#/components/parameters/idPath" }],
        "responses": { "200": { "description": "Full request detail" }, "404": { "description": "Not found" } }
      },
      "patch": {
        "summary": "Update vacancy request",
        "description": "Update status, notes, or convert to vacancy.",
        "tags": ["Vacancies"],
        "parameters": [{ "$ref": "#/components/parameters/idPath" }],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/VacancyRequestUpdate" } } } },
        "responses": { "200": { "description": "Updated request" } }
      }
    },
    "/allocations": {
      "get": {
        "summary": "List allocations",
        "description": "Active technician-to-client assignments. Searchable by title, client_name.",
        "tags": ["Operations"],
        "parameters": [
          { "$ref": "#/components/parameters/limit" },
          { "$ref": "#/components/parameters/offset" },
          { "$ref": "#/components/parameters/search" }
        ],
        "responses": { "200": { "description": "Paginated list" } }
      }
    },
    "/allocations/{id}": {
      "get": {
        "summary": "Get allocation detail",
        "description": "Includes candidate data (nome, email, cidade, estado).",
        "tags": ["Operations"],
        "parameters": [{ "$ref": "#/components/parameters/idPath" }],
        "responses": { "200": { "description": "Allocation with candidate" }, "404": { "description": "Not found" } }
      }
    },
    "/scheduling": {
      "get": {
        "summary": "List scheduling links",
        "description": "Returns scheduling links with generated URLs. Filterable by candidate_id, vacancy_id.",
        "tags": ["Operations"],
        "parameters": [
          { "$ref": "#/components/parameters/limit" },
          { "$ref": "#/components/parameters/offset" },
          { "name": "candidate_id", "in": "query", "schema": { "type": "string", "format": "uuid" } },
          { "name": "vacancy_id", "in": "query", "schema": { "type": "string", "format": "uuid" } }
        ],
        "responses": { "200": { "description": "Scheduling links with scheduling_url field" } }
      },
      "post": {
        "summary": "Create scheduling link",
        "description": "Creates a token-based scheduling link. Expires in 7 days.",
        "tags": ["Operations"],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SchedulingLinkCreate" } } } },
        "responses": { "201": { "description": "Link created with scheduling_url" } }
      }
    },
    "/companies": {
      "get": {
        "summary": "List companies",
        "description": "B2B client companies. Searchable by name, cnpj.",
        "tags": ["CRM"],
        "parameters": [
          { "$ref": "#/components/parameters/limit" },
          { "$ref": "#/components/parameters/offset" },
          { "$ref": "#/components/parameters/search" }
        ],
        "responses": { "200": { "description": "Paginated list" } }
      },
      "post": {
        "summary": "Create company",
        "tags": ["CRM"],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CompanyCreate" } } } },
        "responses": { "201": { "description": "Company created" } }
      }
    },
    "/companies/{id}": {
      "get": {
        "summary": "Get company detail",
        "tags": ["CRM"],
        "parameters": [{ "$ref": "#/components/parameters/idPath" }],
        "responses": { "200": { "description": "Full company data" }, "404": { "description": "Not found" } }
      },
      "patch": {
        "summary": "Update company",
        "tags": ["CRM"],
        "parameters": [{ "$ref": "#/components/parameters/idPath" }],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CompanyUpdate" } } } },
        "responses": { "200": { "description": "Updated company" } }
      }
    },
    "/deal-pipelines": {
      "get": {
        "summary": "List active pipelines",
        "description": "Returns active deal pipelines with their stage configurations.",
        "tags": ["CRM"],
        "responses": { "200": { "description": "Array of pipelines with stages" } }
      }
    },
    "/deals": {
      "get": {
        "summary": "List deals",
        "description": "CRM deals. Searchable by title, contact_name, contact_email.",
        "tags": ["CRM"],
        "parameters": [
          { "$ref": "#/components/parameters/limit" },
          { "$ref": "#/components/parameters/offset" },
          { "$ref": "#/components/parameters/search" },
          { "name": "pipeline_id", "in": "query", "schema": { "type": "string", "format": "uuid" } },
          { "name": "stage", "in": "query", "schema": { "type": "string" } }
        ],
        "responses": { "200": { "description": "Paginated list" } }
      },
      "post": {
        "summary": "Create deal",
        "description": "Creates deal. company_name auto-resolves to company_id. Title auto-generated from contact/company.",
        "tags": ["CRM"],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DealCreate" } } } },
        "responses": { "201": { "description": "Deal created" } }
      }
    },
    "/deals/{id}": {
      "get": {
        "summary": "Get deal detail",
        "description": "Returns deal with resolved company_name from companies table.",
        "tags": ["CRM"],
        "parameters": [{ "$ref": "#/components/parameters/idPath" }],
        "responses": { "200": { "description": "Deal with company_name" }, "404": { "description": "Not found" } }
      },
      "patch": {
        "summary": "Update deal",
        "description": "Stage changes automatically update stage_entered_at and log a deal_activity.",
        "tags": ["CRM"],
        "parameters": [{ "$ref": "#/components/parameters/idPath" }],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DealUpdate" } } } },
        "responses": { "200": { "description": "Updated deal" } }
      }
    },
    "/deal-activities": {
      "get": {
        "summary": "List deal activities",
        "description": "Activities for a specific deal. deal_id is required.",
        "tags": ["CRM"],
        "parameters": [
          { "name": "deal_id", "in": "query", "required": true, "schema": { "type": "string", "format": "uuid" } },
          { "$ref": "#/components/parameters/limit" },
          { "$ref": "#/components/parameters/offset" },
          { "name": "type", "in": "query", "schema": { "type": "string", "enum": ["note", "stage_change", "email", "call", "meeting"] } }
        ],
        "responses": { "200": { "description": "Paginated activities" } }
      },
      "post": {
        "summary": "Create deal activity",
        "tags": ["CRM"],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DealActivityCreate" } } } },
        "responses": { "201": { "description": "Activity created" } }
      }
    },
    "/proposals": {
      "get": {
        "summary": "List proposals",
        "description": "Commercial proposals with pagination. Searchable by title, client_name. Returns: id, title, slug, client_name, proposal_type, status, sent_at, accepted_at, expires_at, created_at.",
        "tags": ["Sales"],
        "parameters": [
          { "$ref": "#/components/parameters/limit" },
          { "$ref": "#/components/parameters/offset" },
          { "$ref": "#/components/parameters/search" },
          { "name": "status", "in": "query", "schema": { "type": "string", "enum": ["rascunho", "ativa", "aceita", "expirada"] }, "description": "Filter by proposal status" },
          { "name": "client_name", "in": "query", "schema": { "type": "string" }, "description": "Filter by client name (partial match)" },
          { "name": "proposal_type", "in": "query", "schema": { "type": "string" }, "description": "Filter by proposal type (e.g. custom, field_service)" }
        ],
        "responses": { "200": { "description": "Paginated list of proposals", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/Proposal" } }, "total": { "type": "integer" }, "limit": { "type": "integer" }, "offset": { "type": "integer" } } } } } } }
      },
      "post": {
        "summary": "Create proposal",
        "description": "Creates a new proposal in rascunho (draft) status. Auto-generates slug from client_name and a signing_token (UUID) for the public acceptance URL. Content should be structured as { sections: [{ title, html, order }] }.",
        "tags": ["Sales"],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProposalCreate" } } } },
        "responses": { "201": { "description": "Proposal created. Returns id, title, slug, client_name, proposal_type, status, signing_token, created_at." } }
      }
    },
    "/proposals/{id}": {
      "get": {
        "summary": "Get proposal detail",
        "description": "Returns all proposal fields including content sections, metadata, signing_token, original_content, client_logo_url, source_file_url, vacancy_request_id, created_by, accepted_by.",
        "tags": ["Sales"],
        "parameters": [{ "$ref": "#/components/parameters/idPath" }],
        "responses": { "200": { "description": "Full proposal data with all fields", "content": { "application/json": { "schema": { "type": "object", "properties": { "data": { "$ref": "#/components/schemas/Proposal" } } } } } }, "404": { "description": "Not found" } }
      },
      "patch": {
        "summary": "Update proposal",
        "description": "Updates proposal fields. Auto-fills sent_at when status transitions to ativa, accepted_at when transitioning to aceita. Allowed fields: status, title, client_name, content, metadata, expires_at, recipient_name, recipient_email, proposal_type, client_logo_url, source_file_url.",
        "tags": ["Sales"],
        "parameters": [{ "$ref": "#/components/parameters/idPath" }],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProposalUpdate" } } } },
        "responses": { "200": { "description": "Updated proposal. Returns id, title, slug, client_name, proposal_type, status, sent_at, accepted_at, expires_at, updated_at." } }
      }
    },
    "/proposals/{id}/tracking": {
      "get": {
        "summary": "Get proposal tracking data",
        "description": "Returns proposal tracking info including signing_token (for public URL /proposta/{token}), sent_at, accepted_at, accepted_by, expires_at, and metadata.",
        "tags": ["Sales"],
        "parameters": [{ "$ref": "#/components/parameters/idPath" }],
        "responses": { "200": { "description": "Tracking data with proposal state and metadata" } }
      }
    },
    "/service-orders": {
      "get": {
        "summary": "List service orders",
        "description": "Searchable by code (OS-YYYY-XXXXX), company_name.",
        "tags": ["Operations"],
        "parameters": [
          { "$ref": "#/components/parameters/limit" },
          { "$ref": "#/components/parameters/offset" },
          { "$ref": "#/components/parameters/search" }
        ],
        "responses": { "200": { "description": "Paginated list" } }
      },
      "post": {
        "summary": "Create service order",
        "description": "Creates with status=pending, source=api. Code auto-generated as OS-YYYY-XXXXX.",
        "tags": ["Operations"],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ServiceOrderCreate" } } } },
        "responses": { "201": { "description": "Service order created with auto-generated code" } }
      }
    },
    "/service-orders/{id}": {
      "get": {
        "summary": "Get service order detail",
        "tags": ["Operations"],
        "parameters": [{ "$ref": "#/components/parameters/idPath" }],
        "responses": { "200": { "description": "Full service order" }, "404": { "description": "Not found" } }
      },
      "patch": {
        "summary": "Update service order",
        "description": "Auto-fills completed_at when status transitions to completed.",
        "tags": ["Operations"],
        "parameters": [{ "$ref": "#/components/parameters/idPath" }],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ServiceOrderUpdate" } } } },
        "responses": { "200": { "description": "Updated service order" } }
      }
    },
    "/tickets": {
      "get": {
        "summary": "List tickets",
        "description": "Helpdesk tickets. Searchable by ticket_number, subject, client_name.",
        "tags": ["Support"],
        "parameters": [
          { "$ref": "#/components/parameters/limit" },
          { "$ref": "#/components/parameters/offset" },
          { "$ref": "#/components/parameters/search" },
          { "name": "status", "in": "query", "schema": { "type": "string", "enum": ["open", "in_progress", "resolved", "closed"] } }
        ],
        "responses": { "200": { "description": "Paginated list" } }
      },
      "post": {
        "summary": "Create ticket",
        "description": "Creates with status=open. ticket_number auto-generated as TK-YYYYMMDD-XXXX.",
        "tags": ["Support"],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TicketCreate" } } } },
        "responses": { "201": { "description": "Ticket created" } }
      }
    },
    "/tickets/{id}": {
      "get": {
        "summary": "Get ticket with messages",
        "description": "Returns ticket with all client_ticket_messages.",
        "tags": ["Support"],
        "parameters": [{ "$ref": "#/components/parameters/idPath" }],
        "responses": { "200": { "description": "Ticket with messages" }, "404": { "description": "Not found" } }
      },
      "patch": {
        "summary": "Update ticket",
        "description": "Auto-fills resolved_at when status transitions to resolved or closed.",
        "tags": ["Support"],
        "parameters": [{ "$ref": "#/components/parameters/idPath" }],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TicketUpdate" } } } },
        "responses": { "200": { "description": "Updated ticket" } }
      }
    },
    "/leads": {
      "get": {
        "summary": "List leads",
        "description": "Leads from diagnostic forms, contact forms, website and CRM deals. Subset of client_tickets filtered by source. Searchable by sender_email, sender_name, subject, client_name.",
        "tags": ["CRM"],
        "parameters": [
          { "$ref": "#/components/parameters/limit" },
          { "$ref": "#/components/parameters/offset" },
          { "$ref": "#/components/parameters/search" },
          { "name": "status", "in": "query", "schema": { "type": "string" }, "description": "Filter by ticket status" },
          { "name": "source", "in": "query", "schema": { "type": "string", "enum": ["diagnostic-form", "diagnostic-form-partial", "contact-form", "website", "crm-deal"] }, "description": "Filter by lead source" }
        ],
        "responses": { "200": { "description": "Paginated list of leads with parsed_data (score, CNPJ, recommended modules, etc.)" } }
      }
    },
    "/leads/{id}": {
      "get": {
        "summary": "Get lead detail",
        "description": "Returns full lead record including parsed_data with diagnostic score, maturity level, recommendations and wizard answers.",
        "tags": ["CRM"],
        "parameters": [{ "$ref": "#/components/parameters/idPath" }],
        "responses": { "200": { "description": "Lead detail" }, "404": { "description": "Lead not found" } }
      }
    },
    "/contracts": {
      "get": {
        "summary": "List contracts",
        "description": "Digital contracts with status, signature timestamps. Each contract includes a nested `candidate` object with `id`, `nome`, and `curriculo_url`.",
        "tags": ["Contracts"],
        "parameters": [
          { "$ref": "#/components/parameters/limit" },
          { "$ref": "#/components/parameters/offset" }
        ],
        "responses": { "200": { "description": "Paginated list" } }
      }
    },
    "/contracts/{id}": {
      "get": {
        "summary": "Get contract with signatures and candidate resume",
        "description": "Returns contract with all contract_signatures records and a nested `candidate` object containing `id`, `nome`, `email`, `telefone`, `curriculo_url`, and `curriculo_mime_type`.",
        "tags": ["Contracts"],
        "parameters": [{ "$ref": "#/components/parameters/idPath" }],
        "responses": { "200": { "description": "Contract with signatures" }, "404": { "description": "Not found" } }
      }
    },
    "/document-signatures": {
      "get": {
        "summary": "List signature requests",
        "description": "Searchable by title. Filterable by status.",
        "tags": ["Documents"],
        "parameters": [
          { "$ref": "#/components/parameters/limit" },
          { "$ref": "#/components/parameters/offset" },
          { "$ref": "#/components/parameters/search" },
          { "name": "status", "in": "query", "schema": { "type": "string" } }
        ],
        "responses": { "200": { "description": "Paginated list" } }
      },
      "post": {
        "summary": "Create signature request",
        "description": "Creates document for signing. External file URLs are downloaded automatically. Signing emails sent to all recipients.",
        "tags": ["Documents"],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DocumentSignatureCreate" } } } },
        "responses": { "201": { "description": "Request created with signing URLs per recipient" } }
      }
    },
    "/document-signatures/{id}": {
      "get": {
        "summary": "Get signature request detail",
        "description": "Returns request with all document_signature_recipients.",
        "tags": ["Documents"],
        "parameters": [{ "$ref": "#/components/parameters/idPath" }],
        "responses": { "200": { "description": "Request with recipients" }, "404": { "description": "Not found" } }
      }
    },
    "/document-signatures/{id}/status": {
      "get": {
        "summary": "Signature status summary",
        "description": "Returns signing progress: total, signed, pending counts with per-recipient status and signing URLs.",
        "tags": ["Documents"],
        "parameters": [{ "$ref": "#/components/parameters/idPath" }],
        "responses": { "200": { "description": "Status summary" } }
      }
    },
    "/document-signatures/{id}/download": {
      "get": {
        "summary": "Download document",
        "description": "Returns signed version if available, original otherwise. Prefers signed file.",
        "tags": ["Documents"],
        "parameters": [
          { "$ref": "#/components/parameters/idPath" },
          { "name": "format", "in": "query", "schema": { "type": "string", "enum": ["url", "binary"], "default": "url" }, "description": "url: 1-hour signed URL. binary: raw PDF bytes." }
        ],
        "responses": { "200": { "description": "Signed URL or binary PDF" }, "404": { "description": "Not found or no file" } }
      }
    },
    "/document-signatures/{id}/resend": {
      "post": {
        "summary": "Resend signing email",
        "description": "Resends signing invitation to pending recipients.",
        "tags": ["Documents"],
        "parameters": [{ "$ref": "#/components/parameters/idPath" }],
        "requestBody": { "content": { "application/json": { "schema": { "type": "object", "properties": { "recipient_id": { "type": "string", "format": "uuid", "description": "Send to specific recipient. If omitted, sends to all pending." } } } } } },
        "responses": { "200": { "description": "Emails resent" } }
      }
    },
    "/document-signatures/{id}/cancel": {
      "post": {
        "summary": "Cancel signature request",
        "description": "Cancels the request and all pending recipients.",
        "tags": ["Documents"],
        "parameters": [{ "$ref": "#/components/parameters/idPath" }],
        "responses": { "200": { "description": "Request cancelled" } }
      }
    },
    "/invoice-batches": {
      "get": {
        "summary": "List invoice batches",
        "description": "Returns batches enriched with employee counts and value totals. Searchable by title.",
        "tags": ["Finance"],
        "parameters": [
          { "$ref": "#/components/parameters/limit" },
          { "$ref": "#/components/parameters/offset" },
          { "$ref": "#/components/parameters/search" },
          { "name": "status", "in": "query", "schema": { "type": "string" } }
        ],
        "responses": { "200": { "description": "Enriched batch list with stats" } }
      }
    },
    "/invoice-batches/{id}": {
      "get": {
        "summary": "Get batch detail",
        "description": "Returns batch with invoices (including employee data), transactions, and stats.",
        "tags": ["Finance"],
        "parameters": [{ "$ref": "#/components/parameters/idPath" }],
        "responses": { "200": { "description": "Full batch with invoices and transactions" }, "404": { "description": "Not found" } }
      }
    },
    "/invoice-batches/{id}/status": {
      "get": {
        "summary": "Payment status",
        "description": "Returns batch info with payment transaction statuses: pending, processing, completed, failed, returned.",
        "tags": ["Finance"],
        "parameters": [{ "$ref": "#/components/parameters/idPath" }],
        "responses": { "200": { "description": "Batch with transaction summary" } }
      }
    },
    "/invoice-batches/{id}/process": {
      "post": {
        "summary": "Process batch (create Transfeera transfers)",
        "description": "Creates PIX/TED transfers for all approved invoices. Features: anti-duplication via idempotency keys, auto-split for values over R$15,000, PIX key type auto-detection. Invoices transition to processing status.",
        "tags": ["Finance"],
        "parameters": [{ "$ref": "#/components/parameters/idPath" }],
        "responses": { "200": { "description": "Processing results with per-invoice status" } }
      }
    },
    "/invoice-batches/{id}/close": {
      "post": {
        "summary": "Close batch (trigger payments)",
        "description": "Closes the Transfeera batch, triggering actual bank transfers. THIS ACTION IS IRREVERSIBLE. Batch must have been processed first.",
        "tags": ["Finance"],
        "parameters": [{ "$ref": "#/components/parameters/idPath" }],
        "responses": { "200": { "description": "Batch closed, payments processing" }, "400": { "description": "Batch not processed yet" } }
      }
    },
    "/employee-invoices": {
      "get": {
        "summary": "List employee invoices",
        "description": "Filterable by status, batch_id, employee_id.",
        "tags": ["Finance"],
        "parameters": [
          { "$ref": "#/components/parameters/limit" },
          { "$ref": "#/components/parameters/offset" },
          { "name": "status", "in": "query", "schema": { "type": "string" } },
          { "name": "batch_id", "in": "query", "schema": { "type": "string", "format": "uuid" } },
          { "name": "employee_id", "in": "query", "schema": { "type": "string", "format": "uuid" } }
        ],
        "responses": { "200": { "description": "Paginated list" } }
      }
    },
    "/employee-invoices/{id}": {
      "get": {
        "summary": "Get invoice detail",
        "description": "Returns invoice with employee data (nome, email, cnpj, cargo, departamento).",
        "tags": ["Finance"],
        "parameters": [{ "$ref": "#/components/parameters/idPath" }],
        "responses": { "200": { "description": "Invoice with employee" }, "404": { "description": "Not found" } }
      },
      "patch": {
        "summary": "Update invoice",
        "description": "Auto-fills paid_at when status transitions to paid.",
        "tags": ["Finance"],
        "parameters": [{ "$ref": "#/components/parameters/idPath" }],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EmployeeInvoiceUpdate" } } } },
        "responses": { "200": { "description": "Updated invoice" } }
      }
    },
    "/invoice-adjustments": {
      "get": {
        "summary": "List invoice adjustments",
        "description": "Returns all extras/deductions for a given invoice, plus a summary with total_additions, total_deductions, and net_applied_to_invoice.",
        "tags": ["Finance"],
        "parameters": [
          { "name": "invoice_id", "in": "query", "required": true, "schema": { "type": "string", "format": "uuid" }, "description": "The employee invoice ID" }
        ],
        "responses": { "200": { "description": "List with summary" } }
      },
      "post": {
        "summary": "Create invoice adjustment",
        "description": "Add an extra (addition) or deduction to an employee invoice. Use apply_to_invoice=true to affect the fiscal total, or false to track without impacting the NF value.",
        "tags": ["Finance"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["invoice_id", "title", "type", "value"],
                "properties": {
                  "invoice_id": { "type": "string", "format": "uuid" },
                  "title": { "type": "string", "example": "Bônus produtividade" },
                  "type": { "type": "string", "enum": ["addition", "deduction"] },
                  "value": { "type": "number", "example": 500 },
                  "apply_to_invoice": { "type": "boolean", "default": true, "description": "If true, value affects the final invoice amount (fiscal). If false, tracked only." },
                  "notes": { "type": "string" }
                }
              }
            }
          }
        },
        "responses": { "201": { "description": "Created adjustment" } }
      }
    },
    "/invoice-adjustments/{id}": {
      "delete": {
        "summary": "Delete invoice adjustment",
        "tags": ["Finance"],
        "parameters": [{ "$ref": "#/components/parameters/idPath" }],
        "responses": { "200": { "description": "Deleted" }, "404": { "description": "Not found" } }
      }
    },
    "/provider-invoices": {
      "get": {
        "summary": "List provider invoices",
        "description": "Invoices from external providers/technicians. Searchable by code. Filterable by status, candidate_id.",
        "tags": ["Finance"],
        "parameters": [
          { "$ref": "#/components/parameters/limit" },
          { "$ref": "#/components/parameters/offset" },
          { "$ref": "#/components/parameters/search" },
          { "name": "status", "in": "query", "schema": { "type": "string" } },
          { "name": "candidate_id", "in": "query", "schema": { "type": "string", "format": "uuid" } }
        ],
        "responses": { "200": { "description": "Paginated list" } }
      }
    },
    "/provider-invoices/{id}": {
      "get": {
        "summary": "Get provider invoice detail",
        "description": "Returns invoice with candidate data (nome, email, cnpj).",
        "tags": ["Finance"],
        "parameters": [{ "$ref": "#/components/parameters/idPath" }],
        "responses": { "200": { "description": "Invoice with candidate" }, "404": { "description": "Not found" } }
      },
      "patch": {
        "summary": "Update provider invoice",
        "description": "Auto-fills reviewed_at on approved, paid_at on paid.",
        "tags": ["Finance"],
        "parameters": [{ "$ref": "#/components/parameters/idPath" }],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProviderInvoiceUpdate" } } } },
        "responses": { "200": { "description": "Updated invoice" } }
      }
    },
    "/whatsapp": {
      "post": {
        "summary": "Send WhatsApp message",
        "description": "Sends a template-based WhatsApp message via Meta Cloud API. Phone numbers auto-normalized to E.164 (Brazilian format).",
        "tags": ["Messaging"],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/WhatsAppSend" } } } },
        "responses": {
          "200": { "description": "Message sent. Returns wamid and provider response." },
          "404": { "description": "Template not found" },
          "405": { "description": "Only POST allowed" }
        }
      }
    },
    "/articles": {
      "get": {
        "summary": "List articles",
        "description": "Blog/knowledge base articles. Searchable by title, slug.",
        "tags": ["Content"],
        "parameters": [
          { "$ref": "#/components/parameters/limit" },
          { "$ref": "#/components/parameters/offset" },
          { "$ref": "#/components/parameters/search" },
          { "name": "status", "in": "query", "schema": { "type": "string", "enum": ["draft", "published", "archived"] } },
          { "name": "category", "in": "query", "schema": { "type": "string" } }
        ],
        "responses": { "200": { "description": "Paginated list" } }
      },
      "post": {
        "summary": "Create article",
        "description": "Creates article. Slug auto-generated from title (NFD normalized, lowercased). 409 on duplicate slug. published_at auto-filled when status=published.",
        "tags": ["Content"],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ArticleCreate" } } } },
        "responses": { "201": { "description": "Article created" }, "409": { "description": "Slug conflict" } }
      }
    },
    "/articles/{id_or_slug}": {
      "get": {
        "summary": "Get article by ID or slug",
        "description": "Accepts UUID or slug string. Returns full article with all SEO fields.",
        "tags": ["Content"],
        "parameters": [{ "name": "id_or_slug", "in": "path", "required": true, "schema": { "type": "string" }, "description": "UUID or URL slug" }],
        "responses": { "200": { "description": "Full article" }, "404": { "description": "Not found" } }
      },
      "patch": {
        "summary": "Update article",
        "description": "All create fields are updatable. Auto-fills published_at on status=published transition.",
        "tags": ["Content"],
        "parameters": [{ "name": "id_or_slug", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": { "200": { "description": "Updated article" } }
      },
      "delete": {
        "summary": "Delete article",
        "description": "Permanently deletes the article. Not recoverable.",
        "tags": ["Content"],
        "parameters": [{ "name": "id_or_slug", "in": "path", "required": true, "schema": { "type": "string" } }],
        "responses": { "200": { "description": "Article deleted" } }
      }
    },
    "/employees": {
      "get": {
        "summary": "List employees",
        "description": "Paginated list with filters. Search by nome, email, cargo.",
        "tags": ["Finance"],
        "parameters": [
          { "name": "status", "in": "query", "schema": { "type": "string", "enum": ["ativo", "desligado", "ferias", "afastado"] } },
          { "name": "departamento", "in": "query", "schema": { "type": "string" } },
          { "name": "tipo_contrato", "in": "query", "schema": { "type": "string", "enum": ["pj", "clt", "estagio"] } },
          { "name": "search", "in": "query", "schema": { "type": "string" } },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 50 } },
          { "name": "offset", "in": "query", "schema": { "type": "integer", "default": 0 } }
        ],
        "responses": { "200": { "description": "Paginated employee list" } }
      },
      "post": {
        "summary": "Create employee",
        "description": "Required: nome, email. Auto-fills cargo=Colaborador, departamento=Geral, tipo_contrato=pj.",
        "tags": ["Finance"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["nome", "email"],
                "properties": {
                  "nome": { "type": "string" },
                  "email": { "type": "string", "format": "email" },
                  "cargo": { "type": "string", "default": "Colaborador" },
                  "departamento": { "type": "string", "default": "Geral" },
                  "tipo_contrato": { "type": "string", "enum": ["pj", "clt", "estagio"], "default": "pj" },
                  "data_admissao": { "type": "string", "format": "date" },
                  "telefone": { "type": "string" },
                  "cpf": { "type": "string" },
                  "cnpj": { "type": "string" },
                  "cidade": { "type": "string" },
                  "estado": { "type": "string" },
                  "salario": { "type": "number" },
                  "pix_key": { "type": "string" },
                  "banco": { "type": "string" },
                  "agencia": { "type": "string" },
                  "conta": { "type": "string" },
                  "observacoes": { "type": "string" },
                  "candidate_id": { "type": "string", "format": "uuid" },
                  "user_id": { "type": "string", "format": "uuid" },
                  "created_by": { "type": "string" }
                }
              }
            }
          }
        },
        "responses": { "201": { "description": "Employee created" } }
      }
    },
    "/employees/{id}": {
      "get": {
        "summary": "Get employee by ID",
        "description": "Returns full employee profile with all fields.",
        "tags": ["Finance"],
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
        "responses": { "200": { "description": "Full employee" }, "404": { "description": "Not found" } }
      }
    },
    "/metrics": {
      "get": {
        "summary": "Platform metrics",
        "description": "Aggregated counts: candidates by stage, total vacancies, open tickets, active service orders.",
        "tags": ["Analytics"],
        "responses": { "200": { "description": "Platform metrics object" } }
      }
    },
    "/payables": {
      "get": {
        "summary": "List payables",
        "description": "List accounts payable with filters for status, date range, and search.",
        "tags": ["Finance"],
        "parameters": [
          { "name": "status", "in": "query", "schema": { "type": "string", "enum": ["pending", "confirmed", "paid", "overdue", "cancelled"] } },
          { "name": "from", "in": "query", "schema": { "type": "string", "format": "date" } },
          { "name": "to", "in": "query", "schema": { "type": "string", "format": "date" } },
          { "name": "search", "in": "query", "schema": { "type": "string" } },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 50 } },
          { "name": "offset", "in": "query", "schema": { "type": "integer", "default": 0 } }
        ],
        "responses": { "200": { "description": "Paginated payables list" } }
      },
      "post": {
        "summary": "Create payable",
        "tags": ["Finance"],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["description", "amount", "due_date"], "properties": { "description": { "type": "string" }, "amount": { "type": "number" }, "due_date": { "type": "string", "format": "date" }, "company_id": { "type": "string" }, "category_id": { "type": "string" }, "bank_account_id": { "type": "string" }, "status": { "type": "string" }, "source": { "type": "string" }, "notes": { "type": "string" } } } } } },
        "responses": { "201": { "description": "Created" } }
      }
    },
    "/payables/{id}": {
      "get": { "summary": "Get payable by ID", "tags": ["Finance"], "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }], "responses": { "200": { "description": "Payable detail with category, company, bank_account" } } },
      "patch": { "summary": "Update payable", "tags": ["Finance"], "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }], "requestBody": { "content": { "application/json": { "schema": { "type": "object", "properties": { "status": { "type": "string" }, "paid_date": { "type": "string" }, "paid_amount": { "type": "number" }, "notes": { "type": "string" } } } } } }, "responses": { "200": { "description": "Updated" } } }
    },
    "/receivables": {
      "get": {
        "summary": "List receivables",
        "description": "List accounts receivable with filters.",
        "tags": ["Finance"],
        "parameters": [
          { "name": "status", "in": "query", "schema": { "type": "string" } },
          { "name": "from", "in": "query", "schema": { "type": "string", "format": "date" } },
          { "name": "to", "in": "query", "schema": { "type": "string", "format": "date" } },
          { "name": "search", "in": "query", "schema": { "type": "string" } },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 50 } },
          { "name": "offset", "in": "query", "schema": { "type": "integer", "default": 0 } }
        ],
        "responses": { "200": { "description": "Paginated receivables list" } }
      },
      "post": {
        "summary": "Create receivable",
        "tags": ["Finance"],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["description", "amount", "due_date"], "properties": { "description": { "type": "string" }, "amount": { "type": "number" }, "due_date": { "type": "string", "format": "date" } } } } } },
        "responses": { "201": { "description": "Created" } }
      }
    },
    "/receivables/{id}": {
      "get": { "summary": "Get receivable by ID", "tags": ["Finance"], "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }], "responses": { "200": { "description": "Receivable detail" } } },
      "patch": { "summary": "Update receivable", "tags": ["Finance"], "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }], "requestBody": { "content": { "application/json": { "schema": { "type": "object", "properties": { "status": { "type": "string" }, "received_date": { "type": "string" }, "received_amount": { "type": "number" } } } } } }, "responses": { "200": { "description": "Updated" } } }
    },
    "/cashflow": {
      "get": {
        "summary": "Cashflow projection",
        "description": "Daily cashflow projection with gross and adjusted balances. Adjusted balance applies default rate (3%) and variable cost (5%) to unpaid receivables.",
        "tags": ["Finance"],
        "parameters": [
          { "name": "from", "in": "query", "schema": { "type": "string", "format": "date" }, "description": "Start date (default: today)" },
          { "name": "to", "in": "query", "schema": { "type": "string", "format": "date" }, "description": "End date" },
          { "name": "days", "in": "query", "schema": { "type": "integer", "default": 90 }, "description": "Number of days (used if 'to' not set)" }
        ],
        "responses": { "200": { "description": "Cashflow summary with daily breakdown" } }
      }
    },
    "/finance-settings": {
      "get": { "summary": "Get finance settings", "tags": ["Finance"], "responses": { "200": { "description": "Current finance settings" } } },
      "patch": { "summary": "Update finance settings", "tags": ["Finance"], "requestBody": { "content": { "application/json": { "schema": { "type": "object", "properties": { "default_default_rate": { "type": "number" }, "default_variable_cost_pct": { "type": "number" }, "payout_batch_day": { "type": "integer" }, "horizon_days": { "type": "integer" } } } } } }, "responses": { "200": { "description": "Updated" } } }
    },
    "/recurring-rules": {
      "get": {
        "summary": "List recurring rules",
        "tags": ["Finance"],
        "parameters": [
          { "name": "type", "in": "query", "schema": { "type": "string", "enum": ["payable", "receivable"] } },
          { "name": "is_active", "in": "query", "schema": { "type": "string", "enum": ["true", "false"] } },
          { "name": "search", "in": "query", "schema": { "type": "string" } }
        ],
        "responses": { "200": { "description": "Paginated recurring rules" } }
      },
      "post": {
        "summary": "Create recurring rule",
        "tags": ["Finance"],
        "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": ["type", "description", "amount", "recurrence", "start_date"], "properties": { "type": { "type": "string", "enum": ["payable", "receivable"] }, "description": { "type": "string" }, "amount": { "type": "number" }, "recurrence": { "type": "string", "enum": ["monthly", "weekly", "biweekly", "quarterly", "yearly"] }, "start_date": { "type": "string", "format": "date" }, "day_of_month": { "type": "integer" }, "end_date": { "type": "string", "format": "date" } } } } } },
        "responses": { "201": { "description": "Created" } }
      }
    },
    "/recurring-rules/{id}": {
      "get": { "summary": "Get recurring rule by ID", "tags": ["Finance"], "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }], "responses": { "200": { "description": "Recurring rule detail" } } },
      "patch": { "summary": "Update recurring rule", "tags": ["Finance"], "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }], "requestBody": { "content": { "application/json": { "schema": { "type": "object", "properties": { "description": { "type": "string" }, "amount": { "type": "number" }, "is_active": { "type": "boolean" } } } } } }, "responses": { "200": { "description": "Updated" } } }
    },
    "/emails": {
      "post": {
        "summary": "Send transactional email",
        "description": "Sends a transactional email via Resend. Supports HTML content, CC/BCC, custom sender, and optional entity/deal tracking. Emails are logged in email_logs and optionally create deal_activities.",
        "tags": ["Email"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["to", "subject", "html"],
                "properties": {
                  "to": { "type": "string", "format": "email", "description": "Recipient email address" },
                  "subject": { "type": "string", "description": "Email subject line" },
                  "html": { "type": "string", "description": "HTML content of the email body" },
                  "text": { "type": "string", "description": "Plain text fallback (auto-generated from subject if omitted)" },
                  "cc": { "type": "array", "items": { "type": "string", "format": "email" }, "description": "CC recipients" },
                  "bcc": { "type": "array", "items": { "type": "string", "format": "email" }, "description": "BCC recipients" },
                  "from_email": { "type": "string", "format": "email", "description": "Override sender email (must be @eunerd.com domain)" },
                  "entity_type": { "type": "string", "description": "Entity type for tracking (e.g. contract, ticket)" },
                  "entity_id": { "type": "string", "format": "uuid", "description": "Entity ID for tracking" },
                  "deal_id": { "type": "string", "format": "uuid", "description": "CRM deal ID — auto-creates deal_activity on success" }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Email sent successfully", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "message": { "type": "string" }, "data": { "type": "object" } } } } } },
          "400": { "description": "Missing required fields or invalid email format" },
          "405": { "description": "Only POST allowed" }
        }
      }
    },
    "/categories": {
      "get": {
        "summary": "List finance categories",
        "operationId": "listCategories",
        "tags": ["Finance"],
        "parameters": [
          { "name": "type", "in": "query", "schema": { "type": "string", "enum": ["payable", "receivable"] }, "description": "Filter by category type" },
          { "name": "search", "in": "query", "schema": { "type": "string" }, "description": "Search by name" },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 50 } },
          { "name": "offset", "in": "query", "schema": { "type": "integer", "default": 0 } }
        ],
        "responses": { "200": { "description": "Paginated categories list" } }
      },
      "post": {
        "summary": "Create finance category",
        "operationId": "createCategory",
        "tags": ["Finance"],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["name", "type"],
                "properties": {
                  "name": { "type": "string" },
                  "type": { "type": "string", "enum": ["payable", "receivable"] },
                  "parent_id": { "type": "string", "format": "uuid", "nullable": true },
                  "omie_code": { "type": "string", "nullable": true, "description": "Omie code for upsert matching" },
                  "is_active": { "type": "boolean", "default": true }
                }
              }
            }
          }
        },
        "responses": { "201": { "description": "Category created or upserted" } }
      }
    },
    "/categories/{id}": {
      "get": { "summary": "Get category by ID", "operationId": "getCategory", "tags": ["Finance"], "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }], "responses": { "200": { "description": "Category detail" } } },
      "patch": { "summary": "Update category", "operationId": "updateCategory", "tags": ["Finance"], "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }], "requestBody": { "content": { "application/json": { "schema": { "type": "object", "properties": { "name": { "type": "string" }, "parent_id": { "type": "string", "format": "uuid", "nullable": true }, "omie_code": { "type": "string", "nullable": true }, "is_active": { "type": "boolean" } } } } } }, "responses": { "200": { "description": "Updated" } } }
    },
    "/bank-accounts": {
      "get": {
        "summary": "List bank accounts",
        "operationId": "listBankAccounts",
        "tags": ["Finance"],
        "parameters": [
          { "name": "is_active", "in": "query", "schema": { "type": "boolean" }, "description": "Filter by active status" },
          { "name": "search", "in": "query", "schema": { "type": "string" }, "description": "Search by name" },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 50 } },
          { "name": "offset", "in": "query", "schema": { "type": "integer", "default": 0 } }
        ],
        "responses": { "200": { "description": "Paginated bank accounts list" } }
      }
    },
    "/bank-accounts/{id}": {
      "get": { "summary": "Get bank account by ID", "operationId": "getBankAccount", "tags": ["Finance"], "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }], "responses": { "200": { "description": "Bank account detail" } } }
    },
    "/interview-bookings": {
      "get": {
        "summary": "List interview bookings",
        "operationId": "listInterviewBookings",
        "tags": ["Operations"],
        "parameters": [
          { "name": "candidate_id", "in": "query", "schema": { "type": "string", "format": "uuid" } },
          { "name": "vacancy_id", "in": "query", "schema": { "type": "string", "format": "uuid" } },
          { "name": "status", "in": "query", "schema": { "type": "string", "enum": ["pending", "confirmed", "cancelled", "completed"] } },
          { "name": "conducted", "in": "query", "schema": { "type": "boolean" } },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 50 } },
          { "name": "offset", "in": "query", "schema": { "type": "integer", "default": 0 } }
        ],
        "responses": { "200": { "description": "Paginated bookings list" } }
      }
    },
    "/interview-bookings/{id}": {
      "get": { "summary": "Get booking by ID", "operationId": "getInterviewBooking", "tags": ["Operations"], "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }], "responses": { "200": { "description": "Booking detail with slot, candidate, vacancy" } } },
      "patch": {
        "summary": "Update interview booking",
        "operationId": "updateInterviewBooking",
        "tags": ["Operations"],
        "parameters": [{ "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "conducted": { "type": "boolean", "description": "Mark as conducted (auto-sets status=completed)" },
                  "conducted_by": { "type": "string", "format": "uuid" },
                  "conduct_notes": { "type": "string" },
                  "conduct_rating": { "type": "integer", "minimum": 1, "maximum": 5 },
                  "status": { "type": "string", "enum": ["pending", "confirmed", "cancelled", "completed"] },
                  "cancellation_reason": { "type": "string" },
                  "notes": { "type": "string" }
                }
              }
            }
          }
        },
        "responses": { "200": { "description": "Booking updated" } }
      }
    },
    "/google-drive/{action}": {
      "post": {
        "summary": "Google Drive operations",
        "operationId": "googleDriveAction",
        "description": "Perform Google Drive operations: resolve-folder (find/create client folder), upload (upload files to folder), save (resolve + upload in one call).",
        "tags": ["Operations"],
        "parameters": [{ "name": "action", "in": "path", "required": true, "schema": { "type": "string", "enum": ["resolve-folder", "upload", "save"] } }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Body varies by action. resolve-folder: {clientName, parentFolderId}. upload: {folderId|clientName+parentFolderId, files[{name,mimeType,content}]}. save: {clientName, parentFolderId, files[...]}.",
                "properties": {
                  "clientName": { "type": "string", "description": "Client folder name (1-255 chars)" },
                  "parentFolderId": { "type": "string", "description": "Google Drive parent folder ID" },
                  "folderId": { "type": "string", "description": "Target folder ID (upload action)" },
                  "files": { "type": "array", "items": { "type": "object", "properties": { "name": { "type": "string" }, "mimeType": { "type": "string" }, "content": { "type": "string", "description": "Base64-encoded file content" } } }, "maxItems": 10 },
                  "overwrite": { "type": "boolean", "default": false },
                  "metadata": { "type": "object", "properties": { "dealId": { "type": "string" }, "conversationId": { "type": "string" }, "generatedBy": { "type": "string" }, "tags": { "type": "array", "items": { "type": "string" } } } }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Operation result with folder info and file upload statuses" },
          "400": { "description": "Invalid action or missing required fields" }
        }
      }
    }
  }
}
