feat(api): Swagger UI + docs/integration для Альтума и других consumer'ов

Springdoc-openapi генерирует OpenAPI 3 spec из аннотаций контроллеров —
интеграторам не нужно поддерживать markdown-ТЗ синхронно с кодом.

- /swagger-ui.html (UI), /v3/api-docs (JSON), /v3/api-docs.yaml.
- OpenApiConfig: title/description/contact/servers (staging+prod+local),
  bearerAuth security scheme (Keycloak JWT).
- SecurityConfig: permitAll на swagger paths.

Документация:
- docs/integration/altum-imaging-order.md — ТЗ интеграции «Заказ съёмки».
  Согласованы: m2m service account через Keycloak, BFF в altum-backend
  (FastAPI), 4 справочника со схемами, cascading select через
  instrument.supported_*_codes, snapshot strategy для аудита.
- docs/tech/api-integration.md — общий гайд для интеграторов: auth flow,
  endpoints, кэш-стратегии, bitemporal модель, current dictionaries,
  cross-refs, best practices.

Скрипты codegen openapi-generator-cli работают off /v3/api-docs.
This commit is contained in:
Zimin A.N.
2026-05-04 15:45:09 +03:00
parent e284fa85be
commit 930df5b888
5 changed files with 580 additions and 0 deletions
@@ -0,0 +1,70 @@
package cloud.nstart.terravault.ordinis.restapi.config;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
import io.swagger.v3.oas.models.servers.Server;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.List;
/**
* OpenAPI 3 spec для Swagger UI на {@code /swagger-ui.html}. Spec — на
* {@code /v3/api-docs}.
*
* <p>Авторизация — JWT bearer от Keycloak ({@code auth.nstart.space}).
* Service account для интеграторов (Альтум — {@code altum-backend}).
*/
@Configuration
public class OpenApiConfig {
@Bean
public OpenAPI ordinisOpenAPI() {
return new OpenAPI()
.info(new Info()
.title("Ordinis НСИ ЦУОД — Admin / Read API")
.version("v1")
.description("""
MDM сервис для НСИ ЦУОД ОДХ.
**Endpoints:**
- `/api/v1/dictionaries` — справочники (admin write).
- `/api/v1/dictionaries/{name}/records` — записи с bitemporal моделью.
- `/api/v1/admin/audit` — журнал аудита (paginated + CSV export).
- `/api/v1/admin/outbox` — статистика и DLQ.
**Read-only API** (Альтум, геопортал, другие consumer'ы) — отдельный
read-сервис на том же базовом URL: те же `GET /dictionaries/...`,
но с поддержкой `?lang=ru/en` для flatten i18n и `?at=<iso>` для
bitemporal queries.
**Auth:** Bearer JWT от Keycloak (`auth.nstart.space/realms/nstart`).
Роль `ordinis-public` достаточна для чтения. На staging авторизация
может быть выключена (`ORDINIS_AUTH_REQUIRED=false`).
**Документация интеграции:** `docs/integration/altum-imaging-order.md`,
`docs/tech/api-integration.md`.
""")
.contact(new Contact()
.name("Ordinis team")
.email("zimin.an@nstart.space"))
.license(new License().name("Internal").url("https://nstart.space")))
.servers(List.of(
new Server().url("https://ordinis.k8s.265.nstart.cloud").description("staging (cluster.265)"),
new Server().url("https://ordinis.k8s.264.nstart.cloud").description("prod (cluster.142)"),
new Server().url("http://localhost:8080").description("local dev")))
.components(new Components()
.addSecuritySchemes("bearerAuth",
new SecurityScheme()
.type(SecurityScheme.Type.HTTP)
.scheme("bearer")
.bearerFormat("JWT")
.description("Keycloak realm `nstart`. Service account для m2m: попросить у Ordinis team.")))
.addSecurityItem(new SecurityRequirement().addList("bearerAuth"));
}
}