opencode-config/.opencode/skills/code-standards/SKILL.md
Sergey 9459e47567
Some checks failed
CI / bootstrap (push) Successful in 52s
CI / lint (push) Successful in 2m2s
CI / typecheck (push) Successful in 27s
CI / test (3.12) (push) Failing after 2m53s
CI / test (3.13) (push) Failing after 2m0s
CI / test (3.14) (push) Failing after 1m48s
CI / complexity (push) Successful in 23s
feat(spec): mobile-first silent enforcement in STACK_REQUIRED + CI e2e (#281)
* feat(spec): mobile-first silent enforcement in STACK_REQUIRED + Template C

* feat(ci): frontend-e2e job with Playwright in fullstack cookiecutter

* docs(skills): mention mobile-first in audit, code-standards, project-status tool

* fix(ci): use npm install instead of npm ci + add e2e regression test

---------

Co-authored-by: opencode-agent <agent@opencode.local>
2026-08-05 07:05:14 +03:00

137 lines
8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
name: code-standards
description: Universal code standards for any language. Use when writing, refactoring, or reviewing code. Also when user says "стандарты кода", "code review", "правила разработки".
---
# Code Standards
## 1. Код как рассказ
- **KISS:** Пиши лаконично, без переусложнений. Код читается как последовательный рассказ
- **Функциональный стиль:** Классы — только когда нужно состояние или интерфейс библиотеки. В остальном — функции
- **Приватность:** Внутреннюю логику модуля скрывай. Префикс `_` в Python/JS, `private` в TS/Rust, internal методы по умолчанию
- **Разделение ответственности:** Бизнес-логика ≠ транспорт ≠ представление. Максимум 200-300 строк на файл. Одна ответственность на файл
## 2. Прагматизм
- **YAGNI:** Только то что нужно сейчас. Никаких заделов «на будущее», оверинжиниринга и самодеятельности
- **Правило 80/20:** Если задача ведёт к неоправданному усложнению — предупреди и предложи альтернативу до написания кода
## 3. Принципы модульности
- Функция/метод — не длиннее 30-50 строк. Если больше — разбивай на мелкие тестируемые функции
- Файл — до 200-300 строк. Больше → декомпозиция
- Конфиги/константы — в отдельный файл, не в логику
- Приватные функции/методы для внутренних деталей (с префиксом `_` или аналогом языка)
## 4. Документирование
- AGENTS.md правило «No comments unless requested» — это **default**: код без комментариев
- Этот skill описывает **исключение**: Google-style docstrings на английском для публичных API — когда контракт warrants (библиотечный API, public surface)
- Описывай **зачем**, а не **что** — код и так говорит что делает
## 5. Architecture: good vs bad
Слои для **backend**: `routes → schemas → services → db/models` (4-tier, однонаправленный). Роуты тонкие (импортируют только `services` + `schemas`), сервисы работают с `db/models`, бизнес-логика здесь. `project-status.py` enforces subset (thin routes, centralized models); этот раздел объясняет «почему».
### Backend (подробно)
**GOOD tree (синтетический):**
```
src/<package>/
├── api/
│ ├── v1/
│ │ ├── routes/users.py ← тонкие роуты, импортируют только services + schemas
│ │ ├── dependencies.py ← Depends(), get_current_user
│ │ └── router.py
│ └── router.py
├── config/
│ ├── settings.py ← pydantic-settings
│ └── logger.py ← loguru setup
├── db/
│ ├── connection.py ← Tortoise.init
│ └── models/ ← ВСЕ ORM-модели здесь (centralized)
│ ├── user.py
│ ├── post.py
│ └── comment.py
├── schemas/ ← Pydantic DTO (НЕ Tortoise models)
│ ├── base.py
│ ├── user.py
│ └── post.py
├── services/ ← бизнес-логика (работает с db/models)
│ ├── user_service.py
│ └── post_service.py
└── utils/
└── metadata.py
```
**Правила GOOD:**
1. Все ORM-модели в `db/models/` (centralized)
2. Schemas (Pydantic) отдельно от models (Tortoise) — НЕ смешивать
3. Роуты тонкие — импортируют только `services` и `schemas`
4. Сервисы работают с `db/models` — бизнес-логика здесь
5. Слои: routes → schemas → services → db/models (4-tier, однонаправленный)
**BAD tree 1 — feature-scatter:**
```
src/<package>/
├── channels/
│ ├── models.py ← ❌ модель здесь (scatter)
│ ├── routes.py
│ └── service.py
├── monitor/
│ ├── models.py ← ❌ ещё модель здесь
│ └── routes.py
├── logs/
│ └── models.py ← ❌ и здесь
├── models.py ← ❌ root-level модель
├── db.py ← ❌ connection flat (не db/connection.py)
└── main.py
```
Проблемы BAD 1: модели раскиданы по feature-папкам; `models.py` в root; `db.py` flat; не publishable; Tortoise `modules` должен перечислять 4+ файла вручную.
**BAD tree 2 — mixed-layers:**
```
src/<package>/
├── api/
│ ├── v1/
│ │ └── users.py ← ❌ роут содержит бизнес-логику + Tortoise queries
│ └── models.py ← ❌ модели в api/ (не в db/models/)
├── services/
│ └── user_service.py
│ └── schemas.py ← ❌ schemas в services/ (не в schemas/)
└── main.py
```
Проблемы BAD 2: роут делает Tortoise queries напрямую (не тонкий); модели в `api/models.py` (не `db/models/`); schemas внутри services (не отдельный слой).
### Fullstack (кратко)
Backend as above (in `backend/` + `frontend/` separation). Frontend: SvelteKit co-located `*.test.ts` в `src/lib/`, `e2e/*.spec.ts` для Playwright. НЕ смешивать backend код в `frontend/` и наоборот. + mobile-first (PWA + Playwright mobile + axe a11y) — silent enforcement через `STACK_REQUIRED["fullstack"]`.
### CLI (кратко)
`cli.py` (Typer commands) + `core.py` (business logic). Нет api/db/schemas layers. `tests/test_cli.py` + `tests/test_core.py`.
## 6. Tests
Что писать (как запускать — в `run-tests` skill). `project-status.py` enforces subset (conftest required, anti-stub, mirror structure); этот раздел объясняет «почему».
### Типы тестов
- **Regression** — воспроизводит конкретный баг, который был исправлен. Ссылается на issue/PR (`test_parser_handles_crlf_regression_#227`).
- **Integration** — пересекает слои (DB+API, scheduler+DB). Имеет `pytest.mark.integration` + `skipif` opt-in. В `tests/integration/`.
- **Unit** — чистая функция/сервис, без DB/сети. В `tests/unit/`.
### Антипаттерны
- **Stub files** — `test_*.py` без `def test_*`/`async def test_*` (digital_factory 50/62 файлов). `project-status` WARNs.
- **Тесты без assertions** — только `print`/`logger.info`. Каждый тест должен иметь минимум 1 `assert`.
- **Тесты ради тестов** — coverage ради coverage, без реальной проверки поведения.
### Mirror structure (backend)
- `tests/unit/``src/<pkg>/services/` (unit-тесты сервисов)
- `tests/api/``src/<pkg>/api/v1/routes/` (route-тесты через TestClient)
- `tests/integration/` ↔ cross-cutting flows (opt-in)
### conftest.py
Обязателен (backend). Shared fixtures: `mock_settings`, `client`, `auth_client`, `create_<entity>` factories.