feat: make server own tabs
CI / build-and-test (push) Canceled after 0s

This commit is contained in:
2026-10-20 16:18:36 +02:00
parent 1e4438ec5a
commit 0ca9f4d16a
31 changed files with 2101 additions and 892 deletions
+13 -40
View File
@@ -1,27 +1,15 @@
import { Injectable } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
import { customerNameKey } from '../planned-tabs/customer-name';
import { tabSummary } from './tab-state';
@Injectable()
export class TabsService {
constructor(private prisma: PrismaService) {}
/** The venue's open tabs as the server holds them; every terminal shows the same. */
async findAll(venueId: string) {
const ownerships = await this.prisma.tabOwnership.findMany({
where: { venueId },
include: {
device: {
select: { id: true, name: true, lastSeenAt: true, revokedAt: true },
},
},
});
const snapshots = ownerships.length === 0 ? [] : await this.prisma.openTabSnapshot.findMany({
where: {
OR: ownerships.map((o) => ({ deviceId: o.deviceId, tabId: o.tabId })),
},
});
const snapshotByKey = new Map(snapshots.map((s) => [`${s.deviceId}:${s.tabId}`, s]));
const tabs = await this.prisma.tab.findMany({ where: { venueId }, orderBy: { openedAt: 'asc' } });
// Customer details (email for reminders) live on the planned customer with the same name
const planned = await this.prisma.plannedTab.findMany({
@@ -30,31 +18,16 @@ export class TabsService {
});
const plannedByKey = new Map(planned.map((p) => [p.customerNameKey, p]));
const tabs = [];
for (const ownership of ownerships) {
const snapshot = snapshotByKey.get(`${ownership.deviceId}:${ownership.tabId}`);
if (snapshot) {
const plannedTab = plannedByKey.get(customerNameKey(snapshot.customerName));
tabs.push({
tabId: snapshot.tabId,
customerName: snapshot.customerName,
version: snapshot.version,
totalInCents: snapshot.totalInCents,
itemCount: snapshot.itemCount,
// null: the terminal's app version doesn't report lines yet
items: snapshot.items ?? null,
deviceId: ownership.device.id,
deviceName: ownership.device.name,
deviceLastSeenAt: ownership.device.lastSeenAt,
deviceRevokedAt: ownership.device.revokedAt,
lastReportedAt: snapshot.reportedAt,
return {
tabs: tabs.map(tabSummary).map(({ updatedAt, ...tab }) => {
const plannedTab = plannedByKey.get(customerNameKey(tab.customerName));
return {
...tab,
lastChangedAt: updatedAt,
plannedTabId: plannedTab?.id ?? null,
email: plannedTab?.email ?? null,
});
}
}
return { tabs };
};
}),
};
}
}
}