docs(api): cheatsheet + quickstart sync с реальным API после Postman audit

Audit Postman collection выявил расхождения docs ↔ runtime — фикс:

Topology clarification:
- Records (consumer) — БЕЗ /dictionaries/ префикса: /api/v1/{name}/records
- History/cascade-preview/changelog/drafts — С /dictionaries/ (writer audit)
- export-selected.csv — POST, не GET

Query params (records list, /{name}/records):
-  as_scope (required, CSV) — было документировано как ?scope= (неверно)
-  at (ISO timestamp) — было ?asOf= (неверно)
-  locale + Accept-Language header
-  bbox / polygon (geo)
-  убраны: ?limit, ?offset (pagination отсутствует),
            ?status/?country (нет ad-hoc filtering по schema полям)

Snapshots params:
-  from / to / granularity (hour/day/week) — было ?asOf= (неверно)

Base URLs:
- prod: ordinis.nstart.cloud (public LE-cert)
- staging: ordinis.k8s.265.nstart.cloud (Swagger UI здесь)
- было: ordinis.k8s.264.nstart.cloud (устаревший internal, prod переехал)

Version: v2.36 → v2.37.x.

Refs MR !242 (snapshots backend fix), Postman collection в
~/Desktop/Ordinis-Postman/.
This commit is contained in:
Zimin A.N.
2026-05-19 23:15:40 +03:00
parent 64a15048f4
commit ae05e17f96
2 changed files with 75 additions and 48 deletions
+41 -25
View File
@@ -2,7 +2,9 @@
Одностраничный референс. Полный гайд — `api-quickstart.md`.
**Base:** `https://ordinis.k8s.264.nstart.cloud/api/v1` · **Version:** `v2.36.0` · **OpenAPI:** `/swagger-ui/index.html`
**Base prod:** `https://ordinis.nstart.cloud/api/v1` (public LE-cert)
**Base staging:** `https://ordinis.k8s.265.nstart.cloud/api/v1` (Swagger UI здесь)
**Version:** `v2.37.x` · **OpenAPI:** `/v3/api-docs` (только staging — на prod Swagger выключен)
## Auth
@@ -29,34 +31,43 @@ Scopes: `PUBLIC` (anon ok) · `INTERNAL` (auth) · `RESTRICTED` (admin).
| `GET` | `/dictionaries/{name}/dependents` | Кто ссылается на этот dict |
| `GET` | `/dictionaries/{name}/changelog` | Список изменений схемы |
| `GET` | `/dictionaries/{name}/changelog/{id}/diff` | Diff между версиями |
| `GET` | `/dictionaries/{name}/snapshots?asOf=` | Snapshot на дату (ISO-8601) |
| `GET` | `/{name}/records` | Список записей (⚠️ не `/dictionaries/{name}/records`) |
| `GET` | `/{name}/records/{businessKey}` | Одна запись |
| `GET` | `/{name}/records/{businessKey}/history` | История версий записи |
| `GET` | `/{name}/records/scheduled-summary` | Будущие версии (count + nearestValidFrom) |
| `GET` | `/{name}/records/export.csv` | Bulk export |
| `GET` | `/search?q=&limit=` | Smart search (≥3 chars, trigram) |
| `GET` | `/dictionaries/{name}/snapshots?from=&to=&granularity=` | Bucket'ы изменений для TimeTravel slider (granularity: hour/day/week) |
| `GET` | `/{name}/records?as_scope=PUBLIC` | Список записей (⚠️ **БЕЗ** `/dictionaries/` префикса) |
| `GET` | `/{name}/records/{businessKey}?as_scope=PUBLIC` | Одна запись |
| `GET` | `/dictionaries/{name}/records/{businessKey}/history?as_scope=PUBLIC` | История версий записи (Envers) — **с** `/dictionaries/` |
| `GET` | `/dictionaries/{name}/records/{businessKey}/cascade-preview?as_scope=PUBLIC` | Preview каскада — **с** `/dictionaries/` |
| `GET` | `/{name}/records/scheduled-summary?as_scope=PUBLIC` | Будущие версии (count + nearestValidFrom) |
| `GET` | `/search?q=` | Поиск по справочникам (records не индексируются) |
| `GET` | `/ai/info` | `{enabled: bool}` AI feature flag |
> ⚠️ **Корень частой путаницы**: consumer endpoints (`/records/...`) идут БЕЗ `/dictionaries/` префикса. Admin-style audit endpoints (history, cascade-preview, changelog, drafts, snapshots) — С `/dictionaries/`. См. [api-quickstart.md § Topology](api-quickstart.md).
### Query params (records)
```
?limit=50&offset=0 pagination
?status=ACTIVE&country=RU фильтр по атрибутам схемы
?scope=INTERNAL если есть права
?asOf=2026-03-15T00:00:00Z bitemporal cut (где поддержано)
?as_scope=PUBLIC,INTERNAL (required) CSV scope filter
?at=2026-03-15T00:00:00Z bitemporal: запись на конкретный момент (validFrom <= at < validTo)
?locale=en-US локаль (или Accept-Language header)
?bbox=lon1,lat1,lon2,lat2 geo: bounding box (для geo-dicts)
?polygon=<GeoJSON> geo: polygon-фильтр
```
**Что НЕ работает (на read-api endpoint):**
- `?limit=`, `?offset=` — pagination отсутствует, возвращается весь массив
- `?status=ACTIVE&country=RU` — нет ad-hoc filtering по schema полям; фильтруй на клиенте
## Write (требует auth)
⚠️ Все write-endpoints — на **writer** сервисе, с `/dictionaries/` префиксом.
| Verb | Path | Что |
|---|---|---|
| `POST` | `/{name}/records` | Создать запись (если approval не нужен) |
| `PUT` | `/{name}/records/{businessKey}` | Обновить |
| `DELETE` | `/{name}/records/{businessKey}` | Soft-delete (tombstone) |
| `POST` | `/{name}/records/bulk-close` | Массовое закрытие |
| `POST` | `/{name}/records/{businessKey}/cascade-close` | Закрыть с зависимыми |
| `GET` | `/{name}/records/{businessKey}/cascade-preview` | Preview каскада |
| `POST` | `/dictionaries/{name}/records` | Создать запись (если approval не нужен) |
| `PUT` | `/dictionaries/{name}/records/{businessKey}` | Обновить |
| `DELETE` | `/dictionaries/{name}/records/{businessKey}` | Soft-delete (tombstone) |
| `POST` | `/dictionaries/{name}/records/bulk-close` | Массовое закрытие |
| `POST` | `/dictionaries/{name}/records/{businessKey}/cascade-close` | Закрыть с зависимыми |
| `POST` | `/dictionaries/{name}/records/export-selected.csv` | Bulk export (выборка по ids в body) |
| `PATCH` | `/dictionaries/{name}/schema` | Изменить схему inline (non-breaking) |
| `PUT` | `/dictionaries/{name}` | Полностью пересоздать (breaking) |
@@ -173,16 +184,21 @@ Action types (13): `DICTIONARY_CREATED · SCHEMA_UPDATED · SCHEMA_PUBLISHED ·
## 60-second smoke
```bash
ORDINIS=https://ordinis.k8s.264.nstart.cloud
ORDINIS=https://ordinis.nstart.cloud # prod (public LE)
# или: ORDINIS=https://ordinis.k8s.265.nstart.cloud # staging
curl -s $ORDINIS/api/v1/version | jq # alive
curl -s $ORDINIS/api/v1/dictionaries | jq 'length' # >= 40
curl -s $ORDINIS/api/v1/dictionaries/spacecraft | jq '.scope' # "PUBLIC"
curl -s "$ORDINIS/api/v1/spacecraft/records?limit=1" | jq '.[0].businessKey'
curl -s "$ORDINIS/api/v1/search?q=Sentinel" | jq '.total' # 12
curl -s $ORDINIS/api/v1/ai/info | jq '.enabled' # true
curl -s $ORDINIS/api/v1/version | jq # alive
curl -s $ORDINIS/api/v1/dictionaries | jq 'length' # 37 на prod / 39 на staging
curl -s $ORDINIS/api/v1/dictionaries/spacecraft | jq '.scope' # "PUBLIC"
curl -s "$ORDINIS/api/v1/spacecraft/records?as_scope=PUBLIC" | jq '.[0].businessKey'
curl -s "$ORDINIS/api/v1/search?q=spacecraft" | jq '.total' # >0
curl -s $ORDINIS/api/v1/ai/info | jq '.enabled' # true / false
```
## Postman collection
Готовая collection с реальными запросами (28 запросов, demo-flow): см. [docs/integration/postman/](postman/) или `~/Desktop/Ordinis-Postman/` (если генерировал локально).
## Связанные доки
`api-quickstart.md` · `bundle-format-spec.md` · `docs/changelog.md` · Swagger UI `/swagger-ui/index.html`