# Пошаговое руководство по курсу

> **Для кого:** инженеры, которые хотят превращать живую телеметрию экосистемы в 3D-визуализацию — опрашивать REST API alien-monitor, моделировать его топологию как типизированный граф и переносить сцены оракулов в React Three Fiber.
> **Язык лаб:** `COURSE_LANG=en|ru|es|fr|zh` · строки UI в `i18n/` · этот гайд на русском.
> [English](step-by-step.md) · [Español](step-by-step.es.md) · [Français](step-by-step.fr.md) · [中文](step-by-step.zh.md)

---

## Сверка с текущей экосистемой

Лабораторные используют `/api/topology` Alien Monitor. У отдельного [Service Mesh API](https://service-mesh.modelmarket.dev/docs) есть `/health`, `/v1/stats`, `/v1/agents` и `/v1/activity`. Для сравнения запросите статистику Mesh и посмотрите `tasks_24h` и `mesh_hops_24h`. Объём в USD относится к телеметрии Mesh за 24 часа. Граф Alien Monitor собирайте по схеме его собственного API.

---

## Зачем этот курс

[alien-monitor](https://github.com/alexar76/alien-monitor) — это живая 3D-карта экосистемы AIMarket: Hub, его пиры федерации и созвездие оракулов, каждый из которых рисуется как анимированная сцена React Three Fiber. Курс учит слою данных за этой картой. Вы научитесь **опрашивать** REST API монитора (`/api/health`, `/api/topology`, `/api/reputation/*`), **моделировать** ответы как типизированные структуры Python, **ранжировать** узлы оценками PageRank/EigenTrust от LUMEN и, наконец, **сопоставлять** слаг каждого оракула с камерой, акцентным цветом и метаданными примитива, которые фронтенд R3F использует для отрисовки сцены.

Каждая лаба **детерминирована и работает без сети**: если живой alien-monitor не запущен на `127.0.0.1:9100`, лаба сама поднимает встроенный мок-сервер с той же формой REST — весь курс проходится без сети и без ключей. Каждая лаба печатает блок `Trace`, чтобы поведение можно было проверить.

---

## Содержание

1. [Выбор трека](#выбор-трека)
2. [Установка (10 минут)](#установка-10-минут)
3. [M1 — Здоровье монитора и режимы](#m1--здоровье-монитора-и-режимы)
4. [M2 — Модель графа топологии](#m2--модель-графа-топологии)
5. [M3 — Репутация федерации](#m3--репутация-федерации)
6. [M4 — Оценки PageRank от LUMEN](#m4--оценки-pagerank-от-lumen)
7. [M5 — Сопоставление сцен оракулов с R3F (продвинутый)](#m5--сопоставление-сцен-оракулов-с-r3f-продвинутый)
8. [Подключение живого монитора](#подключение-живого-монитора)
9. [Упражнения и сертификат](#упражнения-и-сертификат)
10. [Наблюдаемость: блок Trace](#наблюдаемость-блок-trace)
11. [Типичные проблемы](#типичные-проблемы)

---

## Выбор трека

| Трек | Модули | Время | Живой монитор | Фронтенд |
|------|--------|-------|---------------|----------|
| **Базовый** | M1 → M2 → M3 → M4 | ~1,5 ч | Мок (авто) | Нет — чистый Python |
| **Продвинутый** | Базовый + M5 | +30 мин | Мок или живой | Спеки R3F |
| **Мост к живому** | После M4 или M5 | +30 мин | Реальный alien-monitor | Опционально |

Мок-сервер подстраховывает все треки, так что запущенный монитор для прохождения курса не нужен. После **каждой** лабы смотрите [блок Trace](#наблюдаемость-блок-trace).

---

## Установка (10 минут)

### Шаг 1 — Клон и установка

```bash
git clone https://github.com/alexar76/aimarket-courses.git
cd aimarket-courses/3d-data-viz-course
pip install -e ".[dev]"
```

`[dev]` — единственный нужный extra: лабы опрашивают HTTP через стандартную библиотеку Python, тяжёлых зависимостей нет. `[dev]` добавляет `pytest`.

### Шаг 2 — Тесты

```bash
pytest -q
```

**Ожидается:** все тесты проходят (паритет i18n по `en/ru/es/fr/zh`, разбор графа, маппинг R3F, проверки упражнений).

### Шаг 3 — Первая лаба

```bash
python labs/lab01_health_probe.py
python labs/run_exercises.py
```

### Шаг 4 — Язык интерфейса лаб

```bash
export COURSE_LANG=ru   # или es, по умолчанию en
python labs/lab01_health_probe.py
```

Все заголовки модулей, концепции, подписи и подсказки берутся из `i18n/{en,ru,es,fr,zh}.json`.

### Шаг 5 — Google Colab

1. Откройте [сайт курса](https://alexar76.github.io/aimarket-courses/3d-data-viz-course/) → **Открыть в Colab** на любой лабе.
2. Выполните setup-ячейку (clone + `pip install -e ".[dev]"`).
3. При необходимости задайте `os.environ["COURSE_LANG"] = "ru"`.
4. Запустите ячейку лабы — мок-сервер работает и внутри Colab.

---

## M1 — Здоровье монитора и режимы

**Концепция:** опрос `/api/health` и понимание режимов TEST, REAL и UNIVERSE.
**Лаба:** `labs/lab01_health_probe.py` · **~15 мин** · наблюдаемость, SRE

### Шаги

1. Прочитайте docstring в начале файла лабы.
2. `python labs/lab01_health_probe.py`
3. Разберите вывод: доступен ли живой монитор; строка `result: status=ok mode=test`. `mode` — источник данных монитора: `test` (мок), `real` (живая экосистема), `universe` (федеративный мульти-hub вид). Если использован мок — будет соответствующая пометка.
4. Просмотрите `courselib/viz.py`: `probe_health`, `HealthStatus`, `monitor_reachable`, `resolve_monitor_url`.

### Что доказывает

Рабочий REST-опрос и паттерн `resolve_monitor_url()` (живой-или-мок), который переиспользует **каждая** следующая лаба.

### Самопроверка

- [ ] Объясняете смысл `status` и `mode`
- [ ] Понимаете, зачем нужен запасной мок-сервер

---

## M2 — Модель графа топологии

**Концепция:** разбор узлов и связей из `/api/topology` в типизированные графовые структуры.
**Лаба:** `labs/lab02_topology_graph.py` · **~20 мин** · нужен M1 · визуализация графов, React Flow

### Шаги

1. `python labs/lab02_topology_graph.py`
2. Разберите вывод: число узлов и связей, затем до шести узлов с `id`, `group`, 3D-`position` и `status`.
3. Строка `Adjacency list: N directed edges` — `TopologyGraph.adjacency()` убирает дубли рёбер и петли, давая форму для force-directed рендера.
4. Изучите `courselib/viz.py`: `MonitorNode`, `MonitorLink`, `TopologyGraph`, `Vec3.from_dict`. Classmethod-ы `from_api` аккуратно приводят сырой JSON к типизированным dataclass.

### Что доказывает

Типизированный граф в памяти (`nodes`, `links`, `adjacency()`, `node_ids()`, `oracle_slugs()`), на котором строятся M4 и M5.

### Самопроверка

- [ ] Называете поля `MonitorNode`
- [ ] Понимаете, зачем дедупликация смежности и удаление петель

---

## M3 — Репутация федерации

**Концепция:** обогащение графа доверия данными `/api/reputation/peers` из Hub.
**Лаба:** `labs/lab03_reputation_peers.py` · **~20 мин** · нужен M2 · EigenTrust, федерация

### Шаги

1. `python labs/lab03_reputation_peers.py`
2. Вывод: `Federation peers: N (mode)`, затем по каждому пиру `name`, `trust_score`, `url`. Пир без оценки печатается как `—`.
3. В `courselib/viz.py` изучите `ReputationPeer` и `ReputationPeers`. `trust_score` имеет тип `float | None`, поэтому визуализация должна обрабатывать отсутствие данных.

### Что доказывает

Слой федерации графа: каким внешним Hub доверяет этот монитор и насколько — вход для кодирования цвета/размера узлов-пиров.

### Самопроверка

- [ ] Различаете `None` и `0.0` в оценке доверия
- [ ] Видите, как пиры расширяют топологию M2

---

## M4 — Оценки PageRank от LUMEN

**Концепция:** вызов `/api/reputation/lumen` и привязка оценок к узлам графа.
**Лаба:** `labs/lab04_lumen_scores.py` · **~20 мин** · нужен M2 · оракулы репутации

### Шаги

1. `python labs/lab04_lumen_scores.py`
2. Вывод: узлы по убыванию оценки, у каждого столбик `█` и значение с 4 знаками, затем `PageRank iterations: N`.
3. Если LUMEN недоступен, лаба печатает строку `LUMEN error`, а не падает — обратите внимание на проверку `lumen.ok`.
4. В `courselib/viz.py` изучите `LumenScores` и `by_id()`: метод связывает `ids` со `scores`, чтобы присоединить значения PageRank к id узлов из M2.

### Что доказывает

Отображение id узла → вес репутации. LUMEN — оракул степенной итерации EigenTrust/PageRank; эти веса задают размер узлов на живой 3D-карте.

### Самопроверка

- [ ] Присоединяете оценку LUMEN к узлу топологии по id
- [ ] Понимаете, почему сумма оценок ≈ 1,0 (вероятностное распределение)

---

## M5 — Сопоставление сцен оракулов с R3F (продвинутый)

**Концепция:** сопоставление слагов оракулов с камерой, акцентом и метаданными примитивов для сцен Three.js.
**Лаба:** `labs/lab05_r3f_scenes.py` · **~30 мин** · нужен M2 · React Three Fiber, WebGL

### Шаги

1. `python labs/lab05_r3f_scenes.py`
2. Вывод: `Oracle R3F scenes: N`, затем по каждой сцене `slug`, тип (`r3f` или `ambient`), кортеж `camera`, цвет `accent` и усечённое описание `primitive`.
3. В `courselib/viz.py` изучите `ORACLE_SCENE_META`, `R3FSceneSpec.for_oracle` и `map_graph_to_r3f_scenes`. Таблица метаданных зеркалит `alien-monitor/frontend/src/oracleScenes/meta.ts`, поэтому Python-спека и фронтенд остаются синхронными.
4. Обратите внимание на `TopologyGraph.oracle_slugs()`: он снимает префикс `oracle-` или ловит `group == "oracle"`, после чего каждый слаг находит свои камеру/акцент/примитив (с разумными значениями по умолчанию).

### Что доказывает

Список объектов `R3FSceneSpec` — ровно те камера, акцент и примитив, которые нужны `<Canvas>` React Three Fiber для отрисовки оракула. Это замыкает путь от REST-телеметрии к 3D-сцене.

### Самопроверка

- [ ] Прослеживаете слаг оракула до его камеры + акцента + примитива
- [ ] Различаете `ambient`-сцены и обычные `r3f`-сцены
- [ ] Объясняете, зачем метаданные зеркалятся из `meta.ts` фронтенда

---

## Подключение живого монитора

По умолчанию лабы работают со встроенным моком. Чтобы опросить настоящий alien-monitor:

```bash
# направьте лабы на любой запущенный монитор (по умолчанию http://127.0.0.1:9100)
export ALIEN_MONITOR_URL=http://127.0.0.1:9100
python labs/lab01_health_probe.py
```

Когда монитор доступен, `resolve_monitor_url()` пропускает мок, и появляется `Live alien-monitor reachable: True`. Те же пять лаб начнут визуализировать **реальную** экосистему: режимы переключатся с `test` на `real`/`universe`, топология покажет живые узлы, а LUMEN вернёт живые оценки PageRank.

---

## Упражнения и сертификат

После лаб запустите проверки:

```bash
python labs/run_exercises.py             # все пять проверок
python labs/run_exercises.py --module m4 # один модуль
```

Проверка каждого модуля (`exercise_m1_health_ok` … `exercise_m5_r3f_mapping`) утверждает свойство, которому учила лаба, — например, m1 проверяет `status == "ok"` и корректный режим, m4 — что `len(scores) == len(ids)`.

Когда все проверки пройдены, выпустите сертификат:

```bash
python labs/run_exercises.py --certificate "Иван Петров" --lang ru   # или en / es
```

Команда пишет `certificate.html` (id сертификата выводится из имени и даты). Откройте в браузере и **Печать → Сохранить как PDF**. Пройдите все проверки модулей, чтобы открыть сертификат.

---

## Наблюдаемость: блок Trace

После каждой лабы (~5 мин):

1. Найдите строку `trace (N events)` в конце вывода.
2. Лабы логируют структурированные события: M1 — `health`, M2 — по одному `node` на узел, M3 — `peer`, M4 — `lumen_score`, M5 — `r3f_scene`.
3. Сопоставьте каждое событие со строкой stdout — трейс это «лог юнит-теста» лабы: что опросили и что получили.

---

## Типичные проблемы

| Проблема | Решение |
|----------|---------|
| `ModuleNotFoundError: courselib` | Запуск из корня репозитория; лабы добавляют родительскую папку в `sys.path` |
| `Live alien-monitor reachable: False` | Норма без живого монитора — встроенный мок включается автоматически |
| Нужен живой монитор | Запустите alien-monitor на `127.0.0.1:9100` или задайте `ALIEN_MONITOR_URL` |
| Ошибка LUMEN / пустые оценки | Монитор не вернул данные LUMEN; лаба защищена `lumen.ok` и продолжает работу |
| Пустые строки RU/ES | `export COURSE_LANG=ru`; ключи `i18n/ru.json` должны совпадать с `en.json` |
| Падение паритета i18n в pytest | Добавьте недостающий ключ во все три файла `en/ru/es.json` |
| Старый код в Colab | Перезапустите setup-ячейку; закрепите ветку `main` |

---

Гайды в `docs/` правятся вручную — сначала EN, затем зеркала RU/ES.
