Added Helpdesk

This commit is contained in:
2025-10-27 17:40:43 +01:00
parent 8ff63fadec
commit bbd5bbab9b
6 changed files with 624 additions and 0 deletions

View File

@@ -0,0 +1,38 @@
// modules/helpdesk/helpdesk.contact.service.ts
import { FastifyInstance } from 'fastify'
export async function getOrCreateContact(
server: FastifyInstance,
tenant_id: number,
{ email, phone, display_name, customer_id, contact_id }: { email?: string; phone?: string; display_name?: string; customer_id?: number; contact_id?: number }
) {
if (!email && !phone) throw new Error('Contact must have at least an email or phone')
// Bestehenden Kontakt prüfen
const { data: existing, error: findError } = await server.supabase
.from('helpdesk_contacts')
.select('*')
.eq('tenant_id', tenant_id)
.or(`email.eq.${email || ''},phone.eq.${phone || ''}`)
.maybeSingle()
if (findError) throw findError
if (existing) return existing
// Anlegen
const { data: created, error: insertError } = await server.supabase
.from('helpdesk_contacts')
.insert({
tenant_id,
email,
phone,
display_name,
customer_id,
contact_id
})
.select()
.single()
if (insertError) throw insertError
return created
}

View File

@@ -0,0 +1,81 @@
// modules/helpdesk/helpdesk.conversation.service.ts
import { FastifyInstance } from 'fastify'
import { getOrCreateContact } from './helpdesk.contact.service.js'
export async function createConversation(
server: FastifyInstance,
{
tenant_id,
contact,
channel_instance_id,
subject,
customer_id = null,
contact_person_id = null
}: {
tenant_id: number
contact: { email?: string; phone?: string; display_name?: string }
channel_instance_id: string
subject?: string,
customer_id?: number,
contact_person_id?: number
}
) {
const contactRecord = await getOrCreateContact(server, tenant_id, contact)
const { data, error } = await server.supabase
.from('helpdesk_conversations')
.insert({
tenant_id,
contact_id: contactRecord.id,
channel_instance_id,
subject: subject || null,
status: 'open',
created_at: new Date().toISOString(),
customer_id,
contact_person_id
})
.select()
.single()
if (error) throw error
return data
}
export async function getConversations(
server: FastifyInstance,
tenant_id: number,
opts?: { status?: string; limit?: number }
) {
const { status, limit = 50 } = opts || {}
let query = server.supabase.from('helpdesk_conversations').select('*, customer_id(*)').eq('tenant_id', tenant_id)
if (status) query = query.eq('status', status)
query = query.order('last_message_at', { ascending: false }).limit(limit)
const { data, error } = await query
if (error) throw error
return {
...data,
customer: data.customer_id
}
}
export async function updateConversationStatus(
server: FastifyInstance,
conversation_id: string,
status: string
) {
const valid = ['open', 'in_progress', 'waiting_for_customer', 'answered', 'closed']
if (!valid.includes(status)) throw new Error('Invalid status')
const { data, error } = await server.supabase
.from('helpdesk_conversations')
.update({ status })
.eq('id', conversation_id)
.select()
.single()
if (error) throw error
return data
}

View File

@@ -0,0 +1,58 @@
// modules/helpdesk/helpdesk.message.service.ts
import { FastifyInstance } from 'fastify'
export async function addMessage(
server: FastifyInstance,
{
tenant_id,
conversation_id,
author_user_id = null,
direction = 'incoming',
payload,
raw_meta = null,
}: {
tenant_id: number
conversation_id: string
author_user_id?: string | null
direction?: 'incoming' | 'outgoing' | 'internal' | 'system'
payload: any
raw_meta?: any
}
) {
if (!payload?.text) throw new Error('Message payload requires text content')
const { data: message, error } = await server.supabase
.from('helpdesk_messages')
.insert({
tenant_id,
conversation_id,
author_user_id,
direction,
payload,
raw_meta,
created_at: new Date().toISOString(),
})
.select()
.single()
if (error) throw error
// Letzte Nachricht aktualisieren
await server.supabase
.from('helpdesk_conversations')
.update({ last_message_at: new Date().toISOString() })
.eq('id', conversation_id)
return message
}
export async function getMessages(server: FastifyInstance, conversation_id: string) {
const { data, error } = await server.supabase
.from('helpdesk_messages')
.select('*')
.eq('conversation_id', conversation_id)
.order('created_at', { ascending: true })
if (error) throw error
return data
}