Files
mdm-ordinis/docs/integration/api/x-references.md
T
Zimin A.N. d5268b9395 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/).
2026-05-07 23:19:02 +03:00

5.6 KiB
Raw Blame History

Cross-references (FK между справочниками)

JSON Schema extension x-references объявляет, что значение поля должно ссылаться на active record в указанном словаре.

Синтаксис

{
  "type": "object",
  "properties": {
    "satelliteTypeCode": {
      "type": "string",
      "x-references": "satellite_type.code"
    }
  }
}

Format: "<dictionary_name>.<field_name>". Когда POST/PUT приходит, Ordinis делает lookup в satellite_type где data->>code == satelliteTypeCode. Если не найден / не активен / вне scope — 422 Validation Error.

Текущие FK в bundle cuod

Source Target Поле
spacecraft.satelliteTypeCode satellite_type code
spacecraft.statusCode spacecraft_status code
mission.spacecraftCodes (array) spacecraft businessKey
instrument.spacecraftCodes (array) spacecraft businessKey
instrument.supportedFormatCodes (array) data_format businessKey
instrument.supportedLevelCodes (array) processing_level businessKey

(Точное число и список могут меняться с bundle versions — см. Bundle cuod.)

Server-side validation

При POST/PUT ReferenceValidator проверяет каждое x-references поле:

Симптом Error code Описание
Referenced dictionary не существует x_references_dict_not_found Опечатка в schema.
Referenced record не найден / inactive x_references_target_not_found Bad value либо record закрыт.
Value не string (для v1) x_references_non_string v1 поддерживает только string refs.
Schema spec malformed x_references_malformed Bad schema.

Response:

{
  "errors": [
    {
      "path": "/satelliteTypeCode",
      "code": "x_references_target_not_found",
      "message": "Referenced record not found in 'satellite_type' for code='UNKNOWN-TYPE'"
    }
  ]
}

Scope hiding

Если referenced dictionary — INTERNAL/RESTRICTED, а consumer имеет только PUBLIC scope, ReferenceValidator возвращает тот же error (x_references_target_not_found) что и на real not-found. Ordinis не leak'ает existence of out-of-scope dictionary через differential errors.

Orphan reference scanner

Возможна ситуация когда referenced record закрывается, а referencing record остаётся:

1. spacecraft.RESURS-P-3 references satellite_type.EARTH-OPTICAL
2. Admin closes satellite_type.EARTH-OPTICAL  (record.closed event emitted)
3. spacecraft.RESURS-P-3 теперь имеет dangling FK

Periodic scanner (OrphanReferenceScanner, runs каждые 5 мин) находит такие orphan'ы и emit'ит metric:

nsi_orphan_references_total{source_dict="spacecraft",target_dict="satellite_type"} 1

Alert OrdinisOrphanReferences срабатывает при > 0 за 10 мин.

Cascade rules — roadmap (v2)

Сегодня закрытие источника НЕ closes referencing automatically. Это дolжно явно делаться через bulk close либо individual updates.

В v2 планируется schema extension x-references-on-close:

{
  "satelliteTypeCode": {
    "type": "string",
    "x-references": "satellite_type.code",
    "x-references-on-close": "block"
  }
}

Опции:

  • block — закрытие источника невозможно пока есть active referencing (default).
  • warn — закрытие проходит, в response warning + metric nsi_cascade_warnings_total.
  • cascade — все referencing закрываются в той же транзакции.

См. design doc dict-relationships-v2 (внутренний artifact в ~/.gstack/projects/claude/) для полного scope.

Lineage discovery — roadmap (v2)

Сегодня нет endpoint для "что depends on X". Admin должен вручную проходить schemas чтобы найти ссылки. В v2 планируется:

  • GET /api/v1/dictionaries/{name}/dependents — словари которые ссылаются.
  • GET /api/v1/records/{dict}/{key}/dependents — конкретные записи.

См. design выше для подробностей.

Best practices

  1. Используй businessKey как target field для большинства FK. Это стабильный идентификатор. Альтернатива (code, name) работает но требует поддержки x-unique в target (иначе ambiguous matches).
  2. Не делай deeply nested refs — v1 поддерживает только top-level fields. Nested objects с x-references — пропустят validation.
  3. Array refs работают — если поле type: array, items: {type: string, x-references: ...}, каждый элемент валидируется. (Но в v1.2.1 это делается на каждый элемент отдельно — for large arrays медленно. Будет batch'нуто в v2.)
  4. Document FK в displayName"description": "FK на satellite_type через code" помогает при ревью schemas.

Дальше

  • Bundle cuod — список текущих FK в проде
  • События — учитывай cascade closure при инвалидации