- Дефолт-бренд generic: name «Trade-In Estimator» → «МЕРА» (brand.py). Masthead/ footer/подписи секций читают brand.name → отчёт теперь брендирован МЕРА; white-label бренды (реальное name в brands) не тронуты. - Cover: year_built=None утекал литеральным «None» в «Год постройки» → «—». - Cover: убран дубль-бар «Диапазон цен по фактическим сделкам» (уже есть на стр. 03) — часть ужимания cover до одной A4-страницы. Тесты обновлены.
66 lines
1.7 KiB
Python
66 lines
1.7 KiB
Python
"""Brand resolver — multi-tenant white-label.
|
||
|
||
Читает бренд по slug из `brands` Postgres-таблицы.
|
||
Используется PDF exporter + frontend (через /api/v1/brand/{slug} endpoint).
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
import logging
|
||
from dataclasses import dataclass
|
||
|
||
from sqlalchemy import text
|
||
from sqlalchemy.orm import Session
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
|
||
@dataclass(frozen=True, slots=True)
|
||
class Brand:
|
||
slug: str
|
||
name: str
|
||
logo_url: str | None
|
||
primary_color: str
|
||
accent_color: str
|
||
footer_text: str | None
|
||
pdf_disclaimer: str | None
|
||
|
||
|
||
_DEFAULT = Brand(
|
||
slug="generic",
|
||
name="МЕРА",
|
||
logo_url=None,
|
||
primary_color="#1d4ed8",
|
||
accent_color="#f59e0b",
|
||
footer_text=None,
|
||
pdf_disclaimer=None,
|
||
)
|
||
|
||
|
||
def get_brand(slug: str | None, db: Session) -> Brand:
|
||
"""Возвращает Brand по slug. Fallback на 'generic' если не найден."""
|
||
if not slug:
|
||
return _DEFAULT
|
||
row = db.execute(
|
||
text(
|
||
"""
|
||
SELECT slug, name, logo_url, primary_color, accent_color,
|
||
footer_text, pdf_disclaimer
|
||
FROM brands
|
||
WHERE slug = :slug
|
||
"""
|
||
),
|
||
{"slug": slug.lower()},
|
||
).fetchone()
|
||
if row is None:
|
||
logger.info("brand not found: %s — using generic", slug)
|
||
return _DEFAULT
|
||
return Brand(
|
||
slug=row.slug,
|
||
name=row.name,
|
||
logo_url=row.logo_url,
|
||
primary_color=row.primary_color or _DEFAULT.primary_color,
|
||
accent_color=row.accent_color or _DEFAULT.accent_color,
|
||
footer_text=row.footer_text,
|
||
pdf_disclaimer=row.pdf_disclaimer,
|
||
)
|