{
  "openapi": "3.0.3",
  "info": {
    "title": "Protein Contact Universe C++ Backend API",
    "description": "Fast API for protein data. Provides search, metadata lookup, and organism browsing endpoints.",
    "version": "1.0.0",
    "contact": {
      "name": "Protein Contact Universe"
    }
  },
  "servers": [
    {
      "url": "/",
      "description": "Current origin"
    }
  ],
  "tags": [
    {"name": "Health", "description": "Health check endpoints"},
    {"name": "Status", "description": "Database status endpoints"},
    {"name": "Search", "description": "Full-text search across proteins and organisms"},
    {"name": "Uniprot", "description": "UniProt metadata lookup"},
    {"name": "Organisms", "description": "Organism-based protein browsing"}
  ],
  "paths": {
    "/api/health": {
      "get": {
        "tags": ["Health"],
        "summary": "Health check",
        "description": "Returns the health status of the API server.",
        "operationId": "healthCheck",
        "responses": {
          "200": {
            "description": "Server is healthy",
            "content": {
              "application/json": {
                "schema": {"$ref": "#/components/schemas/HealthResponse"},
                "examples": {
                  "default": {
                    "summary": "Healthy backend",
                    "value": {"status": "ok"}
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/db/status": {
      "get": {
        "tags": ["Status"],
        "summary": "Database status",
        "description": "Returns approximate counts of organisms and UniProt entries in the active index database.",
        "operationId": "dbStatus",
        "responses": {
          "200": {
            "description": "Database status information",
            "content": {
              "application/json": {
                "schema": {"$ref": "#/components/schemas/DbStatusResponse"},
                "examples": {
                  "default": {
                    "summary": "Status payload",
                    "value": {
                      "unified_index": {
                        "organism_approx": 240000,
                        "uniprot_approx": 241000000
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/search": {
      "get": {
        "tags": ["Search"],
        "summary": "Search proteins and organisms",
        "description": "Full-text search across proteins, UniProt IDs, and organism names. Defaults are pre-filled so Try it out executes with a valid request.",
        "operationId": "search",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "description": "Search query (min 2 characters, max 500)",
            "schema": {
              "type": "string",
              "minLength": 2,
              "maxLength": 500,
              "default": "kinase"
            },
            "example": "kinase"
          },
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "description": "Filter by result type",
            "schema": {
              "type": "string",
              "enum": ["organism", "uniprot", "protein"]
            },
            "example": "protein"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of results (1-100)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 10
            },
            "example": 10
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Number of results to skip (max 10000)",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 10000,
              "default": 0
            },
            "example": 0
          },
          {
            "name": "organism",
            "in": "query",
            "required": false,
            "description": "Optional organism name filter",
            "schema": {
              "type": "string"
            },
            "example": "Homo sapiens"
          },
          {
            "name": "include_organism",
            "in": "query",
            "required": false,
            "description": "Include organism name in UniProt results",
            "schema": {
              "type": "boolean",
              "default": false
            },
            "example": true
          },
          {
            "name": "source",
            "in": "query",
            "required": false,
            "description": "Data source to query",
            "schema": {
              "type": "string",
              "enum": ["alphafold", "swissprot"],
              "default": "alphafold"
            },
            "example": "alphafold"
          }
        ],
        "responses": {
          "200": {
            "description": "Search results",
            "content": {
              "application/json": {
                "schema": {"$ref": "#/components/schemas/SearchResponse"},
                "examples": {
                  "default": {
                    "summary": "Protein search response",
                    "value": {
                      "query": "kinase",
                      "results": [
                        {
                          "kind": "uniprot",
                          "id": "P31749",
                          "label": "RAC-alpha serine/threonine-protein kinase",
                          "sublabel": "AKT1",
                          "gene_name": "AKT1",
                          "seq_length": 480,
                          "score": 2,
                          "organism": "Homo sapiens"
                        }
                      ],
                      "has_more": false,
                      "limit": 10,
                      "offset": 0
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request (unsupported kind/source)",
            "content": {
              "application/json": {
                "schema": {"$ref": "#/components/schemas/Error"},
                "examples": {
                  "default": {
                    "value": {"detail": "Invalid source: foo. Use 'alphafold' or 'swissprot'."}
                  }
                }
              }
            }
          },
          "422": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {"$ref": "#/components/schemas/Error"},
                "examples": {
                  "default": {
                    "value": {"detail": "query parameter 'q' must be at least 2 characters"}
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/uniprot/{uniprotId}": {
      "get": {
        "tags": ["Uniprot"],
        "summary": "Get UniProt metadata",
        "description": "Returns metadata for a specific UniProt accession.",
        "operationId": "getUniprotMetadata",
        "parameters": [
          {
            "name": "uniprotId",
            "in": "path",
            "required": true,
            "description": "UniProt accession ID (e.g., P69905, A0A0B4J2F2)",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9]+$"
            },
            "example": "P69905"
          }
        ],
        "responses": {
          "200": {
            "description": "UniProt metadata",
            "content": {
              "application/json": {
                "schema": {"$ref": "#/components/schemas/UniprotMetadataResponse"},
                "examples": {
                  "default": {
                    "value": {
                      "uniprot_id": "P69905",
                      "organism": "Homo sapiens"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid UniProt ID format",
            "content": {
              "application/json": {
                "schema": {"$ref": "#/components/schemas/Error"},
                "examples": {
                  "default": {
                    "value": {"detail": "Invalid UniProt ID"}
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/organisms": {
      "get": {
        "tags": ["Organisms"],
        "summary": "List proteins by organism",
        "description": "Returns a paginated protein list for an exact organism name.",
        "operationId": "getOrganismProteins",
        "parameters": [
          {
            "name": "name",
            "in": "query",
            "required": true,
            "description": "Exact organism name (max 200 characters)",
            "schema": {
              "type": "string",
              "maxLength": 200,
              "default": "Homo sapiens"
            },
            "example": "Homo sapiens"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of entries (1-500)",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500,
              "default": 100
            },
            "example": 25
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Number of entries to skip (max 100000)",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 100000,
              "default": 0
            },
            "example": 0
          },
          {
            "name": "source",
            "in": "query",
            "required": false,
            "description": "Data source",
            "schema": {
              "type": "string",
              "enum": ["alphafold", "swissprot"],
              "default": "alphafold"
            },
            "example": "alphafold"
          }
        ],
        "responses": {
          "200": {
            "description": "Organism entries",
            "content": {
              "application/json": {
                "schema": {"$ref": "#/components/schemas/OrganismsResponse"},
                "examples": {
                  "default": {
                    "value": {
                      "organism": "Homo sapiens",
                      "entries": [
                        {
                          "uniprot_id": "P69905",
                          "protein_name": "Hemoglobin subunit alpha",
                          "gene_name": "HBA1",
                          "seq_length": 142
                        }
                      ],
                      "has_more": false,
                      "limit": 25,
                      "offset": 0
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid source",
            "content": {
              "application/json": {
                "schema": {"$ref": "#/components/schemas/Error"},
                "examples": {
                  "default": {
                    "value": {"detail": "Invalid source: foo. Use 'alphafold' or 'swissprot'."}
                  }
                }
              }
            }
          },
          "404": {
            "description": "Organism not found",
            "content": {
              "application/json": {
                "schema": {"$ref": "#/components/schemas/Error"},
                "examples": {
                  "default": {
                    "value": {"detail": "Organism not found"}
                  }
                }
              }
            }
          },
          "422": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {"$ref": "#/components/schemas/Error"},
                "examples": {
                  "default": {
                    "value": {"detail": "query parameter 'name' is required"}
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "HealthResponse": {
        "type": "object",
        "required": ["status"],
        "properties": {
          "status": {
            "type": "string",
            "example": "ok"
          }
        }
      },
      "DbStatusResponse": {
        "type": "object",
        "required": ["unified_index"],
        "properties": {
          "unified_index": {
            "type": "object",
            "required": ["organism_approx", "uniprot_approx"],
            "properties": {
              "organism_approx": {
                "type": "integer",
                "description": "Approximate number of organisms"
              },
              "uniprot_approx": {
                "type": "integer",
                "description": "Approximate number of UniProt entries"
              }
            }
          }
        }
      },
      "SearchResult": {
        "type": "object",
        "required": ["kind", "id", "label", "sublabel", "score"],
        "properties": {
          "kind": {
            "type": "string",
            "enum": ["organism", "uniprot", "protein"]
          },
          "id": {"type": "string"},
          "label": {"type": "string"},
          "sublabel": {"type": "string", "nullable": true},
          "gene_name": {"type": "string", "nullable": true},
          "seq_length": {"type": "integer", "nullable": true},
          "score": {"type": "integer"},
          "organism": {"type": "string"}
        }
      },
      "SearchResponse": {
        "type": "object",
        "required": ["query", "results", "has_more", "limit", "offset"],
        "properties": {
          "query": {"type": "string"},
          "results": {
            "type": "array",
            "items": {"$ref": "#/components/schemas/SearchResult"}
          },
          "has_more": {"type": "boolean"},
          "limit": {"type": "integer"},
          "offset": {"type": "integer"}
        }
      },
      "UniprotMetadataResponse": {
        "type": "object",
        "required": ["uniprot_id", "organism"],
        "properties": {
          "uniprot_id": {"type": "string"},
          "organism": {"type": "string", "nullable": true}
        }
      },
      "OrganismEntry": {
        "type": "object",
        "required": ["uniprot_id", "protein_name", "gene_name", "seq_length"],
        "properties": {
          "uniprot_id": {"type": "string"},
          "protein_name": {"type": "string", "nullable": true},
          "gene_name": {"type": "string", "nullable": true},
          "seq_length": {"type": "integer", "nullable": true}
        }
      },
      "OrganismsResponse": {
        "type": "object",
        "required": ["organism", "entries", "has_more", "limit", "offset"],
        "properties": {
          "organism": {"type": "string"},
          "entries": {
            "type": "array",
            "items": {"$ref": "#/components/schemas/OrganismEntry"}
          },
          "has_more": {"type": "boolean"},
          "limit": {"type": "integer"},
          "offset": {"type": "integer"}
        }
      },
      "Error": {
        "type": "object",
        "required": ["detail"],
        "properties": {
          "detail": {
            "type": "string",
            "description": "Error message"
          }
        }
      }
    }
  }
}