feat: Add creator info, team management for companies, and member access control
- Add creator info (username) to companies, projects, and notes responses - Add company_users table for team management on companies - Add resourceAccessMiddleware for member access control - Members can only see resources they are directly assigned to - Companies, projects, and todos are now filtered by user assignments - Add personal contacts feature 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -7,12 +7,15 @@ import { logCompanyCreated, logCompanyDeleted } from '../services/audit.service.
|
||||
/**
|
||||
* 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;
|
||||
const userId = req.user?.id;
|
||||
const userRole = req.user?.role;
|
||||
|
||||
const companies = await companyService.getAllCompanies(search);
|
||||
const companies = await companyService.getAllCompanies(search, userId, userRole);
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
@@ -333,9 +336,11 @@ export const deleteCompanyReminder = async (req, res, next) => {
|
||||
}
|
||||
};
|
||||
|
||||
export const getReminderSummary = async (_req, res, next) => {
|
||||
export const getReminderSummary = async (req, res, next) => {
|
||||
try {
|
||||
const summary = await companyReminderService.getReminderSummary();
|
||||
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,
|
||||
@@ -345,9 +350,11 @@ export const getReminderSummary = async (_req, res, next) => {
|
||||
}
|
||||
};
|
||||
|
||||
export const getReminderCountsByCompany = async (_req, res, next) => {
|
||||
export const getReminderCountsByCompany = async (req, res, next) => {
|
||||
try {
|
||||
const counts = await companyReminderService.getReminderCountsByCompany();
|
||||
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,
|
||||
@@ -357,9 +364,11 @@ export const getReminderCountsByCompany = async (_req, res, next) => {
|
||||
}
|
||||
};
|
||||
|
||||
export const getUpcomingReminders = async (_req, res, next) => {
|
||||
export const getUpcomingReminders = async (req, res, next) => {
|
||||
try {
|
||||
const reminders = await companyReminderService.getUpcomingReminders();
|
||||
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,
|
||||
@@ -369,3 +378,87 @@ export const getUpcomingReminders = async (_req, res, next) => {
|
||||
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);
|
||||
|
||||
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 { companyId, userId } = req.params;
|
||||
|
||||
const result = await companyService.removeUserFromCompany(companyId, userId);
|
||||
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -5,12 +5,15 @@ import { logProjectCreated, logProjectDeleted } from '../services/audit.service.
|
||||
/**
|
||||
* Get all projects
|
||||
* GET /api/projects?search=query&companyId=xxx
|
||||
* Members only see projects they are assigned to or projects of companies they are assigned to
|
||||
*/
|
||||
export const getAllProjects = async (req, res, next) => {
|
||||
try {
|
||||
const { search, companyId } = req.query;
|
||||
const userId = req.user?.id;
|
||||
const userRole = req.user?.role;
|
||||
|
||||
const projects = await projectService.getAllProjects(search, companyId);
|
||||
const projects = await projectService.getAllProjects(search, companyId, userId, userRole);
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
|
||||
@@ -4,10 +4,13 @@ import { logTodoCreated, logTodoDeleted, logTodoCompleted } from '../services/au
|
||||
/**
|
||||
* Get all todos
|
||||
* GET /api/todos?search=query&projectId=xxx&companyId=xxx&assignedTo=xxx&status=xxx
|
||||
* Members only see todos they are assigned to
|
||||
*/
|
||||
export const getAllTodos = async (req, res, next) => {
|
||||
try {
|
||||
const { search, projectId, companyId, assignedTo, status, completed, priority } = req.query;
|
||||
const userId = req.user?.id;
|
||||
const userRole = req.user?.role;
|
||||
|
||||
// Handle both 'status' and 'completed' query params
|
||||
let statusFilter = status;
|
||||
@@ -24,7 +27,7 @@ export const getAllTodos = async (req, res, next) => {
|
||||
priority,
|
||||
};
|
||||
|
||||
const todos = await todoService.getAllTodos(filters);
|
||||
const todos = await todoService.getAllTodos(filters, userId, userRole);
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
|
||||
Reference in New Issue
Block a user