{
  "openapi": "3.1.0",
  "info": {
    "title": "Enknapp Consultant API",
    "description": "Public read-only API for consultant profiles. Supports JSON Resume format for standard CV consumption by AI agents and tools.",
    "version": "1.0.0",
    "contact": {
      "name": "Enknapp",
      "url": "https://enknapp.nu"
    }
  },
  "servers": [
    {
      "url": "https://func-cvbot-dev-swc.azurewebsites.net/api",
      "description": "Production"
    },
    {
      "url": "http://localhost:7071/api",
      "description": "Local development"
    }
  ],
  "paths": {
    "/consultants": {
      "get": {
        "operationId": "listConsultants",
        "summary": "List active consultants",
        "description": "Returns a summary list of all active consultants for a tenant. Useful for discovering available consultant IDs before fetching full profiles.",
        "parameters": [
          {
            "$ref": "#/components/parameters/tenant_id"
          }
        ],
        "responses": {
          "200": {
            "description": "List of active consultants",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "consultants": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ConsultantSummary"
                      }
                    },
                    "count": {
                      "type": "integer",
                      "description": "Number of consultants returned"
                    }
                  },
                  "required": ["consultants", "count"]
                }
              }
            }
          }
        }
      }
    },
    "/consultant-public/{consultant_id}": {
      "get": {
        "operationId": "getConsultantProfile",
        "summary": "Get public consultant profile",
        "description": "Returns the full public profile for a consultant, filtered by visibility settings. Use `?format=jsonresume` to get the profile in JSON Resume standard format.",
        "parameters": [
          {
            "$ref": "#/components/parameters/consultant_id"
          },
          {
            "$ref": "#/components/parameters/tenant_id"
          },
          {
            "name": "format",
            "in": "query",
            "description": "Response format. Omit for internal format, use 'jsonresume' for JSON Resume standard (jsonresume.org/schema).",
            "required": false,
            "schema": {
              "type": "string",
              "enum": ["jsonresume"]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Consultant profile. Schema depends on the `format` parameter.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/ConsultantProfile"
                    },
                    {
                      "$ref": "#/components/schemas/JSONResume"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/consultant-cv/{consultant_id}": {
      "get": {
        "operationId": "downloadConsultantCV",
        "summary": "Download published CV file",
        "description": "Returns the consultant's published CV file (PDF or DOCX) for download. Only available if the consultant has published a public CV.",
        "parameters": [
          {
            "$ref": "#/components/parameters/consultant_id"
          }
        ],
        "responses": {
          "200": {
            "description": "CV file binary",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/vnd.openxmlformats-officedocument.wordprocessingml.document": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            },
            "headers": {
              "Content-Disposition": {
                "schema": {
                  "type": "string"
                },
                "description": "Attachment with original filename"
              },
              "Cache-Control": {
                "schema": {
                  "type": "string"
                },
                "description": "public, max-age=3600"
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/consultant-photo/{consultant_id}": {
      "get": {
        "operationId": "getConsultantPhoto",
        "summary": "Get consultant photo",
        "description": "Returns the consultant's profile photo from blob storage.",
        "parameters": [
          {
            "$ref": "#/components/parameters/consultant_id"
          }
        ],
        "responses": {
          "200": {
            "description": "Photo binary",
            "content": {
              "image/jpeg": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "image/png": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            },
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string"
                },
                "description": "public, max-age=86400"
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/health": {
      "get": {
        "operationId": "healthCheck",
        "summary": "Health check",
        "description": "Returns API health status.",
        "responses": {
          "200": {
            "description": "API is healthy",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HealthResponse"
                }
              }
            }
          }
        }
      }
    },
    "/openapi.json": {
      "get": {
        "operationId": "getOpenAPISpec",
        "summary": "OpenAPI specification",
        "description": "Returns this OpenAPI 3.1 specification.",
        "responses": {
          "200": {
            "description": "OpenAPI specification",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "parameters": {
      "consultant_id": {
        "name": "consultant_id",
        "in": "path",
        "required": true,
        "description": "Consultant identifier (lowercase alphanumeric with hyphens, e.g. 'claudio-torres')",
        "schema": {
          "type": "string",
          "pattern": "^[a-z0-9-]+$"
        }
      },
      "tenant_id": {
        "name": "tenant_id",
        "in": "query",
        "required": false,
        "description": "Tenant identifier for multi-tenant filtering. Defaults to 'edge-pharos'.",
        "schema": {
          "type": "string",
          "default": "edge-pharos"
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Invalid request",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "NotFound": {
        "description": "Resource not found",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      }
    },
    "schemas": {
      "ConsultantSummary": {
        "type": "object",
        "description": "Summary of a consultant for listing purposes",
        "properties": {
          "id": {
            "type": "string",
            "description": "Consultant identifier"
          },
          "display_name": {
            "type": "string",
            "description": "Full name for display"
          },
          "title": {
            "type": "string",
            "description": "Professional title"
          },
          "bio_short": {
            "type": "string",
            "description": "Short biography"
          },
          "entity_type": {
            "type": "string",
            "enum": ["person", "agent"],
            "description": "Whether this is a person or virtual agent"
          },
          "languages": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Spoken languages"
          },
          "has_public_cv": {
            "type": "boolean",
            "description": "Whether a downloadable CV is available"
          }
        },
        "required": ["id", "display_name"]
      },
      "ConsultantProfile": {
        "type": "object",
        "description": "Full public consultant profile in internal format",
        "properties": {
          "id": {
            "type": "string"
          },
          "schema_version": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "bio_short": {
            "type": "string"
          },
          "entity_type": {
            "type": "string",
            "enum": ["person", "agent"]
          },
          "lastModified": {
            "type": "string",
            "format": "date-time"
          },
          "personal": {
            "type": "object",
            "description": "Personal info (name, headline, location, contact)"
          },
          "summary": {
            "type": "object",
            "properties": {
              "short": { "type": "string" },
              "full": { "type": "string" }
            }
          },
          "skills": {
            "type": "object",
            "description": "Skills organized by category plus languages"
          },
          "employment": {
            "type": "array",
            "description": "Employment history"
          },
          "contracts": {
            "type": "array",
            "description": "Consulting contract history"
          },
          "education": {
            "type": "array",
            "description": "Education history"
          },
          "certifications": {
            "type": "array",
            "description": "Professional certifications"
          },
          "_links": {
            "type": "object",
            "description": "Hypermedia links (self, photo, cv, chat)"
          }
        },
        "required": ["id", "name"]
      },
      "JSONResume": {
        "type": "object",
        "description": "Profile in JSON Resume standard format (jsonresume.org/schema)",
        "properties": {
          "$schema": {
            "type": "string",
            "const": "https://raw.githubusercontent.com/jsonresume/resume-schema/v1.0.0/schema.json"
          },
          "basics": {
            "type": "object",
            "properties": {
              "name": { "type": "string" },
              "label": { "type": "string", "description": "Professional headline" },
              "email": { "type": "string", "format": "email" },
              "phone": { "type": "string" },
              "url": { "type": "string", "format": "uri" },
              "summary": { "type": "string" },
              "image": { "type": "string", "format": "uri" },
              "location": {
                "type": "object",
                "properties": {
                  "city": { "type": "string" },
                  "region": { "type": "string" },
                  "countryCode": { "type": "string" }
                }
              },
              "profiles": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "network": { "type": "string" },
                    "url": { "type": "string", "format": "uri" }
                  }
                }
              }
            },
            "required": ["name"]
          },
          "work": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": { "type": "string", "description": "Company name" },
                "position": { "type": "string" },
                "startDate": { "type": "string" },
                "endDate": { "type": "string" },
                "location": { "type": "string" },
                "summary": { "type": "string" },
                "highlights": {
                  "type": "array",
                  "items": { "type": "string" }
                }
              }
            }
          },
          "projects": {
            "type": "array",
            "description": "Consulting contracts / client projects",
            "items": {
              "type": "object",
              "properties": {
                "name": { "type": "string", "description": "Client name" },
                "type": { "type": "string", "const": "consulting" },
                "description": { "type": "string" },
                "startDate": { "type": "string" },
                "endDate": { "type": "string" },
                "roles": {
                  "type": "array",
                  "items": { "type": "string" }
                },
                "entity": { "type": "string", "description": "Broker/agency" },
                "highlights": {
                  "type": "array",
                  "items": { "type": "string" }
                },
                "keywords": {
                  "type": "array",
                  "items": { "type": "string" },
                  "description": "Technologies used"
                }
              }
            }
          },
          "education": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "institution": { "type": "string" },
                "studyType": { "type": "string", "description": "Degree type" },
                "area": { "type": "string", "description": "Field of study" },
                "startDate": { "type": "string" },
                "endDate": { "type": "string" },
                "courses": {
                  "type": "array",
                  "items": { "type": "string" }
                }
              }
            }
          },
          "certificates": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": { "type": "string" },
                "issuer": { "type": "string" },
                "date": { "type": "string" }
              }
            }
          },
          "skills": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": { "type": "string", "description": "Skill category" },
                "keywords": {
                  "type": "array",
                  "items": { "type": "string" }
                }
              }
            }
          },
          "languages": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "language": { "type": "string" },
                "fluency": { "type": "string" }
              }
            }
          },
          "meta": {
            "type": "object",
            "properties": {
              "canonical": { "type": "string", "format": "uri" },
              "version": { "type": "string" },
              "lastModified": { "type": "string", "format": "date-time" }
            }
          }
        },
        "required": ["basics"]
      },
      "HealthResponse": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": ["healthy", "degraded"]
          },
          "timestamp": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "description": "Error message"
          }
        },
        "required": ["error"]
      }
    }
  }
}
