# Контрибьютинг в студию Рублокса

Спасибо за интерес! Всё что нужно знать.

## Перед первым PR

1. **Подпиши [CLA](./CLA.md)** — открой `https://team.rublox.pro/developer/cla` (нужна роль `developer` — попроси у мейнтейнера) ИЛИ комментарий `/sign-cla` на PR.
2. **Заведи Gitea-аккаунт** через OAuth-привязку к team.rublox.pro.
3. **Добавь SSH-ключ** в профиль Gitea (иначе пуш по HTTPS + пароль).

## Workflow

```bash
# 1. Клонируем (или форкаем — если есть доступ, можно сразу пушить в feature-ветку)
git clone ssh://git@git.rublox.pro:2222/rublox/studio.git
cd player
npm install
cp .env.example .env

# 2. Создаём feature-ветку
git checkout -b feature/короткое-описание

# 3. Делаем изменения
npm run dev      # проверяем локально
npm run lint     # ESLint
npm run format   # Prettier

# 4. Коммитим (Conventional Commits)
git commit -m "feat: добавить анимацию прыжка для GdBall"
# Другие префиксы: fix:, chore:, docs:, refactor:, test:, perf:, ci:

# 5. Пушим и открываем PR
git push origin feature/короткое-описание
# Открыть PR через https://git.rublox.pro/rublox/studio
```

## Стиль кода

Используем **Prettier** (авто-формат) + **ESLint** (линт). Конфиги закоммичены в `.prettierrc` и `.eslintrc.json`.

Главные правила:
- 2-space отступ
- Одинарные кавычки (`'foo'`, не `"foo"`)
- Точки с запятой обязательны
- Trailing comma в многострочных литералах
- Ширина строки 100 символов
- Никаких `eval`, `new Function`, `innerHTML = ...`
- React: hooks-правила обязательны (`react-hooks/rules-of-hooks`)

Запускай перед коммитом:
```bash
npm run format    # авто-фикс большинства
npm run lint      # предупреждения для остального
```

Pre-commit-хук (Husky, если установлен) заблокирует если Prettier-чек провален.

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

| Префикс | Использовать для |
|---|---|
| `feature/...` | Новые фичи |
| `fix/...` | Багфиксы |
| `chore/...` | Рефакторинг, зависимости, тулинг |
| `docs/...` | Только документация |
| `perf/...` | Улучшения производительности |

## Commit-сообщения (Conventional Commits)

```
<тип>: <короткое описание>

[опционально тело]

[опционально футер: BREAKING CHANGE / Closes #N]
```

Типы: `feat`, `fix`, `chore`, `docs`, `refactor`, `test`, `perf`, `ci`, `style`.

**Хорошо:**
- `feat: добавить WaveMode в GdGameModeRegistry`
- `fix: ScriptSandbox падает при таймауте Worker`
- `perf: дросселировать ui.set() до 250мс с diff-проверкой`

**Плохо:**
- `update code`
- `wip`
- `пофиксил всякое`

## Шаблон PR

При открытии PR заполни:

```markdown
## Что

(1-2 предложения: что делает этот PR?)

## Зачем

(мотивация: репорт бага, фича-реквест, связанный issue #N)

## Как протестить

(воспроизводимые шаги для ревьюера)

## Скриншоты / видео (если UI-изменение)

## Чек-лист

- [ ] `npm run lint` проходит
- [ ] `npm run format:check` проходит
- [ ] `npm run build` собирается
- [ ] Протестил локально через `npm run dev`
- [ ] Обновил соответствующие доки (README / ARCHITECTURE / CHANGELOG)
- [ ] CLA подписан
```

## Процесс ревью

- Мейнтейнер репо (МИН) ревьюит каждый PR.
- Ожидай фидбек в течение **48 часов** (часто в тот же день).
- Маленькие PR (<300 строк) ревьюятся быстро. PR'ы >1000 строк попросят раздробить.
- После approval **мерджит мейнтейнер** (право merge только у него).
- После merge **CI автоматически билдит и заливает на оба прод-сервера** (S1 и S2 параллельно через rsync). Время от мержа до прода ~3-5 мин.

## Что не смерджим

- PR с новыми внешними зависимостями без обсуждения
- PR трогающие чувствительные пути (`engine/scripts/ScriptSandbox*.js`, `engine/multiplayer/*`) без security-ревью
- PR ломающие сборку или линт
- PR от контрибьюторов без подписанного CLA
- Массивные рефакторинги без заранее обсуждённого tracking-issue

## Что любим

- Багфиксы с воспроизводимыми тест-кейсами
- Улучшения производительности с before/after метриками
- Новые `engine/gd/Gd*.js` гейммоды
- Новые API для скриптов (в `ScriptSandboxAPI.js`)
- Улучшения документации (особенно с примерами)

## Для мейнтейнеров (включая Lead)

**Даже Lead работает через PR.** Это не бюрократия — это страховка:

- **CI запускается только на PR и push в main**, прямой коммит в main минует CI → можно положить прод.
- **История изменений линейна** — каждое изменение имеет описание, ревьюера (даже самого себя) и chain of trust.
- **Контрибьюторы видят дисциплину Lead'а** и сами начинают её соблюдать.

### Workflow Lead/Maintainer (когда сам себе ревьюер)

```bash
# 1. Feature-ветка от свежей main
git checkout main && git pull
git checkout -b feature/название

# 2. Делаем изменения, коммитим, пушим
git push origin feature/название

# 3. Открываем PR через Gitea UI или git.rublox.pro CLI
# 4. Ждём пока CI зелёный (~2 мин на lint+build)
# 5. Самоапрув + Merge (можно Squash для feature, Rebase для chore)
# 6. CI deploy job сам зальёт на S1+S2 (~3 мин)
```

### Когда можно прямой push в main

**Никогда.** Даже emergency hotfix:

```bash
git checkout -b hotfix/что-сломалось
# фикс + git commit + git push
# Открыть PR → дождаться CI зелёного (~2 мин) → merge
# CI задеплоит за 3 мин
```

Итого hotfix-флоу = ~5 мин от обнаружения проблемы до развёрнутого фикса.
Это быстрее чем хаотичный прямой push с риском сломать прод повторно.

### Если CI deploy сломался (как fallback)

Можно вручную через DevPanel:

```bash
# На локалке
cd c:/Users/min/Desktop/server/rublox-studio
npm run build
# Затем заливка через DevPanel → "rublox-studio" → "Deploy"
# (он использует frontend_deploy.py который тоже бьёт по обоим серверам)
```

Это **временный** обходной путь. После починки CI обязательно вернуться к авто-деплою.

## Безопасность

Нашёл уязвимость? **Не открывай публичный issue.** Пиши на `security@rublox.pro` напрямую. См. [SECURITY.md](./SECURITY.md).

## Вопросы?

- Открой issue с лейблом **Question**
- Или приходи в канал `#разработка` на https://team.rublox.pro/chat
