/** * Локальная разработка: демо бариков у клиента «Анна» (telegramId 100000001): * начисления (доступные и в ожидании), бонус, списание, открытый запрос и предложение системы. * pnpm --filter @barev/api dev:points-demo */ import { DAY } from '@barev/core'; import { getDb } from '@barev/db'; import { accruePoints, redeemPoints, requestRedemption, type Ctx } from '@barev/services'; import { env } from '../src/env.ts'; if (env.isProd) throw new Error('Только для разработки'); const db = getDb(); const ctx: Ctx = { db, notify: { emit: async () => {} }, now: () => new Date() }; const OWNER = { adminId: null, owner: true }; const user = await db.user.findUniqueOrThrow({ where: { telegramId: 100000001n }, include: { client: true } }); const clientId = user.client!.id; // чистим прошлое демо этого клиента await db.pointsRedemptionItem.deleteMany({ where: { redemption: { clientId } } }); await db.pointsRedemption.deleteMany({ where: { clientId } }); await db.pointsReversal.deleteMany({ where: { clientId } }); await db.pointsSuggestion.deleteMany({ where: { clientId } }); await db.pointsAccrual.deleteMany({ where: { clientId } }); await db.client.update({ where: { id: clientId }, data: { pointsActive: 0, pointsPending: 0, pointsDebt: 0, streakCount: 0, streakLastAt: null, pointsActivityAt: null } }); const cat = (code: string) => db.pointsCategory.findUniqueOrThrow({ where: { code } }); const now = Date.now(); const ago = (d: number) => new Date(now - d * DAY); const cleaning = await cat('cleaning'); for (const [i, d] of [50, 25, 3].entries()) { await accruePoints(ctx, { clientId, kind: 'ORDER', categoryId: cleaning.id, orderAmount: 18_000 + i * 2000, serviceDate: ago(d), orderRef: `DEMO-C${i}`, channel: 'WEB' }, OWNER); } await accruePoints(ctx, { clientId, kind: 'ORDER', categoryId: (await cat('documents')).id, orderAmount: 45_000, excludedAmount: 15_000, serviceDate: ago(10), orderRef: 'DEMO-D1', channel: 'WEB' }, OWNER); // ожидание 48 ч от даты услуги: старые уже доступны — активируем const { activatePendingPoints } = await import('@barev/services'); await activatePendingPoints(ctx); // свежая уборка — ещё в ожидании await accruePoints(ctx, { clientId, kind: 'ORDER', categoryId: cleaning.id, orderAmount: 19_000, serviceDate: new Date(), orderRef: 'DEMO-C3', channel: 'AUTO' }, OWNER); const bonus = await db.pointsBonusType.findUniqueOrThrow({ where: { code: 'housewarming' } }); await accruePoints(ctx, { clientId, kind: 'BONUS', bonusTypeId: bonus.id, amount: 5000, serviceDate: new Date(), channel: 'WEB', commentForClient: 'Yerevan Home' }, OWNER); await redeemPoints(ctx, { clientId, amount: 2000, orderAmount: 20_000, orderRef: 'DEMO-R1', reason: 'оплата по звонку', channel: 'WEB' }, OWNER); await requestRedemption(ctx, { clientId, amount: 1500, note: 'Уборка 30 октября, 18 000 ֏' }); await db.pointsSuggestion.create({ data: { clientId, mechanic: 'first_month_route', dedupeKey: `route:${clientId}`, payload: { categories: ['cleaning', 'documents', 'learning'] }, suggestedAmount: 3000 } }); const c = await db.client.findUniqueOrThrow({ where: { id: clientId } }); console.log(`Анна: доступно ${c.pointsActive}, в ожидании ${c.pointsPending}, серия ${c.streakCount}`); process.exit(0);