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:
@@ -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`
|
||||
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user