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
+34 -23
View File
@@ -4,7 +4,7 @@ Practical guide to НСИ-ordinis REST API. Тут не справочник в
(для этого есть OpenAPI / Swagger UI), а минимально-достаточный путь от
«первый запрос» до «подписался на webhook».
**Версия:** v2.36.0 (`/api/v1`)
**Версия:** v2.37.x (`/api/v1`)
**Swagger UI:** `https://ordinis.k8s.265.nstart.cloud/swagger-ui/index.html`
(staging — на prod env-flagged)
@@ -16,14 +16,15 @@ Practical guide to НСИ-ordinis REST API. Тут не справочник в
- Базовый префикс — `/api/v1`. Версионирование URL (breaking changes → `/v2`).
- Auth — Keycloak OIDC, Bearer-токен в `Authorization`. Anon разрешён для
`PUBLIC` scope.
- Pagination — query-params `?limit=N&offset=M`. По умолчанию `limit=50`.
- Pagination — на records list **не поддерживается**, возвращается весь массив. Для больших dicts фильтруй на клиенте или через `?at=` time-slice.
- Ошибки — `application/json` с `{status, code, message, traceId, timestamp}`.
## 1. Base URL и проверка живости
```bash
# Production
ORDINIS=https://ordinis.k8s.264.nstart.cloud
ORDINIS=https://ordinis.nstart.cloud # prod (public LE)
# ORDINIS=https://ordinis.k8s.265.nstart.cloud # staging
# Staging
# ORDINIS=https://ordinis.k8s.265.nstart.cloud
@@ -38,7 +39,7 @@ curl "$ORDINIS/api/v1/version"
"version": "0.1.0-SNAPSHOT",
"commit": "2ca8f053",
"branch": "main",
"tag": "v2.36.0",
"tag": "v2.37.0",
"builtAt": "2026-05-17T08:18:07.437Z"
}
```
@@ -162,9 +163,11 @@ curl "$ORDINIS/api/v1/dictionaries/graph/outgoing"
### 4.1 Список записей
```bash
curl "$ORDINIS/api/v1/spacecraft/records?limit=2"
curl "$ORDINIS/api/v1/spacecraft/records?as_scope=PUBLIC"
```
`as_scope` обязателен (CSV: `PUBLIC,INTERNAL,RESTRICTED`).
```json
[
{
@@ -188,27 +191,34 @@ curl "$ORDINIS/api/v1/spacecraft/records?limit=2"
### 4.2 Одна запись по business key
```bash
curl "$ORDINIS/api/v1/spacecraft/records/1999-068A"
curl "$ORDINIS/api/v1/spacecraft/records/1999-068A?as_scope=PUBLIC"
```
### 4.3 Фильтры
```bash
# По атрибутам схемы (через query-params)
curl "$ORDINIS/api/v1/spacecraft/records?status=OPERATIONAL&country=RU"
# Locale — для x-localized полей сервер вернёт только указанную локаль
curl "$ORDINIS/api/v1/spacecraft/records/1999-068A?as_scope=PUBLIC&locale=en-US"
# или через стандартный header:
curl -H "Accept-Language: en-US" "$ORDINIS/api/v1/spacecraft/records?as_scope=PUBLIC"
# По scope (если у тебя есть доступ к INTERNAL)
# Time-travel: состояние на конкретный момент (validFrom <= at < validTo)
curl "$ORDINIS/api/v1/spacecraft/records/1999-068A?as_scope=PUBLIC&at=2026-01-01T00:00:00Z"
# По scope (если есть права на INTERNAL/RESTRICTED)
curl -H "Authorization: Bearer $TOKEN" \
"$ORDINIS/api/v1/spacecraft/records?scope=INTERNAL"
"$ORDINIS/api/v1/spacecraft/records?as_scope=PUBLIC,INTERNAL"
# Pagination
curl "$ORDINIS/api/v1/spacecraft/records?limit=20&offset=40"
# Geo (для geo-dicts с PostGIS support)
curl "$ORDINIS/api/v1/ground_station/records?as_scope=PUBLIC&bbox=30,55,40,60"
```
⚠️ **НЕ работает на records list endpoint**: `?limit=`, `?offset=` (pagination отсутствует), `?status=...&country=...` (нет ad-hoc filtering по schema полям). Фильтруй на клиенте.
### 4.4 Сводка по запланированным записям
```bash
curl "$ORDINIS/api/v1/spacecraft/records/scheduled-summary"
curl "$ORDINIS/api/v1/spacecraft/records/scheduled-summary?as_scope=PUBLIC"
```
```json
@@ -267,7 +277,7 @@ curl "$ORDINIS/api/v1/spacecraft/records/1999-068A/history"
### 6.2 Snapshot справочника на дату
```bash
curl "$ORDINIS/api/v1/dictionaries/spacecraft/snapshots?asOf=2026-03-15T00:00:00Z"
curl "$ORDINIS/api/v1/dictionaries/spacecraft/snapshots?from=2026-01-01T00:00:00Z&to=2026-05-01T00:00:00Z&granularity=day"
```
Точная реконструкция справочника на момент `asOf`. Все записи, которые
@@ -277,7 +287,7 @@ curl "$ORDINIS/api/v1/dictionaries/spacecraft/snapshots?asOf=2026-03-15T00:00:00
### 6.3 Changelog схемы (структурные изменения)
```bash
curl "$ORDINIS/api/v1/dictionaries/spacecraft/changelog?limit=10"
curl "$ORDINIS/api/v1/dictionaries/spacecraft/changelog"
```
```json
@@ -503,15 +513,15 @@ curl -X POST -H "Authorization: Bearer $TOKEN" \
### curl + jq (CI/CD)
```bash
# Все записи активных операторов
curl -s "$ORDINIS/api/v1/operator/records?status=ACTIVE" \
| jq '.[] | {key: .businessKey, name: .data.name}'
# Все записи операторов в PUBLIC scope; фильтрация на клиенте
curl -s "$ORDINIS/api/v1/operator/records?as_scope=PUBLIC" \
| jq '.[] | select(.data.status == "ACTIVE") | {key: .businessKey, name: .data.name}'
```
### TypeScript / Fetch
```ts
const ORDINIS = 'https://ordinis.k8s.264.nstart.cloud'
const ORDINIS = 'https://ordinis.nstart.cloud'
type SpacecraftRecord = {
businessKey: string
@@ -521,9 +531,10 @@ type SpacecraftRecord = {
}
async function getSpacecraft(): Promise<SpacecraftRecord[]> {
const r = await fetch(`${ORDINIS}/api/v1/spacecraft/records?limit=100`, {
headers: { Accept: 'application/json' },
})
const r = await fetch(
`${ORDINIS}/api/v1/spacecraft/records?as_scope=PUBLIC`,
{ headers: { Accept: 'application/json', 'Accept-Language': 'en-US' } },
)
if (!r.ok) throw new Error(`Ordinis ${r.status}`)
return r.json()
}
@@ -534,7 +545,7 @@ async function getSpacecraft(): Promise<SpacecraftRecord[]> {
```python
import requests
ORDINIS = "https://ordinis.k8s.264.nstart.cloud"
ORDINIS = "https://ordinis.nstart.cloud"
def smart_search(query: str, limit: int = 10) -> dict:
r = requests.get(f"{ORDINIS}/api/v1/search",