Backoffice stage 5: products, broadcasts, activity log, settings
- Products: services with full setup — content (name, description, extras names in 5 languages via text overrides), price tiers and extras, booking window, late-cancel fee, on/off, checklist; category discounts by membership level; membership plan prices; promo codes; relocation steps and documents. - Text overrides: TextOverride table on top of the i18n files; API, bots and the worker reload them every minute, mini apps fetch public.texts at start. - Promo codes applied to orders (admin new-order form and client API): not stacked with membership discount — the larger wins; once per client; validity, limit and categories. - Broadcasts to the client bot by any client filter, per-language texts with Russian fallback, test to yourself, ~25 msg/s, per-recipient status, resume after worker restart, history with progress and stop. - Activity log (who/when/what, filters, details) and Settings page with all owner settings grouped, plus payment methods. - Tests for promo codes and text overrides. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
ac786cc5cc
commit
0edc6432b7
34 files changed
+2704
-26
No files matched your search
@@ -4,7 +4,7 @@ import multipart, { type MultipartFile } from '@fastify/multipart';
|
||||
import * as Sentry from '@sentry/node';
|
||||
import { fastifyTRPCPlugin, type FastifyTRPCPluginOptions } from '@trpc/server/adapters/fastify';
|
||||
import { getFlow } from '@barev/core';
|
||||
import { DomainError, getClientByTelegramId, proIdentity, receiveMessage, setChecklistItem, staffSend } from '@barev/services';
|
||||
import { DomainError, getClientByTelegramId, proIdentity, receiveMessage, setChecklistItem, staffSend, startTextOverrides } from '@barev/services';
|
||||
import { getFile, putFile } from '@barev/services/storage';
|
||||
import { TelegramSender } from '@barev/services/telegram';
|
||||
import Fastify, { type FastifyReply, type FastifyRequest } from 'fastify';
|
||||
@@ -278,6 +278,9 @@ app.post('/client-log', { bodyLimit: 4096 }, async (req, reply) => {
|
||||
|
||||
app.get('/health', async () => ({ ok: true }));
|
||||
|
||||
// тексты из админки поверх переводов (обновляются раз в минуту)
|
||||
startTextOverrides(db);
|
||||
|
||||
await ensureBucket().catch((e) => app.log.warn({ err: e }, 'S3 недоступно — загрузка фото работать не будет'));
|
||||
await app.listen({ port: env.API_PORT, host: '0.0.0.0' });
|
||||
console.log(`API: http://localhost:${env.API_PORT}`);
|
||||
Reference in new issue
Block a user