zov-tech/backend-py/app/config.py
wasrusgen cc38782b85 feat: arrivals module + refactor xlsx parser
- Добавлен /api/arrivals для «Поступление заказов на склад СПб.xlsx»
  (Drive ID захардкожен в ARRIVALS_FILE_ID, дефолт = 1kgrDEIGcVMFnSdZs1Y...)
- _parse_xlsx_groups() — единый парсер для обоих файлов:
  * находит строку заголовков динамически (первая строка с «Товар»),
    чтобы корректно работать с файлом «Поступление» (2 строки шапки перед хедером)
  * пропускает разделители «Кухни» / «Дозаказы» внутри листа
  * пропускает шаблонные пустые строки (Заказ/Дозаказ без данных)
- _xlsx_auth_manager() — вынесена общая проверка initData + роль
- config: поле arrivals_file_id
- frontend: вторая секция «📥 Поступление в СПб» на дашборде менеджера;
  renderManagerShipments принимает label-параметр и переиспользуется для обоих файлов;
  оба запроса загружаются параллельно с измерениями

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 07:49:56 +03:00

61 lines
2.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Конфиг бэкенда — читается из переменных окружения."""
from __future__ import annotations
import os
from dataclasses import dataclass
from functools import lru_cache
@dataclass(frozen=True)
class Config:
bot_token: str
admin_tg_id: int
sheet_id: str
google_credentials_path: str
gigachat_auth_key: str
gigachat_model: str
gigachat_scope: str
active_period_days: int
grace_period_days: int
proxy6_token: str # пусто = без прокси (прямой HTTP)
proxy_static_list: str # статический список прокси через запятую: "http://user:pass@host:port,..."
proxy_list_file: str # путь к файлу со списком прокси в формате "host:port:user:pass" или "http://..."
# Внутренний секрет для вызовов бота → бэкенда (без initData)
internal_secret: str
# Google Drive ID файла ОТГРУЗКИ.xlsx (отгрузки с завода)
shipments_file_id: str
# Google Drive ID файла «Поступление заказов на склад СПб.xlsx»
arrivals_file_id: str
def _required(name: str) -> str:
val = os.getenv(name)
if not val:
raise RuntimeError(f"Missing required env var: {name}")
return val
@lru_cache(maxsize=1)
def get_config() -> Config:
return Config(
bot_token=_required("BOT_TOKEN"),
admin_tg_id=int(os.getenv("ADMIN_TG_ID", "0")),
sheet_id=_required("SHEET_ID"),
google_credentials_path=os.getenv("GOOGLE_CREDENTIALS_PATH", "/app/credentials.json"),
gigachat_auth_key=_required("GIGACHAT_AUTH_KEY"),
gigachat_model=os.getenv("GIGACHAT_MODEL", "GigaChat-Pro"),
gigachat_scope=os.getenv("GIGACHAT_SCOPE", "GIGACHAT_API_PERS"),
active_period_days=int(os.getenv("ACTIVE_PERIOD_DAYS", "90")),
grace_period_days=int(os.getenv("GRACE_PERIOD_DAYS", "14")),
proxy6_token=os.getenv("PROXY6_TOKEN", ""),
proxy_static_list=os.getenv("PROXY_STATIC_LIST", ""),
proxy_list_file=os.getenv("PROXY_LIST_FILE", ""),
internal_secret=os.getenv("INTERNAL_SECRET", ""),
shipments_file_id=os.getenv("SHIPMENTS_FILE_ID", "1fER4NmEgSznvPKJWXOqLDDkTxH6wm78E"),
arrivals_file_id=os.getenv("ARRIVALS_FILE_ID", "1kgrDEIGcVMFnSdZs1Y_QHVhjqsXFQk2h"),
)