diff --git a/backend-py/app/main.py b/backend-py/app/main.py index 381cd90..746b386 100644 --- a/backend-py/app/main.py +++ b/backend-py/app/main.py @@ -3140,7 +3140,7 @@ def _initial(name: str) -> str: def _xlsx_auth_manager(body: dict[str, Any]) -> tuple[Any, dict[str, Any] | None]: - """Проверяет initData и возвращает (tg_id, user) для менеджера или (None, error_dict).""" + """Проверяет initData и возвращает (tg_id, None) для менеджера или (None, error_dict).""" cfg = get_config() auth = verify_init_data(body.get("initData") or "", cfg.bot_token) if not auth or not auth.get("user"): @@ -3153,7 +3153,7 @@ def _xlsx_auth_manager(body: dict[str, Any]) -> tuple[Any, dict[str, Any] | None user = sheets.find_user(tg_id) if not user or not sheets.has_role(user, "manager"): return None, {"error": "only_manager"} - return tg_id, user + return tg_id, None # успешно: вернуть None-ошибку, чтобы caller мог сделать if err: def _parse_xlsx_groups(file_bytes: bytes, source_label: str) -> list[dict[str, Any]]: diff --git a/miniapp/assets/app.js b/miniapp/assets/app.js index b2063c5..8e3d1aa 100644 --- a/miniapp/assets/app.js +++ b/miniapp/assets/app.js @@ -184,25 +184,30 @@ async function renderManagerHome(me) { const pendingContainer = el(`
`); app.insertBefore(pendingContainer, todayContainer); - // Параллельно грузим реальные данные (измерения + pending + отгрузки + поступления) + // Параллельно грузим реальные данные (измерения + pending — критичные) + // Складские данные грузим отдельно, чтобы ошибка Drive не ломала весь дашборд try { const authBody = { initData: tg?.initData || "", initDataUnsafe: tg?.initDataUnsafe || null }; - const [resM, resP, resS, resA] = await Promise.all([ + const [resM, resP] = await Promise.all([ fetch(`${BACKEND_URL}/api/measurements`, { method: "POST", body: JSON.stringify(authBody) }), fetch(`${BACKEND_URL}/api/manager_pending`, { method: "POST", body: JSON.stringify(authBody) }), - fetch(`${BACKEND_URL}/api/shipments`, { method: "POST", body: JSON.stringify(authBody) }), - fetch(`${BACKEND_URL}/api/arrivals`, { method: "POST", body: JSON.stringify(authBody) }), ]); const data = await resM.json(); const pendingData = await resP.json(); - const shipmentsData = await resS.json(); - const arrivalsData = await resA.json(); renderManagerPending(pendingContainer, pendingData.pending || []); renderManagerToday(todayContainer, data.measurements || [], firstName, greetingEl); renderManagerProjects(projectsContainer, data.measurements || []); - renderManagerShipments(shipmentsContainer, shipmentsData.shipments || [], "📦 Отгрузки с завода"); - renderManagerShipments(arrivalsContainer, arrivalsData.shipments || [], "📥 Поступление в СПб"); + + // Складские данные — не критичны; грузим после, ошибка не ломает дашборд + const authBodyStr = JSON.stringify(authBody); + Promise.all([ + fetch(`${BACKEND_URL}/api/shipments`, { method: "POST", body: authBodyStr }).then(r => r.json()).catch(() => ({})), + fetch(`${BACKEND_URL}/api/arrivals`, { method: "POST", body: authBodyStr }).then(r => r.json()).catch(() => ({})), + ]).then(([shipmentsData, arrivalsData]) => { + renderManagerShipments(shipmentsContainer, shipmentsData.shipments || [], "📦 Отгрузки с завода"); + renderManagerShipments(arrivalsContainer, arrivalsData.shipments || [], "📥 Поступление в СПб"); + }).catch(() => { /* тихо — дашборд уже отрисован */ }); } catch (e) { todayContainer.innerHTML = `