This repository has been archived on 2026-05-24. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
app/apps/api/src/lib/buffer.ts
T
Chris Farhood 9c9568b80c feat(GRO-106): portal Communication tab — real backend
- Added GET /portal/conversation and GET /portal/conversation/messages endpoints
- Created Communication.api.ts with typed fetchers and React hooks
- Rewired Communication.tsx to use real API, removed mock data
- Added composer-disabled bar with "Reply from your phone" tooltip
- Added conversation route tests to portal.test.ts

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-14 12:40:06 +00:00

66 lines
1.7 KiB
TypeScript

import { eq } from "@groombook/db";
import { bufferTimeRules, services, type Db } from "@groombook/db";
export async function resolveBufferMinutes({
serviceId,
sizeCategory,
coatType,
db,
}: {
serviceId: string;
sizeCategory: string | null;
coatType: string | null;
db: Db;
}): Promise<number> {
// Query all rules for this service in one DB call
const allRules = await db
.select()
.from(bufferTimeRules)
.where(eq(bufferTimeRules.serviceId, serviceId));
// Priority 1: exact match (serviceId + sizeCategory + coatType all match)
const exact = allRules.find(
(r) =>
r.sizeCategory === sizeCategory &&
r.coatType === coatType
);
if (exact) return exact.bufferMinutes;
// Priority 2: service + size, null coatType
const serviceSize = allRules.find(
(r) =>
r.sizeCategory === sizeCategory &&
r.coatType === null
);
if (serviceSize) return serviceSize.bufferMinutes;
// Priority 3: service + coat, null sizeCategory
const serviceCoat = allRules.find(
(r) =>
r.sizeCategory === null &&
r.coatType === coatType
);
if (serviceCoat) return serviceCoat.bufferMinutes;
// Priority 4: service only (null sizeCategory, null coatType)
const serviceOnly = allRules.find(
(r) =>
r.sizeCategory === null &&
r.coatType === null
);
if (serviceOnly) return serviceOnly.bufferMinutes;
// Priority 5: fallback to service.defaultBufferMinutes
const [service] = await db
.select({ defaultBufferMinutes: services.defaultBufferMinutes })
.from(services)
.where(eq(services.id, serviceId))
.limit(1);
if (service?.defaultBufferMinutes != null) {
return service.defaultBufferMinutes;
}
// Priority 6: final fallback to 0
return 0;
}