feat: add case creation endpoint and auto-title from first message
POST /api/cases lets the frontend actually create a new dava dosyası (no working "Yeni Dosya" flow existed before). chatMessage now generates a short title from a case's first message (like Claude/ ChatGPT auto-titling) and renames the case, returned as `newTitle`.
This commit is contained in:
@@ -2,6 +2,40 @@ import { Response } from 'express';
|
||||
import { supabase } from '../lib/supabase';
|
||||
import { AuthenticatedRequest } from '../middleware/auth';
|
||||
|
||||
// Bir dosyanın ilk mesajından kısa bir başlık üretir (Claude/ChatGPT'nin yaptığı gibi).
|
||||
// Başarısız olursa null döner — çağıran taraf bu durumda "Yeni Sohbet" başlığını korur,
|
||||
// asıl sohbet cevabını etkilemez.
|
||||
async function generateCaseTitle(firstMessage: string): Promise<string | null> {
|
||||
try {
|
||||
const aiModel = process.env.AI_MODEL || 'mizan-fixed';
|
||||
const runpodUrl = process.env.RUNPOD_API_BASE_URL || 'https://q190env94stwis-11434.proxy.runpod.net';
|
||||
const response = await fetch(`${runpodUrl}/api/chat`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
model: aiModel,
|
||||
messages: [
|
||||
{
|
||||
role: 'system',
|
||||
content: 'Kullanıcının hukuki sorusunu en fazla 5 kelimelik, kısa ve açıklayıcı bir Türkçe başlığa çevir. Sadece başlığı yaz; tırnak işareti, noktalama veya başka açıklama ekleme.'
|
||||
},
|
||||
{ role: 'user', content: firstMessage.slice(0, 2000) },
|
||||
],
|
||||
think: false,
|
||||
stream: false,
|
||||
}),
|
||||
});
|
||||
if (!response.ok) return null;
|
||||
const data = await response.json();
|
||||
const raw = (data.message?.content || '').toString().trim().replace(/^["'“”]+|["'“”]+$/g, '');
|
||||
if (!raw) return null;
|
||||
return raw.slice(0, 80);
|
||||
} catch (err) {
|
||||
console.error('Generate Case Title Error:', err);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export const deleteChatHistory = async (req: AuthenticatedRequest, res: Response) => {
|
||||
try {
|
||||
const { caseId } = req.params;
|
||||
@@ -139,7 +173,25 @@ export const chatMessage = async (req: AuthenticatedRequest, res: Response) => {
|
||||
.select().single();
|
||||
if (aiMsgError) throw aiMsgError;
|
||||
|
||||
res.json({ message: aiMessage });
|
||||
// Bu dosyanın ilk mesajıysa (kullanıcının bu isteklen önce hiç mesajı yoktu),
|
||||
// ilk mesajdan kısa bir başlık üretip dosyayı yeniden adlandır.
|
||||
let newTitle: string | null = null;
|
||||
const isFirstMessage = !pastMessages || pastMessages.length <= 1;
|
||||
if (isFirstMessage) {
|
||||
newTitle = await generateCaseTitle(content);
|
||||
if (newTitle) {
|
||||
const { error: titleError } = await supabase
|
||||
.from('cases')
|
||||
.update({ title: newTitle })
|
||||
.eq('id', caseId);
|
||||
if (titleError) {
|
||||
console.error('Case Title Update Error:', titleError);
|
||||
newTitle = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
res.json({ message: aiMessage, newTitle });
|
||||
} catch (error: any) {
|
||||
console.error('Chat Error:', error);
|
||||
res.status(500).json({ error: error.message || 'Internal Server Error' });
|
||||
|
||||
Reference in New Issue
Block a user