Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
# Contributing

The plan and all decisions are in [IMPROVEMENT_PLAN.md](IMPROVEMENT_PLAN.md) (in Russian): section 8 is the order of work, section 10 the decisions.
**English** · [Русский](CONTRIBUTING.ru.md)

The plan and all decisions are in [IMPROVEMENT_PLAN.md](IMPROVEMENT_PLAN.md): section 8 is the order of work, section 10 the decisions.

## Language

The project is open source and **English is the base language**: code, comments, identifiers, commit messages, CLI output, API error messages, specifications and documentation. Russian is the second language: the UI is translated (`ui/src/lib/i18n`) and user documentation has a Russian version (`README.ru.md`). A change to user-facing docs updates both versions.
The project is open source and **English is the base language**: code, comments, identifiers, commit messages, CLI output, API error messages, specifications and documentation. Russian is the second language: the UI is translated (`ui/src/lib/i18n`) and every document comes in a pair: `X.md` in English and `X.ru.md` in Russian, with a language switcher at the top of both. A change to a document updates both versions, and the links of each version lead to documents in the same language. The plan is no exception: `IMPROVEMENT_PLAN.md` and `IMPROVEMENT_PLAN.ru.md` are kept in sync, and an item done is ticked in both.

## Repository layout

Expand Down
97 changes: 97 additions & 0 deletions CONTRIBUTING.ru.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Участие в разработке

[English](CONTRIBUTING.md) · **Русский**

План и все решения — в [IMPROVEMENT_PLAN.ru.md](IMPROVEMENT_PLAN.ru.md): раздел 8 — порядок работ, раздел 10 — решения.

## Язык

Проект открытый, и **базовый язык — английский**: код, комментарии, идентификаторы, сообщения коммитов, вывод CLI, сообщения об ошибках API, спецификации и документация. Русский — второй язык: UI переведён (`ui/src/lib/i18n`), а каждый документ существует в паре: `X.md` на английском и `X.ru.md` на русском, с переключателем языка вверху обоих. Правка документа меняет обе версии, а ссылки каждой версии ведут на документы на том же языке. План — не исключение: `IMPROVEMENT_PLAN.md` и `IMPROVEMENT_PLAN.ru.md` ведутся вместе, сделанный пункт отмечается в обоих.

## Устройство репозитория

| Каталог | Что | Язык |
|---|---|---|
| `client-php/` | PHP-библиотека (отладчик), Composer-пакет, PHP 7.4+; `v1/` — прежняя библиотека, только срочные исправления, вне линтеров | PHP |
| `server/` | Просмотрщик: CLI, сервер, импорт логов, точка входа десктопа | Go 1.26+ |
| `ui/` | Веб-интерфейс, встраивается в Go-бинарник | Svelte 5 + TypeScript |
| `desktop/` | Заметки о сборке десктопа на Wails | — |
| `spec/` | Контракты: фикстуры, JSON Schema, OpenAPI | — |

## Команды

Все проверки запускаются через `make`; CI вызывает те же цели:

```sh
make doctor # что установлено, чего не хватает
make tools # закреплённые версии линтеров в .tools/bin
make deps # зависимости всех компонентов
make test # все тесты
make lint # все линтеры
make ci # всё, что делает CI
make e2e # браузерные тесты (Playwright) собранного просмотрщика на фикстурах логов
make e2e-visual # снимки каждой темы против ui/e2e/__screenshots__ (Docker)
make ssh-e2e # просмотрщик против настоящего OpenSSH-сервера в Docker
make help # все остальные цели
```

`make e2e` один раз нужен Chromium для Playwright: `cd ui && npx playwright install chromium`.

`make e2e-visual` снимает скриншоты внутри Docker-образа Playwright, поэтому шрифты одинаковые на любой машине и в CI. После задуманного изменения внешнего вида `make e2e-visual-update` снимает их заново; посмотрите новые файлы в `ui/e2e/__screenshots__`, прежде чем коммитить. Витрина компонентов, `#/dev/components` (или «Витрина компонентов» в `Ctrl+K`), показывает каждый компонент в каждой встроенной теме.

Цвета живут только в `ui/src/styles/theme.css` как токены; Stylelint не пропустит цвет в любом другом месте.

## TDD

Новый код пишется с теста:

1. Тест, который описывает поведение, — и падает (красный).
2. Минимальная реализация, с которой он проходит (зелёный).
3. Рефакторинг при зелёных тестах.

Код без теста, который его потребовал, не принимается. Баг, найденный вручную, сначала воспроизводится тестом, потом исправляется.

| Компонент | Тесты | Где |
|---|---|---|
| `client-php` | PHPUnit 9.6, матрица PHP 7.4–8.4 в CI | `client-php/tests/` |
| `server` | `go test -race` | рядом с кодом, `*_test.go` |
| `ui` | Vitest + Testing Library | рядом с кодом, `*.test.ts` |

Тесты разбора логов используют фикстуры из `spec/fixtures/`, а не придуманные строки.

## Контракты и сгенерированный код

Сначала меняется контракт в `spec/` (форматы логов, OpenAPI), потом код. Типы Go (`server/internal/api`, `server/internal/libclient`) и TypeScript (`ui/src/lib/api/schema.gen.d.ts`) генерируются из OpenAPI командой `make generate`; файлы `*.gen.*` руками не правятся. CI проверяет, что сгенерированный код совпадает с закоммиченным (`make generate-check`).

## Именование

Венгерская нотация во всём новом коде запрещена: никаких префиксов типа вроде `a`, `s`, `i`, `b`, `o`, `m`, `f`, `fn` (`$aVars`, `$sMessage`, `fnDebugLog`, `oSelectedProject`). Тип выражает система типов.

| Где | Стиль | Пример |
|---|---|---|
| PHP | PSR-12: классы `PascalCase`, методы и свойства `camelCase`, константы `UPPER_SNAKE` | `$projectRoot`, `log()`, `Level::ERROR` |
| Go | идиоматичный Go (`MixedCaps`) | `Project.LogDir()` |
| TypeScript / Svelte | `camelCase`, компоненты `PascalCase` | `selectedRequest`, `RequestList.svelte` |
| Формат логов, конфиг, API, база данных | `snake_case` | `request_id`, `is_cli`, `messages.level` |

Поля DTO из OpenAPI остаются в TypeScript `snake_case` (без слоя конвертации).

Это проверяется автоматически: `client-php/tools/bin/check-naming` для PHP и правило ESLint `naming-convention` для TS/Svelte. Строку с устаревшей обёрткой, которая сохраняет старое имя, можно исключить комментарием `// naming-check:ignore`.

## Тексты UI

Каждая видимая пользователю строка проходит через `i18n.t('key')`. Ключ добавляется в оба словаря в `ui/src/lib/i18n/messages.ts`; тесты проверяют, что у `en` и `ru` одинаковые ключи, одинаковые подстановки и все формы множественного числа (`Intl.PluralRules`). Нативные диалоги браузера (`alert`, `confirm`, `prompt`), `<select>` и подсказки `title` не используются: для них есть свои компоненты.

Словарь: **запрос** (request) — один HTTP- или CLI-запуск и его файл лога; **сообщение** (message) — событие внутри запроса; **контекст** (context) — переменные сообщения; **сервер** (server) — машина, на которой живут проекты; **проект** (project) — приложение на сервере.

## Коммиты

[Conventional Commits](https://www.conventionalcommits.org/) на английском:

```
feat(server): import v2 logs from the saved offset
fix(client-php): mask secrets in nested arrays
chore: update golangci-lint to v2.15
```

Типы: `feat`, `fix`, `refactor`, `test`, `docs`, `chore`, `ci`, `build`. Область (scope) — каталог верхнего уровня (`client-php`, `server`, `ui`, `desktop`, `spec`, `docs`).
Loading
Loading