Prod: new admin on admin.*, old admin moves to admin.*/old/

Dockerfile builds apps/backoffice into /srv/admin and the old admin with
base /old/; nginx serves /old/ with its own uncached index.html.
Worker notification links point to the new admin pages (moves, requests,
chats); BACKOFFICE_URL defaults to ADMIN_URL.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
zabudko-ruandClaude Opus 5.5 committed 2026-10-21 04:22:36 +04:00
1 parent dcba7c200c
commit dda917fc71
5 files changed
+24 -8

No files matched your search

+2
View File
@@ -2,7 +2,9 @@ import react from '@vitejs/plugin-react';
import { defineConfig } from 'vite';
// В разработке API проксируется — Mini App и API на одном origin (удобно и для туннеля https)
// ADMIN_BASE=/old/ — в продакшене старая админка живёт по адресу admin.barevclub.com/old/
export default defineConfig({
base: process.env.ADMIN_BASE ?? '/',
plugins: [react()],
server: {
host: true,
+5 -4
View File
@@ -102,11 +102,12 @@ async function runBroadcast(id: string) {
}
/** Новая админка, если уже на сервере; иначе — раздел переписки в старой */
const BACKOFFICE_URL = process.env.BACKOFFICE_URL ?? '';
// новая админка живёт на admin.* (старая — admin.*/old/), отдельный адрес не обязателен
const BACKOFFICE_URL = process.env.BACKOFFICE_URL || ADMIN_URL;
const chatButton = (threadId: string | null, peer: string): InlineButton | null =>
BACKOFFICE_URL.startsWith('https://') && threadId
? { text: adminT('bot.admin.open'), url: `${BACKOFFICE_URL}/#/chats/${threadId}` }
: adminButton(`/concierge?${peer.startsWith('c:') ? 'client' : 'provider'}=${peer.slice(2)}`);
: adminButton('/chats');
const who = (u: { firstName: string | null; lastName?: string | null; username: string | null }) =>
`${escapeHtml(`${u.firstName ?? ''} ${u.lastName ?? ''}`.trim())}${u.username ? ` (@${escapeHtml(u.username)})` : ''}`;
@@ -395,7 +396,7 @@ async function handle(event: DomainEvent) {
const pkg = lead.package ? adminT(`landing.quiz.package_${lead.package}`) : '—';
await toAdmins(
`🧳 <b>${adminT('bot.admin.newLead', { number: lead.number })}</b>\n${escapeHtml(lead.name)} · ${escapeHtml(lead.contact)}\n${when} · ${pkg}${lead.adminNote ? `\n${escapeHtml(lead.adminNote)}` : ''}`,
compactRows([[adminButton('/leads')]]),
compactRows([[adminButton('/moves')]]),
);
return;
}
@@ -405,7 +406,7 @@ async function handle(event: DomainEvent) {
const what = r.kind === 'SUBSCRIPTION' ? adminT('admin.requests.subscription', { plan: r.plan === 'ELITE' ? 'Barev Elite' : 'Barev+' }) : adminT(`services.${r.serviceCode}.name`);
await toAdmins(
`⭐ <b>${adminT('bot.admin.newRequest', { number: r.number })}</b>\n${who(r.client.user)}\n${escapeHtml(what)}${r.comment ? `\n${escapeHtml(r.comment)}` : ''}`,
compactRows([[{ text: adminT('bot.admin.reply'), callback_data: `ar:c:${r.clientId}` }, adminButton('/app-requests')]]),
compactRows([[{ text: adminT('bot.admin.reply'), callback_data: `ar:c:${r.clientId}` }, adminButton('/requests')]]),
);
return;
}