docs: Diplodoc setup + полное руководство интеграции по API

Новая документация-as-code на платформе Diplodoc (Yandex open-source) с
YFM (Yandex Flavored Markdown). Build → static HTML, deployable куда угодно.

Что добавлено:
- package.json + .yfm + toc.yaml — Diplodoc setup, навигация для sidebar
- index.md — главная страница с tabs для разных audiences
- README.md — инструкция для contributors

Раздел integration/api/ — 11 страниц про интеграцию consumers:
- index — обзор + глоссарий
- auth — Keycloak service accounts, scope mapping
- read-endpoints — GET /dictionaries, list/by-key, spatial filters
- events — Kafka outbox топики, partition keys, idempotency, DLQ
- webhooks — HMAC, SSRF guard, retry policy, test ping endpoint
- bitemporal — validFrom/validTo + history, future-dated entries, bulk close/export
- x-references — FK syntax, validation errors, scope hiding, orphan scanner, v2 cascade preview
- caching — TTL / push / snapshot strategies, hybrid pattern
- errors — full error code reference (validation/auth/conflict/server), retry strategy
- best-practices — 33 numbered rules для consumers
- bundle-cuod — все 40 справочников с FK графом и сценариями

Обновлены:
- ops/README.md — link на новую integration/api/, убран inline <br>
- ops/slo.md — broken cross-repo links заменены на text references

Build:
  cd docs && pnpm install && pnpm build
  → ./_dist (20 HTML files, 7.1M)
  pnpm serve  # → http://localhost:8088

CI deploy job для GitLab Pages — в roadmap (см. docs/README.md).

Существующий tech/api-integration.md оставлен в toc как legacy
(содержимое мигрировано + расширено в integration/api/).
This commit is contained in:
Zimin A.N.
2026-05-07 23:19:02 +03:00
parent 0c79821f8e
commit d5268b9395
20 changed files with 3450 additions and 5 deletions
+156
View File
@@ -0,0 +1,156 @@
# Best practices
Чек-лист для consumer'ов Ordinis API.
## Идентификация записей
1. **Используй `businessKey`, не UUID.** UUID — внутренний идентификатор
записи и **меняется** при создании новой версии (через update).
`businessKey` стабилен через всю жизнь записи.
2. **Не делай FK на копию справочника.** Если копируешь данные к себе для
snapshot — храни `business_key VARCHAR` как key, не `id UUID` либо
`internal_id`. Это устойчиво к updates.
## Авторизация
3. **Кэшируй access token с TTL = `expires_in - 30s`.** Не делай новый
token request на каждый API call — Keycloak rate limits + латентность.
4. **Refresh JWT перед TTL.** Не дожидайся 401 — большинство Keycloak SDK
рефрешат автоматически.
5. **Не храни `client_secret` в коде / git.** Vault либо secret manager.
## Чтение
6. **Кэшируй per `(dictionary, lang)`.** Inline в коде — `staleTime` /
TTL. См. [Caching](caching.md).
7. **Используй `?lang=` параметр** для flatten i18n полей если UI на одном
языке. Без `lang` ответ возвращает `{ru-RU: "...", en-US: "..."}`
объект — лишний размер payload + проще баг.
8. **Не запрашивай history endpoint** на hot path. История нужна только
admin UI / audit. Список + by-key endpoints достаточны для типичного
consumer.
## Запись (admin only)
9. **Не пиши массовых update'ов** через одиночные API calls. Ordinis
оптимизирован под редкие записи и частые чтения. Для bulk import
используй `POST /admin/bundle/import` (через bundle Maven module).
10. **Bulk close через `_bulk-close`** endpoint, не loop одиночных POST.
Per-record transactions, classification (skipped vs error vs closed),
меньше latency.
11. **Bulk export CSV** через `_export?format=csv` для extracting filtered
данные в legacy системы.
## Обработка событий
12. **Idempotency** — события at-least-once, могут прийти дважды. Используй
`(dictionary, businessKey, txTime, version)` либо `deliveryId` (для webhooks)
как dedup key.
13. **Async обработка** — отвечай webhook'у `202 Accepted` сразу, обрабатывай
в background. Жёсткий timeout 10s.
14. **HMAC verify первым** — до парсинга JSON. Защита от spoofed events.
15. **Stale cache на 5xx / timeout** — отдавай старые данные с warn'ом, не
падай каскадно.
## Производительность
16. **Parallel-fetch related dictionaries** при cascading select:
```ts
const [spacecrafts, satTypes, instruments] = await Promise.all([
fetch('/api/v1/spacecraft/records?lang=ru'),
fetch('/api/v1/satellite_type/records?lang=ru'),
fetch('/api/v1/instrument/records?lang=ru'),
])
```
Не последовательные `await`, не N+1 loops.
17. **Cascading filters в memory** — после loading dictionaries фильтруй
клиент-side вместо новых API calls:
```ts
const allowedFormats = formats.filter(f =>
instrument.data.supportedFormatCodes.includes(f.businessKey))
```
18. **Не делай polling в tight loop** — используй webhooks либо Kafka events
для realtime invalidation. Polling каждые 5 мин — OK, каждые 10 сек — нет.
## Error handling
19. **Don't retry 4xx (кроме 401 и 429).** Permanent errors требуют code
fix, не retry.
20. **Exponential backoff на 5xx / timeout.** Base 0.5s, multiplier 2,
jitter 0-0.5s, max 5 attempts. См. [Errors](errors.md).
21. **Сохраняй `traceId`** при эскалации в Ordinis team. Без traceId
investigation в Tempo занимает в 10x дольше.
## Bundle versioning
22. **Forward compatibility** — допускай новые поля в API responses которые
ты не знаешь. Не fail on unknown fields. Schema validation у consumer'а
должна быть `additionalProperties: true` (либо аналог).
23. **Подписывайся на `nsi.dictionary.changed` events** для новых
справочников — они появляются с минор-bump bundle.
24. **Monitor schema versions** в `GET /dictionaries` response — если
`schemaVersion` поменялся, проверь твой mapping не сломался.
## Безопасность
25. **HTTPS обязателен** — webhook URLs тоже только https. SSRF guard
блокирует http:// и private CIDR.
26. **Не log access tokens** в plaintext. Большинство logging frameworks
имеют redaction patterns для `Authorization` header.
27. **Rotate `client_secret`** регулярно. Раз в квартал — minimum, раз
в месяц — recommended для production. Coordinate с Ordinis team
при rotation.
## Коммуникация с командой
28. **Прежде чем bulk import** > 1000 records — talk to Ordinis team. У
нас есть staging environment + bulk-import endpoint без rate limits.
29. **Запрашивай новый scope / role** через `zimin.an@nstart.space`
либо issue с label `keycloak-role-request`.
30. **При проблеме**: воспроизведи на staging, скопируй traceId, открой
issue. Скриншоты UI ошибок помогают.
## Тестирование
31. **Mock Ordinis в unit tests** — не завись от availability staging
cluster. Нашa OpenAPI spec accurate, генерируй mock client.
32. **Integration tests против staging** — не prod. Staging данные — тестовые,
можно create/close без последствий.
33. **Load tests на staging** в low-traffic окно. Координируй с Ordinis
team — мы можем включить дополнительные replicas для вашего теста.
## Reference: bundle cuod
См. [Bundle cuod](bundle-cuod.md) — список 40 справочников, их связи,
типичные operations.
## Дальше
- [События](events.md) — push-обновления
- [Caching](caching.md) — стратегии кэша
- [Errors](errors.md) — обработка ошибок