--- 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// ├── 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// ├── 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// ├── 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//services/` (unit-тесты сервисов) - `tests/api/` ↔ `src//api/v1/routes/` (route-тесты через TestClient) - `tests/integration/` ↔ cross-cutting flows (opt-in) ### conftest.py Обязателен (backend). Shared fixtures: `mock_settings`, `client`, `auth_client`, `create_` factories.