Chats: show which order a provider writes about, or that there is no order
- Provider messages store the order that was current when they wrote: a started order first, otherwise the nearest assigned one within -4h..+12h; none — "no order". - Admin chat: order tag above each provider message, "now / next" order strip in the conversation header, order number (or "no order") in the thread list. - Telegram notification to the team gets an order line or "no current order". - Test for the order-picking rule; demo shows both cases. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
23ffb2bf1d
commit
2772837e29
14 files changed
+321
-13
No files matched your search
@@ -5,6 +5,7 @@ import {
|
||||
chatRecipients,
|
||||
clientConversation,
|
||||
closeThread,
|
||||
createOrder,
|
||||
conversation,
|
||||
DomainError,
|
||||
getThreadForStaff,
|
||||
@@ -20,7 +21,7 @@ import {
|
||||
startClient,
|
||||
threadCounts,
|
||||
} from '../src/index.ts';
|
||||
import { db, fixtures, makeCtx, NOW, tgUser } from './helpers.ts';
|
||||
import { db, fixtures, makeCtx, NOW, slotAt, tgUser } from './helpers.ts';
|
||||
|
||||
beforeEach(async () => {
|
||||
await fixtures();
|
||||
@@ -174,6 +175,39 @@ describe('чаты: поддержка и консьерж', () => {
|
||||
void boss;
|
||||
});
|
||||
|
||||
it('исполнитель: сообщение помечается текущим заказом, без заказа — пометка «нет заказа»', async () => {
|
||||
const { ctx, clock } = makeCtx(NOW);
|
||||
const fx = await db.provider.findFirstOrThrow({ where: { name: 'Maria' } });
|
||||
const kentron = await db.district.findUniqueOrThrow({ where: { code: 'kentron' } });
|
||||
const clientId = await client(ctx, 771);
|
||||
const order = await createOrder(ctx, { clientId, serviceCode: 'cleaning', params: { cleaningType: 'regular', rooms: 2 }, scheduledAt: slotAt(2, 11), addressText: 'Абовяна 10', districtId: kentron.id });
|
||||
|
||||
// заказ через двое суток — сейчас исполнитель без заказа, но он «ближайший»
|
||||
await db.order.update({ where: { id: order.id }, data: { providerId: fx.id, status: 'ASSIGNED' } });
|
||||
const free = (await receiveMessage(ctx, { providerId: fx.id }, { text: 'Есть работа на завтра?' }))!;
|
||||
expect(free.message.orderId).toBeNull();
|
||||
const view = await getThreadForStaff(ctx, free.thread.id);
|
||||
expect(view.currentOrder).toBeNull();
|
||||
expect(view.nextOrder).toMatchObject({ number: order.number, address: 'Абовяна 10' });
|
||||
expect(view.messages[0]!.order).toBeNull();
|
||||
|
||||
// за 2 часа до начала — уже текущий
|
||||
clock.now = new Date(order.scheduledAt.getTime() - 2 * 3600_000);
|
||||
const soon = (await receiveMessage(ctx, { providerId: fx.id }, { text: 'Код от подъезда?' }))!;
|
||||
expect(soon.message.orderId).toBe(order.id);
|
||||
|
||||
// начатый заказ — текущий даже после планового времени
|
||||
await db.order.update({ where: { id: order.id }, data: { status: 'CLEANING' } });
|
||||
clock.now = new Date(order.scheduledAt.getTime() + 5 * 3600_000);
|
||||
expect((await receiveMessage(ctx, { providerId: fx.id }, { text: 'Задерживаюсь' }))!.message.orderId).toBe(order.id);
|
||||
|
||||
// завершён — снова без заказа; клиентские сообщения заказ не помечает
|
||||
await db.order.update({ where: { id: order.id }, data: { status: 'DONE' } });
|
||||
expect((await receiveMessage(ctx, { providerId: fx.id }, { text: 'Готово' }))!.message.orderId).toBeNull();
|
||||
expect((await addClientMessage(ctx, clientId, 'Спасибо'))!.message.orderId).toBeNull();
|
||||
expect((await listThreads(ctx, { channels: ['SUPPORT'], filter: 'open', adminUserId: 'x' })).find((x) => x.providerId === fx.id)!.lastOrder).toBeNull();
|
||||
});
|
||||
|
||||
it('ответ из старой админки / из Telegram попадает в последний диалог клиента', async () => {
|
||||
const { ctx } = makeCtx(NOW);
|
||||
const clientId = await client(ctx, 761, true);
|
||||
|
||||
Reference in new issue
Block a user