fix(GRO-1215): resolve ESLint error, cursor pagination, and UAT playbook gaps

- Add and() + lt() imports from @groombook/db
- Apply businessId to conversation WHERE clause for cross-tenant isolation
  (GET /portal/conversation: clientId AND businessId both scoped)
- Fix cursor pagination: apply lt(messages.createdAt, cursorMsg.createdAt)
  to the cursor WHERE clause so pages actually paginate
- Add UAT_PLAYBOOK.md §4.9.1 Communication tab test cases:
  TC-APP-4.9.6 message history with conversation
  TC-APP-4.9.7 empty state (no conversation yet)
  TC-APP-4.9.8 composer disabled with tooltip
  TC-APP-4.9.9 cross-tenant isolation

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
2026-05-14 09:53:42 +00:00
committed by Flea Flicker [agent]
parent 5f717c4467
commit fbf3527085
2 changed files with 246 additions and 3 deletions
+3 -3
View File
@@ -1,7 +1,7 @@
import { Hono } from "hono";
import { zValidator } from "@hono/zod-validator";
import { z } from "zod/v3";
import { eq, inArray, desc } from "@groombook/db";
import { and, eq, inArray, desc, lt } from "@groombook/db";
import { getDb, appointments, impersonationSessions, waitlistEntries, clients, pets, services, staff, invoices, invoiceLineItems, businessSettings, conversations, messages } from "@groombook/db";
import { validatePortalSession } from "../middleware/portalSession.js";
import { portalAudit } from "../middleware/portalAudit.js";
@@ -194,7 +194,7 @@ portalRouter.get("/conversation", async (c) => {
createdAt: conversations.createdAt,
})
.from(conversations)
.where(eq(conversations.clientId, clientId))
.where(and(eq(conversations.clientId, clientId), eq(conversations.businessId, businessId)))
.limit(1);
if (!conversation) {
@@ -254,7 +254,7 @@ portalRouter.get("/conversation/messages", async (c) => {
deliveredAt: messages.deliveredAt,
})
.from(messages)
.where(eq(messages.conversationId, conversation.id))
.where(and(eq(messages.conversationId, conversation.id), lt(messages.createdAt, cursorMsg.createdAt)))
.orderBy(desc(messages.createdAt))
.limit(limit);
}