hazo_chat 4.0.2 → 4.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. package/README.md +46 -6
  2. package/SETUP_CHECKLIST.md +12 -2
  3. package/dist/api/index.d.ts +41 -0
  4. package/dist/api/index.d.ts.map +1 -0
  5. package/dist/api/index.js +40 -0
  6. package/dist/api/index.js.map +1 -0
  7. package/dist/api/messages.d.ts +85 -0
  8. package/dist/api/messages.d.ts.map +1 -0
  9. package/dist/api/messages.js +626 -0
  10. package/dist/api/messages.js.map +1 -0
  11. package/dist/api/types.d.ts +134 -0
  12. package/dist/api/types.d.ts.map +1 -0
  13. package/dist/api/types.js +8 -0
  14. package/dist/api/types.js.map +1 -0
  15. package/dist/api/unread_count.d.ts +82 -0
  16. package/dist/api/unread_count.d.ts.map +1 -0
  17. package/dist/api/unread_count.js +111 -0
  18. package/dist/api/unread_count.js.map +1 -0
  19. package/dist/components/hazo_chat/hazo_chat.d.ts +28 -0
  20. package/dist/components/hazo_chat/hazo_chat.d.ts.map +1 -0
  21. package/dist/components/hazo_chat/hazo_chat.js +230 -0
  22. package/dist/components/hazo_chat/hazo_chat.js.map +1 -0
  23. package/dist/components/hazo_chat/hazo_chat_attachment_preview.d.ts +17 -0
  24. package/dist/components/hazo_chat/hazo_chat_attachment_preview.d.ts.map +1 -0
  25. package/dist/components/hazo_chat/hazo_chat_attachment_preview.js +60 -0
  26. package/dist/components/hazo_chat/hazo_chat_attachment_preview.js.map +1 -0
  27. package/dist/components/hazo_chat/hazo_chat_context.d.ts +46 -0
  28. package/dist/components/hazo_chat/hazo_chat_context.d.ts.map +1 -0
  29. package/dist/components/hazo_chat/hazo_chat_context.js +277 -0
  30. package/dist/components/hazo_chat/hazo_chat_context.js.map +1 -0
  31. package/dist/components/hazo_chat/hazo_chat_document_viewer.d.ts +15 -0
  32. package/dist/components/hazo_chat/hazo_chat_document_viewer.d.ts.map +1 -0
  33. package/dist/components/hazo_chat/hazo_chat_document_viewer.js +140 -0
  34. package/dist/components/hazo_chat/hazo_chat_document_viewer.js.map +1 -0
  35. package/dist/components/hazo_chat/hazo_chat_header.d.ts +16 -0
  36. package/dist/components/hazo_chat/hazo_chat_header.d.ts.map +1 -0
  37. package/dist/components/hazo_chat/hazo_chat_header.js +45 -0
  38. package/dist/components/hazo_chat/hazo_chat_header.js.map +1 -0
  39. package/dist/components/hazo_chat/hazo_chat_input.d.ts +16 -0
  40. package/dist/components/hazo_chat/hazo_chat_input.d.ts.map +1 -0
  41. package/dist/components/hazo_chat/hazo_chat_input.js +75 -0
  42. package/dist/components/hazo_chat/hazo_chat_input.js.map +1 -0
  43. package/dist/components/hazo_chat/hazo_chat_messages.d.ts +18 -0
  44. package/dist/components/hazo_chat/hazo_chat_messages.d.ts.map +1 -0
  45. package/dist/components/hazo_chat/hazo_chat_messages.js +255 -0
  46. package/dist/components/hazo_chat/hazo_chat_messages.js.map +1 -0
  47. package/dist/components/hazo_chat/hazo_chat_reference_list.d.ts +16 -0
  48. package/dist/components/hazo_chat/hazo_chat_reference_list.d.ts.map +1 -0
  49. package/dist/components/hazo_chat/hazo_chat_reference_list.js +59 -0
  50. package/dist/components/hazo_chat/hazo_chat_reference_list.js.map +1 -0
  51. package/dist/components/hazo_chat/hazo_chat_sidebar.d.ts +18 -0
  52. package/dist/components/hazo_chat/hazo_chat_sidebar.d.ts.map +1 -0
  53. package/dist/components/hazo_chat/hazo_chat_sidebar.js +72 -0
  54. package/dist/components/hazo_chat/hazo_chat_sidebar.js.map +1 -0
  55. package/dist/components/hazo_chat/index.d.ts +16 -0
  56. package/dist/components/hazo_chat/index.d.ts.map +1 -0
  57. package/dist/components/hazo_chat/index.js +19 -0
  58. package/dist/components/hazo_chat/index.js.map +1 -0
  59. package/dist/components/index.d.ts +9 -0
  60. package/dist/components/index.d.ts.map +1 -0
  61. package/dist/components/index.js +11 -0
  62. package/dist/components/index.js.map +1 -0
  63. package/dist/components/ui/avatar.d.ts +13 -0
  64. package/dist/components/ui/avatar.d.ts.map +1 -0
  65. package/dist/components/ui/avatar.js +28 -0
  66. package/dist/components/ui/avatar.js.map +1 -0
  67. package/dist/components/ui/badge.d.ts +16 -0
  68. package/dist/components/ui/badge.d.ts.map +1 -0
  69. package/dist/components/ui/badge.js +36 -0
  70. package/dist/components/ui/badge.js.map +1 -0
  71. package/dist/components/ui/button.d.ts +18 -0
  72. package/dist/components/ui/button.d.ts.map +1 -0
  73. package/dist/components/ui/button.js +47 -0
  74. package/dist/components/ui/button.js.map +1 -0
  75. package/dist/components/ui/chat_bubble.d.ts +18 -0
  76. package/dist/components/ui/chat_bubble.d.ts.map +1 -0
  77. package/dist/components/ui/chat_bubble.js +130 -0
  78. package/dist/components/ui/chat_bubble.js.map +1 -0
  79. package/dist/components/ui/hover-card.d.ts +13 -0
  80. package/dist/components/ui/hover-card.d.ts.map +1 -0
  81. package/dist/components/ui/hover-card.js +17 -0
  82. package/dist/components/ui/hover-card.js.map +1 -0
  83. package/dist/components/ui/index.d.ts +19 -0
  84. package/dist/components/ui/index.d.ts.map +1 -0
  85. package/dist/components/ui/index.js +21 -0
  86. package/dist/components/ui/index.js.map +1 -0
  87. package/dist/components/ui/input.d.ts +11 -0
  88. package/dist/components/ui/input.d.ts.map +1 -0
  89. package/dist/components/ui/input.js +18 -0
  90. package/dist/components/ui/input.js.map +1 -0
  91. package/dist/components/ui/loading_skeleton.d.ts +19 -0
  92. package/dist/components/ui/loading_skeleton.d.ts.map +1 -0
  93. package/dist/components/ui/loading_skeleton.js +30 -0
  94. package/dist/components/ui/loading_skeleton.js.map +1 -0
  95. package/dist/components/ui/scroll-area.d.ts +12 -0
  96. package/dist/components/ui/scroll-area.d.ts.map +1 -0
  97. package/dist/components/ui/scroll-area.js +25 -0
  98. package/dist/components/ui/scroll-area.js.map +1 -0
  99. package/dist/components/ui/separator.d.ts +11 -0
  100. package/dist/components/ui/separator.d.ts.map +1 -0
  101. package/dist/components/ui/separator.js +18 -0
  102. package/dist/components/ui/separator.js.map +1 -0
  103. package/dist/components/ui/skeleton.d.ts +9 -0
  104. package/dist/components/ui/skeleton.d.ts.map +1 -0
  105. package/dist/components/ui/skeleton.js +16 -0
  106. package/dist/components/ui/skeleton.js.map +1 -0
  107. package/dist/components/ui/textarea.d.ts +11 -0
  108. package/dist/components/ui/textarea.d.ts.map +1 -0
  109. package/dist/components/ui/textarea.js +18 -0
  110. package/dist/components/ui/textarea.js.map +1 -0
  111. package/dist/components/ui/tooltip.d.ts +14 -0
  112. package/dist/components/ui/tooltip.d.ts.map +1 -0
  113. package/dist/components/ui/tooltip.js +30 -0
  114. package/dist/components/ui/tooltip.js.map +1 -0
  115. package/dist/hooks/index.d.ts +10 -0
  116. package/dist/hooks/index.d.ts.map +1 -0
  117. package/dist/hooks/index.js +10 -0
  118. package/dist/hooks/index.js.map +1 -0
  119. package/dist/hooks/use_chat_messages.d.ts +38 -0
  120. package/dist/hooks/use_chat_messages.d.ts.map +1 -0
  121. package/dist/hooks/use_chat_messages.js +584 -0
  122. package/dist/hooks/use_chat_messages.js.map +1 -0
  123. package/dist/hooks/use_chat_references.d.ts +17 -0
  124. package/dist/hooks/use_chat_references.d.ts.map +1 -0
  125. package/dist/hooks/use_chat_references.js +133 -0
  126. package/dist/hooks/use_chat_references.js.map +1 -0
  127. package/dist/hooks/use_file_upload.d.ts +26 -0
  128. package/dist/hooks/use_file_upload.d.ts.map +1 -0
  129. package/dist/hooks/use_file_upload.js +216 -0
  130. package/dist/hooks/use_file_upload.js.map +1 -0
  131. package/dist/index.d.ts +13 -0
  132. package/dist/index.d.ts.map +1 -0
  133. package/dist/index.js +17 -0
  134. package/dist/index.js.map +1 -0
  135. package/dist/lib/config.d.ts +41 -0
  136. package/dist/lib/config.d.ts.map +1 -0
  137. package/dist/lib/config.js +93 -0
  138. package/dist/lib/config.js.map +1 -0
  139. package/dist/lib/constants.d.ts +41 -0
  140. package/dist/lib/constants.d.ts.map +1 -0
  141. package/dist/lib/constants.js +72 -0
  142. package/dist/lib/constants.js.map +1 -0
  143. package/dist/lib/index.d.ts +9 -0
  144. package/dist/lib/index.d.ts.map +1 -0
  145. package/dist/lib/index.js +9 -0
  146. package/dist/lib/index.js.map +1 -0
  147. package/dist/lib/utils.d.ts +17 -0
  148. package/dist/lib/utils.d.ts.map +1 -0
  149. package/dist/lib/utils.js +20 -0
  150. package/dist/lib/utils.js.map +1 -0
  151. package/dist/types/index.d.ts +572 -0
  152. package/dist/types/index.d.ts.map +1 -0
  153. package/dist/types/index.js +11 -0
  154. package/dist/types/index.js.map +1 -0
  155. package/package.json +2 -6
@@ -0,0 +1,626 @@
1
+ /**
2
+ * Messages API Handler Factory
3
+ *
4
+ * Creates GET, POST, and DELETE handlers for the /api/hazo_chat/messages endpoint.
5
+ * These handlers should be used in a Next.js API route.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * // app/api/hazo_chat/messages/route.ts
10
+ * import { createMessagesHandler } from 'hazo_chat/api';
11
+ * import { getHazoConnectSingleton } from 'hazo_connect/nextjs/setup';
12
+ *
13
+ * export const dynamic = 'force-dynamic';
14
+ *
15
+ * const { GET, POST } = createMessagesHandler({
16
+ * getHazoConnect: () => getHazoConnectSingleton()
17
+ * });
18
+ *
19
+ * export { GET, POST };
20
+ * ```
21
+ */
22
+ import { NextResponse } from 'next/server';
23
+ import { cookies } from 'next/headers';
24
+ import { createCrudService, getSqliteAdminService } from 'hazo_connect/server';
25
+ // ============================================================================
26
+ // Constants for validation
27
+ // ============================================================================
28
+ /** Maximum message length in characters */
29
+ const MAX_MESSAGE_LENGTH = 5000;
30
+ /** Maximum length for reference_id */
31
+ const MAX_REFERENCE_ID_LENGTH = 255;
32
+ /** Maximum length for reference_type */
33
+ const MAX_REFERENCE_TYPE_LENGTH = 100;
34
+ /** Default messages per page */
35
+ const DEFAULT_LIMIT = 50;
36
+ /** Maximum messages per page */
37
+ const MAX_LIMIT = 100;
38
+ // ============================================================================
39
+ // Helper Functions
40
+ // ============================================================================
41
+ /** Generate a UUID v4 */
42
+ function generateUUID() {
43
+ return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
44
+ const r = (Math.random() * 16) | 0;
45
+ const v = c === 'x' ? r : (r & 0x3) | 0x8;
46
+ return v.toString(16);
47
+ });
48
+ }
49
+ /** Create a standardized error response */
50
+ function createErrorResponse(error, status, error_code) {
51
+ return NextResponse.json({
52
+ success: false,
53
+ error,
54
+ error_code,
55
+ }, { status });
56
+ }
57
+ /** Create a standardized success response */
58
+ function createSuccessResponse(data) {
59
+ return NextResponse.json({
60
+ success: true,
61
+ data,
62
+ });
63
+ }
64
+ /**
65
+ * Default function to get user ID from request cookies
66
+ */
67
+ async function defaultGetUserIdFromRequest() {
68
+ const cookieStore = await cookies();
69
+ return cookieStore.get('hazo_auth_user_id')?.value || null;
70
+ }
71
+ /**
72
+ * Verify that a user is a member of a chat group
73
+ * @returns The membership record if found, null otherwise
74
+ */
75
+ async function verifyGroupMembership(hazoConnect, user_id, chat_group_id, logger) {
76
+ const membershipService = createCrudService(hazoConnect, 'hazo_chat_group_users');
77
+ try {
78
+ const memberships = await membershipService.list((qb) => qb.select('*')
79
+ .where('chat_group_id', 'eq', chat_group_id)
80
+ .where('user_id', 'eq', user_id));
81
+ return memberships[0] || null;
82
+ }
83
+ catch (error) {
84
+ logger.error('[hazo_chat] Error verifying group membership:', { error });
85
+ return null;
86
+ }
87
+ }
88
+ /**
89
+ * Creates GET and POST handlers for chat messages
90
+ *
91
+ * @param options - Configuration options
92
+ * @returns Object with GET and POST handlers
93
+ */
94
+ export function createMessagesHandler(options) {
95
+ const { getHazoConnect, getLogger, getUserIdFromRequest } = options;
96
+ const logger = getLogger();
97
+ /**
98
+ * GET handler - Fetch chat messages with pagination
99
+ *
100
+ * Query params:
101
+ * - chat_group_id (required): The chat group to fetch messages from
102
+ * - reference_id (optional): Filter by reference ID
103
+ * - reference_type (optional): Filter by reference type
104
+ * - limit (optional): Number of messages per page (default: 50, max: 100)
105
+ * - cursor (optional): Cursor for pagination (created_at timestamp of last message)
106
+ * - direction (optional): 'older' or 'newer' relative to cursor (default: 'older')
107
+ */
108
+ async function GET(request) {
109
+ try {
110
+ // Get current user ID
111
+ const current_user_id = getUserIdFromRequest
112
+ ? await getUserIdFromRequest(request)
113
+ : await defaultGetUserIdFromRequest();
114
+ if (!current_user_id) {
115
+ logger.error('[hazo_chat/messages GET] No user ID - not authenticated');
116
+ return createErrorResponse('User not authenticated', 401, 'UNAUTHENTICATED');
117
+ }
118
+ // Get query params
119
+ const { searchParams } = new URL(request.url);
120
+ const chat_group_id = searchParams.get('chat_group_id');
121
+ const reference_id = searchParams.get('reference_id') || '';
122
+ const reference_type = searchParams.get('reference_type') || '';
123
+ const cursor = searchParams.get('cursor') || '';
124
+ const direction = searchParams.get('direction') || 'older';
125
+ const limit_param = searchParams.get('limit');
126
+ // Validate required params
127
+ if (!chat_group_id) {
128
+ logger.error('[hazo_chat/messages GET] Missing chat_group_id');
129
+ return createErrorResponse('chat_group_id is required', 400, 'MISSING_CHAT_GROUP');
130
+ }
131
+ // Get hazo_connect instance early for membership check
132
+ const hazoConnect = getHazoConnect();
133
+ // Verify user is a member of the chat group
134
+ const membership = await verifyGroupMembership(hazoConnect, current_user_id, chat_group_id, logger);
135
+ if (!membership) {
136
+ logger.error('[hazo_chat/messages GET] User is not a member of chat group:', {
137
+ current_user_id,
138
+ chat_group_id,
139
+ });
140
+ return createErrorResponse('Access denied - not a member of this chat group', 403, 'FORBIDDEN');
141
+ }
142
+ // Validate input lengths
143
+ if (reference_id && reference_id.length > MAX_REFERENCE_ID_LENGTH) {
144
+ return createErrorResponse(`reference_id exceeds maximum length of ${MAX_REFERENCE_ID_LENGTH}`, 400, 'INVALID_REFERENCE_ID');
145
+ }
146
+ if (reference_type && reference_type.length > MAX_REFERENCE_TYPE_LENGTH) {
147
+ return createErrorResponse(`reference_type exceeds maximum length of ${MAX_REFERENCE_TYPE_LENGTH}`, 400, 'INVALID_REFERENCE_TYPE');
148
+ }
149
+ // Parse and validate limit
150
+ let limit = DEFAULT_LIMIT;
151
+ if (limit_param) {
152
+ const parsed_limit = parseInt(limit_param, 10);
153
+ if (isNaN(parsed_limit) || parsed_limit < 1) {
154
+ return createErrorResponse('limit must be a positive integer', 400, 'INVALID_LIMIT');
155
+ }
156
+ limit = Math.min(parsed_limit, MAX_LIMIT);
157
+ }
158
+ logger.info('[hazo_chat/messages GET] Fetching messages:', {
159
+ current_user_id,
160
+ chat_group_id,
161
+ reference_id,
162
+ reference_type,
163
+ cursor,
164
+ direction,
165
+ limit,
166
+ });
167
+ // Create CRUD service (hazoConnect already obtained above)
168
+ const chatService = createCrudService(hazoConnect, 'hazo_chat');
169
+ let messages = [];
170
+ try {
171
+ // Build query with proper filtering
172
+ const all_messages = await chatService.list((qb) => {
173
+ let builder = qb.select('*');
174
+ // Filter by chat group - this is the primary filter
175
+ builder = builder.where('chat_group_id', 'eq', chat_group_id);
176
+ // Filter by reference if provided
177
+ if (reference_id) {
178
+ builder = builder.where('reference_id', 'eq', reference_id);
179
+ }
180
+ if (reference_type) {
181
+ builder = builder.where('reference_type', 'eq', reference_type);
182
+ }
183
+ // Apply cursor-based pagination
184
+ if (cursor) {
185
+ if (direction === 'newer') {
186
+ builder = builder.where('created_at', 'gt', cursor);
187
+ }
188
+ else {
189
+ builder = builder.where('created_at', 'lt', cursor);
190
+ }
191
+ }
192
+ // Order by created_at
193
+ // For 'older' direction, we want desc to get the most recent first before cursor
194
+ // For 'newer' or initial load, we want asc
195
+ if (direction === 'older' && cursor) {
196
+ builder = builder.order('created_at', 'desc');
197
+ }
198
+ else {
199
+ builder = builder.order('created_at', 'asc');
200
+ }
201
+ return builder;
202
+ });
203
+ // Filter out deleted messages (membership check already done above)
204
+ const filtered_messages = all_messages.filter((msg) => !msg.deleted_at);
205
+ // Apply limit after filtering
206
+ messages = filtered_messages.slice(0, limit);
207
+ // If we fetched in desc order, reverse to return in asc order
208
+ if (direction === 'older' && cursor) {
209
+ messages.reverse();
210
+ }
211
+ }
212
+ catch (dbError) {
213
+ logger.error('[hazo_chat/messages GET] Database error:', { dbError });
214
+ throw dbError;
215
+ }
216
+ logger.info('[hazo_chat/messages GET] Found messages:', { count: messages.length });
217
+ // Determine if there are more messages
218
+ const has_more = messages.length === limit;
219
+ // Get cursors for next/prev page
220
+ const next_cursor = messages.length > 0 ? messages[messages.length - 1].created_at : null;
221
+ const prev_cursor = messages.length > 0 ? messages[0].created_at : null;
222
+ return NextResponse.json({
223
+ success: true,
224
+ messages,
225
+ current_user_id,
226
+ pagination: {
227
+ limit,
228
+ has_more,
229
+ next_cursor,
230
+ prev_cursor,
231
+ },
232
+ });
233
+ }
234
+ catch (error) {
235
+ const error_message = error instanceof Error ? error.message : 'Unknown error';
236
+ logger.error('[hazo_chat/messages GET] Error:', { error_message, error });
237
+ return createErrorResponse('Failed to fetch messages', 500, 'INTERNAL_ERROR');
238
+ }
239
+ }
240
+ /**
241
+ * POST handler - Create a new chat message
242
+ *
243
+ * Request body:
244
+ * - chat_group_id (required): The chat group to send the message to
245
+ * - message_text (required): The message content (max 5000 chars)
246
+ * - reference_id (optional): Reference ID for context grouping
247
+ * - reference_type (optional): Reference type (default: 'chat')
248
+ */
249
+ async function POST(request) {
250
+ try {
251
+ // Get current user ID (sender)
252
+ const sender_user_id = getUserIdFromRequest
253
+ ? await getUserIdFromRequest(request)
254
+ : await defaultGetUserIdFromRequest();
255
+ if (!sender_user_id) {
256
+ logger.error('[hazo_chat/messages POST] No user ID - not authenticated');
257
+ return createErrorResponse('User not authenticated', 401, 'UNAUTHENTICATED');
258
+ }
259
+ // Parse request body
260
+ const body = await request.json();
261
+ const { chat_group_id, message_text, reference_id, reference_type } = body;
262
+ // Validate required fields
263
+ if (!chat_group_id) {
264
+ logger.error('[hazo_chat/messages POST] Missing chat_group_id');
265
+ return createErrorResponse('chat_group_id is required', 400, 'MISSING_CHAT_GROUP');
266
+ }
267
+ // Get hazo_connect instance early for membership check
268
+ const hazoConnect = getHazoConnect();
269
+ // Verify user is a member of the chat group
270
+ const membership = await verifyGroupMembership(hazoConnect, sender_user_id, chat_group_id, logger);
271
+ if (!membership) {
272
+ logger.error('[hazo_chat/messages POST] User is not a member of chat group:', {
273
+ sender_user_id,
274
+ chat_group_id,
275
+ });
276
+ return createErrorResponse('Access denied - not a member of this chat group', 403, 'FORBIDDEN');
277
+ }
278
+ // Validate message_text
279
+ if (!message_text || typeof message_text !== 'string') {
280
+ logger.error('[hazo_chat/messages POST] Missing message_text');
281
+ return createErrorResponse('message_text is required', 400, 'MISSING_MESSAGE');
282
+ }
283
+ const trimmed_message = message_text.trim();
284
+ if (trimmed_message === '') {
285
+ logger.error('[hazo_chat/messages POST] Empty message_text');
286
+ return createErrorResponse('message_text cannot be empty or whitespace-only', 400, 'EMPTY_MESSAGE');
287
+ }
288
+ if (trimmed_message.length > MAX_MESSAGE_LENGTH) {
289
+ logger.error('[hazo_chat/messages POST] Message too long:', { length: trimmed_message.length });
290
+ return createErrorResponse(`Message exceeds maximum length of ${MAX_MESSAGE_LENGTH} characters`, 400, 'MESSAGE_TOO_LONG');
291
+ }
292
+ // Validate reference_id length
293
+ if (reference_id && reference_id.length > MAX_REFERENCE_ID_LENGTH) {
294
+ return createErrorResponse(`reference_id exceeds maximum length of ${MAX_REFERENCE_ID_LENGTH}`, 400, 'INVALID_REFERENCE_ID');
295
+ }
296
+ // Validate reference_type length
297
+ if (reference_type && reference_type.length > MAX_REFERENCE_TYPE_LENGTH) {
298
+ return createErrorResponse(`reference_type exceeds maximum length of ${MAX_REFERENCE_TYPE_LENGTH}`, 400, 'INVALID_REFERENCE_TYPE');
299
+ }
300
+ // Create CRUD service (hazoConnect already obtained above)
301
+ const chatService = createCrudService(hazoConnect, 'hazo_chat');
302
+ // Generate message ID and timestamps
303
+ const message_id = generateUUID();
304
+ const now = new Date().toISOString();
305
+ // Create message record
306
+ const message_record = {
307
+ id: message_id,
308
+ reference_id: reference_id || '',
309
+ reference_type: reference_type || 'chat',
310
+ sender_user_id,
311
+ chat_group_id,
312
+ message_text: trimmed_message,
313
+ reference_list: null,
314
+ read_at: null,
315
+ deleted_at: null,
316
+ created_at: now,
317
+ changed_at: now,
318
+ };
319
+ logger.info('[hazo_chat/messages POST] Saving message:', {
320
+ id: message_id,
321
+ sender_user_id,
322
+ chat_group_id,
323
+ reference_id: reference_id || '',
324
+ reference_type: reference_type || 'chat',
325
+ message_length: trimmed_message.length,
326
+ });
327
+ // Save to database
328
+ try {
329
+ await chatService.insert(message_record);
330
+ }
331
+ catch (dbError) {
332
+ logger.error('[hazo_chat/messages POST] Database error:', { dbError });
333
+ throw dbError;
334
+ }
335
+ logger.info('[hazo_chat/messages POST] Message saved successfully:', { message_id });
336
+ return NextResponse.json({
337
+ success: true,
338
+ message: {
339
+ id: message_id,
340
+ sender_user_id,
341
+ chat_group_id,
342
+ reference_id: reference_id || '',
343
+ reference_type: reference_type || 'chat',
344
+ message_text: trimmed_message,
345
+ reference_list: null,
346
+ read_at: null,
347
+ deleted_at: null,
348
+ created_at: now,
349
+ changed_at: now,
350
+ },
351
+ });
352
+ }
353
+ catch (error) {
354
+ const error_message = error instanceof Error ? error.message : 'Unknown error';
355
+ logger.error('[hazo_chat/messages POST] Error:', { error_message, error });
356
+ return createErrorResponse('Failed to save message', 500, 'INTERNAL_ERROR');
357
+ }
358
+ }
359
+ return { GET, POST };
360
+ }
361
+ /**
362
+ * Creates a PATCH handler for marking a message as read
363
+ *
364
+ * This handler should be used in a Next.js API route like:
365
+ * /api/hazo_chat/messages/[id]/read/route.ts
366
+ *
367
+ * @param options - Configuration options
368
+ * @returns PATCH handler function
369
+ */
370
+ export function createMarkAsReadHandler(options) {
371
+ const { getHazoConnect, getLogger, getUserIdFromRequest } = options;
372
+ const logger = getLogger();
373
+ /**
374
+ * PATCH handler - Mark a message as read
375
+ *
376
+ * Route params:
377
+ * - id (required): The message ID to mark as read
378
+ *
379
+ * Note: In Next.js 13+ App Router, params may be a Promise
380
+ */
381
+ async function PATCH(request, context) {
382
+ try {
383
+ // Get current user ID
384
+ const current_user_id = getUserIdFromRequest
385
+ ? await getUserIdFromRequest(request)
386
+ : await defaultGetUserIdFromRequest();
387
+ if (!current_user_id) {
388
+ logger.error('[hazo_chat/messages/[id]/read PATCH] No user ID - not authenticated');
389
+ return NextResponse.json({ success: false, error: 'User not authenticated' }, { status: 401 });
390
+ }
391
+ // Handle params as Promise (Next.js 15+) or direct object (Next.js 13-14)
392
+ const params = context.params instanceof Promise ? await context.params : context.params;
393
+ const message_id = params.id;
394
+ if (!message_id) {
395
+ logger.error('[hazo_chat/messages/[id]/read PATCH] Missing message ID');
396
+ return NextResponse.json({ success: false, error: 'Message ID is required' }, { status: 400 });
397
+ }
398
+ logger.info('[hazo_chat/messages/[id]/read PATCH] Marking message as read:', {
399
+ message_id,
400
+ current_user_id,
401
+ });
402
+ // Get hazo_connect instance and create CRUD service
403
+ const hazoConnect = getHazoConnect();
404
+ const chatService = createCrudService(hazoConnect, 'hazo_chat');
405
+ // First, fetch the message to verify ownership
406
+ let message = null;
407
+ try {
408
+ const messages = await chatService.list((qb) => qb.select('*').where('id', 'eq', message_id));
409
+ message = messages[0] || null;
410
+ }
411
+ catch (dbError) {
412
+ logger.error('[hazo_chat/messages/[id]/read PATCH] Database error fetching message:', { dbError });
413
+ throw dbError;
414
+ }
415
+ if (!message) {
416
+ logger.error('[hazo_chat/messages/[id]/read PATCH] Message not found:', { message_id });
417
+ return NextResponse.json({ success: false, error: 'Message not found' }, { status: 404 });
418
+ }
419
+ // Verify that the current user is a member of the chat group
420
+ const membership = await verifyGroupMembership(hazoConnect, current_user_id, message.chat_group_id, logger);
421
+ if (!membership) {
422
+ logger.error('[hazo_chat/messages/[id]/read PATCH] User is not a member of chat group:', {
423
+ message_id,
424
+ current_user_id,
425
+ chat_group_id: message.chat_group_id,
426
+ });
427
+ return NextResponse.json({ success: false, error: 'Unauthorized - not a member of this chat group' }, { status: 403 });
428
+ }
429
+ // Cannot mark your own messages as read
430
+ if (message.sender_user_id === current_user_id) {
431
+ logger.error('[hazo_chat/messages/[id]/read PATCH] User cannot mark own message as read:', {
432
+ message_id,
433
+ current_user_id,
434
+ });
435
+ return NextResponse.json({ success: false, error: 'Cannot mark your own messages as read' }, { status: 400 });
436
+ }
437
+ // Don't update if already read
438
+ if (message.read_at) {
439
+ logger.info('[hazo_chat/messages/[id]/read PATCH] Message already read:', { message_id });
440
+ return NextResponse.json({
441
+ success: true,
442
+ message: {
443
+ ...message,
444
+ read_at: message.read_at,
445
+ },
446
+ });
447
+ }
448
+ // Update the read_at timestamp
449
+ // Use SQLite admin service's updateRows method for reliable updates
450
+ const now = new Date().toISOString();
451
+ try {
452
+ // Use the SQLite admin service which has updateRows method
453
+ const sqliteService = getSqliteAdminService();
454
+ const updated_rows = await sqliteService.updateRows('hazo_chat', { id: message_id }, // criteria: update where id matches
455
+ { read_at: now, changed_at: now } // data to update
456
+ );
457
+ if (updated_rows.length === 0) {
458
+ logger.warn('[hazo_chat/messages/[id]/read PATCH] No rows updated - message may not exist:', { message_id });
459
+ // Don't throw error, just log warning - message might have been deleted
460
+ }
461
+ else {
462
+ logger.info('[hazo_chat/messages/[id]/read PATCH] Successfully updated', { rows: updated_rows.length });
463
+ }
464
+ }
465
+ catch (dbError) {
466
+ logger.error('[hazo_chat/messages/[id]/read PATCH] Database error updating message:', { dbError });
467
+ throw dbError;
468
+ }
469
+ logger.info('[hazo_chat/messages/[id]/read PATCH] Message marked as read successfully:', { message_id });
470
+ return NextResponse.json({
471
+ success: true,
472
+ message: {
473
+ ...message,
474
+ read_at: now,
475
+ changed_at: now,
476
+ },
477
+ });
478
+ }
479
+ catch (error) {
480
+ const error_message = error instanceof Error ? error.message : 'Unknown error';
481
+ logger.error('[hazo_chat/messages/[id]/read PATCH] Error:', { error_message, error });
482
+ return NextResponse.json({ success: false, error: 'Failed to mark message as read' }, { status: 500 });
483
+ }
484
+ }
485
+ return { PATCH };
486
+ }
487
+ /**
488
+ * Creates a DELETE handler for soft-deleting a message
489
+ *
490
+ * This handler should be used in a Next.js API route like:
491
+ * /api/hazo_chat/messages/[id]/route.ts
492
+ *
493
+ * @example
494
+ * ```typescript
495
+ * // app/api/hazo_chat/messages/[id]/route.ts
496
+ * import { createDeleteHandler } from 'hazo_chat/api';
497
+ * import { getHazoConnectSingleton } from 'hazo_connect/nextjs/setup';
498
+ *
499
+ * export const dynamic = 'force-dynamic';
500
+ *
501
+ * const { DELETE } = createDeleteHandler({
502
+ * getHazoConnect: () => getHazoConnectSingleton()
503
+ * });
504
+ *
505
+ * export { DELETE };
506
+ * ```
507
+ *
508
+ * @param options - Configuration options
509
+ * @returns DELETE handler function
510
+ */
511
+ export function createDeleteHandler(options) {
512
+ const { getHazoConnect, getLogger, getUserIdFromRequest } = options;
513
+ const logger = getLogger();
514
+ /**
515
+ * DELETE handler - Soft delete a message
516
+ *
517
+ * Route params:
518
+ * - id (required): The message ID to delete
519
+ *
520
+ * Note: This performs a soft delete by setting deleted_at timestamp.
521
+ * Only the sender can delete their own messages.
522
+ */
523
+ async function DELETE(request, context) {
524
+ try {
525
+ // Get current user ID
526
+ const current_user_id = getUserIdFromRequest
527
+ ? await getUserIdFromRequest(request)
528
+ : await defaultGetUserIdFromRequest();
529
+ if (!current_user_id) {
530
+ logger.error('[hazo_chat/messages/[id] DELETE] No user ID - not authenticated');
531
+ return createErrorResponse('User not authenticated', 401, 'UNAUTHENTICATED');
532
+ }
533
+ // Handle params as Promise (Next.js 15+) or direct object (Next.js 13-14)
534
+ const params = context.params instanceof Promise ? await context.params : context.params;
535
+ const message_id = params.id;
536
+ if (!message_id) {
537
+ logger.error('[hazo_chat/messages/[id] DELETE] Missing message ID');
538
+ return createErrorResponse('Message ID is required', 400, 'MISSING_MESSAGE_ID');
539
+ }
540
+ logger.info('[hazo_chat/messages/[id] DELETE] Deleting message:', {
541
+ message_id,
542
+ current_user_id,
543
+ });
544
+ // Get hazo_connect instance and create CRUD service
545
+ const hazoConnect = getHazoConnect();
546
+ const chatService = createCrudService(hazoConnect, 'hazo_chat');
547
+ // Fetch the message to verify ownership
548
+ let message = null;
549
+ try {
550
+ const messages = await chatService.list((qb) => qb.select('*').where('id', 'eq', message_id));
551
+ message = messages[0] || null;
552
+ }
553
+ catch (dbError) {
554
+ logger.error('[hazo_chat/messages/[id] DELETE] Database error fetching message:', { dbError });
555
+ throw dbError;
556
+ }
557
+ if (!message) {
558
+ logger.error('[hazo_chat/messages/[id] DELETE] Message not found:', { message_id });
559
+ return createErrorResponse('Message not found', 404, 'MESSAGE_NOT_FOUND');
560
+ }
561
+ // Verify that the current user is a member of the chat group
562
+ const membership = await verifyGroupMembership(hazoConnect, current_user_id, message.chat_group_id, logger);
563
+ if (!membership) {
564
+ logger.error('[hazo_chat/messages/[id] DELETE] User is not a member of chat group:', {
565
+ message_id,
566
+ current_user_id,
567
+ chat_group_id: message.chat_group_id,
568
+ });
569
+ return createErrorResponse('Unauthorized - not a member of this chat group', 403, 'FORBIDDEN');
570
+ }
571
+ // Verify that the current user is the sender (only senders can delete their messages)
572
+ if (message.sender_user_id !== current_user_id) {
573
+ logger.error('[hazo_chat/messages/[id] DELETE] User is not the sender:', {
574
+ message_id,
575
+ current_user_id,
576
+ sender_user_id: message.sender_user_id,
577
+ });
578
+ return createErrorResponse('Unauthorized - only the sender can delete their messages', 403, 'UNAUTHORIZED');
579
+ }
580
+ // Check if already deleted
581
+ if (message.deleted_at) {
582
+ logger.info('[hazo_chat/messages/[id] DELETE] Message already deleted:', { message_id });
583
+ return NextResponse.json({
584
+ success: true,
585
+ message: {
586
+ ...message,
587
+ message_text: null,
588
+ },
589
+ });
590
+ }
591
+ // Soft delete: set deleted_at timestamp and clear message_text
592
+ const now = new Date().toISOString();
593
+ try {
594
+ const sqliteService = getSqliteAdminService();
595
+ const updated_rows = await sqliteService.updateRows('hazo_chat', { id: message_id }, { deleted_at: now, message_text: null, changed_at: now });
596
+ if (updated_rows.length === 0) {
597
+ logger.warn('[hazo_chat/messages/[id] DELETE] No rows updated - message may not exist:', { message_id });
598
+ }
599
+ else {
600
+ logger.info('[hazo_chat/messages/[id] DELETE] Successfully deleted', { rows: updated_rows.length });
601
+ }
602
+ }
603
+ catch (dbError) {
604
+ logger.error('[hazo_chat/messages/[id] DELETE] Database error deleting message:', { dbError });
605
+ throw dbError;
606
+ }
607
+ logger.info('[hazo_chat/messages/[id] DELETE] Message deleted successfully:', { message_id });
608
+ return NextResponse.json({
609
+ success: true,
610
+ message: {
611
+ ...message,
612
+ deleted_at: now,
613
+ message_text: null,
614
+ changed_at: now,
615
+ },
616
+ });
617
+ }
618
+ catch (error) {
619
+ const error_message = error instanceof Error ? error.message : 'Unknown error';
620
+ logger.error('[hazo_chat/messages/[id] DELETE] Error:', { error_message, error });
621
+ return createErrorResponse('Failed to delete message', 500, 'INTERNAL_ERROR');
622
+ }
623
+ }
624
+ return { DELETE };
625
+ }
626
+ //# sourceMappingURL=messages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/api/messages.ts"],"names":[],"mappings":"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"}