Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

DiorditsPV/interview-graph

Repository files navigation

Интервью · граф вопросов

Локальный веб-сервис для технических интервью по дата-инженерному стеку команды. Ядро — интерактивный направленный граф вопросов: каждая нода = вопрос/задача + ответ + оценка; ветвление по теме, сложности и условное (по оценке). Контент импортируется из Markdown и JSON.

Стек: FastAPI + SQLite (бэкенд) · React + Vite + React Flow (фронт). Только локально.

Быстрый старт

./run.sh # поднимет venv, соберёт фронт (если нужно) и запустит сервер
# открыть http://localhost:8000

Пересобрать фронт принудительно: ./run.sh --build.

Режим разработки (hot reload)

Два процесса:

# терминал 1 — бэкенд
cd backend && . .venv/bin/activate && uvicorn app.main:app --reload --port 8000
# терминал 2 — фронт (Vite проксирует /api на :8000)
cd frontend && npm run dev # http://localhost:5173

Управление во время интервью

Раскладка — swimlanes: вертикальная колонка на каждое направление (Фреймворки / Базы данных / Python / Платформа) с заголовком и цветным полупрозрачным фоном; внутри колонки вопросы ранжированы сверху вниз по сложности (base → junior → middle → senior, левая ось).

Блок можно делить на под-колонки по технологиям через поле subblock во frontmatter (напр. Фреймворки → Airflow / PySpark / dbt / Streaming): под общим заголовком блока появляются под-колонки с собственными хедерами. Если у нод блока один subblock — блок остаётся одной колонкой. Порядок под-блоков задаётся в frontend/src/layout.ts (PREFERRED_SUB).

Карточка показывает короткий заголовок (title) и теги — полный текст вопроса/ответа открывается в drawer. Зависимостей между вопросами (рёбер) нет — это просто доска карточек, сгруппированная по направлениям и сложности.

  • Клик по ноде — открывает drawer (полный текст) и делает её «текущей».
  • HUD снизу — текущий вопрос + оценка 1–5 + «Дальше →» (следующий неоцененный вопрос) + «✕».
  • Панель фильтров (справа) — переключатели направлений, сложностей и тегов + прогресс done/total. Активные теги гасят нерелевантные карточки (подсветка/фильтр).
  • Клавиатура: 1–5 — оценить текущий, ↑↓ — по сложности в колонке, ←→ — между колонками, Enter — открыть drawer, n — следующий неоцененный, Esc — снять текущий.
  • Тема — кнопка 🌙/☀️ в шапке переключает светлую/тёмную (запоминается в localStorage; по умолчанию берётся системная). Канва React Flow, контролы и миникарта тоже темнеют.
  • 📥 Скачать — выгружает результаты текущей сессии самодостаточным HTML-отчётом (кандидат, дата, средний балл и охват по блокам, таблицы оценённых вопросов с темой/тегами/ баллами). Открывается в браузере и печатается в PDF. Генерируется на клиенте (src/report.ts).

Контент

Вопросы лежат в content/<блок>/*.md или *.json. Блоки: frameworks, databases, python, platform. Веса блоков (балансировка) — в content/weights.yaml.

Формат Markdown

---
id: spark-shuffle-01
kind: question # question | task
block: frameworks # frameworks | databases | python | platform
subblock: pyspark # (опц.) под-колонка внутри блока
title: Shuffle в Spark # короткий заголовок для карточки
topic: distributed-batch
difficulty: middle # base | junior | middle | senior
weight: 13
tags: [spark, optimization]
---
## Вопрос
Текст вопроса...
## Ответ
Текст ответа (Markdown, поддерживаются блоки кода)...
  • title — короткий заголовок, отображается на карточке (полный текст — в drawer).
  • tags — отображаются чипами на карточке и доступны для фильтра справа.
  • Для kind: task доступны поля starterCode (стартовый код) и rubric (критерии), а тело можно писать через ## Задача / ## Решение.

Парсинг тела: строки, начинающиеся с #, трактуются как заголовки-маркеры разбиения на вопрос/ответ. Если в ответе нужен текст, начинающийся с # вне блока кода, — задайте question/answer прямо во frontmatter (тогда тело не парсится).

API

метод путь назначение
GET /api/graph ноды + ошибки импорта
GET /api/weights веса блоков
POST /api/interview собрать набор вопросов пропорц. весам ({count, difficulties?, seed?})
POST /api/sessions создать сессию кандидата
POST /api/sessions/{id}/score выставить оценку ({nodeId, score})
GET /api/sessions/{id} сессия с оценками

Это ядро. Полный список ручек (кандидаты/интервьюеры, CRUD нод /api/nodes, импорт /api/import, сравнение сессий /api/sessions/compare, live-обновления по SSE /api/sessions/{id}/events) и схемы — в Swagger UI на /docs.

Тесты

Бэкенд (54 теста — test_app.py импорт MD/JSON, sampler, API, сессии; test_nodes.py CRUD нод; test_people.py кандидаты/интервьюеры, изоляция тенантов):

cd backend && . .venv/bin/activate && pytest -q

Фронтенд — headless smoke-тест реального рантайма (граф рендерится, нода → drawer, оценка проставляется и отражается в HUD/прогрессе). Требует запущенного сервера на :8000:

cd frontend && npm run smoke

Конфигурация (env)

  • INTERVIEW_CONTENT_DIR — каталог контента (по умолч. ./content)
  • INTERVIEW_DB_PATH — путь к SQLite (по умолч. backend/interview.db)
  • INTERVIEW_FRONTEND_DIR — каталог собранного фронта (по умолч. frontend/dist)

Деплой

Автодеплой на сервер при merge в main (GitHub Actions → SSH). Порт 8800. Подробности и разовая настройка секретов/ключа — в DEPLOY.md.

См. REPORT.md — отчёт-исследование и архитектурные решения.

About

Граф вопросов для технических интервью по дата-инженерному стеку (FastAPI + React Flow)

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

Contributors

AltStyle によって変換されたページ (->オリジナル) /