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

8 KiB
Raw Permalink Blame History

name description
code-standards 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 filestest_*.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.