This commit is contained in:
2026-06-23 10:07:36 +02:00
5 changed files with 32 additions and 2 deletions
@@ -0,0 +1,4 @@
ALTER TABLE notifications ADD COLUMN IF NOT EXISTS context_id UUID;
ALTER TABLE notifications ADD COLUMN IF NOT EXISTS context_type VARCHAR(50);
CREATE INDEX IF NOT EXISTS idx_notifications_context ON notifications(context_type, context_id) WHERE context_type IS NOT NULL;
+3
View File
@@ -34,5 +34,8 @@ BEGIN;
\echo '=== Running 009_settings.sql (Company Settings + User Preferences) ===' \echo '=== Running 009_settings.sql (Company Settings + User Preferences) ==='
\i 009_settings.sql \i 009_settings.sql
\echo '=== Running 010_chat_notifications.sql (Chat Message Notifications) ==='
\i 010_chat_notifications.sql
\echo '=== Migration Complete ===' \echo '=== Migration Complete ==='
COMMIT; COMMIT;
@@ -116,13 +116,28 @@ export async function POST(
) )
const msg = result.rows[0] const msg = result.rows[0]
const senderName = `${user.firstName} ${user.lastName}`
const otherResult = await query(
`SELECT user_id FROM conversation_participants
WHERE conversation_id = $1 AND user_id != $2`,
[id, user.id],
)
for (const row of otherResult.rows) {
await query(
`INSERT INTO notifications (user_id, type, title, description, link, context_id, context_type)
VALUES ($1, 'chat_message', 'New Message', $2, '/chats', $3, 'conversation')`,
[row.user_id, `${senderName} sent a message`, id],
)
}
return NextResponse.json({ return NextResponse.json({
message: { message: {
id: msg.id, id: msg.id,
conversationId: id, conversationId: id,
senderId: user.id, senderId: user.id,
senderName: `${user.firstName} ${user.lastName}`, senderName,
senderAvatar: user.avatar, senderAvatar: user.avatar,
content: content.trim(), content: content.trim(),
timestamp: formatTime(new Date(msg.created_at)), timestamp: formatTime(new Date(msg.created_at)),
@@ -19,6 +19,12 @@ export async function POST(
[id, user.id], [id, user.id],
) )
await query(
`UPDATE notifications SET is_read = TRUE
WHERE user_id = $1 AND context_type = 'conversation' AND context_id = $2 AND is_read = FALSE`,
[user.id, id],
)
return NextResponse.json({ success: true }) return NextResponse.json({ success: true })
} catch (error) { } catch (error) {
console.error("Mark read error:", error) console.error("Mark read error:", error)
+3 -1
View File
@@ -8,7 +8,7 @@ export async function GET() {
if (!user) return NextResponse.json({ error: "Unauthorized" }, { status: 401 }) if (!user) return NextResponse.json({ error: "Unauthorized" }, { status: 401 })
const result = await query( const result = await query(
`SELECT id, type, title, description, link, is_read, created_at `SELECT id, type, title, description, link, is_read, created_at, context_id, context_type
FROM notifications FROM notifications
WHERE user_id = $1 WHERE user_id = $1
ORDER BY created_at DESC ORDER BY created_at DESC
@@ -24,6 +24,8 @@ export async function GET() {
link: r.link, link: r.link,
read: r.is_read, read: r.is_read,
timestamp: r.created_at, timestamp: r.created_at,
contextId: r.context_id,
contextType: r.context_type,
})) }))
const unreadResult = await query( const unreadResult = await query(