diff --git a/src/controllers/company-note.controller.js b/src/controllers/company-note.controller.js new file mode 100644 index 0000000..9a99618 --- /dev/null +++ b/src/controllers/company-note.controller.js @@ -0,0 +1,74 @@ +import * as noteService from '../services/note.service.js'; + +export const getCompanyNotes = async (req, res, next) => { + try { + const { companyId } = req.params; + + const notes = await noteService.getNotesByCompanyId(companyId); + + res.status(200).json({ + success: true, + count: notes.length, + data: notes, + }); + } catch (error) { + next(error); + } +}; + +export const addCompanyNote = async (req, res, next) => { + try { + const userId = req.userId; + const { companyId } = req.params; + const { content, dueDate } = req.body; + + const note = await noteService.createNote(userId, { + content, + companyId, + dueDate, + }); + + res.status(201).json({ + success: true, + data: note, + message: 'Poznámka bola pridaná', + }); + } catch (error) { + next(error); + } +}; + +export const updateCompanyNote = async (req, res, next) => { + try { + const { noteId } = req.params; + const { content, dueDate } = req.body; + + const note = await noteService.updateNote(noteId, { + content, + dueDate, + }); + + res.status(200).json({ + success: true, + data: note, + message: 'Poznámka bola aktualizovaná', + }); + } catch (error) { + next(error); + } +}; + +export const deleteCompanyNote = async (req, res, next) => { + try { + const { noteId } = req.params; + + const result = await noteService.deleteNote(noteId); + + res.status(200).json({ + success: true, + message: result.message, + }); + } catch (error) { + next(error); + } +}; diff --git a/src/controllers/company-reminder.controller.js b/src/controllers/company-reminder.controller.js new file mode 100644 index 0000000..f0bd6ce --- /dev/null +++ b/src/controllers/company-reminder.controller.js @@ -0,0 +1,112 @@ +import * as companyReminderService from '../services/company-reminder.service.js'; + +export const getCompanyReminders = async (req, res, next) => { + try { + const { companyId } = req.params; + + const reminders = await companyReminderService.getRemindersByCompanyId(companyId); + + res.status(200).json({ + success: true, + count: reminders.length, + data: reminders, + }); + } catch (error) { + next(error); + } +}; + +export const createCompanyReminder = async (req, res, next) => { + try { + const userId = req.userId; + const { companyId } = req.params; + const { description, dueDate, isChecked } = req.body; + + const reminder = await companyReminderService.createReminder(companyId, { description, dueDate, isChecked }, { userId, ipAddress: req.ip, userAgent: req.headers['user-agent'] }); + + res.status(201).json({ + success: true, + data: reminder, + message: 'Reminder bol pridaný', + }); + } catch (error) { + next(error); + } +}; + +export const updateCompanyReminder = async (req, res, next) => { + try { + const userId = req.userId; + const { companyId, reminderId } = req.params; + const { description, dueDate, isChecked } = req.body; + + const reminder = await companyReminderService.updateReminder(companyId, reminderId, { description, dueDate, isChecked }, { userId, ipAddress: req.ip, userAgent: req.headers['user-agent'] }); + + res.status(200).json({ + success: true, + data: reminder, + message: 'Reminder bol aktualizovaný', + }); + } catch (error) { + next(error); + } +}; + +export const deleteCompanyReminder = async (req, res, next) => { + try { + const userId = req.userId; + const { companyId, reminderId } = req.params; + + const result = await companyReminderService.deleteReminder(companyId, reminderId, { userId, ipAddress: req.ip, userAgent: req.headers['user-agent'] }); + + res.status(200).json({ + success: true, + message: result.message, + }); + } catch (error) { + next(error); + } +}; + +export const getReminderSummary = async (req, res, next) => { + try { + const userId = req.user?.id; + const userRole = req.user?.role; + const summary = await companyReminderService.getReminderSummary(userId, userRole); + res.status(200).json({ + success: true, + data: summary, + }); + } catch (error) { + next(error); + } +}; + +export const getReminderCountsByCompany = async (req, res, next) => { + try { + const userId = req.user?.id; + const userRole = req.user?.role; + const counts = await companyReminderService.getReminderCountsByCompany(userId, userRole); + res.status(200).json({ + success: true, + data: counts, + }); + } catch (error) { + next(error); + } +}; + +export const getUpcomingReminders = async (req, res, next) => { + try { + const userId = req.user?.id; + const userRole = req.user?.role; + const reminders = await companyReminderService.getUpcomingReminders(userId, userRole); + res.status(200).json({ + success: true, + count: reminders.length, + data: reminders, + }); + } catch (error) { + next(error); + } +}; diff --git a/src/controllers/company-team.controller.js b/src/controllers/company-team.controller.js new file mode 100644 index 0000000..08b3803 --- /dev/null +++ b/src/controllers/company-team.controller.js @@ -0,0 +1,68 @@ +import * as companyService from '../services/company.service.js'; + +export const getCompanyUsers = async (req, res, next) => { + try { + const { companyId } = req.params; + + const users = await companyService.getCompanyUsers(companyId); + + res.status(200).json({ + success: true, + count: users.length, + data: users, + }); + } catch (error) { + next(error); + } +}; + +export const assignUserToCompany = async (req, res, next) => { + try { + const currentUserId = req.userId; + const { companyId } = req.params; + const { userId, role } = req.body; + + const assignment = await companyService.assignUserToCompany(companyId, userId, currentUserId, role, { userId: currentUserId, ipAddress: req.ip, userAgent: req.headers['user-agent'] }); + + res.status(201).json({ + success: true, + data: assignment, + message: 'Používateľ bol priradený k firme', + }); + } catch (error) { + next(error); + } +}; + +export const removeUserFromCompany = async (req, res, next) => { + try { + const currentUserId = req.userId; + const { companyId, userId } = req.params; + + const result = await companyService.removeUserFromCompany(companyId, userId, { userId: currentUserId, ipAddress: req.ip, userAgent: req.headers['user-agent'] }); + + res.status(200).json({ + success: true, + message: result.message, + }); + } catch (error) { + next(error); + } +}; + +export const updateUserRoleOnCompany = async (req, res, next) => { + try { + const { companyId, userId } = req.params; + const { role } = req.body; + + const assignment = await companyService.updateUserRoleOnCompany(companyId, userId, role); + + res.status(200).json({ + success: true, + data: assignment, + message: 'Rola používateľa bola aktualizovaná', + }); + } catch (error) { + next(error); + } +}; diff --git a/src/controllers/company.controller.js b/src/controllers/company.controller.js index 47ba82f..20fcb6a 100644 --- a/src/controllers/company.controller.js +++ b/src/controllers/company.controller.js @@ -1,13 +1,6 @@ import * as companyService from '../services/company.service.js'; -import * as noteService from '../services/note.service.js'; -import * as companyReminderService from '../services/company-reminder.service.js'; import * as companyEmailService from '../services/company-email.service.js'; -/** - * Get all companies - * GET /api/companies?search=query - * Members only see companies they are assigned to - */ export const getAllCompanies = async (req, res, next) => { try { const { search } = req.query; @@ -26,10 +19,6 @@ export const getAllCompanies = async (req, res, next) => { } }; -/** - * Get company by ID - * GET /api/companies/:companyId - */ export const getCompanyById = async (req, res, next) => { try { const { companyId } = req.params; @@ -45,16 +34,11 @@ export const getCompanyById = async (req, res, next) => { } }; -/** - * Get company email threads aggregated across user's email accounts - * GET /api/companies/:companyId/email-threads - */ export const getCompanyEmailThreads = async (req, res, next) => { try { const userId = req.userId; const { companyId } = req.params; - // Ensure company exists await companyService.getCompanyById(companyId); const result = await companyEmailService.getCompanyEmailThreads(companyId, userId); @@ -68,10 +52,6 @@ export const getCompanyEmailThreads = async (req, res, next) => { } }; -/** - * Get unread email counts grouped by company for current user - * GET /api/companies/email-unread - */ export const getCompanyUnreadCounts = async (req, res, next) => { try { const userId = req.userId; @@ -86,10 +66,6 @@ export const getCompanyUnreadCounts = async (req, res, next) => { } }; -/** - * Get company with relations (projects, todos, notes) - * GET /api/companies/:companyId/details - */ export const getCompanyWithRelations = async (req, res, next) => { try { const { companyId } = req.params; @@ -105,11 +81,6 @@ export const getCompanyWithRelations = async (req, res, next) => { } }; -/** - * Create new company - * POST /api/companies - * Body: { name, description, address, city, country, phone, email, website } - */ export const createCompany = async (req, res, next) => { try { const userId = req.userId; @@ -127,11 +98,6 @@ export const createCompany = async (req, res, next) => { } }; -/** - * Update company - * PATCH /api/companies/:companyId - * Body: { name, description, address, city, country, phone, email, website } - */ export const updateCompany = async (req, res, next) => { try { const userId = req.userId; @@ -150,10 +116,6 @@ export const updateCompany = async (req, res, next) => { } }; -/** - * Delete company - * DELETE /api/companies/:companyId - */ export const deleteCompany = async (req, res, next) => { try { const { companyId } = req.params; @@ -169,292 +131,3 @@ export const deleteCompany = async (req, res, next) => { next(error); } }; - -/** - * Get company notes - * GET /api/companies/:companyId/notes - */ -export const getCompanyNotes = async (req, res, next) => { - try { - const { companyId } = req.params; - - const notes = await noteService.getNotesByCompanyId(companyId); - - res.status(200).json({ - success: true, - count: notes.length, - data: notes, - }); - } catch (error) { - next(error); - } -}; - -/** - * Add company note - * POST /api/companies/:companyId/notes - */ -export const addCompanyNote = async (req, res, next) => { - try { - const userId = req.userId; - const { companyId } = req.params; - const { content, dueDate } = req.body; - - const note = await noteService.createNote(userId, { - content, - companyId, - dueDate, - }); - - res.status(201).json({ - success: true, - data: note, - message: 'Poznámka bola pridaná', - }); - } catch (error) { - next(error); - } -}; - -/** - * Update company note - * PATCH /api/companies/:companyId/notes/:noteId - */ -export const updateCompanyNote = async (req, res, next) => { - try { - const { noteId } = req.params; - const { content, dueDate } = req.body; - - const note = await noteService.updateNote(noteId, { - content, - dueDate, - }); - - res.status(200).json({ - success: true, - data: note, - message: 'Poznámka bola aktualizovaná', - }); - } catch (error) { - next(error); - } -}; - -/** - * Delete company note - * DELETE /api/companies/:companyId/notes/:noteId - */ -export const deleteCompanyNote = async (req, res, next) => { - try { - const { noteId } = req.params; - - const result = await noteService.deleteNote(noteId); - - res.status(200).json({ - success: true, - message: result.message, - }); - } catch (error) { - next(error); - } -}; - -/** - * Company reminders - * CRUD for /api/companies/:companyId/reminders - */ -export const getCompanyReminders = async (req, res, next) => { - try { - const { companyId } = req.params; - - const reminders = await companyReminderService.getRemindersByCompanyId(companyId); - - res.status(200).json({ - success: true, - count: reminders.length, - data: reminders, - }); - } catch (error) { - next(error); - } -}; - -export const createCompanyReminder = async (req, res, next) => { - try { - const userId = req.userId; - const { companyId } = req.params; - const { description, dueDate, isChecked } = req.body; - - const reminder = await companyReminderService.createReminder(companyId, { description, dueDate, isChecked }, { userId, ipAddress: req.ip, userAgent: req.headers['user-agent'] }); - - res.status(201).json({ - success: true, - data: reminder, - message: 'Reminder bol pridaný', - }); - } catch (error) { - next(error); - } -}; - -export const updateCompanyReminder = async (req, res, next) => { - try { - const userId = req.userId; - const { companyId, reminderId } = req.params; - const { description, dueDate, isChecked } = req.body; - - const reminder = await companyReminderService.updateReminder(companyId, reminderId, { description, dueDate, isChecked }, { userId, ipAddress: req.ip, userAgent: req.headers['user-agent'] }); - - res.status(200).json({ - success: true, - data: reminder, - message: 'Reminder bol aktualizovaný', - }); - } catch (error) { - next(error); - } -}; - -export const deleteCompanyReminder = async (req, res, next) => { - try { - const userId = req.userId; - const { companyId, reminderId } = req.params; - - const result = await companyReminderService.deleteReminder(companyId, reminderId, { userId, ipAddress: req.ip, userAgent: req.headers['user-agent'] }); - - res.status(200).json({ - success: true, - message: result.message, - }); - } catch (error) { - next(error); - } -}; - -export const getReminderSummary = async (req, res, next) => { - try { - const userId = req.user?.id; - const userRole = req.user?.role; - const summary = await companyReminderService.getReminderSummary(userId, userRole); - res.status(200).json({ - success: true, - data: summary, - }); - } catch (error) { - next(error); - } -}; - -export const getReminderCountsByCompany = async (req, res, next) => { - try { - const userId = req.user?.id; - const userRole = req.user?.role; - const counts = await companyReminderService.getReminderCountsByCompany(userId, userRole); - res.status(200).json({ - success: true, - data: counts, - }); - } catch (error) { - next(error); - } -}; - -export const getUpcomingReminders = async (req, res, next) => { - try { - const userId = req.user?.id; - const userRole = req.user?.role; - const reminders = await companyReminderService.getUpcomingReminders(userId, userRole); - res.status(200).json({ - success: true, - count: reminders.length, - data: reminders, - }); - } catch (error) { - next(error); - } -}; - -/** - * Get company users (team members) - * GET /api/companies/:companyId/users - */ -export const getCompanyUsers = async (req, res, next) => { - try { - const { companyId } = req.params; - - const users = await companyService.getCompanyUsers(companyId); - - res.status(200).json({ - success: true, - count: users.length, - data: users, - }); - } catch (error) { - next(error); - } -}; - -/** - * Assign user to company - * POST /api/companies/:companyId/users - * Body: { userId, role } - */ -export const assignUserToCompany = async (req, res, next) => { - try { - const currentUserId = req.userId; - const { companyId } = req.params; - const { userId, role } = req.body; - - const assignment = await companyService.assignUserToCompany(companyId, userId, currentUserId, role, { userId: currentUserId, ipAddress: req.ip, userAgent: req.headers['user-agent'] }); - - res.status(201).json({ - success: true, - data: assignment, - message: 'Používateľ bol priradený k firme', - }); - } catch (error) { - next(error); - } -}; - -/** - * Remove user from company - * DELETE /api/companies/:companyId/users/:userId - */ -export const removeUserFromCompany = async (req, res, next) => { - try { - const currentUserId = req.userId; - const { companyId, userId } = req.params; - - const result = await companyService.removeUserFromCompany(companyId, userId, { userId: currentUserId, ipAddress: req.ip, userAgent: req.headers['user-agent'] }); - - res.status(200).json({ - success: true, - message: result.message, - }); - } catch (error) { - next(error); - } -}; - -/** - * Update user role on company - * PATCH /api/companies/:companyId/users/:userId - * Body: { role } - */ -export const updateUserRoleOnCompany = async (req, res, next) => { - try { - const { companyId, userId } = req.params; - const { role } = req.body; - - const assignment = await companyService.updateUserRoleOnCompany(companyId, userId, role); - - res.status(200).json({ - success: true, - data: assignment, - message: 'Rola používateľa bola aktualizovaná', - }); - } catch (error) { - next(error); - } -}; diff --git a/src/routes/company.routes.js b/src/routes/company.routes.js index c0a1e1b..bc59006 100644 --- a/src/routes/company.routes.js +++ b/src/routes/company.routes.js @@ -1,5 +1,8 @@ import express from 'express'; import * as companyController from '../controllers/company.controller.js'; +import * as companyNoteController from '../controllers/company-note.controller.js'; +import * as companyReminderController from '../controllers/company-reminder.controller.js'; +import * as companyTeamController from '../controllers/company-team.controller.js'; import * as personalContactController from '../controllers/personal-contact.controller.js'; import * as companyDocumentController from '../controllers/company-document.controller.js'; import { authenticate } from '../middlewares/auth/authMiddleware.js'; @@ -18,9 +21,9 @@ const router = express.Router(); router.use(authenticate); // Reminder summaries (must be before :companyId routes) -router.get('/reminders/summary', companyController.getReminderSummary); -router.get('/reminders/counts', companyController.getReminderCountsByCompany); -router.get('/reminders/upcoming', companyController.getUpcomingReminders); +router.get('/reminders/summary', companyReminderController.getReminderSummary); +router.get('/reminders/counts', companyReminderController.getReminderCountsByCompany); +router.get('/reminders/upcoming', companyReminderController.getUpcomingReminders); // Company unread email summary router.get('/email-unread', companyController.getCompanyUnreadCounts); @@ -77,7 +80,7 @@ router.get( '/:companyId/notes', validateParams(z.object({ companyId: z.string().uuid() })), checkCompanyAccess, - companyController.getCompanyNotes + companyNoteController.getCompanyNotes ); router.post( @@ -88,7 +91,7 @@ router.post( content: z.string().min(1), dueDate: z.string().optional().or(z.literal('')), })), - companyController.addCompanyNote + companyNoteController.addCompanyNote ); router.patch( @@ -102,7 +105,7 @@ router.patch( content: z.string().min(1).optional(), dueDate: z.string().optional().or(z.literal('').or(z.null())), })), - companyController.updateCompanyNote + companyNoteController.updateCompanyNote ); router.delete( @@ -112,7 +115,7 @@ router.delete( companyId: z.string().uuid(), noteId: z.string().uuid() })), - companyController.deleteCompanyNote + companyNoteController.deleteCompanyNote ); // Company reminders @@ -120,7 +123,7 @@ router.get( '/:companyId/reminders', validateParams(z.object({ companyId: z.string().uuid() })), checkCompanyAccess, - companyController.getCompanyReminders + companyReminderController.getCompanyReminders ); router.post( @@ -128,7 +131,7 @@ router.post( requireAdmin, validateParams(z.object({ companyId: z.string().uuid() })), validateBody(createCompanyReminderSchema), - companyController.createCompanyReminder + companyReminderController.createCompanyReminder ); router.patch( @@ -139,7 +142,7 @@ router.patch( reminderId: z.string().uuid() })), validateBody(updateCompanyReminderSchema), - companyController.updateCompanyReminder + companyReminderController.updateCompanyReminder ); router.delete( @@ -149,7 +152,7 @@ router.delete( companyId: z.string().uuid(), reminderId: z.string().uuid() })), - companyController.deleteCompanyReminder + companyReminderController.deleteCompanyReminder ); // Company Users (Team Management) @@ -157,7 +160,7 @@ router.get( '/:companyId/users', validateParams(z.object({ companyId: z.string().uuid() })), checkCompanyAccess, - companyController.getCompanyUsers + companyTeamController.getCompanyUsers ); router.post( @@ -168,7 +171,7 @@ router.post( userId: z.string().uuid(), role: z.string().optional(), })), - companyController.assignUserToCompany + companyTeamController.assignUserToCompany ); router.patch( @@ -181,7 +184,7 @@ router.patch( validateBody(z.object({ role: z.string().optional(), })), - companyController.updateUserRoleOnCompany + companyTeamController.updateUserRoleOnCompany ); router.delete( @@ -191,7 +194,7 @@ router.delete( companyId: z.string().uuid(), userId: z.string().uuid() })), - companyController.removeUserFromCompany + companyTeamController.removeUserFromCompany ); // Company Contacts (Personal contacts linked to company)