| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- import { Conversation } from "../models/Conversation.model.js";
- import { Message } from "../models/Message.model.js";
- export async function listConversations(userId, { limit = 50, offset = 0 } = {}) {
- const safeLimit = Math.min(Number(limit) || 50, 100);
- const safeOffset = Math.max(Number(offset) || 0, 0);
- return Conversation.query()
- .where({ UsuarioId: userId })
- .orderBy("UpdatedAt", "desc")
- .limit(safeLimit)
- .offset(safeOffset)
- .select("Id", "Title", "CreatedAt", "UpdatedAt")
- .select(Conversation.relatedQuery("messages").count().as("MessageCount"));
- }
- export async function createConversation(userId, title = "Nova conversa") {
- const conv = await Conversation.query().insert({
- UsuarioId: userId,
- Title: String(title).slice(0, 255)
- });
- return { id: conv.Id, title };
- }
- export async function getConversationMessages(conversationId, userId) {
- const conv = await Conversation.query().findOne({ Id: conversationId, UsuarioId: userId });
- if (!conv) return null;
- const msgs = await Message.query()
- .where({ ConversationId: conversationId })
- .orderBy("SentAt", "asc")
- .select("Id", "Role", "Content", "Sources", "SentAt");
- return msgs;
- }
- export async function verifyConversationOwner(conversationId, userId) {
- const conv = await Conversation.query().findOne({ Id: conversationId, UsuarioId: userId });
- return Boolean(conv);
- }
- export async function getRecentMessages(conversationId, userId, limit = 12) {
- if (userId) {
- const owns = await verifyConversationOwner(conversationId, userId);
- if (!owns) return [];
- }
- const msgs = await Message.query()
- .where({ ConversationId: conversationId })
- .orderBy("SentAt", "desc")
- .limit(limit)
- .select("Role", "Content");
- return msgs.reverse();
- }
- export async function addMessage(conversationId, { role, content, sources = null }) {
- await Conversation.transaction(async (trx) => {
- await Message.query(trx).insert({
- ConversationId: conversationId,
- Role: role,
- Content: content,
- Sources: sources ? JSON.stringify(sources) : null
- });
- await Conversation.query(trx)
- .patch({ UpdatedAt: trx.fn.now() })
- .where({ Id: conversationId });
- });
- }
- export async function updateConversationTitle(conversationId, userId, title) {
- await Conversation.query()
- .patch({ Title: String(title).slice(0, 255), UpdatedAt: Conversation.knex().fn.now() })
- .where({ Id: conversationId, UsuarioId: userId });
- }
- export async function deleteConversation(conversationId, userId) {
- await Conversation.query().delete().where({ Id: conversationId, UsuarioId: userId });
- }
- export async function getConversationForExport(conversationId, userId) {
- const conv = await Conversation.query().findOne({ Id: conversationId, UsuarioId: userId });
- if (!conv) return null;
- const msgs = await Message.query()
- .where({ ConversationId: conversationId })
- .orderBy("SentAt", "asc")
- .select("Role", "Content", "SentAt");
- return { title: conv.Title, createdAt: conv.CreatedAt, messages: msgs };
- }
- export async function exportConversationAsMarkdown(conversationId, userId) {
- const data = await getConversationForExport(conversationId, userId);
- if (!data) return null;
- const date = new Date(data.createdAt).toLocaleDateString("pt-BR", {
- day: "2-digit", month: "2-digit", year: "numeric"
- });
- const lines = [`# ${data.title}`, `*Exportado em ${date}*`, ""];
- for (const msg of data.messages) {
- const author = msg.Role === "user" ? "**Você**" : "**Oráculo**";
- lines.push(`${author}:`, "", msg.Content, "");
- lines.push("---", "");
- }
- return lines.join("\n");
- }
|