import * as contactService from '../services/contact.service.js'; import { discoverContactsFromJMAP, getJmapConfigFromAccount } from '../services/jmap/index.js'; import * as emailAccountService from '../services/email-account.service.js'; /** * Get all contacts for an email account * GET /api/contacts?accountId=xxx (required) */ export const getContacts = async (req, res, next) => { try { const userId = req.userId; const { accountId } = req.query; if (!accountId) { return res.status(400).json({ success: false, error: { message: 'accountId je povinný parameter', statusCode: 400, }, }); } // Verify user has access to this email account await emailAccountService.getEmailAccountById(accountId, userId); // Get contacts for email account const contacts = await contactService.getContactsForEmailAccount(accountId); res.status(200).json({ success: true, count: contacts.length, data: contacts, }); } catch (error) { next(error); } }; /** * Discover potential contacts from JMAP (email senders) * GET /api/contacts/discover?accountId=xxx&search=query&limit=50 */ export const discoverContacts = async (req, res, next) => { try { const userId = req.userId; const { accountId, search = '', limit = 50 } = req.query; // Get email account (or primary if not specified) let emailAccount; if (accountId) { emailAccount = await emailAccountService.getEmailAccountWithCredentials(accountId, userId); } else { const primaryAccount = await emailAccountService.getPrimaryEmailAccount(userId); if (!primaryAccount) { return res.status(400).json({ success: false, error: { message: 'Najprv musíš pripojiť email účet v Profile', statusCode: 400, }, }); } emailAccount = await emailAccountService.getEmailAccountWithCredentials(primaryAccount.id, userId); } const jmapConfig = getJmapConfigFromAccount(emailAccount); const potentialContacts = await discoverContactsFromJMAP( jmapConfig, emailAccount.id, // emailAccountId search, parseInt(limit) ); res.status(200).json({ success: true, count: potentialContacts.length, data: potentialContacts, }); } catch (error) { next(error); } }; /** * Add a new contact * POST /api/contacts * Body: { email, name, notes, accountId } */ export const addContact = async (req, res, next) => { try { const userId = req.userId; const { email, name = '', notes = '', accountId } = req.body; if (!email) { return res.status(400).json({ success: false, error: { message: 'Email je povinný', statusCode: 400, }, }); } // Get email account (or primary if not specified) let emailAccount; if (accountId) { emailAccount = await emailAccountService.getEmailAccountWithCredentials(accountId, userId); } else { const primaryAccount = await emailAccountService.getPrimaryEmailAccount(userId); if (!primaryAccount) { return res.status(400).json({ success: false, error: { message: 'Najprv musíš pripojiť email účet v Profile', statusCode: 400, }, }); } emailAccount = await emailAccountService.getEmailAccountWithCredentials(primaryAccount.id, userId); } const jmapConfig = getJmapConfigFromAccount(emailAccount); const contact = await contactService.addContact( emailAccount.id, jmapConfig, email, name, notes, userId // addedByUserId ); res.status(201).json({ success: true, data: contact, message: 'Kontakt pridaný a emaily synchronizované', }); } catch (error) { next(error); } }; /** * Remove a contact * DELETE /api/contacts/:contactId?accountId=xxx */ export const removeContact = async (req, res, next) => { try { const userId = req.userId; const { contactId } = req.params; const { accountId } = req.query; if (!accountId) { return res.status(400).json({ success: false, error: { message: 'accountId je povinný parameter', statusCode: 400, }, }); } // Verify user has access to this email account await emailAccountService.getEmailAccountById(accountId, userId); const result = await contactService.removeContact(contactId, accountId); res.status(200).json({ success: true, message: result.message, }); } catch (error) { next(error); } }; /** * Update a contact * PATCH /api/contacts/:contactId?accountId=xxx */ export const updateContact = async (req, res, next) => { try { const userId = req.userId; const { contactId } = req.params; const { accountId } = req.query; const { name, notes } = req.body; if (!accountId) { return res.status(400).json({ success: false, error: { message: 'accountId je povinný parameter', statusCode: 400, }, }); } // Verify user has access to this email account await emailAccountService.getEmailAccountById(accountId, userId); const updated = await contactService.updateContact(contactId, accountId, { name, notes }); res.status(200).json({ success: true, data: updated, message: 'Kontakt aktualizovaný', }); } catch (error) { next(error); } }; /** * Link company to contact * POST /api/contacts/:contactId/link-company?accountId=xxx * Body: { companyId } */ export const linkCompanyToContact = async (req, res, next) => { try { const userId = req.userId; const { contactId } = req.params; const { accountId } = req.query; const { companyId } = req.body; if (!accountId) { return res.status(400).json({ success: false, error: { message: 'accountId je povinný parameter', statusCode: 400, }, }); } if (!companyId) { return res.status(400).json({ success: false, error: { message: 'companyId je povinný', statusCode: 400, }, }); } // Verify user has access to this email account await emailAccountService.getEmailAccountById(accountId, userId); const updated = await contactService.linkCompanyToContact(contactId, accountId, companyId); res.status(200).json({ success: true, data: updated, message: 'Firma bola linknutá ku kontaktu', }); } catch (error) { next(error); } }; /** * Unlink company from contact * POST /api/contacts/:contactId/unlink-company?accountId=xxx */ export const unlinkCompanyFromContact = async (req, res, next) => { try { const userId = req.userId; const { contactId } = req.params; const { accountId } = req.query; if (!accountId) { return res.status(400).json({ success: false, error: { message: 'accountId je povinný parameter', statusCode: 400, }, }); } // Verify user has access to this email account await emailAccountService.getEmailAccountById(accountId, userId); const updated = await contactService.unlinkCompanyFromContact(contactId, accountId); res.status(200).json({ success: true, data: updated, message: 'Firma bola odlinknutá od kontaktu', }); } catch (error) { next(error); } }; /** * Create company from contact * POST /api/contacts/:contactId/create-company?accountId=xxx * Body: { name, email, phone, address, city, country, website, description } (all optional, uses contact data as defaults) */ export const createCompanyFromContact = async (req, res, next) => { try { const userId = req.userId; const { contactId } = req.params; const { accountId } = req.query; const companyData = req.body; if (!accountId) { return res.status(400).json({ success: false, error: { message: 'accountId je povinný parameter', statusCode: 400, }, }); } // Verify user has access to this email account await emailAccountService.getEmailAccountById(accountId, userId); const result = await contactService.createCompanyFromContact(contactId, accountId, userId, companyData); res.status(201).json({ success: true, data: result, message: 'Firma bola vytvorená z kontaktu', }); } catch (error) { next(error); } };