fix email issues, add company,project,todos
This commit is contained in:
223
src/controllers/company.controller.js
Normal file
223
src/controllers/company.controller.js
Normal file
@@ -0,0 +1,223 @@
|
||||
import * as companyService from '../services/company.service.js';
|
||||
import * as noteService from '../services/note.service.js';
|
||||
import { formatErrorResponse } from '../utils/errors.js';
|
||||
|
||||
/**
|
||||
* Get all companies
|
||||
* GET /api/companies?search=query
|
||||
*/
|
||||
export const getAllCompanies = async (req, res) => {
|
||||
try {
|
||||
const { search } = req.query;
|
||||
|
||||
const companies = await companyService.getAllCompanies(search);
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
count: companies.length,
|
||||
data: companies,
|
||||
});
|
||||
} catch (error) {
|
||||
const errorResponse = formatErrorResponse(error, process.env.NODE_ENV === 'development');
|
||||
res.status(error.statusCode || 500).json(errorResponse);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get company by ID
|
||||
* GET /api/companies/:companyId
|
||||
*/
|
||||
export const getCompanyById = async (req, res) => {
|
||||
try {
|
||||
const { companyId } = req.params;
|
||||
|
||||
const company = await companyService.getCompanyById(companyId);
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
data: company,
|
||||
});
|
||||
} catch (error) {
|
||||
const errorResponse = formatErrorResponse(error, process.env.NODE_ENV === 'development');
|
||||
res.status(error.statusCode || 500).json(errorResponse);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get company with relations (projects, todos, notes)
|
||||
* GET /api/companies/:companyId/details
|
||||
*/
|
||||
export const getCompanyWithRelations = async (req, res) => {
|
||||
try {
|
||||
const { companyId } = req.params;
|
||||
|
||||
const company = await companyService.getCompanyWithRelations(companyId);
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
data: company,
|
||||
});
|
||||
} catch (error) {
|
||||
const errorResponse = formatErrorResponse(error, process.env.NODE_ENV === 'development');
|
||||
res.status(error.statusCode || 500).json(errorResponse);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Create new company
|
||||
* POST /api/companies
|
||||
* Body: { name, description, address, city, country, phone, email, website }
|
||||
*/
|
||||
export const createCompany = async (req, res) => {
|
||||
try {
|
||||
const userId = req.userId;
|
||||
const data = req.body;
|
||||
|
||||
const company = await companyService.createCompany(userId, data);
|
||||
|
||||
res.status(201).json({
|
||||
success: true,
|
||||
data: company,
|
||||
message: 'Firma bola vytvorená',
|
||||
});
|
||||
} catch (error) {
|
||||
const errorResponse = formatErrorResponse(error, process.env.NODE_ENV === 'development');
|
||||
res.status(error.statusCode || 500).json(errorResponse);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Update company
|
||||
* PATCH /api/companies/:companyId
|
||||
* Body: { name, description, address, city, country, phone, email, website }
|
||||
*/
|
||||
export const updateCompany = async (req, res) => {
|
||||
try {
|
||||
const { companyId } = req.params;
|
||||
const data = req.body;
|
||||
|
||||
const company = await companyService.updateCompany(companyId, data);
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
data: company,
|
||||
message: 'Firma bola aktualizovaná',
|
||||
});
|
||||
} catch (error) {
|
||||
const errorResponse = formatErrorResponse(error, process.env.NODE_ENV === 'development');
|
||||
res.status(error.statusCode || 500).json(errorResponse);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete company
|
||||
* DELETE /api/companies/:companyId
|
||||
*/
|
||||
export const deleteCompany = async (req, res) => {
|
||||
try {
|
||||
const { companyId } = req.params;
|
||||
|
||||
const result = await companyService.deleteCompany(companyId);
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
message: result.message,
|
||||
});
|
||||
} catch (error) {
|
||||
const errorResponse = formatErrorResponse(error, process.env.NODE_ENV === 'development');
|
||||
res.status(error.statusCode || 500).json(errorResponse);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get company notes
|
||||
* GET /api/companies/:companyId/notes
|
||||
*/
|
||||
export const getCompanyNotes = async (req, res) => {
|
||||
try {
|
||||
const { companyId } = req.params;
|
||||
|
||||
const notes = await noteService.getNotesByCompanyId(companyId);
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
count: notes.length,
|
||||
data: notes,
|
||||
});
|
||||
} catch (error) {
|
||||
const errorResponse = formatErrorResponse(error, process.env.NODE_ENV === 'development');
|
||||
res.status(error.statusCode || 500).json(errorResponse);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Add company note
|
||||
* POST /api/companies/:companyId/notes
|
||||
*/
|
||||
export const addCompanyNote = async (req, res) => {
|
||||
try {
|
||||
const userId = req.userId;
|
||||
const { companyId } = req.params;
|
||||
const { content, reminderAt } = req.body;
|
||||
|
||||
const note = await noteService.createNote(userId, {
|
||||
content,
|
||||
companyId,
|
||||
reminderDate: reminderAt, // Map reminderAt to reminderDate
|
||||
});
|
||||
|
||||
res.status(201).json({
|
||||
success: true,
|
||||
data: note,
|
||||
message: 'Poznámka bola pridaná',
|
||||
});
|
||||
} catch (error) {
|
||||
const errorResponse = formatErrorResponse(error, process.env.NODE_ENV === 'development');
|
||||
res.status(error.statusCode || 500).json(errorResponse);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Update company note
|
||||
* PATCH /api/companies/:companyId/notes/:noteId
|
||||
*/
|
||||
export const updateCompanyNote = async (req, res) => {
|
||||
try {
|
||||
const { noteId } = req.params;
|
||||
const { content, reminderAt } = req.body;
|
||||
|
||||
const note = await noteService.updateNote(noteId, {
|
||||
content,
|
||||
reminderDate: reminderAt, // Map reminderAt to reminderDate
|
||||
});
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
data: note,
|
||||
message: 'Poznámka bola aktualizovaná',
|
||||
});
|
||||
} catch (error) {
|
||||
const errorResponse = formatErrorResponse(error, process.env.NODE_ENV === 'development');
|
||||
res.status(error.statusCode || 500).json(errorResponse);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete company note
|
||||
* DELETE /api/companies/:companyId/notes/:noteId
|
||||
*/
|
||||
export const deleteCompanyNote = async (req, res) => {
|
||||
try {
|
||||
const { noteId } = req.params;
|
||||
|
||||
const result = await noteService.deleteNote(noteId);
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
message: result.message,
|
||||
});
|
||||
} catch (error) {
|
||||
const errorResponse = formatErrorResponse(error, process.env.NODE_ENV === 'development');
|
||||
res.status(error.statusCode || 500).json(errorResponse);
|
||||
}
|
||||
};
|
||||
@@ -238,3 +238,125 @@ export const updateContact = async (req, res) => {
|
||||
res.status(error.statusCode || 500).json(errorResponse);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Link company to contact
|
||||
* POST /api/contacts/:contactId/link-company?accountId=xxx
|
||||
* Body: { companyId }
|
||||
*/
|
||||
export const linkCompanyToContact = async (req, res) => {
|
||||
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) {
|
||||
const errorResponse = formatErrorResponse(error, process.env.NODE_ENV === 'development');
|
||||
res.status(error.statusCode || 500).json(errorResponse);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Unlink company from contact
|
||||
* POST /api/contacts/:contactId/unlink-company?accountId=xxx
|
||||
*/
|
||||
export const unlinkCompanyFromContact = async (req, res) => {
|
||||
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) {
|
||||
const errorResponse = formatErrorResponse(error, process.env.NODE_ENV === 'development');
|
||||
res.status(error.statusCode || 500).json(errorResponse);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 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) => {
|
||||
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) {
|
||||
const errorResponse = formatErrorResponse(error, process.env.NODE_ENV === 'development');
|
||||
res.status(error.statusCode || 500).json(errorResponse);
|
||||
}
|
||||
};
|
||||
|
||||
159
src/controllers/note.controller.js
Normal file
159
src/controllers/note.controller.js
Normal file
@@ -0,0 +1,159 @@
|
||||
import * as noteService from '../services/note.service.js';
|
||||
import { formatErrorResponse } from '../utils/errors.js';
|
||||
|
||||
/**
|
||||
* Get all notes
|
||||
* GET /api/notes?search=query&companyId=xxx&projectId=xxx&todoId=xxx&contactId=xxx
|
||||
*/
|
||||
export const getAllNotes = async (req, res) => {
|
||||
try {
|
||||
const { search, companyId, projectId, todoId, contactId } = req.query;
|
||||
|
||||
const filters = {
|
||||
searchTerm: search,
|
||||
companyId,
|
||||
projectId,
|
||||
todoId,
|
||||
contactId,
|
||||
};
|
||||
|
||||
const notes = await noteService.getAllNotes(filters);
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
count: notes.length,
|
||||
data: notes,
|
||||
});
|
||||
} catch (error) {
|
||||
const errorResponse = formatErrorResponse(error, process.env.NODE_ENV === 'development');
|
||||
res.status(error.statusCode || 500).json(errorResponse);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get note by ID
|
||||
* GET /api/notes/:noteId
|
||||
*/
|
||||
export const getNoteById = async (req, res) => {
|
||||
try {
|
||||
const { noteId } = req.params;
|
||||
|
||||
const note = await noteService.getNoteById(noteId);
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
data: note,
|
||||
});
|
||||
} catch (error) {
|
||||
const errorResponse = formatErrorResponse(error, process.env.NODE_ENV === 'development');
|
||||
res.status(error.statusCode || 500).json(errorResponse);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Create new note
|
||||
* POST /api/notes
|
||||
* Body: { title, content, companyId, projectId, todoId, contactId }
|
||||
*/
|
||||
export const createNote = async (req, res) => {
|
||||
try {
|
||||
const userId = req.userId;
|
||||
const data = req.body;
|
||||
|
||||
const note = await noteService.createNote(userId, data);
|
||||
|
||||
res.status(201).json({
|
||||
success: true,
|
||||
data: note,
|
||||
message: 'Poznámka bola vytvorená',
|
||||
});
|
||||
} catch (error) {
|
||||
const errorResponse = formatErrorResponse(error, process.env.NODE_ENV === 'development');
|
||||
res.status(error.statusCode || 500).json(errorResponse);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Update note
|
||||
* PATCH /api/notes/:noteId
|
||||
* Body: { title, content, companyId, projectId, todoId, contactId }
|
||||
*/
|
||||
export const updateNote = async (req, res) => {
|
||||
try {
|
||||
const { noteId } = req.params;
|
||||
const data = req.body;
|
||||
|
||||
const note = await noteService.updateNote(noteId, data);
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
data: note,
|
||||
message: 'Poznámka bola aktualizovaná',
|
||||
});
|
||||
} catch (error) {
|
||||
const errorResponse = formatErrorResponse(error, process.env.NODE_ENV === 'development');
|
||||
res.status(error.statusCode || 500).json(errorResponse);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete note
|
||||
* DELETE /api/notes/:noteId
|
||||
*/
|
||||
export const deleteNote = async (req, res) => {
|
||||
try {
|
||||
const { noteId } = req.params;
|
||||
|
||||
const result = await noteService.deleteNote(noteId);
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
message: result.message,
|
||||
});
|
||||
} catch (error) {
|
||||
const errorResponse = formatErrorResponse(error, process.env.NODE_ENV === 'development');
|
||||
res.status(error.statusCode || 500).json(errorResponse);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get upcoming reminders for current user
|
||||
* GET /api/notes/my-reminders
|
||||
*/
|
||||
export const getMyReminders = async (req, res) => {
|
||||
try {
|
||||
const userId = req.userId;
|
||||
|
||||
const reminders = await noteService.getUpcomingRemindersForUser(userId);
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
count: reminders.length,
|
||||
data: reminders,
|
||||
});
|
||||
} catch (error) {
|
||||
const errorResponse = formatErrorResponse(error, process.env.NODE_ENV === 'development');
|
||||
res.status(error.statusCode || 500).json(errorResponse);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Mark reminder as sent
|
||||
* POST /api/notes/:noteId/mark-reminder-sent
|
||||
*/
|
||||
export const markReminderSent = async (req, res) => {
|
||||
try {
|
||||
const { noteId } = req.params;
|
||||
|
||||
const updated = await noteService.markReminderAsSent(noteId);
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
data: updated,
|
||||
message: 'Reminder označený ako odoslaný',
|
||||
});
|
||||
} catch (error) {
|
||||
const errorResponse = formatErrorResponse(error, process.env.NODE_ENV === 'development');
|
||||
res.status(error.statusCode || 500).json(errorResponse);
|
||||
}
|
||||
};
|
||||
316
src/controllers/project.controller.js
Normal file
316
src/controllers/project.controller.js
Normal file
@@ -0,0 +1,316 @@
|
||||
import * as projectService from '../services/project.service.js';
|
||||
import * as noteService from '../services/note.service.js';
|
||||
import { formatErrorResponse } from '../utils/errors.js';
|
||||
|
||||
/**
|
||||
* Get all projects
|
||||
* GET /api/projects?search=query&companyId=xxx
|
||||
*/
|
||||
export const getAllProjects = async (req, res) => {
|
||||
try {
|
||||
const { search, companyId } = req.query;
|
||||
|
||||
const projects = await projectService.getAllProjects(search, companyId);
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
count: projects.length,
|
||||
data: projects,
|
||||
});
|
||||
} catch (error) {
|
||||
const errorResponse = formatErrorResponse(error, process.env.NODE_ENV === 'development');
|
||||
res.status(error.statusCode || 500).json(errorResponse);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get project by ID
|
||||
* GET /api/projects/:projectId
|
||||
*/
|
||||
export const getProjectById = async (req, res) => {
|
||||
try {
|
||||
const { projectId } = req.params;
|
||||
|
||||
const project = await projectService.getProjectById(projectId);
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
data: project,
|
||||
});
|
||||
} catch (error) {
|
||||
const errorResponse = formatErrorResponse(error, process.env.NODE_ENV === 'development');
|
||||
res.status(error.statusCode || 500).json(errorResponse);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get project with relations (company, todos, notes, timesheets)
|
||||
* GET /api/projects/:projectId/details
|
||||
*/
|
||||
export const getProjectWithRelations = async (req, res) => {
|
||||
try {
|
||||
const { projectId } = req.params;
|
||||
|
||||
const project = await projectService.getProjectWithRelations(projectId);
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
data: project,
|
||||
});
|
||||
} catch (error) {
|
||||
const errorResponse = formatErrorResponse(error, process.env.NODE_ENV === 'development');
|
||||
res.status(error.statusCode || 500).json(errorResponse);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Create new project
|
||||
* POST /api/projects
|
||||
* Body: { name, description, companyId, status, startDate, endDate }
|
||||
*/
|
||||
export const createProject = async (req, res) => {
|
||||
try {
|
||||
const userId = req.userId;
|
||||
const data = req.body;
|
||||
|
||||
const project = await projectService.createProject(userId, data);
|
||||
|
||||
res.status(201).json({
|
||||
success: true,
|
||||
data: project,
|
||||
message: 'Projekt bol vytvorený',
|
||||
});
|
||||
} catch (error) {
|
||||
const errorResponse = formatErrorResponse(error, process.env.NODE_ENV === 'development');
|
||||
res.status(error.statusCode || 500).json(errorResponse);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Update project
|
||||
* PATCH /api/projects/:projectId
|
||||
* Body: { name, description, companyId, status, startDate, endDate }
|
||||
*/
|
||||
export const updateProject = async (req, res) => {
|
||||
try {
|
||||
const { projectId } = req.params;
|
||||
const data = req.body;
|
||||
|
||||
const project = await projectService.updateProject(projectId, data);
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
data: project,
|
||||
message: 'Projekt bol aktualizovaný',
|
||||
});
|
||||
} catch (error) {
|
||||
const errorResponse = formatErrorResponse(error, process.env.NODE_ENV === 'development');
|
||||
res.status(error.statusCode || 500).json(errorResponse);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete project
|
||||
* DELETE /api/projects/:projectId
|
||||
*/
|
||||
export const deleteProject = async (req, res) => {
|
||||
try {
|
||||
const { projectId } = req.params;
|
||||
|
||||
const result = await projectService.deleteProject(projectId);
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
message: result.message,
|
||||
});
|
||||
} catch (error) {
|
||||
const errorResponse = formatErrorResponse(error, process.env.NODE_ENV === 'development');
|
||||
res.status(error.statusCode || 500).json(errorResponse);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get project notes
|
||||
* GET /api/projects/:projectId/notes
|
||||
*/
|
||||
export const getProjectNotes = async (req, res) => {
|
||||
try {
|
||||
const { projectId } = req.params;
|
||||
|
||||
const notes = await noteService.getNotesByProjectId(projectId);
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
count: notes.length,
|
||||
data: notes,
|
||||
});
|
||||
} catch (error) {
|
||||
const errorResponse = formatErrorResponse(error, process.env.NODE_ENV === 'development');
|
||||
res.status(error.statusCode || 500).json(errorResponse);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Add project note
|
||||
* POST /api/projects/:projectId/notes
|
||||
*/
|
||||
export const addProjectNote = async (req, res) => {
|
||||
try {
|
||||
const userId = req.userId;
|
||||
const { projectId } = req.params;
|
||||
const { content, reminderAt } = req.body;
|
||||
|
||||
const note = await noteService.createNote(userId, {
|
||||
content,
|
||||
projectId,
|
||||
reminderDate: reminderAt, // Map reminderAt to reminderDate
|
||||
});
|
||||
|
||||
res.status(201).json({
|
||||
success: true,
|
||||
data: note,
|
||||
message: 'Poznámka bola pridaná',
|
||||
});
|
||||
} catch (error) {
|
||||
const errorResponse = formatErrorResponse(error, process.env.NODE_ENV === 'development');
|
||||
res.status(error.statusCode || 500).json(errorResponse);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Update project note
|
||||
* PATCH /api/projects/:projectId/notes/:noteId
|
||||
*/
|
||||
export const updateProjectNote = async (req, res) => {
|
||||
try {
|
||||
const { noteId } = req.params;
|
||||
const { content, reminderAt } = req.body;
|
||||
|
||||
const note = await noteService.updateNote(noteId, {
|
||||
content,
|
||||
reminderDate: reminderAt, // Map reminderAt to reminderDate
|
||||
});
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
data: note,
|
||||
message: 'Poznámka bola aktualizovaná',
|
||||
});
|
||||
} catch (error) {
|
||||
const errorResponse = formatErrorResponse(error, process.env.NODE_ENV === 'development');
|
||||
res.status(error.statusCode || 500).json(errorResponse);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete project note
|
||||
* DELETE /api/projects/:projectId/notes/:noteId
|
||||
*/
|
||||
export const deleteProjectNote = async (req, res) => {
|
||||
try {
|
||||
const { noteId } = req.params;
|
||||
|
||||
const result = await noteService.deleteNote(noteId);
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
message: result.message,
|
||||
});
|
||||
} catch (error) {
|
||||
const errorResponse = formatErrorResponse(error, process.env.NODE_ENV === 'development');
|
||||
res.status(error.statusCode || 500).json(errorResponse);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get project users (team members)
|
||||
* GET /api/projects/:projectId/users
|
||||
*/
|
||||
export const getProjectUsers = async (req, res) => {
|
||||
try {
|
||||
const { projectId } = req.params;
|
||||
|
||||
const users = await projectService.getProjectUsers(projectId);
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
count: users.length,
|
||||
data: users,
|
||||
});
|
||||
} catch (error) {
|
||||
const errorResponse = formatErrorResponse(error, process.env.NODE_ENV === 'development');
|
||||
res.status(error.statusCode || 500).json(errorResponse);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Assign user to project
|
||||
* POST /api/projects/:projectId/users
|
||||
* Body: { userId, role }
|
||||
*/
|
||||
export const assignUserToProject = async (req, res) => {
|
||||
try {
|
||||
const currentUserId = req.userId;
|
||||
const { projectId } = req.params;
|
||||
const { userId, role } = req.body;
|
||||
|
||||
const assignment = await projectService.assignUserToProject(
|
||||
projectId,
|
||||
userId,
|
||||
currentUserId,
|
||||
role
|
||||
);
|
||||
|
||||
res.status(201).json({
|
||||
success: true,
|
||||
data: assignment,
|
||||
message: 'Používateľ bol priradený k projektu',
|
||||
});
|
||||
} catch (error) {
|
||||
const errorResponse = formatErrorResponse(error, process.env.NODE_ENV === 'development');
|
||||
res.status(error.statusCode || 500).json(errorResponse);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove user from project
|
||||
* DELETE /api/projects/:projectId/users/:userId
|
||||
*/
|
||||
export const removeUserFromProject = async (req, res) => {
|
||||
try {
|
||||
const { projectId, userId } = req.params;
|
||||
|
||||
const result = await projectService.removeUserFromProject(projectId, userId);
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
message: result.message,
|
||||
});
|
||||
} catch (error) {
|
||||
const errorResponse = formatErrorResponse(error, process.env.NODE_ENV === 'development');
|
||||
res.status(error.statusCode || 500).json(errorResponse);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Update user role on project
|
||||
* PATCH /api/projects/:projectId/users/:userId
|
||||
* Body: { role }
|
||||
*/
|
||||
export const updateUserRoleOnProject = async (req, res) => {
|
||||
try {
|
||||
const { projectId, userId } = req.params;
|
||||
const { role } = req.body;
|
||||
|
||||
const updated = await projectService.updateUserRoleOnProject(projectId, userId, role);
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
data: updated,
|
||||
message: 'Rola používateľa bola aktualizovaná',
|
||||
});
|
||||
} catch (error) {
|
||||
const errorResponse = formatErrorResponse(error, process.env.NODE_ENV === 'development');
|
||||
res.status(error.statusCode || 500).json(errorResponse);
|
||||
}
|
||||
};
|
||||
191
src/controllers/todo.controller.js
Normal file
191
src/controllers/todo.controller.js
Normal file
@@ -0,0 +1,191 @@
|
||||
import * as todoService from '../services/todo.service.js';
|
||||
import { formatErrorResponse } from '../utils/errors.js';
|
||||
|
||||
/**
|
||||
* Get all todos
|
||||
* GET /api/todos?search=query&projectId=xxx&companyId=xxx&assignedTo=xxx&status=xxx
|
||||
*/
|
||||
export const getAllTodos = async (req, res) => {
|
||||
try {
|
||||
const { search, projectId, companyId, assignedTo, status } = req.query;
|
||||
|
||||
const filters = {
|
||||
searchTerm: search,
|
||||
projectId,
|
||||
companyId,
|
||||
assignedTo,
|
||||
status,
|
||||
};
|
||||
|
||||
const todos = await todoService.getAllTodos(filters);
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
count: todos.length,
|
||||
data: todos,
|
||||
});
|
||||
} catch (error) {
|
||||
const errorResponse = formatErrorResponse(error, process.env.NODE_ENV === 'development');
|
||||
res.status(error.statusCode || 500).json(errorResponse);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get my todos (assigned to current user)
|
||||
* GET /api/todos/my?status=xxx
|
||||
*/
|
||||
export const getMyTodos = async (req, res) => {
|
||||
try {
|
||||
const userId = req.userId;
|
||||
const { status } = req.query;
|
||||
|
||||
const filters = {
|
||||
assignedTo: userId,
|
||||
status,
|
||||
};
|
||||
|
||||
const todos = await todoService.getAllTodos(filters);
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
count: todos.length,
|
||||
data: todos,
|
||||
});
|
||||
} catch (error) {
|
||||
const errorResponse = formatErrorResponse(error, process.env.NODE_ENV === 'development');
|
||||
res.status(error.statusCode || 500).json(errorResponse);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get todo by ID
|
||||
* GET /api/todos/:todoId
|
||||
*/
|
||||
export const getTodoById = async (req, res) => {
|
||||
try {
|
||||
const { todoId } = req.params;
|
||||
|
||||
const todo = await todoService.getTodoById(todoId);
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
data: todo,
|
||||
});
|
||||
} catch (error) {
|
||||
const errorResponse = formatErrorResponse(error, process.env.NODE_ENV === 'development');
|
||||
res.status(error.statusCode || 500).json(errorResponse);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Get todo with relations (project, company, assigned user, notes)
|
||||
* GET /api/todos/:todoId/details
|
||||
*/
|
||||
export const getTodoWithRelations = async (req, res) => {
|
||||
try {
|
||||
const { todoId } = req.params;
|
||||
|
||||
const todo = await todoService.getTodoWithRelations(todoId);
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
data: todo,
|
||||
});
|
||||
} catch (error) {
|
||||
const errorResponse = formatErrorResponse(error, process.env.NODE_ENV === 'development');
|
||||
res.status(error.statusCode || 500).json(errorResponse);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Create new todo
|
||||
* POST /api/todos
|
||||
* Body: { title, description, projectId, companyId, assignedTo, status, priority, dueDate }
|
||||
*/
|
||||
export const createTodo = async (req, res) => {
|
||||
try {
|
||||
const userId = req.userId;
|
||||
const data = req.body;
|
||||
|
||||
const todo = await todoService.createTodo(userId, data);
|
||||
|
||||
res.status(201).json({
|
||||
success: true,
|
||||
data: todo,
|
||||
message: 'Todo bolo vytvorené',
|
||||
});
|
||||
} catch (error) {
|
||||
const errorResponse = formatErrorResponse(error, process.env.NODE_ENV === 'development');
|
||||
res.status(error.statusCode || 500).json(errorResponse);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Update todo
|
||||
* PATCH /api/todos/:todoId
|
||||
* Body: { title, description, projectId, companyId, assignedTo, status, priority, dueDate }
|
||||
*/
|
||||
export const updateTodo = async (req, res) => {
|
||||
try {
|
||||
const { todoId } = req.params;
|
||||
const data = req.body;
|
||||
|
||||
const todo = await todoService.updateTodo(todoId, data);
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
data: todo,
|
||||
message: 'Todo bolo aktualizované',
|
||||
});
|
||||
} catch (error) {
|
||||
const errorResponse = formatErrorResponse(error, process.env.NODE_ENV === 'development');
|
||||
res.status(error.statusCode || 500).json(errorResponse);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete todo
|
||||
* DELETE /api/todos/:todoId
|
||||
*/
|
||||
export const deleteTodo = async (req, res) => {
|
||||
try {
|
||||
const { todoId } = req.params;
|
||||
|
||||
const result = await todoService.deleteTodo(todoId);
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
message: result.message,
|
||||
});
|
||||
} catch (error) {
|
||||
const errorResponse = formatErrorResponse(error, process.env.NODE_ENV === 'development');
|
||||
res.status(error.statusCode || 500).json(errorResponse);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Toggle todo completion status
|
||||
* PATCH /api/todos/:todoId/toggle
|
||||
*/
|
||||
export const toggleTodo = async (req, res) => {
|
||||
try {
|
||||
const { todoId } = req.params;
|
||||
|
||||
// Get current todo
|
||||
const todo = await todoService.getTodoById(todoId);
|
||||
|
||||
// Toggle completed status
|
||||
const updated = await todoService.updateTodo(todoId, {
|
||||
status: todo.status === 'completed' ? 'pending' : 'completed',
|
||||
});
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
data: updated,
|
||||
message: 'Todo status aktualizovaný',
|
||||
});
|
||||
} catch (error) {
|
||||
const errorResponse = formatErrorResponse(error, process.env.NODE_ENV === 'development');
|
||||
res.status(error.statusCode || 500).json(errorResponse);
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user