1. **Remove duplicate staffReadAt** in `packages/db/src/schema.ts`
(TS1117 duplicate identifier — merge conflict artifact)
2. **Add count to db index exports** in `packages/db/src/index.ts`
(`count` from drizzle-orm was used in conversations.ts but not exported)
3. **Use dev version of conversations.ts** (no type errors, sql\`count(*)\`)
— PR branch version had incompatible type errors (staff.businessId,
count, optedOutAt fields not in schema)
4. **Remove duplicate conversationsRouter import** in `apps/api/src/index.ts`
All 289 tests pass, 0 lint errors.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- 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>
- Add `staffReadAt` column to conversations table schema
- Add migration 0032_staff_read_at.sql for the new column
- Create /api/conversations router with GET / (list), GET /:id/messages (paginated), POST /:id/messages (send)
- Mark conversations as read (staffReadAt = NOW()) when staff fetches messages
- Return 409 when client has opted out of SMS
- 404 on cross-tenant access
- Add conversations.test.ts covering all 5 acceptance criteria
Co-Authored-By: Paperclip <noreply@paperclip.ing>