114 lines
3.2 KiB
JavaScript
114 lines
3.2 KiB
JavaScript
'use strict'
|
|
|
|
const { query, queryOne } = require('../database/postgres')
|
|
|
|
class DirectMessage {
|
|
/**
|
|
* Enviar DM para um colaborador
|
|
*/
|
|
static async send(tenantId, fromAccountId, toAccountId, content) {
|
|
if (!fromAccountId || !toAccountId || !content?.trim()) {
|
|
throw new Error('fromAccountId, toAccountId e content obrigatórios')
|
|
}
|
|
const row = await queryOne(
|
|
`INSERT INTO direct_messages (tenant_id, from_account, to_account, content, created_at)
|
|
VALUES ($1, $2, $3, $4, NOW())
|
|
RETURNING id, from_account, to_account, content, created_at`,
|
|
[tenantId, fromAccountId, toAccountId, content]
|
|
)
|
|
return row
|
|
}
|
|
|
|
/**
|
|
* Listar histórico de DMs entre dois colaboradores (conversação)
|
|
*/
|
|
static async getConversation(tenantId, accountId1, accountId2, limit = 50) {
|
|
const msgs = await query(
|
|
`SELECT
|
|
id, from_account, to_account, content, read_at, created_at
|
|
FROM direct_messages
|
|
WHERE tenant_id = $1
|
|
AND ((from_account = $2 AND to_account = $3)
|
|
OR (from_account = $3 AND to_account = $2))
|
|
ORDER BY created_at DESC
|
|
LIMIT $4`,
|
|
[tenantId, accountId1, accountId2, limit]
|
|
)
|
|
return msgs.reverse() // mais antigos primeiro
|
|
}
|
|
|
|
/**
|
|
* Listar últimas DMs por colaborador (preview de conversas)
|
|
* Retorna a última mensagem em cada conversação
|
|
*/
|
|
static async getLastMessagesByAccount(tenantId, accountId) {
|
|
const msgs = await query(
|
|
`SELECT DISTINCT ON (other_account)
|
|
id, from_account, to_account, content, read_at, created_at,
|
|
CASE
|
|
WHEN from_account = $2 THEN to_account
|
|
ELSE from_account
|
|
END AS other_account
|
|
FROM direct_messages
|
|
WHERE tenant_id = $1
|
|
AND (from_account = $2 OR to_account = $2)
|
|
ORDER BY other_account, created_at DESC`,
|
|
[tenantId, accountId]
|
|
)
|
|
return msgs
|
|
}
|
|
|
|
/**
|
|
* Contar DMs não lidas para um colaborador
|
|
*/
|
|
static async getUnreadCount(tenantId, accountId) {
|
|
const row = await queryOne(
|
|
`SELECT COUNT(*) as count
|
|
FROM direct_messages
|
|
WHERE tenant_id = $1
|
|
AND to_account = $2
|
|
AND read_at IS NULL`,
|
|
[tenantId, accountId]
|
|
)
|
|
return Number(row?.count ?? 0)
|
|
}
|
|
|
|
/**
|
|
* Marcar DMs como lidas
|
|
*/
|
|
static async markAsRead(tenantId, accountId, fromAccountId) {
|
|
await query(
|
|
`UPDATE direct_messages
|
|
SET read_at = NOW()
|
|
WHERE tenant_id = $1
|
|
AND to_account = $2
|
|
AND from_account = $3
|
|
AND read_at IS NULL`,
|
|
[tenantId, accountId, fromAccountId]
|
|
)
|
|
}
|
|
|
|
/**
|
|
* Contar DMs não lidas por remetente
|
|
* Útil para badges de quantas DMs cada pessoa tem
|
|
*/
|
|
static async getUnreadCountByContact(tenantId, accountId) {
|
|
const rows = await query(
|
|
`SELECT from_account, COUNT(*) as unread_count
|
|
FROM direct_messages
|
|
WHERE tenant_id = $1
|
|
AND to_account = $2
|
|
AND read_at IS NULL
|
|
GROUP BY from_account`,
|
|
[tenantId, accountId]
|
|
)
|
|
const map = {}
|
|
rows.forEach(r => {
|
|
map[r.from_account] = Number(r.unread_count)
|
|
})
|
|
return map
|
|
}
|
|
}
|
|
|
|
module.exports = DirectMessage
|