Skip to content

Архитектурные требования к проектам #1

Description

@skulidropek

Линтеры:

  1. Максимум размер файла: 400 строк (за исключением автогенерируемых модулей типо swagger)
  2. Максимум размер функции: 50 строчек (Маленькие функции: Функции должны быть короткими и выполнять только одну задачу)
  3. Максимум переданных параметров в метод: 5
  4. Максимальная глубина вложенности блоков: 4
  5. Максимальная сложность(ветвление): 8
  6. Блокировка любых подавлений ошибок типо: "/* eslint-disable no-console, eqeqeq */"
  7. Блокировка любых any, unknown, dynamic
  8. Monorepo должно делиться на модули
    Каждый модуль максимум 5000 строчек кода.
    Каждый модуль должен отвечать за свою отдельную функциональность.
    Если модуль требует больше 5000 строчек кода, значит уже пора делить этот модуль на несколько частей:
    • на подмодули
    • на отдельные packages
    • на отдельные bounded contexts
    • на отдельные сервисы, если реально нужна отдельная runtime/deployment-граница
      Модуль не должен быть большой общей папкой, куда складывается всё подряд.
  9. В одной папке не должно лежать больше 10 файлов с кодом
    Если в папке больше 10 файлов с кодом, скорее всего надо создавать подпапки и раскладывать код по смыслу.
    Цель правила: в одной папке не должно быть большой плоской кучи кода.
  10. Не должно быть не используемых зависимостей в коде.
  11. Не должно быть неиспользуемых модулей в коде
    Если есть методы/классы/функции/модули, которые нигде не вызываются, должна быть ошибка или warning.
    Исключение: публичный API библиотеки/модуля.
    Но если код является публичным API, он должен быть явно экспортирован и считаться частью public contract.
  12. Не должно быть дублей кода
    Для TypeScript используется библиотека jscpd.
    Также нужен агент-ревьюер, который будет детально изучать, дублирует ли код другой код по смыслу.
    Причина: автоматический поиск дублей может не находить случаи, когда один и тот же смысл написан разными словами.
  13. Обязательно надо использовать ORM или typed query layer для работы с базой данных
    Запрещено писать SQL прямо внутри business logic.
    Все обращения к базе должны идти через:
    • ORM
    • repository layer
    • typed query layer
    • другой типизированный слой доступа к данным
      Raw SQL разрешён только как исключение:
    • если ORM не может нормально выразить запрос
    • если запрос performance-critical
    • если запрос parameterized
    • если у запроса явно описаны input/output types
    • если есть тест
    • если есть комментарий/architecture note, почему ORM недостаточно
  14. Использовать Swagger/OpenAPI и swagger-api-generated для доступа к API
    Всегда работаем с доказуемыми типами.
    API schema является source of truth.
    Для доступа к API обязательно использовать generated client/types из Swagger/OpenAPI schema.
    Запрещено:
    • руками писать fetch/axios вызовы к внутренним API
    • руками дублировать DTO-типы между клиентом и сервером
    • руками описывать request/response-типы, если они уже есть в OpenAPI schema
    • обращаться к API без generated client
      Если меняется endpoint/request/response, сначала должна быть обновлена Swagger/OpenAPI schema, потом сгенерированы новые типы и клиент.
  15. Запрещено писать cast, as и любые способы ломать типизацию в коде

Для CI/CD:

  1. Сделать прогон safe lint --fix в CI/CD
    Если кто-то забыл прогнать fix локально, CI/CD должен сам прогнать fix и добавить эти изменения в код автоматически.
    Auto-fix должен быть:
    • deterministic
    • idempotent
    • безопасным
    • с зафиксированной версией toolchain
    • отдельным commit от CI/CD bot
    • полностью видимым в PR diff
      После auto-fix CI/CD обязан заново прогнать:
    • lint
    • typecheck
    • tests
    • build
      Если после повторного auto-fix снова появляются изменения, значит fix не достиг fixed point и CI/CD должен упасть.

Тесты:

  1. Test coverage минимум 10%
  2. Обязательно использование property-based testing там, где есть инварианты
    Например:
    • парсеры
    • сериализация/десериализация
    • нормализация данных
    • state machines
    • permission logic
    • financial/math logic
    • retry/idempotency logic
    • validation logic
  3. Обязательно использование e2e тестирования
    E2E тестами должны быть покрыты основные пользовательские сценарии и критические бизнес-флоу.
  4. В открытом PR должно быть покрыто 100% нового и изменённого кода тестами
    Если PR добавляет новый код, к нему должны быть добавлены тесты.
    Если PR меняет старый код, тесты должны покрывать изменённое поведение.
  5. Использование mutation testing на изменения в PR
    Mutation testing должен запускаться на изменённых файлах с кодом.
    Цель mutation testing: проверять не только наличие тестов, но и то, что тесты реально ловят поломки.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions