1. Структура репозитория
Рекомендуемая структура папок:
text
Переносить
Свернуть
Копировать
/src
/core
/calculator # чистая логика расчётов (без UI и API)
- calculate.ts
- types.ts
- utils.ts
/api
- handler.ts # основной хендлер (FastAPI/Express/etc.)
- routes.ts # роуты
- validators.ts # валидация запросов
/catalog
- sync.ts # импорт/синхронизация каталога (CSV/API)
- search.ts # поиск и фильтрация
/tests
- calculator.spec.ts
- api.spec.ts
/docs
- architecture.md
- api-spec.md
- data-model.md
/data
- sample-catalog.json
- sample-catalog.csv
/scripts
- sync-catalog.sh # скрипт синхронизации
/docker
- Dockerfile
- docker-compose.yml
.gitignore
README.md
package.json / pyproject.toml
2. Стек технологий (рекомендуемый)
Язык: TypeScript (Node.js) или Python (FastAPI) — выбрать один.
HTTP: Express (TS) или FastAPI (Py).
Валидация: Zod (TS) / Pydantic (Py).
Тестирование: Vitest (TS) / pytest (Py), плюс unit-тесты для формул.
CI/CD: встроенный в SourceCraft пайплайн (lint → test → build → deploy).
Контейнеризация: Docker.
Хранение данных каталога: локальный JSON/SQLite для MVP; в будущем — внешняя БД.
3. Требования к функционалу
3.1. Ядро калькулятора (src/core/calculator)
Должны быть чистые функции без побочных эффектов:
calculateRoomMetrics(room) → периметр, площадь стен, площадь проёмов, полезная площадь.
calculatePatternLength(height, rapport) → длина полотна с учётом раппорта.
calculateRollsNeeded(params) → количество полотен, рулонов, стоимость, запас.
Все расчёты должны быть детерминированными и покрытыми тестами.
3.2. API (src/api)
Эндпоинты:
POST /api/calculate — принимает параметры комнаты и рулона, возвращает расчёт.
GET /api/catalog — список товаров с фильтрами (ширина, раппорт, цена, наличие).
POST /api/sync-catalog — загрузка каталога из CSV/JSON или триггер синхронизации.
Валидация входных данных обязательна (диапазоны, типы, обязательность полей).
3.3. Каталог (src/catalog)
Поддержка двух режимов:
Импорт из файла: CSV/JSON с жёсткой схемой (см. ниже).
Синхронизация: скрипт, который обновляет локальные данные из внешнего источника.
Поиск и фильтрация по: ширине рулона, раппорту, цене, наличию, коллекции, цвету (текстовый поиск).
4. Модель данных каталога (JSON-пример)
json
Переносить
Свернуть
Копировать
[
{
"article": "OB-12345",
"name": "Обои Коллекция Весна",
"collection": "Весна 2026",
"roll_width_m": 1.06,
"roll_length_m": 10,
"rapport_m": 0.64,
"price_rub": 2500,
"stock_qty": 42,
"join_type": "смещённая",
"color": "бежевый",
"material": "флизелин"
}
]
Для CSV — строго фиксированные заголовки колонок, совпадающие с JSON-ключами.
5. Формулы и правила расчёта (для реализации в коде)
Периметр:
P=2⋅(длина+ширина).
Площадь стен:
S
стен
=P⋅высота.
Площадь проёмов:
S
проёмов
=∑(ширина⋅высота) по всем окнам и дверям.
Полезная площадь:
S
полезная
=S
стен
−S
проёмов
.
Длина полотна:
L
полотно
=высота+(раппорт⋅n), где
n — минимальное целое, при котором стык совпадает.
Количество полотен:
N
полотен
=⌈S
полезная
/(L
полотно
⋅ширина)⌉.
Количество рулонов:
N
рулонов
=⌈(N
полотен
⋅L
полотно
⋅ширина)/(ширина⋅длина)⌉, округление вверх.
Стоимость:
Стоимость=N
рулонов
⋅цена.
Запас: коэффициент (по умолчанию 1.10, диапазон 1.05–1.20).
Округления выполнять через Math.ceil (или аналог) и проверять на граничных значениях.
6. Требования к качеству и тестированию
Все формулы вынести в отдельные функции и покрыть юнит‑тестами.
Добавить негативные тесты: отрицательные значения, нули, слишком большие числа.
Для API — тесты валидации и проверки кодов ответов.
В CI SourceCraft: lint → unit-тесты → сборка образа → (опционально) интеграционные тесты.
Примеры тестовых кейсов:
Комната 4×5 м, высота 2.7 м, 1 окно 1.5×1.2 м, 1 дверь 0.9×2.1 м.
Рулон 1.06×10 м, раппорт 0.64 м, цена 2500 руб.
Ожидаемый результат: количество рулонов и стоимость (с запасом 10 %).
за 90 дней34 → 25−9максимум 34, 26 сенместо в рейтинге на дату пересчёта 13558начало периода — по неполным данным
Оценканеполные данные: вне рейтингасобытия
Что изменилось за 90 дней: по категориям и событиям · событий: 2
Что изменилось за 90 дней
Категория
Динамика
Оценка
Вклад в оценку
Security25%
— → —
—
CI/CD20%
— → —
—
Активность15%
32 → 9
−7,8
Документация15%
37 → 33
−1,3
Issues15%
— → 35
—
Code health10%
— → —
—
Смена состава данныхпоявились данные: Issues, веса остальных перенормированы
+0,2
Оценка
34 → 25
−9
Вклад = вес категории × изменение её оценки / сумма весов. Строки складываются в итог с точностью до округления. Наведите строку — справа подсветятся связанные события.
События
2
18 окт 2026 · источник данных
Issues: данные появились
Источник стал доступен
без изменения
1
18 окт 2026 · ухудшение
Активность 32 → 9
Заметное изменение оценки категории между пересчётами