# Ordinis НСИ ЦУОД — Operator Runbook

Карточки процедур для on-call инженера. Каждая карточка self-contained: можно
открыть в момент инцидента и пройти по шагам без необходимости понимать всю
архитектуру.

## Indexed by symptom

| Симптом                                                       | Карточка |
|---------------------------------------------------------------|----------|
| Spring Boot pod'ы залипли в `Init:0/1` после reboot           | [vault-unseal.md](vault-unseal.md) |
| Kafka pod не Running, либо `vault-agent` не достукивается     | [kafka-restart.md](kafka-restart.md) |
| Метрика `ordinis_outbox_dlq_size > 0`                         | [outbox-dlq.md](outbox-dlq.md) |
| Pod в `CrashLoopBackOff` с liquibase ошибкой в логах          | [db-migrations.md](db-migrations.md) |
| API возвращает 401 на любые запросы                           | См. §1 ниже |
| API возвращает 500 на конкретный endpoint                     | См. §2 ниже |
| Admin UI не загружается (502/503)                             | См. §3 ниже |

## 1. 401 Unauthorized

Сейчас на staging `ORDINIS_AUTH_REQUIRED=true`. Anonymous = 401. Проверить:

```bash
# 1. Header передан?
curl -v -H "Authorization: Bearer $TOKEN" ... | grep -i authorization

# 2. JWT валиден?
echo $TOKEN | cut -d. -f2 | base64 -d 2>/dev/null | jq
# проверить exp, iss, realm_access.roles

# 3. Issuer правильный?
# должен быть https://altum.nstart.cloud/auth/realms/altum
```

Если JWT прошёл проверку, но 401 — backend логи:
```bash
kubectl logs -n ordinis-staging deploy/ordinis-app -c app --tail=50 \
  | grep -iE "jwt|invalid_token|expired"
```

Типичные причины:
- `Invalid signature` — Keycloak ротировал ключи, но бэкенд кэширует старый. Restart pod.
- `Token expired` — refresh token не сработал, юзер должен перелогиниться.
- `Issuer mismatch` — JWT issued другим Keycloak realm'ом.

## 2. 500 Internal Server Error на endpoint

```bash
# Найти trace_id из ответа
curl -i ... | grep -i traceid
# либо UI показывает traceId в alert

# Найти полный stack trace
kubectl logs -n ordinis-staging deploy/ordinis-app -c app --tail=200 \
  | grep "<traceId>"
```

Типичные причины (в наших коммитах):
- `could not determine data type of parameter $N` — Hibernate JPQL с `IS NULL`
  на nullable timestamp. Решение — sentinel value (см. fix audit search).
- `DataIntegrityViolationException dictionary_records_no_overlap` — bitemporal
  exclusion constraint, период пересекается. Friendly 409 уже маппится — если
  500 значит код-путь неуспел поймать.
- `JsonMappingException` — payload поломан (фронт передал stale schema).

## 3. Admin UI не загружается / 502 / 503

```bash
kubectl get pods -n ordinis-staging | grep admin-ui
```

| Status                | Причина |
|-----------------------|---------|
| `ImagePullBackOff`    | Тег image не существует в registry. Проверь `kubectl describe`. Восстановить: `kubectl set image deployment/ordinis-admin-ui ui=<registry>/ordinis-admin-ui:main -n ordinis-staging` |
| `CrashLoopBackOff`    | nginx config invalid либо resolver недоступен. См. logs. |
| `Running 1/1`, но 502 | Upstream (writer/read-api) сам в дауне. Проверь те pod'ы. |

## 4. Что-то ещё — где смотреть

- **Pod state:** `kubectl get pods -n ordinis-staging`
- **Recent events:** `kubectl get events -n ordinis-staging --sort-by='.lastTimestamp' | tail -20`
- **Resource usage:** `kubectl top pod -n ordinis-staging`
- **Logs:** `kubectl logs -n ordinis-staging deploy/<name> -c app --tail=100`
- **Liveness/readiness probes:** `kubectl describe pod -n ordinis-staging <pod>`
- **Ingress:** `kubectl get ingress -n ordinis-staging`
- **Helm release:** `helm history ordinis -n ordinis-staging`

## 5. Эскалация

>30 мин downtime, не понятно куда копать → tech lead (zimin.an@nstart.space).

## 6. Связанные ресурсы

- API integration guide: [../integration/api/index.md](../integration/api/index.md) (Diplodoc, latest)
- Альтум integration: [../integration/altum-imaging-order.md](../integration/altum-imaging-order.md)
- Project state snapshots: см. `docs/status/*-state.md` в repo (исключены из Diplodoc build)
- Helm chart: `ordinis-infra/charts/ordinis/`
- Vault setup: `ordinis-infra/k8s/vault/setup.sh`
