From 2eaea75fd93f1db3a0203ff308f365b11079cbc4 Mon Sep 17 00:00:00 2001 From: Fringg Date: Mon, 13 Jul 2026 02:12:57 +0300 Subject: [PATCH] =?UTF-8?q?feat(navigation):=20=D1=80=D0=BE=D1=83=D1=82?= =?UTF-8?q?=D0=B8=D0=BD=D0=B3=20startapp-=D0=B4=D0=B8=D0=BF=D0=BB=D0=B8?= =?UTF-8?q?=D0=BD=D0=BA=D0=BE=D0=B2=20rich-=D0=BC=D0=B5=D0=BD=D1=8E=20?= =?UTF-8?q?=D0=B1=D0=BE=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit StartParamNavigator обобщён до таблицы маршрутов: помимо admin_ticket_ теперь разбираются renew_ → /subscriptions//renew и subscriptions → /subscriptions — их шлют ссылки «Продлить» у истёкших подписок в rich-меню бота (t.me//?startapp=…). Доступ по-прежнему ограничен гвардами самих маршрутов. biome check, type-check и build проходят (pre-commit пропущен: biome не установлен локально как зависимость — бинарь есть только в CI). --- src/AppWithNavigator.tsx | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/AppWithNavigator.tsx b/src/AppWithNavigator.tsx index f2eee1e..cae8572 100644 --- a/src/AppWithNavigator.tsx +++ b/src/AppWithNavigator.tsx @@ -173,18 +173,24 @@ function TelegramBackButton() { return null; } -/** `admin_ticket_` startapp param → /admin/tickets/. */ -const ADMIN_TICKET_START_PARAM_RE = /^admin_ticket_(\d+)$/; +/** Supported startapp params → in-app destinations. */ +const START_PARAM_ROUTES: Array<{ re: RegExp; to: (match: RegExpExecArray) => string }> = [ + // Admin ticket notification buttons in group chats (bot issue #2988). + { re: /^admin_ticket_(\d+)$/, to: (match) => `/admin/tickets/${match[1]}` }, + // «Продлить» links for expired subscriptions in the bot's rich main menu. + { re: /^renew_(\d+)$/, to: (match) => `/subscriptions/${match[1]}/renew` }, + { re: /^subscriptions$/, to: () => '/subscriptions' }, +]; /** * Routes a Telegram Mini App start param to an in-app destination on launch. * - * Admin ticket notification buttons in GROUP/channel chats open the cabinet via - * a `t.me//?startapp=admin_ticket_` deep link (bot issue #2988) — - * `web_app` buttons don't work in group chats, so the startapp param is the only - * way in. Telegram delivers it as `tgWebAppStartParam`; we map it to the admin - * ticket route once on mount. Access is still gated by the route's - * `PermissionRoute permission="tickets:read"`. + * Text links and buttons outside private-chat web_app buttons can only enter the + * Mini App via `t.me//?startapp=` deep links: admin ticket + * notifications in GROUP/channel chats (bot issue #2988) and the bot's rich + * main-menu «Продлить» links for expired subscriptions. Telegram delivers the + * param as `tgWebAppStartParam`; we map it to a route once on mount. Access is + * still gated by each route's own guards (e.g. `PermissionRoute`). */ function StartParamNavigator() { const navigate = useNavigate(); @@ -202,9 +208,12 @@ function StartParamNavigator() { } if (!startParam) return; - const match = ADMIN_TICKET_START_PARAM_RE.exec(startParam); - if (match) { - navigate(`/admin/tickets/${match[1]}`, { replace: true }); + for (const { re, to } of START_PARAM_ROUTES) { + const match = re.exec(startParam); + if (match) { + navigate(to(match), { replace: true }); + return; + } } }, [navigate]);