feat(GRO-106): staff messages page

- Adds staff conversations API (GET /api/conversations, GET /api/conversations/:id/messages, POST /api/conversations/:id/messages) with auth scoping and cross-tenant protection
- Adds staffReadAt column to conversations table for unread tracking
- Adds staff Messages page with two-column inbox layout (thread list + conversation view + composer)
- Adds Messages entry to staff sidebar navigation
- Includes tests for the MessagesPage component

Part of GRO-106 (SMS/MMS integration) Phase 1.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-14 10:27:06 +00:00
committed by Flea Flicker [agent]
parent fbf3527085
commit d2291e3a4a
9 changed files with 3820 additions and 3 deletions
@@ -0,0 +1,4 @@
-- Add staffReadAt column to conversations for unread tracking
ALTER TABLE "conversations" ADD COLUMN "staff_read_at" timestamp;
CREATE INDEX "idx_conversations_business_id_staff_read_at" ON "conversations"("business_id", "staff_read_at" DESC);
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -220,10 +220,10 @@
"breakpoints": true
},
{
"idx": 31,
"idx": 32,
"version": "7",
"when": 1778732072097,
"tag": "0031_steady_veda",
"when": 1778818472097,
"tag": "0032_add_staff_read_at",
"breakpoints": true
}
]
+1
View File
@@ -463,6 +463,7 @@ export const conversations = pgTable(
businessNumber: text("business_number").notNull(),
lastMessageAt: timestamp("last_message_at"),
status: text("status").notNull().default("active"),
staffReadAt: timestamp("staff_read_at"),
createdAt: timestamp("created_at").notNull().defaultNow(),
updatedAt: timestamp("updated_at").notNull().defaultNow(),
},