architect/standards/4-policy/policy-code.md

type: standard
aspect: policy
title: "Политики кода"
version: 1.0.0
date: 2026-02-19
status: active


Политики кода

Обязательные правила написания, организации и проверки кода.


ПРИНЦИП

КОД = ЧИТАЕМЫЙ + БЕЗОПАСНЫЙ + ПЕРЕИСПОЛЬЗУЕМЫЙ

Код пишется один раз, читается много раз.


1. СТИЛЬ КОДА

Обязательные стандарты

Язык Стандарт Инструмент Конфиг
Python PEP 8 + Black black, ruff pyproject.toml
JavaScript Airbnb Style Guide prettier, eslint .eslintrc.json
TypeScript Google TypeScript Style prettier, tslint tsconfig.json
Bash Google Shell Style shellcheck, shfmt .shellcheckrc

Подробнее: format-code.md

Автоматическое форматирование

ОБЯЗАТЕЛЬНО: Запускать форматтер перед каждым коммитом.

# Python
black .
ruff check --fix .

# JavaScript/TypeScript
prettier --write .
eslint --fix .

# Bash
shfmt -w *.sh

Pre-commit hook:

#!/bin/bash
# .git/hooks/pre-commit
black . || exit 1
ruff check . || exit 1

2. ИМПОРТЫ

Порядок импортов

Python (PEP 8):

# 1. Стандартная библиотека
import os
import sys
from typing import List, Dict

# 2. Сторонние библиотеки
import requests
from fastapi import FastAPI

# 3. Локальные модули
from library.connectors import OzonClient
from .models import User

JavaScript/TypeScript:

// 1. Внешние библиотеки
import React from 'react';
import { useEffect } from 'react';

// 2. Внутренние модули
import { Button } from '@/components';
import { useAuth } from '@/hooks';

// 3. Локальные
import styles from './styles.module.css';

Абсолютные vs относительные

Правило:
- Абсолютные — для импорта из library/, system/
- Относительные — для импорта из той же папки

# ✅ Хорошо
from library.connectors.ozon import OzonClient  # Абсолютный
from .models import User                         # Относительный (та же папка)

# ❌ Плохо
from ../../library/connectors/ozon import OzonClient  # Слишком сложно

Подробнее: naming-code-imports.md


3. СТРУКТУРА КОДА

Организация модулей

Правило: Один класс/функция = один файл (если > 200 строк).

library/connectors/ozon/
├── __init__.py           Экспорты
├── client.py             Главный класс OzonClient
├── models.py             Data classes
├── operations.py         Операции
└── exceptions.py         Исключения

Подробнее: structure-component.md

Размер файлов

Размер Действие
< 200 строк ✅ OK
200-500 строк ⚠️ Рассмотреть разбиение
> 500 строк ❌ Обязательно разбить

Размер функций

Размер Действие
< 20 строк ✅ OK
20-50 строк ⚠️ Желательно разбить
> 50 строк ❌ Обязательно разбить

4. КОММЕНТАРИИ И ДОКУМЕНТАЦИЯ

Docstrings (обязательно)

Python (Google Style):

def sync_orders(api_key: str, date_from: str, limit: int = 100) -> Dict[str, int]:
    """Синхронизировать заказы из OZON API.

    Args:
        api_key: API ключ OZON
        date_from: Дата начала в формате YYYY-MM-DD
        limit: Максимальное количество заказов (default: 100)

    Returns:
        Dict с ключами:
            - synced: количество синхронизированных заказов
            - errors: количество ошибок

    Raises:
        ValueError: Если date_from в неверном формате
        APIError: Если API вернул ошибку
    """
    pass

JavaScript/TypeScript (JSDoc):

/**
 * Синхронизировать заказы из OZON API.
 *
 * @param apiKey - API ключ OZON
 * @param dateFrom - Дата начала в формате YYYY-MM-DD
 * @param limit - Максимальное количество заказов (default: 100)
 * @returns Объект с количеством синхронизированных заказов
 * @throws {ValueError} Если dateFrom в неверном формате
 */
function syncOrders(apiKey: string, dateFrom: string, limit: number = 100): SyncResult {
    // ...
}

Комментарии в коде

Когда комментировать:
- ✅ Сложная логика (алгоритмы)
- ✅ Неочевидные решения
- ✅ Обходы багов/ограничений
- ✅ TODO/FIXME/HACK

Когда НЕ комментировать:
- ❌ Очевидный код
- ❌ Дублирование имени функции
- ❌ Устаревшие комментарии

# ❌ Плохо (очевидно)
# Увеличить счётчик на 1
count += 1

# ✅ Хорошо (объясняет почему)
# OZON API возвращает время в UTC+3, конвертируем в UTC
order_time = order_time - timedelta(hours=3)

5. ТИПИЗАЦИЯ

Python Type Hints (обязательно)

from typing import List, Dict, Optional, Union

def get_user(user_id: int) -> Optional[User]:
    """Получить пользователя по ID."""
    pass

def process_orders(orders: List[Order]) -> Dict[str, int]:
    """Обработать список заказов."""
    pass

Проверка типов:

mypy .

TypeScript (обязательно)

interface User {
    id: number;
    name: string;
    email: string;
}

function getUser(userId: number): User | null {
    // ...
}

function processOrders(orders: Order[]): Record<string, number> {
    // ...
}

6. ОБРАБОТКА ОШИБОК

Правила

  1. Не игнорировать ошибки:
    ```python
    # ❌ Плохо
    try:
    risky_operation()
    except:
    pass

# ✅ Хорошо
try:
risky_operation()
except SpecificError as e:
logger.error(f"Failed: {e}")
raise
```

  1. Специфичные исключения:
    ```python
    # ❌ Плохо
    except Exception:
    pass

# ✅ Хорошо
except (ValueError, KeyError) as e:
handle_error(e)
```

  1. Логирование:
    python try: result = api_call() except APIError as e: logger.error(f"API call failed: {e}", exc_info=True) raise

7. БЕЗОПАСНОСТЬ

Запрещено

Проблема Пример Правильно
SQL Injection f"SELECT * FROM users WHERE id={user_id}" Параметризованные запросы
Command Injection os.system(f"rm {filename}") subprocess.run(["rm", filename])
Hardcoded credentials API_KEY = "abc123" Переменные окружения
eval() eval(user_input) Никогда не использовать
pickle pickle.loads(data) Только для доверенных данных

Обязательно

Подробнее: policy-security.md


8. ПЕРЕИСПОЛЬЗОВАНИЕ КОДА

Правило library/

ПЕРЕД написанием нового кода — проверить library/ и system/.

library/
├── connectors/     API клиенты (OZON, 1C, Telegram)
├── functions/      Утилиты (парсеры, валидаторы)
└── internal/       Хелперы

Если есть в library/ — использовать, не дублировать.

Подробнее: structure-library.md

DRY (Don't Repeat Yourself)

# ❌ Плохо (дублирование)
def process_order_a(order):
    validate(order)
    save(order)
    notify(order)

def process_order_b(order):
    validate(order)
    save(order)
    notify(order)

# ✅ Хорошо (переиспользование)
def process_order(order):
    validate(order)
    save(order)
    notify(order)

9. ТЕСТИРОВАНИЕ

Обязательные тесты

Тип Когда Инструмент
Unit Для каждой функции pytest, jest
Integration Для API, БД pytest, supertest
E2E Для критических flow playwright, cypress

Coverage (обязательно)

Минимальное покрытие: 80%

# Python
pytest --cov=. --cov-report=term-missing

# JavaScript
npm test -- --coverage

Структура тестов

project/
├── src/
│   └── module.py
└── tests/
    ├── unit/
    │   └── test_module.py
    └── integration/
        └── test_api.py

Подробнее: process-testing.md


10. GIT И ВЕРСИОНИРОВАНИЕ

Коммиты

Формат:

type(scope): short description

Longer description if needed

Fixes #123

Типы:
- feat: Новая функция
- fix: Исправление бага
- refactor: Рефакторинг
- docs: Документация
- test: Тесты
- chore: Инфраструктура

Пример:

feat(ozon): add order sync method

Implemented sync_orders() method that fetches
orders from OZON API and saves to database.

Fixes #42

Ветки

main          ← Продакшн
dev           ← Разработка
test          ← Тестирование
feature/*     ← Фичи
fix/*         ← Багфиксы

ПРОВЕРКИ ПЕРЕД КОММИТОМ

Чеклист

Pre-commit hook (пример)

#!/bin/bash
# .git/hooks/pre-commit

echo "Running pre-commit checks..."

# Форматирование
black . || exit 1
prettier --write . || exit 1

# Линтинг
ruff check . || exit 1
eslint . || exit 1

# Типы
mypy . || exit 1

# Тесты
pytest || exit 1

echo "✅ All checks passed"

СВЯЗАННЫЕ ПОЛИТИКИ

Политика Связь
policy-security.md Безопасность кода
policy-code-data-separation.md Разделение код/данные
policy-docker.md Docker контейнеры
format-code.md Стиль кода
naming-variables.md Именование переменных
structure-library.md Организация библиотеки

CHANGELOG

2026-02-19 — v1.0.0


Версия: 1.0.0
Статус: active
Владелец: architect