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:
1 parent
dcba7c200c
commit
dda917fc71
5 files changed
+24
-8
No files matched your search
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# Barev Club — образы для продакшена.
|
||||
# app — Node: API + воркер + боты (один процесс) и лендинг Next.js (тот же образ)
|
||||
# web — nginx: статика Mini App и админки + прокси /trpc и /files на API
|
||||
# admin.* — новая админка (apps/backoffice), admin.*/old/ — старая (apps/admin)
|
||||
FROM node:22-alpine AS deps
|
||||
RUN corepack enable
|
||||
WORKDIR /repo
|
||||
@@ -15,13 +16,15 @@ ARG CLIENT_BOT_USERNAME=barevclub_bot
|
||||
ENV VITE_LANDING_URL=$LANDING_URL NEXT_PUBLIC_API_URL=$API_PUBLIC_URL CLIENT_BOT_USERNAME=$CLIENT_BOT_USERNAME NEXT_TELEMETRY_DISABLED=1
|
||||
RUN pnpm --filter @barev/miniapp-client build \
|
||||
&& pnpm --filter @barev/miniapp-pro build \
|
||||
&& pnpm --filter @barev/admin build \
|
||||
&& ADMIN_BASE=/old/ pnpm --filter @barev/admin build \
|
||||
&& VITE_OLD_ADMIN_URL=/old/ pnpm --filter @barev/backoffice build \
|
||||
&& pnpm --filter @barev/landing build
|
||||
|
||||
FROM nginx:alpine AS web
|
||||
COPY --from=build /repo/apps/miniapp-client/dist /srv/client
|
||||
COPY --from=build /repo/apps/miniapp-pro/dist /srv/pro
|
||||
COPY --from=build /repo/apps/admin/dist /srv/admin
|
||||
COPY --from=build /repo/apps/backoffice/dist /srv/admin
|
||||
COPY --from=build /repo/apps/admin/dist /srv/admin/old
|
||||
COPY infra/prod/nginx.conf /etc/nginx/conf.d/default.conf
|
||||
|
||||
FROM node:22-alpine AS app
|
||||
|
||||
@@ -16,8 +16,8 @@ LANDING_URL=https://barevclub.com
|
||||
CLIENT_MINIAPP_URL=https://app.barevclub.com
|
||||
PRO_MINIAPP_URL=https://pro.barevclub.com
|
||||
ADMIN_URL=https://admin.barevclub.com
|
||||
# новая админка — когда выложим: тогда «Открыть» в уведомлениях о сообщениях ведёт в её чаты
|
||||
# BACKOFFICE_URL=https://team.barevclub.com
|
||||
# новая админка — на ADMIN_URL (старая — ADMIN_URL/old/); BACKOFFICE_URL нужен, только если она на другом адресе
|
||||
# BACKOFFICE_URL=
|
||||
# серверный адрес API для лендинга (внутри docker-сети)
|
||||
API_URL=http://barev-app:4000
|
||||
API_PORT=4000
|
||||
|
||||
@@ -75,6 +75,16 @@ server {
|
||||
add_header Cache-Control "no-cache";
|
||||
}
|
||||
|
||||
# старая админка: admin.barevclub.com/old/ — своя index.html, тоже без кеша
|
||||
location ^~ /old/ {
|
||||
root /srv/$barev_site;
|
||||
try_files $uri $uri/ /old/index.html;
|
||||
location ~ \.html$ {
|
||||
root /srv/$barev_site;
|
||||
add_header Cache-Control "no-cache";
|
||||
}
|
||||
}
|
||||
|
||||
# статика с хешами в имени — кешируем надолго
|
||||
location /assets/ {
|
||||
root /srv/$barev_site;
|
||||
|
||||
Reference in new issue
Block a user