refactor: Split company.controller.js into focused controllers

Split company.controller.js (461 lines, 5 concerns) into:
- company.controller.js: CRUD + email (134 lines)
- company-note.controller.js: note operations
- company-reminder.controller.js: reminder operations
- company-team.controller.js: user assignment operations

Update company.routes.js to import from new controllers.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
richardtekula
2026-01-28 07:41:31 +01:00
parent 3aba6c2955
commit 240dd5f4c8
5 changed files with 272 additions and 342 deletions

View File

@@ -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);
}
};

View File

@@ -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);
}
};

View File

@@ -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);
}
};

View File

@@ -1,13 +1,6 @@
import * as companyService from '../services/company.service.js'; 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'; 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) => { export const getAllCompanies = async (req, res, next) => {
try { try {
const { search } = req.query; 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) => { export const getCompanyById = async (req, res, next) => {
try { try {
const { companyId } = req.params; 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) => { export const getCompanyEmailThreads = async (req, res, next) => {
try { try {
const userId = req.userId; const userId = req.userId;
const { companyId } = req.params; const { companyId } = req.params;
// Ensure company exists
await companyService.getCompanyById(companyId); await companyService.getCompanyById(companyId);
const result = await companyEmailService.getCompanyEmailThreads(companyId, userId); 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) => { export const getCompanyUnreadCounts = async (req, res, next) => {
try { try {
const userId = req.userId; 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) => { export const getCompanyWithRelations = async (req, res, next) => {
try { try {
const { companyId } = req.params; 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) => { export const createCompany = async (req, res, next) => {
try { try {
const userId = req.userId; 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) => { export const updateCompany = async (req, res, next) => {
try { try {
const userId = req.userId; 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) => { export const deleteCompany = async (req, res, next) => {
try { try {
const { companyId } = req.params; const { companyId } = req.params;
@@ -169,292 +131,3 @@ export const deleteCompany = async (req, res, next) => {
next(error); 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);
}
};

View File

@@ -1,5 +1,8 @@
import express from 'express'; import express from 'express';
import * as companyController from '../controllers/company.controller.js'; 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 personalContactController from '../controllers/personal-contact.controller.js';
import * as companyDocumentController from '../controllers/company-document.controller.js'; import * as companyDocumentController from '../controllers/company-document.controller.js';
import { authenticate } from '../middlewares/auth/authMiddleware.js'; import { authenticate } from '../middlewares/auth/authMiddleware.js';
@@ -18,9 +21,9 @@ const router = express.Router();
router.use(authenticate); router.use(authenticate);
// Reminder summaries (must be before :companyId routes) // Reminder summaries (must be before :companyId routes)
router.get('/reminders/summary', companyController.getReminderSummary); router.get('/reminders/summary', companyReminderController.getReminderSummary);
router.get('/reminders/counts', companyController.getReminderCountsByCompany); router.get('/reminders/counts', companyReminderController.getReminderCountsByCompany);
router.get('/reminders/upcoming', companyController.getUpcomingReminders); router.get('/reminders/upcoming', companyReminderController.getUpcomingReminders);
// Company unread email summary // Company unread email summary
router.get('/email-unread', companyController.getCompanyUnreadCounts); router.get('/email-unread', companyController.getCompanyUnreadCounts);
@@ -77,7 +80,7 @@ router.get(
'/:companyId/notes', '/:companyId/notes',
validateParams(z.object({ companyId: z.string().uuid() })), validateParams(z.object({ companyId: z.string().uuid() })),
checkCompanyAccess, checkCompanyAccess,
companyController.getCompanyNotes companyNoteController.getCompanyNotes
); );
router.post( router.post(
@@ -88,7 +91,7 @@ router.post(
content: z.string().min(1), content: z.string().min(1),
dueDate: z.string().optional().or(z.literal('')), dueDate: z.string().optional().or(z.literal('')),
})), })),
companyController.addCompanyNote companyNoteController.addCompanyNote
); );
router.patch( router.patch(
@@ -102,7 +105,7 @@ router.patch(
content: z.string().min(1).optional(), content: z.string().min(1).optional(),
dueDate: z.string().optional().or(z.literal('').or(z.null())), dueDate: z.string().optional().or(z.literal('').or(z.null())),
})), })),
companyController.updateCompanyNote companyNoteController.updateCompanyNote
); );
router.delete( router.delete(
@@ -112,7 +115,7 @@ router.delete(
companyId: z.string().uuid(), companyId: z.string().uuid(),
noteId: z.string().uuid() noteId: z.string().uuid()
})), })),
companyController.deleteCompanyNote companyNoteController.deleteCompanyNote
); );
// Company reminders // Company reminders
@@ -120,7 +123,7 @@ router.get(
'/:companyId/reminders', '/:companyId/reminders',
validateParams(z.object({ companyId: z.string().uuid() })), validateParams(z.object({ companyId: z.string().uuid() })),
checkCompanyAccess, checkCompanyAccess,
companyController.getCompanyReminders companyReminderController.getCompanyReminders
); );
router.post( router.post(
@@ -128,7 +131,7 @@ router.post(
requireAdmin, requireAdmin,
validateParams(z.object({ companyId: z.string().uuid() })), validateParams(z.object({ companyId: z.string().uuid() })),
validateBody(createCompanyReminderSchema), validateBody(createCompanyReminderSchema),
companyController.createCompanyReminder companyReminderController.createCompanyReminder
); );
router.patch( router.patch(
@@ -139,7 +142,7 @@ router.patch(
reminderId: z.string().uuid() reminderId: z.string().uuid()
})), })),
validateBody(updateCompanyReminderSchema), validateBody(updateCompanyReminderSchema),
companyController.updateCompanyReminder companyReminderController.updateCompanyReminder
); );
router.delete( router.delete(
@@ -149,7 +152,7 @@ router.delete(
companyId: z.string().uuid(), companyId: z.string().uuid(),
reminderId: z.string().uuid() reminderId: z.string().uuid()
})), })),
companyController.deleteCompanyReminder companyReminderController.deleteCompanyReminder
); );
// Company Users (Team Management) // Company Users (Team Management)
@@ -157,7 +160,7 @@ router.get(
'/:companyId/users', '/:companyId/users',
validateParams(z.object({ companyId: z.string().uuid() })), validateParams(z.object({ companyId: z.string().uuid() })),
checkCompanyAccess, checkCompanyAccess,
companyController.getCompanyUsers companyTeamController.getCompanyUsers
); );
router.post( router.post(
@@ -168,7 +171,7 @@ router.post(
userId: z.string().uuid(), userId: z.string().uuid(),
role: z.string().optional(), role: z.string().optional(),
})), })),
companyController.assignUserToCompany companyTeamController.assignUserToCompany
); );
router.patch( router.patch(
@@ -181,7 +184,7 @@ router.patch(
validateBody(z.object({ validateBody(z.object({
role: z.string().optional(), role: z.string().optional(),
})), })),
companyController.updateUserRoleOnCompany companyTeamController.updateUserRoleOnCompany
); );
router.delete( router.delete(
@@ -191,7 +194,7 @@ router.delete(
companyId: z.string().uuid(), companyId: z.string().uuid(),
userId: z.string().uuid() userId: z.string().uuid()
})), })),
companyController.removeUserFromCompany companyTeamController.removeUserFromCompany
); );
// Company Contacts (Personal contacts linked to company) // Company Contacts (Personal contacts linked to company)