Skip to content

Разработка

Подготовка окружения

Одного uv sync для зелёного прогона тестов недостаточно:

uv sync                  # группы default и dev
npm --prefix webapp ci   # без этого inv test пропустит фронтенд

inv test пропускает набор тестов фронтенда, когда нет webapp/node_modules, а CI — нет: прогон без npm ci неполный. Добавление python-зависимости требует ещё и uv lock; CI ставит зависимости с --frozen.

languages.toml нужен только чтобы запустить приложение, и inv dev создаёт его из languages.example.toml.

Команды

Задача Команда
Линт, форматирование и проверка типов uv run inv pre
Полный набор тестов (Python + фронтенд) uv run inv test
Только Python-тесты uv run pytest
Только тесты фронтенда npm --prefix webapp test
Дев-сервер с автоперезагрузкой uv run inv dev
Сборка PWA в _static/ uv run inv build-static
Список всех задач uv run inv --list

Префикс uv run не нужен внутри активированного .venv.

Warning

Никогда не вызывайте Ruff напрямую. inv pre запускает ruff, ruff-format, pyrefly и хуки гигиены файлов с настройками проекта — это единственная проверка, совпадающая с CI.

Для горячей перезагрузки при работе над Vue запустите дев-сервер Vite во втором терминале — он проксирует /api на бэкенд, слушающий порт 8080:

npm --prefix webapp run dev   # http://127.0.0.1:5173

vite dev не регистрирует service worker. Поведение офлайн и PWA проверяйте на настоящей сборке _static/.

Язык интерфейса

Строки PWA лежат в webapp/src/i18n/{en,ru}.js и достаются через t("key"); переключатель в шапке пишет выбор в localStorage, а клиент отправляет его в заголовке Accept-Language при каждом запросе к API. Подсказки, которые показывает сам бэкенд — проверка ввода и ошибки неизвестного языка, — лежат в src/echo_words/i18n.py и выбираются по этому заголовку для каждого запроса. Оба набора тестов проверяют, что в двух каталогах ровно одинаковые ключи, так что строка, добавленная в одном языке, не пропадёт молча в другом.

Текст, который сервер отдаёт в общую историю и поток событий, — статусы карточек и сам разбор — не зависит от клиента и так не переводится. Язык разбора задаётся ECHOWORDS_TARGET_LANG.

Тесты

Каждый новый модуль или функция приезжают с тестами в том же коммите. Никаких настоящих сетевых вызовов, синхронизаций Anki, обращений к LLM или TTS в тестах — все границы подменяются. Стенд в experiments/ — санкционированное исключение, в CI он не входит.

CI прогоняет матрицу Python 3.12/3.13, набор тестов Vitest и Ruff. Отчёты публикуются в Allure.

Спецификации

В spec/ лежат функциональное описание и записи о принятых решениях — интервальные повторения, TTS, LLM-бэкенд, интерфейс и хост развёртывания. На этот сайт они не публикуются. Если spec/ и код расходятся, прав код.