feat(tyres): доступ к выдаче резины по праву склада, не только админам
Плитка «Выдача резины» и маршруты /wh/tyres* открываются по признаку warehouse:tyres из /me (или is_admin) — новый гейт RequireTyres вместо RequireAdmin. Приёмка/инвентаризация остаются админскими. Бэкенд: право warehouse.tyres в crm2. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -44,6 +44,22 @@ function RequireAdmin({ children }: { children: React.ReactNode }) {
|
|||||||
return <>{children}</>;
|
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 <Navigate to="/login" replace />;
|
||||||
|
if (meQuery.isLoading) return null;
|
||||||
|
const me = meQuery.data;
|
||||||
|
if (!me?.is_admin && !me?.permissions?.includes("warehouse:tyres")) {
|
||||||
|
return <Navigate to="/" replace />;
|
||||||
|
}
|
||||||
|
return <>{children}</>;
|
||||||
|
}
|
||||||
|
|
||||||
export default function App() {
|
export default function App() {
|
||||||
// У35: фоновая сверка прав механика раз в 5 минут — выкидывает на /login
|
// У35: фоновая сверка прав механика раз в 5 минут — выкидывает на /login
|
||||||
// с сообщением «Доступ отозван», если админ снял can_login_pwa или вывел
|
// с сообщением «Доступ отозван», если админ снял can_login_pwa или вывел
|
||||||
@@ -72,10 +88,10 @@ export default function App() {
|
|||||||
<Route path="/wh/receipts/:id" element={<RequireAdmin><ReceiptDetailPage /></RequireAdmin>} />
|
<Route path="/wh/receipts/:id" element={<RequireAdmin><ReceiptDetailPage /></RequireAdmin>} />
|
||||||
<Route path="/wh/stocktake" element={<RequireAdmin><StocktakePage /></RequireAdmin>} />
|
<Route path="/wh/stocktake" element={<RequireAdmin><StocktakePage /></RequireAdmin>} />
|
||||||
<Route path="/wh/stocktake/:id" element={<RequireAdmin><StocktakeSessionPage /></RequireAdmin>} />
|
<Route path="/wh/stocktake/:id" element={<RequireAdmin><StocktakeSessionPage /></RequireAdmin>} />
|
||||||
{/* Сезонная выдача резины — тот же круг, что приёмка и инвентаризация. */}
|
{/* Сезонная выдача резины — по складскому праву (не только админам). */}
|
||||||
<Route path="/wh/tyres" element={<RequireAdmin><TyresPage /></RequireAdmin>} />
|
<Route path="/wh/tyres" element={<RequireTyres><TyresPage /></RequireTyres>} />
|
||||||
<Route path="/wh/tyres/sizes" element={<RequireAdmin><TyreSizesPage /></RequireAdmin>} />
|
<Route path="/wh/tyres/sizes" element={<RequireTyres><TyreSizesPage /></RequireTyres>} />
|
||||||
<Route path="/wh/tyres/journal" element={<RequireAdmin><TyreJournalPage /></RequireAdmin>} />
|
<Route path="/wh/tyres/journal" element={<RequireTyres><TyreJournalPage /></RequireTyres>} />
|
||||||
<Route path="*" element={<Navigate to="/" replace />} />
|
<Route path="*" element={<Navigate to="/" replace />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ export default function ActionMenu() {
|
|||||||
emoji: "🔧",
|
emoji: "🔧",
|
||||||
onClick: () => navigate("/repairs"),
|
onClick: () => navigate("/repairs"),
|
||||||
},
|
},
|
||||||
// Складские разделы правят остатки и деньги — пока только админам
|
// Приёмка и инвентаризация правят остатки и деньги — пока только админам
|
||||||
// (тот же гейт стоит на сервере, здесь просто не показываем лишнего).
|
// (тот же гейт стоит на сервере, здесь просто не показываем лишнего).
|
||||||
...(meQuery.data?.is_admin
|
...(meQuery.data?.is_admin
|
||||||
? [
|
? [
|
||||||
@@ -52,6 +52,12 @@ export default function ActionMenu() {
|
|||||||
emoji: "📋",
|
emoji: "📋",
|
||||||
onClick: () => navigate("/wh/stocktake"),
|
onClick: () => navigate("/wh/stocktake"),
|
||||||
},
|
},
|
||||||
|
]
|
||||||
|
: []),
|
||||||
|
// Выдача резины — по складскому праву (не только админам): признак
|
||||||
|
// warehouse:tyres приходит в /me, если у механика есть право склада.
|
||||||
|
...(meQuery.data?.is_admin || meQuery.data?.permissions?.includes("warehouse:tyres")
|
||||||
|
? [
|
||||||
{
|
{
|
||||||
key: "tyres",
|
key: "tyres",
|
||||||
title: "Выдача резины",
|
title: "Выдача резины",
|
||||||
|
|||||||
Reference in New Issue
Block a user