593 lines
34 KiB
Markdown
593 lines
34 KiB
Markdown
# MANAGEMENT_RUNBOOK.md
|
||
|
||
Единый runbook по management-командам проекта.
|
||
|
||
Документ отвечает на 3 вопроса:
|
||
- что запускать;
|
||
- когда запускать;
|
||
- как безопасно откатываться/повторять запуск.
|
||
|
||
## Каталог команд
|
||
|
||
1. `generate_sitemaps` — оффлайн генерация sitemap-файлов.
|
||
2. `regenerate_seria_prerender` — оффлайн пересборка pre-render шаблонов для `catalog_seria_info`.
|
||
3. `populate_seo_fields` — автозаполнение SEO-полей блога из существующих данных.
|
||
4. `make_rating` — пересчёт рейтингов профилей и стеклопакетов методом Манна-Уитни.
|
||
|
||
## Общие правила запуска
|
||
|
||
- Запускать команды из корня репозитория.
|
||
- Для локального/CI запуска использовать `poetry`.
|
||
- Не запускать тяжелые операции через HTTP-эндпоинты `/service/*`.
|
||
- Перезапуск веб-сервера (`gunicorn`/`uWSGI`) делать отдельным шагом оркестрации, а не из кода Django.
|
||
|
||
Базовый шаблон запуска:
|
||
|
||
```bash
|
||
cd /Users/e-serg/PRJ/2022-oknardia
|
||
poetry run python oknardia/manage.py <command> [args]
|
||
```
|
||
|
||
## 1) Команда `generate_sitemaps`
|
||
|
||
Назначение:
|
||
- пересобрать `sitemap.xml` и chunk-файлы в `MEDIA_ROOT/_serv_sitemap`.
|
||
|
||
Базовый запуск:
|
||
|
||
```bash
|
||
cd /Users/e-serg/PRJ/2022-oknardia
|
||
poetry run python oknardia/manage.py generate_sitemaps
|
||
```
|
||
|
||
Запуск с параметрами:
|
||
|
||
```bash
|
||
cd /Users/e-serg/PRJ/2022-oknardia
|
||
poetry run python oknardia/manage.py generate_sitemaps \
|
||
--compare-min-depth 2 \
|
||
--compare-max-depth 4 \
|
||
--max-items 40000 \
|
||
--max-file-size 5242880 \
|
||
--max-files-qty 998
|
||
```
|
||
|
||
Когда запускать:
|
||
- после деплоя;
|
||
- по расписанию (cron/systemd timer);
|
||
- после крупных изменений данных каталога/блога.
|
||
|
||
### Важные замечания
|
||
|
||
Чтобы `sitemap.xml` отдавал прокси-nginx напрямую из файловой системы, нужно, чтобы он физически лежал
|
||
в `MEDIA_ROOT/_serv_sitemap/sitemap.xml`.
|
||
|
||
Допустимо, что файл доступен по двум URL (корневой и media), но в `robots.txt` должен быть указан один
|
||
канонический вариант `sitemap.xml`
|
||
|
||
#### NGINX snippet (alias для корневого sitemap)
|
||
|
||
```nginx
|
||
# Корневой sitemap.xml (для привычного для поисковиков URL)
|
||
location = /sitemap.xml {
|
||
alias /<путь-к-каталогку-с-докер-приложением>/media/_serv_sitemap/sitemap.xml;
|
||
default_type application/xml;
|
||
add_header Cache-Control "public, max-age=300";
|
||
}
|
||
```
|
||
|
||
## 2) Команда `regenerate_seria_prerender`
|
||
|
||
Назначение:
|
||
- пересобрать pre-render шаблоны для страниц серий (`catalog_seria_info`) в каталоге `seria_info/prepared/`.
|
||
|
||
Проверка без записи файлов:
|
||
|
||
```bash
|
||
cd /Users/e-serg/PRJ/2022-oknardia
|
||
poetry run python oknardia/manage.py regenerate_seria_prerender --dry-run
|
||
```
|
||
|
||
Пересборка только отсутствующих файлов:
|
||
|
||
```bash
|
||
cd /Users/e-serg/PRJ/2022-oknardia
|
||
poetry run python oknardia/manage.py regenerate_seria_prerender
|
||
```
|
||
|
||
Принудительная пересборка всех root-серий:
|
||
|
||
```bash
|
||
cd /Users/e-serg/PRJ/2022-oknardia
|
||
poetry run python oknardia/manage.py regenerate_seria_prerender --force
|
||
```
|
||
|
||
Выборочная пересборка:
|
||
|
||
```bash
|
||
cd /Users/e-serg/PRJ/2022-oknardia
|
||
poetry run python oknardia/manage.py regenerate_seria_prerender --seria-id 843 --seria-id 2100 --force
|
||
```
|
||
|
||
Когда запускать:
|
||
- после обновления логики `catalog_seria_info`;
|
||
- после массового обновления данных серий/окон/квартир;
|
||
- после очистки `seria_info/prepared/`.
|
||
|
||
## 3) Команда `populate_seo_fields`
|
||
|
||
Назначение:
|
||
- автозаполнить SEO-поля (`sSlug`, `sMetaDescription`, `sMetaKeywords`) для всех существующих записей блога.
|
||
|
||
Используется:
|
||
- при первом развертывании новой версии с автогенерацией SEO-полей;
|
||
- при восстановлении из бэкапа где SEO-поля пусты;
|
||
- при изменении логики автогенерации (с флагом `--force`).
|
||
|
||
### Базовый запуск
|
||
|
||
Заполнить только пустые SEO-поля (стандартный вариант):
|
||
|
||
```bash
|
||
cd /Users/e-serg/PRJ/2022-oknardia
|
||
poetry run python oknardia/manage.py populate_seo_fields
|
||
```
|
||
|
||
### Параметры запуска
|
||
|
||
**`--dry-run`** — только показать что будет сделано (без сохранения в БД):
|
||
|
||
```bash
|
||
poetry run python oknardia/manage.py populate_seo_fields --dry-run
|
||
```
|
||
|
||
**`--force`** — переполнить ВСЕ SEO-поля, даже уже заполненные:
|
||
|
||
```bash
|
||
poetry run python oknardia/manage.py populate_seo_fields --force
|
||
```
|
||
|
||
**`--clean`** — очистить все SEO-поля перед заполнением (для переделки):
|
||
|
||
```bash
|
||
poetry run python oknardia/manage.py populate_seo_fields --clean
|
||
```
|
||
|
||
**Комбинация флагов** — сухой прогон переполнения всех полей:
|
||
|
||
```bash
|
||
poetry run python oknardia/manage.py populate_seo_fields --dry-run --force
|
||
```
|
||
|
||
### Что заполняется
|
||
|
||
| Поле | Источник | Результат |
|
||
|------|----------|-----------|
|
||
| `sSlug` | `sPostHeader` | URL-безопасный слаг (max 200 символов) |
|
||
| `sMetaDescription` | `sPostContent` | Первые 160 символов (исключая теги `<cut>`) |
|
||
| `sMetaKeywords` | `sPostHeader` | Заголовок + префикс "oknardia, окнардия, блог, публикация" (max 256 символов) |
|
||
|
||
Пример результата:
|
||
|
||
```python
|
||
sPostHeader = "Профиль Brusbox Super Aero"
|
||
↓
|
||
sSlug = "profil-brusbox-super-aero"
|
||
sMetaDescription = "brusbox-super-aero-pyatikamernaya-profil-sistema..."
|
||
sMetaKeywords = "oknardia, окнардия, блог, публикация, Профиль Brusbox Super Aero"
|
||
```
|
||
|
||
### Когда запускать
|
||
|
||
- **После первого развертывания** — заполнить SEO-поля всех 29 существующих постов одной командой.
|
||
- **Один раз** — команда идемпотентна (при повторном запуске не будет ничего менять, т.к. пустые поля остатся).
|
||
- **При изменении логики** — использовать `--clean --force` для полной переделки всех SEO-полей.
|
||
|
||
### Пример полного сценария
|
||
|
||
```bash
|
||
cd /Users/e-serg/PRJ/2022-oknardia
|
||
|
||
# Шаг 1: Проверить что будет заполнено
|
||
poetry run python oknardia/manage.py populate_seo_fields --dry-run
|
||
|
||
# Шаг 2: Если результат устраивает — запустить реально
|
||
poetry run python oknardia/manage.py populate_seo_fields
|
||
|
||
# Шаг 3: Проверить что заполнилось
|
||
poetry run python oknardia/manage.py shell -c "
|
||
from oknardia.models import BlogPosts
|
||
posts = BlogPosts.objects.all()
|
||
print(f'Пусто sSlug: {posts.filter(sSlug=\"\").count()}')
|
||
print(f'Пусто sMetaDescription: {posts.filter(sMetaDescription=\"\").count()}')
|
||
print(f'Пусто sMetaKeywords: {posts.filter(sMetaKeywords=\"\").count()}')
|
||
"
|
||
```
|
||
|
||
### Возвращаемая информация
|
||
|
||
```
|
||
======================================================================
|
||
ИТОГОВЫЙ ОТЧЕТ
|
||
======================================================================
|
||
|
||
✓ sSlug заполнено: 28 раз
|
||
✓ sMetaDescription заполнено: 28 раз
|
||
✓ sMetaKeywords заполнено: 28 раз
|
||
✓ Записей обновлено в БД: 28
|
||
✗ Ошибок при обработке: 0
|
||
|
||
✅ Обновлено 28 записей успешно!
|
||
```
|
||
|
||
### Откат и безопасность
|
||
|
||
- ✅ **Безопасна для повторного запуска** — пустые поля не изменяются при повторной работе.
|
||
- ✅ **Откат через SQL** — если нужно очистить, используй: `UPDATE oknardia_blogposts SET sSlug='', sMetaDescription='', sMetaKeywords='';`
|
||
- ✅ **Всегда используй `--dry-run`** перед первым запуском для проверки.
|
||
|
||
## 4) Команда `make_rating`
|
||
|
||
Назначение:
|
||
- пересчитать рейтинги оконных профилей, стеклопакетов и наборов услуг используя адаптированный метод Манна-Уитни (Mann-Whitney U Step Rank).
|
||
- сохранить результаты в поля `fProfileRating`, `fGlazingRating`, `fSetRating` (0.0 … 5.0 звёзд).
|
||
- заполнить JSON-состав рейтинга (детальный разбор по каждому параметру) в поля `sProfileDescription`, `sGlazingDescription`, `sSetDescription`.
|
||
- алгоритм рассчитывает три этапа ранжирования: профили → стеклопакеты → наборы (которые зависят от профилей и стеклопакетов).
|
||
|
||
### Базовый запуск
|
||
|
||
Пересчитать рейтинги всех профилей и стеклопакетов (стандартный режим):
|
||
|
||
```bash
|
||
cd /Users/e-serg/PRJ/2022-oknardia
|
||
poetry run python oknardia/manage.py make_rating
|
||
```
|
||
|
||
### Параметры запуска
|
||
|
||
**`--verbosity 0`** — минимум информации (только ошибки):
|
||
**`--verbosity 1`** — стандартная информация (по умолчанию):
|
||
**`--verbosity 3`** — очень подробный вывод (для отладки, для каждого профиля/стеклопакета таблица):
|
||
|
||
Пример использования с параметром `--verbosity`:
|
||
|
||
```bash
|
||
poetry run python oknardia/manage.py make_rating --verbosity 3 | head -500
|
||
```
|
||
|
||
### АЛГОРИТМ: Метод Манна-Уитни (Mann-Whitney U Step Rank)
|
||
|
||
Команда использует адаптированный вариант критерия Манна-Уитни для ранжирования параметров качества оконных
|
||
предложений и комопнентов (профилей, стеклопакетов, наборов услуг) на основе их технических характеристик
|
||
и популярности у поставщиков.
|
||
|
||
#### Как это работает:
|
||
|
||
1. **Сортировка объектов** по одному параметру (например, по теплопередаче):
|
||
- Профиль A: 0.60 Ro → ранг = 0.0
|
||
- Профиль B: 0.60 Ro → ранг = 0.0 (то же значение, ранг не меняется)
|
||
- Профиль C: 0.80 Ro → ранг = 1.0 (новое значение, добавляем вес параметра)
|
||
- Профиль D: 0.95 Ro → ранг = 2.0 (ещё новое значение)
|
||
|
||
2. **Направление ранжирования** определяется флагом `revers`:
|
||
- `revers=False` — **БОЛЬШЕ = ЛУЧШЕ** (например, теплопередача, звукоизоляция)
|
||
- `revers=True` — **МЕНЬШЕ = ЛУЧШЕ** (например, высота в проёме для прочности)
|
||
|
||
3. **Нормализация рангов** к диапазону 0.0 … 1.0:
|
||
- Профиль A: 0.0 / 2.0 = 0.0
|
||
- Профиль B: 0.0 / 2.0 = 0.0
|
||
- Профиль C: 1.0 / 2.0 = 0.5
|
||
- Профиль D: 2.0 / 2.0 = 1.0
|
||
|
||
4. **Суммирование рангов** по всем параметрам:
|
||
- TmpRating = Σ(ранг_параметра × вес_параметра)
|
||
|
||
5. **Преобразование в звёзды** (0.0 … 5.0):
|
||
- ТmpRating нормализуется к 0..1
|
||
- Умножается на 5.0 для получения финального рейтинга
|
||
|
||
#### Пример итогового рейтинга профиля:
|
||
|
||
```
|
||
Профиль "Brusbox Super Aero"
|
||
Теплопередача: 0.60 Ro (ранг 0.9, вес 1.0)
|
||
Звукоизоляция: 33 дБ (ранг 0.8, вес 1.0)
|
||
Высота в проёме: 112 мм (ранг 0.6, вес 0.3)
|
||
Количество камер: 6 шт (ранг 0.7, вес 0.1)
|
||
|
||
Итого: (0.9×1.0 + 0.8×1.0 + 0.6×0.3 + 0.7×0.1) / 2.3 ≈ 3.8 звёзд ⭐⭐⭐⭐
|
||
```
|
||
|
||
### ПРОФИЛИ: какие параметры учитываются
|
||
|
||
| № | Параметр | Поле БД | ЛУЧШЕ | Вес | Описание |
|
||
|---|----------------------|----------------------------|--------------------|-----|-----------------------------------------------------|
|
||
| 1 | Звукоизоляция | `fProfileSoundproofing` | БОЛЬШЕ дБ | 1.0 | Сопротивление шуму (дБ) |
|
||
| 2 | Теплопередача | `fProfileHeatTransf` | БОЛЬШЕ Ro | 1.0 | Сопротивление теплопередаче (м²×°C/Вт) |
|
||
| 3 | Высота в проёме | `iProfileHeight` | МЕНЬШЕ мм | 0.3 | Видимая высота в световом проёме (экономия) |
|
||
| 4 | Высота фальца | `iProfileRabbet` | БОЛЬШЕ мм | 0.2 | Глубина фальца для герметизации |
|
||
| 5 | Толщина стеклопакета | `iProfileGlazingThickness` | БОЛЬШЕ мм | 0.2 | Максимальная толщина стеклопакета |
|
||
| 6 | Толщина профиля | `iProfileThickness` | БОЛЬШЕ мм | 0.2 | Монтажная (боковая) ширина профиля |
|
||
| 7 | Контуры уплотнения | `fProfileSeals` | БОЛЬШЕ контуров | 1.2 | Количество контуров уплотнения |
|
||
| 8 | Количество камер | `iProfileCameras` | БОЛЬШЕ шт | 0.1 | Число камер в профиле (из рамки + створки) |
|
||
| 9 | Популярность | `NumOffer` | БОЛЬШЕ предложений | 0.1 | Используется ли профиль в коммерческих предложениях |
|
||
|
||
**Примеры интерпретации:**
|
||
- Профиль с рейтингом **5.0 ⭐⭐⭐⭐⭐**: отличная теплопередача + звукоизоляция + много камер + многоконтурные
|
||
уплотнения.
|
||
- Профиль с рейтингом **2.0 ⭐⭐**: среднее качество, слабые характеристики.
|
||
- Профиль с рейтингом **0.5 ⭐**: слабые характеристики или производить не предоставил данных и их нет в отрытых источниках.
|
||
|
||
### СТЕКЛОПАКЕТЫ: какие параметры учитываются
|
||
|
||
| № | Параметр | Поле БД | ЛУЧШЕ | Вес | Описание |
|
||
|---|-------------------|-----------------------------|--------------|------|----------------------------------------------------------------------------------------|
|
||
| 1 | Звукоизоляция | `fGlazingSoundproofing` | БОЛЬШЕ дБ | 1.0 | Звукоизоляционный коэффициент (дБ) |
|
||
| 2 | Теплопередача | `fGlazingHeatTransfer` | БОЛЬШЕ Ro | 1.0 | Сопротивление теплопередаче (м²×°C/Вт) |
|
||
| 3 | Светопропускание | `fGlazingLightTransmission` | БОЛЬШЕ % | 0.25 | Коэффициент пропускания видимого света (%), отражение света снаружи |
|
||
| 4 | Солнцепропускание | `fGlazingPassingSun` | **МЕНЬШЕ %** | 0.15 | Коэффициент солнечного излучения (SHGC) — В России меньше = лучше для охлаждения летом |
|
||
| 5 | Толщина | `iGlazingThickness` | БОЛЬШЕ мм | 0.1 | Общая толщина стеклопакета |
|
||
| 6 | Количество камер | `iGlazingCamerasN` | БОЛЬШЕ шт | 0.1 | Число воздушных/аргоновых камер |
|
||
|
||
**Особенности стеклопакетов:**
|
||
- **Светопропускание** = как много естественного света проходит в помещение (больше = лучше)
|
||
- **Солнцепропускание** = как много солнечного тепла/излучения проходит (в России: меньше = лучше, потому что внутри есть отражающее напыление)
|
||
- Двухкамерный (с аргоном) почти всегда лучше однокамерного
|
||
- Трёхкамерные = премиум для холодного климата
|
||
|
||
**Примеры интерпретации:**
|
||
- **5.0 ⭐⭐⭐⭐⭐**: трёхкамерный с хорошей теплопередачей, звукоизоляцией (обычно с аргоном и напылением).
|
||
- **3.0 ⭐⭐⭐**: двухкамерный, среднее качество
|
||
- **1.0 ⭐**: однокамерный старого образца или с плохими характеристиками
|
||
|
||
### НАБОРЫ: какие параметры учитываются
|
||
|
||
| № | Параметр | Поле БД | ЛУЧШЕ | Вес | Описание |
|
||
|---|-------------------|--------------------------|------------------|-----|---------------------------------------------------|
|
||
| 1 | Актуальность | `dModify` | МЕНЬШЕ (свежее) | 0.3 | Дата последнего обновления (timestamp) |
|
||
| 2 | Доставка | `bSetDelivery` | ДА (1) | 0.8 | Включена ли доставка в стоимость |
|
||
| 3 | Монтаж/демонтаж | `bSetUninstallInstall` | ДА (1) | 1.0 | Включены ли услуги монтажа и демонтажа |
|
||
| 4 | Подоконник | `sSetSill` | ДА (1) | 0.5 | Включен ли подоконник |
|
||
| 5 | Водоотлив | `sSetPanes` | ДА (1) | 0.8 | Включен ли водоотлив/козырёк |
|
||
| 6 | Откос | `sSetSlope` | ДА (1) | 0.5 | Включены ли откосы |
|
||
| 7 | Климат-контроль | `sSetClimateControl` | ДА (1) | 0.3 | Включено ли управление микроклиматом |
|
||
| 8 | Число предложений | `NumOffer` | БОЛЬШЕ | 0.2 | Популярность набора (кол-во активных предложений) |
|
||
| 9 | Гибкость скидок | `iDiscountVariantsCount` | БОЛЬШЕ вариантов | 0.5 | Кол-во вариантов скидок из формулы офиса |
|
||
| 10| Размер скидок | `fDiscountMax` | БОЛЬШЕ % | 1.0 | Максимальная скидка из всех вариантов |
|
||
|
||
**ВАЖНО: Итоговый рейтинг набора состоит из трёх компонентов:**
|
||
- Рейтинг параметров услуг (Актуальность, Доставка, Монтаж, Подоконник и т.д.)
|
||
- Рейтинг входящего стеклопакета (ранжируется отдельно)
|
||
- Рейтинг входящего профиля (ранжируется отдельно)
|
||
|
||
Формула итогового рейтинга набора (fSetRating):
|
||
```
|
||
k1 = нормализованный TmpRating (услуги) * вес услуг
|
||
k2 = нормализованный рейтинг стеклопакета * RARING_WEIGHT_GLAZING_IN_SET (обычно 1.5)
|
||
k3 = нормализованный рейтинг профиля * RARING_WEIGHT_PVC_PROFILE_IN_SET (обычно 1.5)
|
||
|
||
fSetRating = k1 + k2 + k3 (итого от 0.0 до 5.0 звёзд)
|
||
```
|
||
|
||
**Примеры интерпретации:**
|
||
- **5.0 ⭐⭐⭐⭐⭐**: набор с премиум компонентами (хороший профиль и стеклопакет) + полный пакет услуг (доставка, монтаж, подоконник, откос, климат-контроль) + значительные скидки.
|
||
- **3.5 ⭐⭐⭐⭐**: хороший профиль/стеклопакет + базовые услуги (доставка, монтаж) + скромные скидки.
|
||
- **2.0 ⭐⭐**: эконом компоненты или слабые услуги (нет доставки, нет откосов).
|
||
- **1.0 ⭐**: минимальный пакет или устаревшие предложения (давно не обновлялись).
|
||
|
||
### Когда запускать
|
||
|
||
- **После первого развертывания** — заполнить рейтинги всех профилей, стеклопакетов и наборов.
|
||
- **После изменения каталога** (добавление нового профиля/стеклопакета/набора).
|
||
- **После уточнения характеристик** (например, поставщик предоставил новые данные).
|
||
```bash
|
||
poetry run python oknardia/manage.py make_rating
|
||
```
|
||
|
||
- **По расписанию** (например, ежемесячно, чтобы пересчитать популярность):
|
||
```bash
|
||
30 2 * * 1 cd /home/user/app-path/2022-oknardia && poetry run python oknardia/manage.py make_rating >> /var/log/oknardia-rating.log 2>&1
|
||
```
|
||
- **После обновления весов** в `settings.py` (константы `RANK_PVCP_*`, `RANK_GLAZ_*`).
|
||
|
||
### Откат и безопасность
|
||
|
||
- **Безопасна для повторного запуска** — пересчитывает все рейтинги заново.
|
||
- **Всегда обновляет только рейтинги** — другие данные в таблицах не меняются.
|
||
- **Откат через SQL** — если нужно установить нулевые значения (перед запуском рекомендуется бэкап базы):
|
||
```sql
|
||
-- Очистить рейтинги профилей
|
||
UPDATE oknardia_pvcprofiles SET fProfileRating = 0.0, sProfileDescription = '{}';
|
||
|
||
-- Очистить рейтинги стеклопакетов
|
||
UPDATE oknardia_glazing SET fGlazingRating = 0.0, sGlazingDescription = '{}';
|
||
|
||
-- Очистить рейтинги наборов
|
||
UPDATE oknardia_setkit SET fSetRating = 0.0, sSetDescription = '{}';
|
||
```
|
||
|
||
### Примеры из реальных данных
|
||
|
||
Пример вывода `--verbosity 1`:
|
||
|
||
```
|
||
=== НАЧАЛИ ПЕРЕСЧЁТ РЕЙТИНГОВ ===
|
||
|
||
========================================
|
||
[ЭТАП 1]: Пересчёт рейтингов ПРОФИЛЕЙ...
|
||
========================================
|
||
✓ Обнулены рейтинги у 94 профилей
|
||
✓ Найдено 94 профилей для ранжирования
|
||
✓ Сохранено 94 профилей с финальными рейтингами
|
||
|
||
=============================================
|
||
[ЭТАП 2]: Пересчёт рейтингов СТЕКЛОПАКЕТОВ...
|
||
=============================================
|
||
✓ Обнулены рейтинги у 97 стеклопакетов
|
||
✓ Найдено 97 стеклопакетов для ранжирования
|
||
✓ Сохранено 97 стеклопакетов с финальными рейтингами
|
||
|
||
================================================
|
||
[ЭТАП 3]: Пересчёт рейтингов НАБОРОВ (SetKit)...
|
||
================================================
|
||
✓ Обнулены рейтинги у 27 наборов
|
||
✓ Найдено 27 наборов для ранжирования
|
||
✓ Сохранено 27 наборов с финальными рейтингами
|
||
|
||
[OK!] ПЕРЕСЧЁТ РЕЙТИНГОВ ЗАВЕРШЁН УСПЕШНО!
|
||
• Обновлено профилей: 94
|
||
• Обновлено стеклопакетов: 97
|
||
• Обновлено наборов: 27
|
||
```
|
||
|
||
Пример вывода `--verbosity 3` (наиболее подробный):
|
||
|
||
```
|
||
=== НАЧАЛИ ПЕРЕСЧЁТ РЕЙТИНГОВ ===
|
||
|
||
========================================
|
||
[ЭТАП 1]: Пересчёт рейтингов ПРОФИЛЕЙ...
|
||
========================================
|
||
|
||
✓ Обнулены рейтинги у 94 профилей
|
||
✓ Найдено 94 профилей для ранжирования
|
||
...
|
||
...
|
||
====================================================================================================
|
||
ПРОФИЛЬ: politech W80 (ID: 78)
|
||
====================================================================================================
|
||
Характеристика Значение Ранг (0..1) Вклад
|
||
----------------------------------------------------------------------------------------------------
|
||
Высота в проёме 120 мм 0.368 *
|
||
Популярность 0 предл. 0.000
|
||
Теплопередача 0.91 Ro 0.657 ***
|
||
Толщина профиля 80 мм 0.588 **
|
||
Толщина стеклопакета 42 мм 0.409 **
|
||
Уплотнители 3 контуров 1.000 *****
|
||
Фальц 14 мм 0.150
|
||
Число камер 12 шт 0.714 ***
|
||
Шумоизоляция 44.00 дБ 0.909 ****
|
||
----------------------------------------------------------------------------------------------------
|
||
ИТОГО: Рейтинг = 4.94/5.0 ****
|
||
...
|
||
...
|
||
✓ Сохранено 94 профилей с финальными рейтингами
|
||
|
||
=============================================
|
||
[ЭТАП 2]: Пересчёт рейтингов СТЕКЛОПАКЕТОВ...
|
||
=============================================
|
||
|
||
✓ Обнулены рейтинги у 97 стеклопакетов
|
||
✓ Найдено 97 стеклопакетов для ранжирования
|
||
...
|
||
...
|
||
====================================================================================================
|
||
СТЕКЛОПАКЕТ: Однокамерный 5-4, 25 мм (И+аргон) (ID: 60) | Марка:СПО 5М1-Ar16-И4
|
||
====================================================================================================
|
||
Характеристика Значение Ранг (0..1) Вклад
|
||
----------------------------------------------------------------------------------------------------
|
||
Камеры — 0.000
|
||
Светопропускание 74.00% 0.824 ****
|
||
Солнцепропускание 58.00% 0.450 **
|
||
Теплопередача 0.91 Ro 0.936 ****
|
||
Толщина 25 мм 0.400 **
|
||
Шумоизоляция — 0.429 **
|
||
----------------------------------------------------------------------------------------------------
|
||
ИТОГО: Рейтинг = 4.87/5.0 ****
|
||
...
|
||
...
|
||
✓ Сохранено 97 стеклопакетов с финальными рейтингами
|
||
|
||
================================================
|
||
[ЭТАП 3]: Пересчёт рейтингов НАБОРОВ (SetKit)...
|
||
================================================
|
||
✓ Обнулены рейтинги у 27 наборов
|
||
✓ Найдено 27 наборов для ранжирования
|
||
...
|
||
...
|
||
========================================================================================================================
|
||
НАБОР: Элит (ID: 3)
|
||
========================================================================================================================
|
||
Параметр Значение Ранг (0..1) Вклад
|
||
------------------------------------------------------------------------------------------------------------------------
|
||
Актуальность свежий 0.375 *
|
||
Водоотлив ✓ Да 1.000 *****
|
||
Гибкость скидок 0 вариантов 0.500 **
|
||
Доставка ✓ Да 1.000 *****
|
||
Климат-контроль ✓ Да 1.000 *****
|
||
Монтаж ✓ Да 1.000 *****
|
||
Откос ✓ Да 1.000 *****
|
||
Подоконник ✓ Да 1.000 *****
|
||
Размер скидок 0.0% 0.500 **
|
||
Число предложений 46 шт 0.250 *
|
||
------------------------------------------------------------------------------------------------------------------------
|
||
ИТОГО: Рейтинг = 4.16/5.0 ****
|
||
...
|
||
...
|
||
|
||
[OK!] ПЕРЕСЧЁТ РЕЙТИНГОВ ЗАВЕРШЁН УСПЕШНО!
|
||
• Обновлено профилей: 94
|
||
• Обновлено стеклопакетов: 97
|
||
• Обновлено наборов: 27
|
||
```
|
||
|
||
## Оркестрация и reload веб-сервера
|
||
|
||
Важно:
|
||
- reload веб-сервера не встроен в management-команды;
|
||
- это отдельная операция окружения.
|
||
|
||
Пример для systemd + gunicorn:
|
||
|
||
```bash
|
||
sudo systemctl reload gunicorn
|
||
```
|
||
|
||
Рекомендуемый batch-сценарий:
|
||
|
||
```bash
|
||
cd /Users/e-serg/PRJ/2022-oknardia
|
||
poetry run python oknardia/manage.py regenerate_seria_prerender --force
|
||
poetry run python oknardia/manage.py generate_sitemaps
|
||
sudo systemctl reload gunicorn
|
||
```
|
||
|
||
## Cron/systemd timer (пример)
|
||
|
||
Пример cron (раз в сутки в 03:20):
|
||
|
||
```bash
|
||
20 3 * * * cd /Users/e-serg/PRJ/2022-oknardia && poetry run python oknardia/manage.py regenerate_seria_prerender --force && poetry run python oknardia/manage.py generate_sitemaps >> /var/log/oknardia-maintenance.log 2>&1
|
||
```
|
||
|
||
Если нужен reload после batch, добавляй отдельной строкой/шагом оркестратора.
|
||
|
||
## Диагностика
|
||
|
||
Быстрая проверка конфигурации:
|
||
|
||
```bash
|
||
cd /Users/e-serg/PRJ/2022-oknardia
|
||
poetry run python oknardia/manage.py check
|
||
```
|
||
|
||
Типовые причины проблем:
|
||
- нет прав записи в директории `templates/seria_info/prepared` или `MEDIA_ROOT/_serv_sitemap`;
|
||
- устаревшее виртуальное окружение / неустановленные зависимости;
|
||
- запуск не из того каталога.
|
||
|
||
## План миграции `/service/*` -> management commands
|
||
|
||
Текущее направление:
|
||
- все тяжелые и административные операции переносить из HTTP в management-команды;
|
||
- `/service/*` оставлять только как thin UI/мониторинг или убрать полностью.
|
||
|
||
|
||
|
||
---
|
||
|
||
См. также:
|
||
- `SETUP.md`
|
||
- `README.md`
|
||
|