{"openapi":"3.0.0","paths":{"/":{"get":{"operationId":"DefaultController_getStatusPage","summary":"Comprobar que la API está operativa","parameters":[],"responses":{"200":{"description":"Página HTML de estado y accesos a la documentación.","content":{"text/html":{"schema":{"type":"string","example":"<!doctype html><html lang=\"es\">...</html>"}}}}}}},"/api/countries":{"post":{"operationId":"CountriesController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCountryDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CountryResponseDto"}}}},"400":{"description":"Petición o datos de entrada no válidos.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"401":{"description":"Clave administrativa ausente o no válida.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"503":{"description":"ADMIN_API_KEY no está configurada en el servidor.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}}},"tags":["countries"],"security":[{"adminApiKey":[]}]},"get":{"operationId":"CountriesController_findAll","parameters":[{"name":"active","required":false,"in":"query","schema":{"type":"boolean"}},{"name":"isoAlfa2","required":false,"in":"query","schema":{"type":"string"}},{"name":"name","required":false,"in":"query","schema":{"type":"string"}},{"name":"alias","required":false,"in":"query","schema":{"type":"string"}},{"name":"slug","required":false,"in":"query","schema":{"type":"string"}},{"name":"year","required":false,"in":"query","schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CountryResponseDto"}}}}}},"tags":["countries"]}},"/api/countries/slug/{slug}":{"get":{"operationId":"CountriesController_findOneBySlug","parameters":[{"name":"slug","required":true,"in":"path","schema":{"example":"espana","type":"string"}},{"name":"year","required":false,"in":"query","schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/CountryResponseDto"}],"example":{"id":1,"name":"España","slug":"espana","alias":["España","Spain"],"isoAlfa2":"ES","isoAlfa3":"ESP","isoNum3":"724","population":48619695,"populationYear":2025,"area":505990,"latitude":40.4637,"longitude":-3.7492,"active":true}}}}},"400":{"description":"Parámetro de ruta o consulta no válido.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"404":{"description":"Country not found","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}}},"tags":["countries"]}},"/api/countries/{id}":{"get":{"operationId":"CountriesController_findOne","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}},{"name":"year","required":false,"in":"query","schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CountryResponseDto"}}}},"400":{"description":"Parámetro de ruta o consulta no válido.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"404":{"description":"Recurso no encontrado.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}}},"tags":["countries"]},"patch":{"operationId":"CountriesController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCountryDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CountryResponseDto"}}}},"400":{"description":"Petición o datos de entrada no válidos.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"401":{"description":"Clave administrativa ausente o no válida.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"404":{"description":"Recurso no encontrado.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"503":{"description":"ADMIN_API_KEY no está configurada en el servidor.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}}},"tags":["countries"],"security":[{"adminApiKey":[]}]},"delete":{"operationId":"CountriesController_remove","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteResponseDto"}}}},"400":{"description":"Petición o datos de entrada no válidos.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"401":{"description":"Clave administrativa ausente o no válida.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"404":{"description":"Recurso no encontrado.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"503":{"description":"ADMIN_API_KEY no está configurada en el servidor.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}}},"tags":["countries"],"security":[{"adminApiKey":[]}]}},"/api/regions":{"post":{"operationId":"RegionsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRegionDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegionResponseDto"}}}},"400":{"description":"Petición o datos de entrada no válidos.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"401":{"description":"Clave administrativa ausente o no válida.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"503":{"description":"ADMIN_API_KEY no está configurada en el servidor.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}}},"tags":["regions"],"security":[{"adminApiKey":[]}]},"get":{"operationId":"RegionsController_findAll","parameters":[{"name":"country","required":false,"in":"query","schema":{"type":"string"}},{"name":"name","required":false,"in":"query","schema":{"type":"string"}},{"name":"alias","required":false,"in":"query","schema":{"type":"string"}},{"name":"code","required":false,"in":"query","schema":{"type":"string"}},{"name":"slug","required":false,"in":"query","schema":{"type":"string"}},{"name":"active","required":false,"in":"query","schema":{"type":"boolean"}},{"name":"year","required":false,"in":"query","schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/RegionResponseDto"}}}}}},"tags":["regions"]}},"/api/regions/slug/{slug}":{"get":{"operationId":"RegionsController_findOneBySlug","parameters":[{"name":"slug","required":true,"in":"path","schema":{"example":"andalucia","type":"string"}},{"name":"year","required":false,"in":"query","schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/RegionResponseDto"}],"example":{"id":1,"country":"ES","name":"Andalucía","slug":"andalucia","alias":["Andalucía","Andalucia"],"code":"01","area":87599,"latitude":37.5443,"longitude":-4.7278,"active":true,"population":8631862,"populationYear":2025}}}}},"400":{"description":"Parámetro de ruta o consulta no válido.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"404":{"description":"Region not found","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}}},"tags":["regions"]}},"/api/regions/{id}":{"get":{"operationId":"RegionsController_findOne","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}},{"name":"year","required":false,"in":"query","schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegionResponseDto"}}}},"400":{"description":"Parámetro de ruta o consulta no válido.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"404":{"description":"Recurso no encontrado.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}}},"tags":["regions"]},"patch":{"operationId":"RegionsController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateRegionDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegionResponseDto"}}}},"400":{"description":"Petición o datos de entrada no válidos.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"401":{"description":"Clave administrativa ausente o no válida.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"404":{"description":"Recurso no encontrado.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"503":{"description":"ADMIN_API_KEY no está configurada en el servidor.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}}},"tags":["regions"],"security":[{"adminApiKey":[]}]},"delete":{"operationId":"RegionsController_remove","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteResponseDto"}}}},"400":{"description":"Petición o datos de entrada no válidos.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"401":{"description":"Clave administrativa ausente o no válida.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"404":{"description":"Recurso no encontrado.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"503":{"description":"ADMIN_API_KEY no está configurada en el servidor.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}}},"tags":["regions"],"security":[{"adminApiKey":[]}]}},"/api/provinces":{"post":{"operationId":"ProvincesController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProvinceDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProvinceResponseDto"}}}},"400":{"description":"Petición o datos de entrada no válidos.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"401":{"description":"Clave administrativa ausente o no válida.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"503":{"description":"ADMIN_API_KEY no está configurada en el servidor.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}}},"tags":["provinces"],"security":[{"adminApiKey":[]}]},"get":{"operationId":"ProvincesController_findAll","parameters":[{"name":"region","required":false,"in":"query","schema":{"type":"integer","format":"int64"}},{"name":"name","required":false,"in":"query","schema":{"type":"string"}},{"name":"alias","required":false,"in":"query","schema":{"type":"string"}},{"name":"code","required":false,"in":"query","schema":{"type":"string"}},{"name":"slug","required":false,"in":"query","schema":{"type":"string"}},{"name":"active","required":false,"in":"query","schema":{"type":"boolean"}},{"name":"year","required":false,"in":"query","schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ProvinceResponseDto"}}}}}},"tags":["provinces"]}},"/api/provinces/slug/{slug}":{"get":{"operationId":"ProvincesController_findOneBySlug","parameters":[{"name":"slug","required":true,"in":"path","schema":{"example":"almeria","type":"string"}},{"name":"year","required":false,"in":"query","schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ProvinceResponseDto"}],"example":{"id":4,"region":1,"name":"Almería","slug":"almeria","alias":["Almería","Almeria"],"code":"04","area":8774,"latitude":37.196,"longitude":-2.344,"active":true,"population":753364,"populationYear":2025}}}}},"400":{"description":"Parámetro de ruta o consulta no válido.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"404":{"description":"Province not found","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}}},"tags":["provinces"]}},"/api/provinces/{id}/geojson":{"get":{"operationId":"ProvincesController_findGeoJson","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"integer","format":"int64","minimum":1}}],"responses":{"200":{"description":"Provincia como Feature GeoJSON.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProvinceGeoJsonFeatureDto"}}}},"400":{"description":"Parámetro de ruta o consulta no válido.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"404":{"description":"Province geometry not found","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}}},"tags":["provinces"]}},"/api/provinces/{id}/localities/geojson":{"get":{"operationId":"ProvincesController_findLocalitiesGeoJson","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"integer","format":"int64","minimum":1}},{"name":"year","required":true,"in":"query","schema":{"type":"integer","format":"int32","minimum":2000},"description":"Año de los datos criminalísticos que debe tener el municipio."}],"responses":{"200":{"description":"GeoJSON FeatureCollection de municipios activos con geometría.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LocalityGeoJsonFeatureCollectionDto"}}}},"400":{"description":"Parámetro de ruta o consulta no válido.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"404":{"description":"Province not found","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}}},"tags":["provinces"]}},"/api/provinces/{id}":{"get":{"operationId":"ProvincesController_findOne","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}},{"name":"year","required":false,"in":"query","schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProvinceResponseDto"}}}},"400":{"description":"Parámetro de ruta o consulta no válido.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"404":{"description":"Recurso no encontrado.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}}},"tags":["provinces"]},"patch":{"operationId":"ProvincesController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateProvinceDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProvinceResponseDto"}}}},"400":{"description":"Petición o datos de entrada no válidos.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"401":{"description":"Clave administrativa ausente o no válida.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"404":{"description":"Recurso no encontrado.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"503":{"description":"ADMIN_API_KEY no está configurada en el servidor.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}}},"tags":["provinces"],"security":[{"adminApiKey":[]}]},"delete":{"operationId":"ProvincesController_remove","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteResponseDto"}}}},"400":{"description":"Petición o datos de entrada no válidos.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"401":{"description":"Clave administrativa ausente o no válida.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"404":{"description":"Recurso no encontrado.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"503":{"description":"ADMIN_API_KEY no está configurada en el servidor.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}}},"tags":["provinces"],"security":[{"adminApiKey":[]}]}},"/api/localities":{"post":{"operationId":"LocalitiesController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLocalityDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LocalityResponseDto"}}}},"400":{"description":"Petición o datos de entrada no válidos.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"401":{"description":"Clave administrativa ausente o no válida.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"503":{"description":"ADMIN_API_KEY no está configurada en el servidor.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}}},"tags":["localities"],"security":[{"adminApiKey":[]}]},"get":{"operationId":"LocalitiesController_findAll","parameters":[{"name":"province","required":false,"in":"query","schema":{"type":"integer","format":"int64"}},{"name":"name","required":false,"in":"query","schema":{"type":"string"}},{"name":"alias","required":false,"in":"query","schema":{"type":"string"}},{"name":"code","required":false,"in":"query","schema":{"type":"string"}},{"name":"slug","required":false,"in":"query","schema":{"type":"string"}},{"name":"active","required":false,"in":"query","schema":{"type":"boolean"}},{"name":"year","required":false,"in":"query","schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LocalityResponseDto"}}}}}},"tags":["localities"]}},"/api/localities/slug/{slug}":{"get":{"operationId":"LocalitiesController_findOneBySlug","parameters":[{"name":"slug","required":true,"in":"path","schema":{"example":"almeria-04013","type":"string"}},{"name":"year","required":false,"in":"query","schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/LocalityResponseDto"}],"example":{"id":13,"province":4,"name":"Almería","slug":"almeria-04013","alias":["Almería","Almeria"],"code":"04013","area":296.21,"latitude":36.834,"longitude":-2.4637,"active":true,"population":203741,"populationYear":2025}}}}},"400":{"description":"Parámetro de ruta o consulta no válido.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"404":{"description":"Locality not found","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}}},"tags":["localities"]}},"/api/localities/{id}":{"get":{"operationId":"LocalitiesController_findOne","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}},{"name":"year","required":false,"in":"query","schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LocalityResponseDto"}}}},"400":{"description":"Parámetro de ruta o consulta no válido.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"404":{"description":"Recurso no encontrado.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}}},"tags":["localities"]},"patch":{"operationId":"LocalitiesController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateLocalityDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LocalityResponseDto"}}}},"400":{"description":"Petición o datos de entrada no válidos.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"401":{"description":"Clave administrativa ausente o no válida.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"404":{"description":"Recurso no encontrado.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"503":{"description":"ADMIN_API_KEY no está configurada en el servidor.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}}},"tags":["localities"],"security":[{"adminApiKey":[]}]},"delete":{"operationId":"LocalitiesController_remove","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteResponseDto"}}}},"400":{"description":"Petición o datos de entrada no válidos.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"401":{"description":"Clave administrativa ausente o no válida.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"404":{"description":"Recurso no encontrado.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"503":{"description":"ADMIN_API_KEY no está configurada en el servidor.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}}},"tags":["localities"],"security":[{"adminApiKey":[]}]}},"/api/crime-categories":{"post":{"operationId":"CrimeCategoriesController_create","summary":"Crear una categoría personalizada de criminalidad","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCrimeCategoryDto"}}}},"responses":{"201":{"description":"Categoría creada con su slug generado.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrimeCategoryResponseDto"}}}},"400":{"description":"Petición o datos de entrada no válidos.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"401":{"description":"Clave administrativa ausente o no válida.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"503":{"description":"ADMIN_API_KEY no está configurada en el servidor.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}}},"tags":["crime-categories"],"security":[{"adminApiKey":[]}]},"get":{"operationId":"CrimeCategoriesController_findAll","summary":"Listar categorías personalizadas de criminalidad","parameters":[{"name":"active","required":false,"in":"query","description":"Filtra por estado activo.","schema":{"type":"boolean"}},{"name":"name","required":false,"in":"query","description":"Coincidencia parcial por nombre.","schema":{"type":"string"}},{"name":"slug","required":false,"in":"query","description":"Coincidencia exacta por slug.","schema":{"example":"delitos-contra-el-patrimonio","type":"string"}},{"name":"alias","required":false,"in":"query","description":"Tipología penal incluida en los alias; se normaliza como slug.","schema":{"type":"string"}},{"name":"year","required":false,"in":"query","schema":{"type":"integer","format":"int32"},"description":"Devuelve solo categorías con datos de criminalidad para el año indicado."}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CrimeCategoryResponseDto"}}}}}},"tags":["crime-categories"]}},"/api/crime-categories/slug/{slug}":{"get":{"operationId":"CrimeCategoriesController_findOneBySlug","summary":"Obtener una categoría personalizada por slug","parameters":[{"name":"slug","required":true,"in":"path","schema":{"example":"delitos-contra-el-patrimonio","type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrimeCategoryResponseDto"}}}},"400":{"description":"Parámetro de ruta o consulta no válido.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"404":{"description":"Crime category not found","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}}},"tags":["crime-categories"]}},"/api/crime-categories/{id}":{"get":{"operationId":"CrimeCategoriesController_findOne","summary":"Obtener una categoría personalizada por ID","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrimeCategoryResponseDto"}}}},"400":{"description":"Parámetro de ruta o consulta no válido.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"404":{"description":"Crime category not found","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}}},"tags":["crime-categories"]},"patch":{"operationId":"CrimeCategoriesController_update","summary":"Actualizar una categoría personalizada","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCrimeCategoryDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrimeCategoryResponseDto"}}}},"400":{"description":"Petición o datos de entrada no válidos.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"401":{"description":"Clave administrativa ausente o no válida.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"404":{"description":"Crime category not found","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"503":{"description":"ADMIN_API_KEY no está configurada en el servidor.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}}},"tags":["crime-categories"],"security":[{"adminApiKey":[]}]},"delete":{"operationId":"CrimeCategoriesController_remove","summary":"Eliminar una categoría personalizada","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteResponseDto"}}}},"400":{"description":"Petición o datos de entrada no válidos.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"401":{"description":"Clave administrativa ausente o no válida.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"404":{"description":"Crime category not found","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"503":{"description":"ADMIN_API_KEY no está configurada en el servidor.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}}},"tags":["crime-categories"],"security":[{"adminApiKey":[]}]}},"/api/crime-balances":{"post":{"operationId":"CrimeBalancesController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCrimeBalanceDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrimeBalanceResponseDto"}}}},"400":{"description":"Petición o datos de entrada no válidos.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"401":{"description":"Clave administrativa ausente o no válida.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"503":{"description":"ADMIN_API_KEY no está configurada en el servidor.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}}},"tags":["crime-balances"],"security":[{"adminApiKey":[]}]},"get":{"operationId":"CrimeBalancesController_findAll","parameters":[{"name":"country","required":false,"in":"query","schema":{"type":"string"}},{"name":"year","required":false,"in":"query","schema":{"type":"integer","format":"int32"}},{"name":"numQuarter","required":false,"in":"query","schema":{"enum":[1,2,3,4],"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CrimeBalanceResponseDto"}}}}}},"tags":["crime-balances"]}},"/api/crime-balances/{country}/{year}/{numQuarter}/file":{"get":{"operationId":"CrimeBalancesController_downloadFile","parameters":[{"name":"country","required":true,"in":"path","schema":{"type":"string"}},{"name":"year","required":true,"in":"path","schema":{"type":"number"}},{"name":"numQuarter","required":true,"in":"path","schema":{"enum":[1,2,3,4],"type":"number"}}],"responses":{"200":{"description":"Documento original almacenado en el balance.","content":{"application/pdf":{"schema":{"type":"string","format":"binary"}},"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"Parámetro de ruta o consulta no válido.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"404":{"description":"Crime balance file not found","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}}},"tags":["crime-balances"]}},"/api/crime-balances/{country}/{year}/{numQuarter}":{"get":{"operationId":"CrimeBalancesController_findOne","parameters":[{"name":"country","required":true,"in":"path","schema":{"type":"string"}},{"name":"year","required":true,"in":"path","schema":{"type":"number"}},{"name":"numQuarter","required":true,"in":"path","schema":{"enum":[1,2,3,4],"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrimeBalanceResponseDto"}}}},"400":{"description":"Parámetro de ruta o consulta no válido.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"404":{"description":"Recurso no encontrado.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}}},"tags":["crime-balances"]},"delete":{"operationId":"CrimeBalancesController_remove","parameters":[{"name":"country","required":true,"in":"path","schema":{"type":"string"}},{"name":"year","required":true,"in":"path","schema":{"type":"number"}},{"name":"numQuarter","required":true,"in":"path","schema":{"enum":[1,2,3,4],"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteResponseDto"}}}},"400":{"description":"Petición o datos de entrada no válidos.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"401":{"description":"Clave administrativa ausente o no válida.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"404":{"description":"Recurso no encontrado.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"503":{"description":"ADMIN_API_KEY no está configurada en el servidor.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}}},"tags":["crime-balances"],"security":[{"adminApiKey":[]}]}},"/api/crime-data":{"post":{"operationId":"CrimeDataController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCrimeDataDto"}}}},"responses":{"201":{"description":"Dato de criminalidad creado.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrimeDataResponseDto"}}}},"400":{"description":"El cuerpo de la petición no es válido.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiErrorDto"}],"example":{"statusCode":400,"message":["numCrimes must not be less than 0"],"error":"Bad Request"}}}}},"401":{"description":"Clave administrativa ausente o no válida.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"409":{"description":"Ya existe un dato para el mismo balance, territorio y tipología penal.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiErrorDto"}],"example":{"statusCode":409,"message":"Crime data already exists for this balance, territory and penal typology","error":"Conflict"}}}}},"503":{"description":"ADMIN_API_KEY no está configurada en el servidor.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}}},"tags":["crime-data"],"security":[{"adminApiKey":[]}]},"get":{"operationId":"CrimeDataController_findAll","summary":"Obtener datos de criminalidad","description":"Devuelve todos los registros que cumplen los filtros, sin paginación ni límite máximo aplicado por la API. Para volúmenes grandes se recomienda acotar por balance y territorio.","parameters":[{"name":"balanceCountry","required":false,"in":"query","schema":{"example":"ES","type":"string"}},{"name":"balanceYear","required":false,"in":"query","schema":{"type":"integer","format":"int32"}},{"name":"balanceNumQuarter","required":false,"in":"query","schema":{"type":"integer","format":"int32","enum":[1,2,3,4],"example":4}},{"name":"territoryLevel","required":false,"in":"query","description":"Nivel de desglose de los registros devueltos. Por ejemplo, territoryType=region&territorySlug=andalucia&territoryLevel=province devuelve las provincias de Andalucía. Combinaciones válidas: country→country|region|province|locality; region→region|province|locality; province→province|locality; locality→locality.","schema":{"enum":["country","region","province","locality"],"type":"string"}},{"name":"territorySlug","required":false,"in":"query","description":"Slug público del territorio que delimita el ámbito. Requiere territoryType.","schema":{"example":"andalucia","type":"string"}},{"name":"territoryType","required":false,"in":"query","description":"Tipo del territorio identificado por territorySlug. Ambos parámetros delimitan el ámbito geográfico; territoryLevel decide el nivel de los registros.","schema":{"enum":["country","region","province","locality"],"type":"string"}},{"name":"includeZeroCrimes","required":false,"in":"query","schema":{"example":false,"type":"boolean"}}],"responses":{"200":{"description":"Listado completo de registros filtrados.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CrimeDataResponseDto"},"example":[{"id":42,"balanceCountry":"ES","balanceYear":2025,"balanceNumQuarter":4,"territoryLevel":"province","province":4,"penalTypology":"Robos con fuerza en domicilios","penalTypologySlug":"robos-con-fuerza-en-domicilios","numCrimes":153}]}}}},"400":{"description":"Los filtros de consulta no son válidos.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiErrorDto"}],"example":{"statusCode":400,"message":"territorySlug and territoryType must be provided together","error":"Bad Request"}}}}}},"tags":["crime-data"]}},"/api/crime-data/import/bulk":{"post":{"operationId":"CrimeDataController_importBulk","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportCrimeDataBulkDto"}}}},"responses":{"201":{"description":"Resultado de la importación masiva.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportCrimeDataBulkResponseDto"}}}},"400":{"description":"La carga masiva no cumple el formato o los límites permitidos.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiErrorDto"}],"example":{"statusCode":400,"message":["records must contain no more than 5000 elements"],"error":"Bad Request"}}}}},"401":{"description":"Clave administrativa ausente o no válida.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"503":{"description":"ADMIN_API_KEY no está configurada en el servidor.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}}},"tags":["crime-data"],"security":[{"adminApiKey":[]}]}},"/api/crime-data/summary":{"get":{"operationId":"CrimeDataController_summarize","summary":"Obtener el total de criminalidad","description":"Aplica los mismos filtros territoriales y de balance que el listado y devuelve un elemento por territorio. Con balanceYear, cada entrada contiene solo categorías personalizadas activas con datos en ese año, calculadas mediante sus alias.","parameters":[{"name":"balanceCountry","required":false,"in":"query","schema":{"example":"ES","type":"string"}},{"name":"balanceYear","required":false,"in":"query","schema":{"type":"integer","format":"int32"}},{"name":"balanceNumQuarter","required":false,"in":"query","schema":{"type":"integer","format":"int32","enum":[1,2,3,4],"example":4}},{"name":"territoryLevel","required":false,"in":"query","description":"Nivel de desglose sobre el que se suman los datos. Combinaciones válidas con el ámbito: country→country|region|province|locality; region→region|province|locality; province→province|locality; locality→locality.","schema":{"enum":["country","region","province","locality"],"type":"string"}},{"name":"territorySlug","required":false,"in":"query","description":"Slug público del territorio que delimita el ámbito. Requiere territoryType.","schema":{"example":"almeria","type":"string"}},{"name":"territoryType","required":false,"in":"query","description":"Tipo de territorySlug. El slug y territoryType delimitan el ámbito; territoryLevel determina el nivel de desglose.","schema":{"enum":["country","region","province","locality"],"type":"string"}}],"responses":{"200":{"description":"Resúmenes agrupados por territorio del nivel solicitado.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CrimeDataSummaryResponseDto"},"example":[{"territoryCode":"04","territorySlug":"almeria","territoryName":"Almería","territoryLevel":"province","population":753364,"populationYear":2025,"area":8774,"totalCrimes":1842,"crimes":[{"categoryId":3,"categoryName":"Delitos contra el patrimonio","categorySlug":"delitos-contra-el-patrimonio","subcategories":[{"subcategoryName":"Robos con fuerza en domicilios","subcategorySlug":"robos-con-fuerza-en-domicilios","totalCrimes":1842}],"totalCrimes":1842,"hasData":true}]}]}}}},"400":{"description":"Los filtros territoriales del resumen no son válidos.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiErrorDto"}],"example":{"statusCode":400,"message":"territoryLevel must be equal to or more detailed than territoryType","error":"Bad Request"}}}}}},"tags":["crime-data"]}},"/api/crime-data/available-periods":{"get":{"operationId":"CrimeDataController_findAvailablePeriods","summary":"Obtener los periodos con datos de criminalidad disponibles","parameters":[{"name":"country","required":true,"in":"query","schema":{"example":"ES","type":"string"}}],"responses":{"200":{"description":"Años y trimestres disponibles para el país, ordenados del año más reciente al más antiguo.","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","required":["year","quarters"],"properties":{"year":{"type":"integer","example":2027},"quarters":{"type":"array","items":{"type":"integer","enum":[1,2,3,4]},"example":[1,2]}}},"example":[{"year":2027,"quarters":[1,2]},{"year":2026,"quarters":[4]}]}}}},"400":{"description":"El código de país no es válido.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiErrorDto"}],"example":{"statusCode":400,"message":"country must be a two-letter ISO code","error":"Bad Request"}}}}}},"tags":["crime-data"]}},"/api/crime-data/{id}":{"get":{"operationId":"CrimeDataController_findOne","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"Dato de criminalidad solicitado.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrimeDataResponseDto"}}}},"400":{"description":"El ID no es un número entero válido.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiErrorDto"}],"example":{"statusCode":400,"message":"Validation failed (numeric string is expected)","error":"Bad Request"}}}}},"404":{"description":"Dato de criminalidad no encontrado.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiErrorDto"}],"example":{"statusCode":404,"message":"Crime data not found","error":"Not Found"}}}}}},"tags":["crime-data"]},"patch":{"operationId":"CrimeDataController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCrimeDataDto"}}}},"responses":{"200":{"description":"Dato de criminalidad actualizado.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrimeDataResponseDto"}}}},"400":{"description":"El ID o el cuerpo de la actualización no son válidos.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiErrorDto"}],"example":{"statusCode":400,"message":["numCrimes must not be less than 0"],"error":"Bad Request"}}}}},"401":{"description":"Clave administrativa ausente o no válida.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"404":{"description":"Dato de criminalidad no encontrado.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiErrorDto"}],"example":{"statusCode":404,"message":"Crime data not found","error":"Not Found"}}}}},"409":{"description":"La actualización produciría un dato de criminalidad duplicado.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiErrorDto"}],"example":{"statusCode":409,"message":"Crime data already exists for this balance, territory and penal typology","error":"Conflict"}}}}},"503":{"description":"ADMIN_API_KEY no está configurada en el servidor.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}}},"tags":["crime-data"],"security":[{"adminApiKey":[]}]},"delete":{"operationId":"CrimeDataController_remove","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"Confirmación de borrado.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteResponseDto"}}}},"400":{"description":"El ID no es un número entero válido.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiErrorDto"}],"example":{"statusCode":400,"message":"Validation failed (numeric string is expected)","error":"Bad Request"}}}}},"401":{"description":"Clave administrativa ausente o no válida.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"404":{"description":"Dato de criminalidad no encontrado.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ApiErrorDto"}],"example":{"statusCode":404,"message":"Crime data not found","error":"Not Found"}}}}},"503":{"description":"ADMIN_API_KEY no está configurada en el servidor.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}}},"tags":["crime-data"],"security":[{"adminApiKey":[]}]}},"/api/crime-data/import/pdf":{"post":{"operationId":"CrimeDataImportController_importPdf","parameters":[],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"country":{"type":"string","example":"ES"},"year":{"type":"integer","example":2025},"numQuarter":{"type":"integer","enum":[1,2,3,4],"example":4},"createMissingTerritories":{"type":"boolean","example":false},"pdf":{"type":"string","format":"binary"}},"required":["country","year","pdf"]}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportCrimeDataPdfResponseDto"}}}},"400":{"description":"PDF ausente, inválido o sin filas reconocibles para el año solicitado.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"401":{"description":"Clave administrativa ausente o no válida.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"413":{"description":"El fichero supera el límite de subida configurado.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"500":{"description":"El servidor no tiene disponible el binario pdftotext.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"503":{"description":"ADMIN_API_KEY no está configurada en el servidor.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}}},"tags":["crime-data"],"security":[{"adminApiKey":[]}]}},"/api/crime-data/import/delimited":{"post":{"operationId":"CrimeDataImportController_importDelimited","parameters":[],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"country":{"type":"string","example":"ES"},"year":{"type":"integer","example":2024,"description":"Opcional; se infiere de la cabecera."},"numQuarter":{"type":"integer","enum":[1,2,3,4],"example":4,"description":"Opcional; se infiere de la cabecera."},"createMissingTerritories":{"type":"boolean","default":true,"description":"Crea territorios ausentes. En este importador está activado por defecto."},"dataFile":{"type":"string","format":"binary","description":"CSV o TXT oficial usado para extraer los datos."},"pdf":{"type":"string","format":"binary","description":"PDF original que se conservará en el balance."}},"required":["country","dataFile","pdf"]}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportCrimeDataPdfResponseDto"}}}},"400":{"description":"Falta el fichero de datos o el PDF, o no se pueden inferir año, trimestre o registros.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"401":{"description":"Clave administrativa ausente o no válida.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"413":{"description":"El CSV/TXT o el PDF supera el límite de subida configurado.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"500":{"description":"Error inesperado al almacenar el balance o sus datos.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"503":{"description":"ADMIN_API_KEY no está configurada en el servidor.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}}},"tags":["crime-data"],"security":[{"adminApiKey":[]}]}},"/api/territories/import/reference":{"post":{"operationId":"TerritoryReferenceImportController_importReference","parameters":[],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"country":{"type":"string","example":"ES"},"file":{"type":"string","format":"binary"}},"required":["file"]}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportTerritoryReferenceResponseDto"}}}},"400":{"description":"Fichero ausente, vacío o con un formato no soportado.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"401":{"description":"Clave administrativa ausente o no válida.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"413":{"description":"El fichero supera el límite de subida configurado.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"500":{"description":"Error inesperado al procesar o almacenar la importación.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"503":{"description":"ADMIN_API_KEY no está configurada en el servidor.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}}},"tags":["territories"],"security":[{"adminApiKey":[]}]}},"/api/territories/import/enrichment":{"post":{"operationId":"TerritoryReferenceImportController_importEnrichment","parameters":[],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"mode":{"type":"string","enum":["areas","population","both"],"example":"both"},"country":{"type":"string","example":"ES"},"minYear":{"type":"number","example":2015},"maxYear":{"type":"number","example":2025},"areasFile":{"type":"string","format":"binary"},"populationFile":{"type":"string","format":"binary"}},"required":["mode"]}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportTerritoryEnrichmentResponseDto"}}}},"400":{"description":"Falta un fichero requerido por el modo seleccionado o el contenido no es válido.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"401":{"description":"Clave administrativa ausente o no válida.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"413":{"description":"El fichero supera el límite de subida configurado.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"500":{"description":"Error inesperado al procesar o almacenar la importación.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"503":{"description":"ADMIN_API_KEY no está configurada en el servidor.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}}},"tags":["territories"],"security":[{"adminApiKey":[]}]}},"/api/territory-populations":{"post":{"operationId":"TerritoryPopulationsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTerritoryPopulationDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TerritoryPopulationResponseDto"}}}},"400":{"description":"Petición o datos de entrada no válidos.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"401":{"description":"Clave administrativa ausente o no válida.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"503":{"description":"ADMIN_API_KEY no está configurada en el servidor.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}}},"tags":["territory-populations"],"security":[{"adminApiKey":[]}]},"get":{"operationId":"TerritoryPopulationsController_findAll","parameters":[{"name":"year","required":false,"in":"query","schema":{"type":"integer","format":"int32"}},{"name":"region","required":false,"in":"query","schema":{"type":"integer","format":"int64"}},{"name":"province","required":false,"in":"query","schema":{"type":"integer","format":"int64"}},{"name":"locality","required":false,"in":"query","schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TerritoryPopulationResponseDto"}}}}}},"tags":["territory-populations"]}},"/api/territory-populations/import":{"post":{"operationId":"TerritoryPopulationsController_importPopulations","parameters":[],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"country":{"type":"string","example":"ES"},"minYear":{"type":"integer","format":"int32","example":2015},"maxYear":{"type":"integer","format":"int32","example":2025},"file":{"type":"string","format":"binary"}},"required":["file"]}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportTerritoryPopulationResponseDto"}}}},"400":{"description":"Petición o datos de entrada no válidos.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"401":{"description":"Clave administrativa ausente o no válida.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"413":{"description":"El fichero supera el límite de subida configurado.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"500":{"description":"Error inesperado al procesar o almacenar la importación.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"503":{"description":"ADMIN_API_KEY no está configurada en el servidor.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}}},"tags":["territory-populations"],"security":[{"adminApiKey":[]}]}},"/api/territory-populations/{id}":{"get":{"operationId":"TerritoryPopulationsController_findOne","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TerritoryPopulationResponseDto"}}}},"400":{"description":"Parámetro de ruta o consulta no válido.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"404":{"description":"Recurso no encontrado.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}}},"tags":["territory-populations"]},"patch":{"operationId":"TerritoryPopulationsController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTerritoryPopulationDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TerritoryPopulationResponseDto"}}}},"400":{"description":"Petición o datos de entrada no válidos.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"401":{"description":"Clave administrativa ausente o no válida.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"404":{"description":"Recurso no encontrado.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"503":{"description":"ADMIN_API_KEY no está configurada en el servidor.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}}},"tags":["territory-populations"],"security":[{"adminApiKey":[]}]},"delete":{"operationId":"TerritoryPopulationsController_remove","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteResponseDto"}}}},"400":{"description":"Petición o datos de entrada no válidos.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"401":{"description":"Clave administrativa ausente o no válida.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"404":{"description":"Recurso no encontrado.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}},"503":{"description":"ADMIN_API_KEY no está configurada en el servidor.","content":{"application/json":{"schema":{"type":"object","required":["statusCode","message"],"properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"Bad Request"},{"type":"array","items":{"type":"string"}}]},"error":{"type":"string","example":"Bad Request"}}}}}}},"tags":["territory-populations"],"security":[{"adminApiKey":[]}]}}},"info":{"title":"InfoDelito API","description":"API REST para gestionar catalogos territoriales y datos agregados de criminalidad.","version":"1.0.0","contact":{}},"tags":[{"name":"countries","description":"Paises"},{"name":"regions","description":"Comunidades autonomas o regiones"},{"name":"provinces","description":"Provincias"},{"name":"localities","description":"Municipios o localidades"},{"name":"territories","description":"Importacion de referencias territoriales"},{"name":"territory-populations","description":"Poblacion anual por territorio"},{"name":"crime-categories","description":"Categorias penales"},{"name":"crime-balances","description":"Balances de criminalidad"},{"name":"crime-data","description":"Datos agregados de criminalidad"}],"servers":[],"components":{"securitySchemes":{"adminApiKey":{"type":"apiKey","in":"header","name":"X-Admin-Api-Key","description":"Obligatoria para POST, PUT, PATCH y DELETE."}},"schemas":{"CountryResponseDto":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"slug":{"type":"string","example":"espana"},"alias":{"type":"array","items":{"type":"string"}},"isoAlfa2":{"type":"string"},"isoAlfa3":{"type":"string"},"isoNum3":{"type":"string"},"population":{"type":"integer","nullable":true,"format":"int64"},"populationYear":{"type":"integer","nullable":true,"format":"int32"},"area":{"type":"number","format":"double"},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"active":{"type":"boolean"}},"required":["id","name","slug","alias","isoAlfa2","isoAlfa3","isoNum3","area","active"]},"CreateCountryDto":{"type":"object","properties":{"population":{"type":"integer","minimum":0,"format":"int64"},"name":{"type":"string","minLength":1,"maxLength":200},"alias":{"type":"array","items":{"type":"string","maxLength":200,"minLength":1}},"isoAlfa2":{"type":"string","minLength":2,"maxLength":2},"isoAlfa3":{"type":"string","minLength":3,"maxLength":3},"isoNum3":{"type":"string","minLength":3,"maxLength":3},"area":{"type":"number","minimum":0},"latitude":{"type":"number","minimum":-90,"maximum":90},"longitude":{"type":"number","minimum":-180,"maximum":180},"active":{"type":"boolean"}},"required":["population","name","isoAlfa2","isoAlfa3","isoNum3","area"]},"UpdateCountryDto":{"type":"object","properties":{"population":{"type":"integer","minimum":0,"format":"int64"},"name":{"type":"string","minLength":1,"maxLength":200},"alias":{"type":"array","items":{"type":"string","maxLength":200,"minLength":1}},"isoAlfa2":{"type":"string","minLength":2,"maxLength":2},"isoAlfa3":{"type":"string","minLength":3,"maxLength":3},"isoNum3":{"type":"string","minLength":3,"maxLength":3},"area":{"type":"number","minimum":0},"latitude":{"type":"number","minimum":-90,"maximum":90},"longitude":{"type":"number","minimum":-180,"maximum":180},"active":{"type":"boolean"}}},"DeleteResponseDto":{"type":"object","properties":{"deleted":{"type":"boolean","example":true}},"required":["deleted"]},"RegionResponseDto":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"country":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string","example":"andalucia"},"alias":{"type":"array","items":{"type":"string"}},"code":{"type":"string"},"area":{"type":"number","format":"double"},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"active":{"type":"boolean"},"population":{"type":"integer","nullable":true,"format":"int64"},"populationYear":{"type":"integer","nullable":true,"format":"int32"}},"required":["id","country","name","slug","alias","area","active"]},"CreateRegionDto":{"type":"object","properties":{"country":{"type":"string","minLength":2,"maxLength":2},"name":{"type":"string","minLength":1,"maxLength":200},"alias":{"type":"array","items":{"type":"string","maxLength":200,"minLength":1}},"code":{"type":"string","minLength":1,"maxLength":10},"area":{"type":"number","minimum":0},"latitude":{"type":"number","minimum":-90,"maximum":90},"longitude":{"type":"number","minimum":-180,"maximum":180},"active":{"type":"boolean"}},"required":["country","name","area"]},"UpdateRegionDto":{"type":"object","properties":{"country":{"type":"string","minLength":2,"maxLength":2},"name":{"type":"string","minLength":1,"maxLength":200},"alias":{"type":"array","items":{"type":"string","maxLength":200,"minLength":1}},"code":{"type":"string","minLength":1,"maxLength":10},"area":{"type":"number","minimum":0},"latitude":{"type":"number","minimum":-90,"maximum":90},"longitude":{"type":"number","minimum":-180,"maximum":180},"active":{"type":"boolean"}}},"ProvinceResponseDto":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"region":{"type":"integer","format":"int64"},"name":{"type":"string"},"slug":{"type":"string","example":"almeria"},"alias":{"type":"array","items":{"type":"string"}},"code":{"type":"string"},"area":{"type":"number","format":"double"},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"active":{"type":"boolean"},"population":{"type":"integer","nullable":true,"format":"int64"},"populationYear":{"type":"integer","nullable":true,"format":"int32"}},"required":["id","region","name","slug","alias","area","active"]},"CreateProvinceDto":{"type":"object","properties":{"region":{"type":"integer","minimum":1,"format":"int64"},"name":{"type":"string","minLength":1,"maxLength":200},"alias":{"type":"array","items":{"type":"string","maxLength":200,"minLength":1}},"code":{"type":"string","minLength":1,"maxLength":10},"area":{"type":"number","minimum":0},"latitude":{"type":"number","minimum":-90,"maximum":90},"longitude":{"type":"number","minimum":-180,"maximum":180},"active":{"type":"boolean"}},"required":["region","name","area"]},"GeoJsonGeometryDto":{"type":"object","properties":{"type":{"type":"string","enum":["Point","MultiPoint","LineString","MultiLineString","Polygon","MultiPolygon","GeometryCollection"]},"coordinates":{"oneOf":[{"type":"array","items":{"type":"number","format":"double"}},{"type":"array","items":{"type":"array","items":{"type":"number","format":"double"}}},{"type":"array","items":{"type":"array","items":{"type":"array","items":{"type":"number","format":"double"}}}},{"type":"array","items":{"type":"array","items":{"type":"array","items":{"type":"array","items":{"type":"number","format":"double"}}}}}],"description":"Coordenadas GeoJSON como arrays anidados. La profundidad depende de type."}},"required":["type","coordinates"]},"ProvinceGeoJsonPropertiesDto":{"type":"object","properties":{"code":{"type":"string","nullable":true,"example":"04"},"name":{"type":"string"},"slug":{"type":"string","example":"almeria"},"region":{"type":"integer","format":"int64"}},"required":["name","slug","region"]},"ProvinceGeoJsonFeatureDto":{"type":"object","properties":{"type":{"type":"string","enum":["Feature"]},"geometry":{"$ref":"#/components/schemas/GeoJsonGeometryDto"},"properties":{"$ref":"#/components/schemas/ProvinceGeoJsonPropertiesDto"}},"required":["type","geometry","properties"]},"LocalityGeoJsonPropertiesDto":{"type":"object","properties":{"code":{"type":"string","nullable":true,"example":"04013"},"name":{"type":"string"},"slug":{"type":"string","example":"almeria-04013"},"province":{"type":"integer","format":"int64"}},"required":["name","slug","province"]},"LocalityGeoJsonFeatureDto":{"type":"object","properties":{"type":{"type":"string","enum":["Feature"]},"geometry":{"$ref":"#/components/schemas/GeoJsonGeometryDto"},"properties":{"$ref":"#/components/schemas/LocalityGeoJsonPropertiesDto"}},"required":["type","geometry","properties"]},"LocalityGeoJsonFeatureCollectionDto":{"type":"object","properties":{"type":{"type":"string","enum":["FeatureCollection"]},"features":{"type":"array","items":{"$ref":"#/components/schemas/LocalityGeoJsonFeatureDto"}}},"required":["type","features"]},"UpdateProvinceDto":{"type":"object","properties":{"region":{"type":"integer","minimum":1,"format":"int64"},"name":{"type":"string","minLength":1,"maxLength":200},"alias":{"type":"array","items":{"type":"string","maxLength":200,"minLength":1}},"code":{"type":"string","minLength":1,"maxLength":10},"area":{"type":"number","minimum":0},"latitude":{"type":"number","minimum":-90,"maximum":90},"longitude":{"type":"number","minimum":-180,"maximum":180},"active":{"type":"boolean"}}},"LocalityResponseDto":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"province":{"type":"integer","format":"int64"},"name":{"type":"string"},"slug":{"type":"string","example":"almeria"},"alias":{"type":"array","items":{"type":"string"}},"code":{"type":"string"},"area":{"type":"number","format":"double"},"latitude":{"type":"number","format":"double"},"longitude":{"type":"number","format":"double"},"active":{"type":"boolean"},"population":{"type":"integer","nullable":true,"format":"int64"},"populationYear":{"type":"integer","nullable":true,"format":"int32"}},"required":["id","province","name","slug","alias","area","active"]},"CreateLocalityDto":{"type":"object","properties":{"province":{"type":"integer","minimum":1,"format":"int64"},"name":{"type":"string","minLength":1,"maxLength":200},"alias":{"type":"array","items":{"type":"string","maxLength":200,"minLength":1}},"code":{"type":"string","minLength":1,"maxLength":20},"area":{"type":"number","minimum":0},"latitude":{"type":"number","minimum":-90,"maximum":90},"longitude":{"type":"number","minimum":-180,"maximum":180},"active":{"type":"boolean"}},"required":["province","name","area"]},"UpdateLocalityDto":{"type":"object","properties":{"province":{"type":"integer","minimum":1,"format":"int64"},"name":{"type":"string","minLength":1,"maxLength":200},"alias":{"type":"array","items":{"type":"string","maxLength":200,"minLength":1}},"code":{"type":"string","minLength":1,"maxLength":20},"area":{"type":"number","minimum":0},"latitude":{"type":"number","minimum":-90,"maximum":90},"longitude":{"type":"number","minimum":-180,"maximum":180},"active":{"type":"boolean"}}},"CreateCrimeCategoryDto":{"type":"object","properties":{"alias":{"example":["Hurtos","Robos con fuerza en domicilios"],"description":"Tipologías penales agrupadas por la categoría. El backend normaliza cada valor como slug; el slug de la categoría se genera por separado.","type":"array","items":{"type":"string"}},"name":{"type":"string","minLength":1,"maxLength":200},"active":{"type":"boolean"}},"required":["alias","name"]},"CrimeCategoryResponseDto":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"name":{"type":"string"},"slug":{"type":"string","example":"delitos-contra-el-patrimonio","description":"Identificador público único generado por el backend a partir del nombre.","readOnly":true},"alias":{"example":["robos-con-fuerza-en-domicilios"],"description":"Slugs normalizados de las tipologías penales asociadas; no incluye el slug de la categoría.","type":"array","items":{"type":"string"}},"active":{"type":"boolean"}},"required":["id","name","slug","alias","active"]},"UpdateCrimeCategoryDto":{"type":"object","properties":{"alias":{"example":["Hurtos","Robos con fuerza en domicilios"],"description":"Lista completa de tipologías penales agrupadas. Sustituye la lista anterior y no incluye el slug de la categoría.","type":"array","items":{"type":"string"}},"name":{"type":"string","minLength":1,"maxLength":200},"active":{"type":"boolean"}}},"CreateCrimeBalanceDto":{"type":"object","properties":{"year":{"type":"integer","format":"int32"},"numQuarter":{"type":"number","enum":[1,2,3,4],"format":"int32"},"country":{"type":"string","minLength":2,"maxLength":2}},"required":["year","numQuarter","country"]},"CrimeBalanceResponseDto":{"type":"object","properties":{"country":{"type":"string"},"year":{"type":"integer","format":"int32"},"numQuarter":{"type":"number","format":"int32","enum":[1,2,3,4]},"fileName":{"type":"string"},"fileMimeType":{"type":"string"},"fileSize":{"type":"integer","format":"int64"},"fileUploadedAt":{"type":"string","format":"date-time"},"hasFile":{"type":"boolean"}},"required":["country","year","numQuarter"]},"ApiErrorDto":{"type":"object","properties":{"statusCode":{"type":"integer","format":"int32","example":400},"message":{"oneOf":[{"type":"string","example":"territorySlug and territoryType must be provided together"},{"type":"array","items":{"type":"string"},"example":["balanceYear must be an integer number"]}]},"error":{"type":"string","example":"Bad Request"}},"required":["statusCode","message","error"]},"CrimeDataResponseDto":{"type":"object","properties":{"id":{"type":"integer","format":"int64","example":42},"balanceCountry":{"type":"string","example":"ES"},"balanceYear":{"type":"integer","format":"int32","example":2025},"balanceNumQuarter":{"type":"number","format":"int32","enum":[1,2,3,4],"example":4},"territoryLevel":{"type":"string","enum":["country","region","province","locality"],"example":"province"},"region":{"type":"integer","format":"int64","example":7},"province":{"type":"integer","format":"int64","example":28},"locality":{"type":"integer","format":"int64","example":79},"penalTypology":{"type":"string","example":"Robos con fuerza en domicilios","description":"Nombre textual de la tipología penal almacenada en los datos de criminalidad."},"penalTypologySlug":{"type":"string","example":"robos-con-fuerza-en-domicilios","description":"Código público estable generado por el backend a partir de la tipología penal."},"numCrimes":{"type":"integer","format":"int64","example":153}},"required":["id","balanceCountry","balanceYear","balanceNumQuarter","territoryLevel","penalTypology","penalTypologySlug","numCrimes"]},"CrimeDataSummarySubcategoryDto":{"type":"object","properties":{"subcategoryName":{"type":"string","example":"Robos con fuerza en domicilios"},"subcategorySlug":{"type":"string","example":"robos-con-fuerza-en-domicilios"},"totalCrimes":{"type":"integer","nullable":true,"format":"int64","example":153,"description":"Total propio de la tipología; null cuando no existen registros para el territorio."}},"required":["subcategoryName","subcategorySlug","totalCrimes"]},"CrimeDataSummaryCrimeDto":{"type":"object","properties":{"categoryId":{"type":"integer","format":"int64","example":3},"categoryName":{"type":"string","example":"Delitos contra el patrimonio","description":"Nombre de la categoría personalizada activa."},"categorySlug":{"type":"string","example":"delitos-contra-el-patrimonio"},"subcategories":{"description":"Tipologías penales de la categoría que tienen datos en el territorio y periodo, con su total individual.","type":"array","items":{"$ref":"#/components/schemas/CrimeDataSummarySubcategoryDto"}},"totalCrimes":{"type":"integer","nullable":true,"format":"int64","example":731,"description":"Suma de los alias cuando existen registros; 0 si existen con valor cero y null si la categoría no está contemplada."},"hasData":{"type":"boolean","example":true,"description":"Indica si existe al menos un registro original para alguno de los alias de la categoría."}},"required":["categoryId","categoryName","categorySlug","subcategories","totalCrimes","hasData"]},"CrimeDataSummaryResponseDto":{"type":"object","properties":{"territoryCode":{"type":"string","example":"04","description":"Código público del territorio; usa el código oficial disponible o un slug estable del nombre."},"territorySlug":{"type":"string","example":"almeria","description":"Slug público persistido del territorio."},"territoryName":{"type":"string","example":"Almería","description":"Nombre del territorio representado."},"territoryLevel":{"type":"string","enum":["country","region","province","locality"],"example":"province"},"population":{"type":"integer","nullable":true,"format":"int64","example":753364,"description":"Población del año solicitado, o la más reciente disponible."},"populationYear":{"type":"integer","nullable":true,"format":"int32","example":2025,"description":"Año al que corresponde population; null cuando no existe una referencia anual."},"area":{"type":"number","format":"double","example":8774,"description":"Área del territorio en km²."},"totalCrimes":{"type":"integer","format":"int64","example":1842,"description":"Mayor valor de las tipologías originales incluidas en la consulta. Se calcula antes de agrupar por categorías personalizadas y nunca suma categorías ni alias."},"crimes":{"description":"Categorías personalizadas activas agregadas a partir de sus alias de tipologías penales.","type":"array","items":{"$ref":"#/components/schemas/CrimeDataSummaryCrimeDto"}}},"required":["territoryCode","territorySlug","territoryName","territoryLevel","population","populationYear","area","totalCrimes","crimes"]},"CreateCrimeDataDto":{"type":"object","properties":{"balanceCountry":{"type":"string","minLength":2,"maxLength":2,"example":"ES"},"balanceYear":{"type":"integer","format":"int32","example":2025},"balanceNumQuarter":{"type":"number","enum":[1,2,3,4],"format":"int32","example":4},"territoryLevel":{"type":"string","enum":["country","region","province","locality"],"description":"Si se omite, el backend lo infiere de locality, province o region; sin ninguno usa country.","example":"province"},"region":{"type":"integer","minimum":1,"format":"int64","example":1},"province":{"type":"integer","minimum":1,"format":"int64","example":4},"locality":{"type":"integer","minimum":1,"format":"int64","example":1},"penalTypology":{"type":"string","minLength":1,"maxLength":255,"example":"Robos con fuerza en domicilios"},"numCrimes":{"type":"integer","minimum":0,"format":"int64","example":153}},"required":["balanceCountry","balanceYear","balanceNumQuarter","penalTypology","numCrimes"]},"ImportCrimeDataBulkDto":{"type":"object","properties":{"records":{"type":"array","items":{"$ref":"#/components/schemas/CreateCrimeDataDto"}}},"required":["records"]},"ImportCrimeDataBulkResponseDto":{"type":"object","properties":{"receivedRecords":{"type":"integer","format":"int32","example":2},"createdRecords":{"type":"integer","format":"int32","example":1},"duplicatedRecords":{"type":"integer","format":"int32","example":1},"duplicatedIndexes":{"type":"array","items":{"type":"integer","format":"int32"},"example":[1]}},"required":["receivedRecords","createdRecords","duplicatedRecords","duplicatedIndexes"]},"UpdateCrimeDataDto":{"type":"object","properties":{"balanceCountry":{"type":"string","minLength":2,"maxLength":2,"example":"ES"},"balanceYear":{"type":"integer","format":"int32","example":2025},"balanceNumQuarter":{"type":"number","enum":[1,2,3,4],"format":"int32","example":4},"territoryLevel":{"type":"string","enum":["country","region","province","locality"],"example":"province"},"region":{"type":"integer","minimum":1,"format":"int64"},"province":{"type":"integer","minimum":1,"format":"int64"},"locality":{"type":"integer","minimum":1,"format":"int64"},"penalTypology":{"type":"string","minLength":1,"maxLength":255,"example":"Robos con fuerza en domicilios"},"numCrimes":{"type":"integer","minimum":0,"format":"int64","example":153}}},"ImportCreatedTerritoryDto":{"type":"object","properties":{"territoryLevel":{"type":"string","enum":["country","region","province","locality"]},"name":{"type":"string"},"id":{"type":"integer","format":"int64"},"coordinatesFound":{"type":"boolean"}},"required":["territoryLevel","name","id","coordinatesFound"]},"ImportSkippedCrimeRecordDto":{"type":"object","properties":{"territoryLevel":{"type":"string","enum":["country","region","province","locality","unsupported"]},"territoryName":{"type":"string"},"penalTypology":{"type":"string"},"reason":{"type":"string"}},"required":["territoryLevel","territoryName","reason"]},"ImportCrimeDataPdfResponseDto":{"type":"object","properties":{"country":{"type":"string","example":"ES"},"year":{"type":"integer","example":2025},"numQuarter":{"type":"number","enum":[1,2,3,4],"example":4},"parsedRecords":{"type":"integer"},"derivedProvinceRecords":{"type":"integer","description":"Registros provinciales derivados de filas de comunidades uniprovinciales."},"createdRecords":{"type":"integer"},"duplicatedRecords":{"type":"integer"},"createdTerritories":{"type":"array","items":{"$ref":"#/components/schemas/ImportCreatedTerritoryDto"}},"territoriesWithoutCoordinates":{"type":"array","items":{"$ref":"#/components/schemas/ImportCreatedTerritoryDto"}},"skippedRecords":{"type":"array","items":{"$ref":"#/components/schemas/ImportSkippedCrimeRecordDto"}}},"required":["country","year","numQuarter","parsedRecords","derivedProvinceRecords","createdRecords","duplicatedRecords","createdTerritories","territoriesWithoutCoordinates","skippedRecords"]},"ImportSkippedRowDto":{"type":"object","properties":{"row":{"type":"integer","example":12},"reason":{"type":"string","example":"territory could not be resolved"}},"required":["row","reason"]},"ImportCountersDto":{"type":"object","properties":{"created":{"type":"integer","example":10},"updated":{"type":"integer","example":5},"reused":{"type":"integer","example":2}},"required":["created","updated","reused"]},"ImportTerritoryReferenceResponseDto":{"type":"object","properties":{"country":{"type":"string","example":"ES"},"parsedRows":{"type":"integer","example":8132},"skippedRows":{"type":"array","items":{"$ref":"#/components/schemas/ImportSkippedRowDto"}},"regions":{"$ref":"#/components/schemas/ImportCountersDto"},"provinces":{"$ref":"#/components/schemas/ImportCountersDto"},"localities":{"$ref":"#/components/schemas/ImportCountersDto"}},"required":["country","parsedRows","skippedRows","regions","provinces","localities"]},"ImportTerritoryPopulationResponseDto":{"type":"object","properties":{"country":{"type":"string","example":"ES"},"minYear":{"type":"integer","example":2015},"maxYear":{"type":"integer","example":2025},"parsedRows":{"type":"integer","example":89452},"skippedRows":{"type":"array","items":{"$ref":"#/components/schemas/ImportSkippedRowDto"}},"populations":{"$ref":"#/components/schemas/ImportCountersDto"}},"required":["country","minYear","maxYear","parsedRows","skippedRows","populations"]},"ImportTerritoryEnrichmentResponseDto":{"type":"object","properties":{"mode":{"type":"string","enum":["areas","population","both"],"example":"both"},"areas":{"$ref":"#/components/schemas/ImportTerritoryReferenceResponseDto"},"population":{"$ref":"#/components/schemas/ImportTerritoryPopulationResponseDto"}},"required":["mode"]},"CreateTerritoryPopulationDto":{"type":"object","properties":{"year":{"type":"integer","minimum":1900,"format":"int32"},"population":{"type":"integer","minimum":0,"format":"int64"},"region":{"type":"integer","minimum":1,"format":"int64"},"province":{"type":"integer","minimum":1,"format":"int64"},"locality":{"type":"integer","minimum":1,"format":"int64"}},"required":["year","population"]},"TerritoryPopulationResponseDto":{"type":"object","properties":{"id":{"type":"integer","format":"int64"},"year":{"type":"integer","format":"int32"},"population":{"type":"integer","format":"int64"},"region":{"type":"integer","format":"int64"},"province":{"type":"integer","format":"int64"},"locality":{"type":"integer","format":"int64"}},"required":["id","year","population"]},"UpdateTerritoryPopulationDto":{"type":"object","properties":{"year":{"type":"integer","minimum":1900,"format":"int32"},"population":{"type":"integer","minimum":0,"format":"int64"},"region":{"type":"integer","minimum":1,"format":"int64"},"province":{"type":"integer","minimum":1,"format":"int64"},"locality":{"type":"integer","minimum":1,"format":"int64"}}}}}}