From b3e5d05849449cc87802c9f88e4bdc84235a9f22 Mon Sep 17 00:00:00 2001 From: vladtechno Date: Wed, 9 Sep 2026 16:11:17 +1000 Subject: [PATCH] =?UTF-8?q?feat(tyres):=20=D0=B4=D0=BE=D1=81=D1=82=D1=83?= =?UTF-8?q?=D0=BF=20=D0=BA=20=D0=B2=D1=8B=D0=B4=D0=B0=D1=87=D0=B5=20=D1=80?= =?UTF-8?q?=D0=B5=D0=B7=D0=B8=D0=BD=D1=8B=20=D0=BF=D0=BE=20=D0=BF=D1=80?= =?UTF-8?q?=D0=B0=D0=B2=D1=83=20=D1=81=D0=BA=D0=BB=D0=B0=D0=B4=D0=B0,=20?= =?UTF-8?q?=D0=BD=D0=B5=20=D1=82=D0=BE=D0=BB=D1=8C=D0=BA=D0=BE=20=D0=B0?= =?UTF-8?q?=D0=B4=D0=BC=D0=B8=D0=BD=D0=B0=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Плитка «Выдача резины» и маршруты /wh/tyres* открываются по признаку warehouse:tyres из /me (или is_admin) — новый гейт RequireTyres вместо RequireAdmin. Приёмка/инвентаризация остаются админскими. Бэкенд: право warehouse.tyres в crm2. Co-Authored-By: Claude Fable 5 --- mechanic-pwa/frontend/src/App.tsx | 24 +++++++++++++++---- .../frontend/src/pages/ActionMenu.tsx | 8 ++++++- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/mechanic-pwa/frontend/src/App.tsx b/mechanic-pwa/frontend/src/App.tsx index 1c75fc9..50eb33b 100644 --- a/mechanic-pwa/frontend/src/App.tsx +++ b/mechanic-pwa/frontend/src/App.tsx @@ -44,6 +44,22 @@ function RequireAdmin({ children }: { children: React.ReactNode }) { return <>{children}; } +/** + * Выдача резины — по складскому праву (warehouse:tyres в /me), не только + * админам. Приёмка и инвентаризация остаются под RequireAdmin. + */ +function RequireTyres({ children }: { children: React.ReactNode }) { + const token = useAuth((s) => s.token); + const meQuery = useQuery({ queryKey: ["me"], queryFn: getMe, staleTime: 60_000, enabled: !!token }); + if (!token) return ; + if (meQuery.isLoading) return null; + const me = meQuery.data; + if (!me?.is_admin && !me?.permissions?.includes("warehouse:tyres")) { + return ; + } + return <>{children}; +} + export default function App() { // У35: фоновая сверка прав механика раз в 5 минут — выкидывает на /login // с сообщением «Доступ отозван», если админ снял can_login_pwa или вывел @@ -72,10 +88,10 @@ export default function App() { } /> } /> } /> - {/* Сезонная выдача резины — тот же круг, что приёмка и инвентаризация. */} - } /> - } /> - } /> + {/* Сезонная выдача резины — по складскому праву (не только админам). */} + } /> + } /> + } /> } /> ); diff --git a/mechanic-pwa/frontend/src/pages/ActionMenu.tsx b/mechanic-pwa/frontend/src/pages/ActionMenu.tsx index efe6519..788b63f 100644 --- a/mechanic-pwa/frontend/src/pages/ActionMenu.tsx +++ b/mechanic-pwa/frontend/src/pages/ActionMenu.tsx @@ -34,7 +34,7 @@ export default function ActionMenu() { emoji: "🔧", onClick: () => navigate("/repairs"), }, - // Складские разделы правят остатки и деньги — пока только админам + // Приёмка и инвентаризация правят остатки и деньги — пока только админам // (тот же гейт стоит на сервере, здесь просто не показываем лишнего). ...(meQuery.data?.is_admin ? [ @@ -52,6 +52,12 @@ export default function ActionMenu() { emoji: "📋", onClick: () => navigate("/wh/stocktake"), }, + ] + : []), + // Выдача резины — по складскому праву (не только админам): признак + // warehouse:tyres приходит в /me, если у механика есть право склада. + ...(meQuery.data?.is_admin || meQuery.data?.permissions?.includes("warehouse:tyres") + ? [ { key: "tyres", title: "Выдача резины",