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:
@@ -2,6 +2,7 @@ import express from 'express';
|
||||
import * as companyController from '../controllers/company.controller.js';
|
||||
import { authenticate } from '../middlewares/auth/authMiddleware.js';
|
||||
import { requireAdmin } from '../middlewares/auth/roleMiddleware.js';
|
||||
import { checkCompanyAccess } from '../middlewares/auth/resourceAccessMiddleware.js';
|
||||
import { validateBody, validateParams } from '../middlewares/security/validateInput.js';
|
||||
import { createCompanySchema, updateCompanySchema, createCompanyReminderSchema, updateCompanyReminderSchema } from '../validators/crm.validators.js';
|
||||
import { z } from 'zod';
|
||||
@@ -23,6 +24,7 @@ router.get('/email-unread', companyController.getCompanyUnreadCounts);
|
||||
router.get(
|
||||
'/:companyId/email-threads',
|
||||
validateParams(z.object({ companyId: z.string().uuid() })),
|
||||
checkCompanyAccess,
|
||||
companyController.getCompanyEmailThreads
|
||||
);
|
||||
|
||||
@@ -37,6 +39,7 @@ router.get('/', companyController.getAllCompanies);
|
||||
router.get(
|
||||
'/:companyId',
|
||||
validateParams(z.object({ companyId: z.string().uuid() })),
|
||||
checkCompanyAccess,
|
||||
companyController.getCompanyById
|
||||
);
|
||||
|
||||
@@ -69,6 +72,7 @@ router.delete(
|
||||
router.get(
|
||||
'/:companyId/notes',
|
||||
validateParams(z.object({ companyId: z.string().uuid() })),
|
||||
checkCompanyAccess,
|
||||
companyController.getCompanyNotes
|
||||
);
|
||||
|
||||
@@ -109,6 +113,7 @@ router.delete(
|
||||
router.get(
|
||||
'/:companyId/reminders',
|
||||
validateParams(z.object({ companyId: z.string().uuid() })),
|
||||
checkCompanyAccess,
|
||||
companyController.getCompanyReminders
|
||||
);
|
||||
|
||||
@@ -141,4 +146,46 @@ router.delete(
|
||||
companyController.deleteCompanyReminder
|
||||
);
|
||||
|
||||
// Company Users (Team Management)
|
||||
router.get(
|
||||
'/:companyId/users',
|
||||
validateParams(z.object({ companyId: z.string().uuid() })),
|
||||
checkCompanyAccess,
|
||||
companyController.getCompanyUsers
|
||||
);
|
||||
|
||||
router.post(
|
||||
'/:companyId/users',
|
||||
requireAdmin,
|
||||
validateParams(z.object({ companyId: z.string().uuid() })),
|
||||
validateBody(z.object({
|
||||
userId: z.string().uuid(),
|
||||
role: z.string().optional(),
|
||||
})),
|
||||
companyController.assignUserToCompany
|
||||
);
|
||||
|
||||
router.patch(
|
||||
'/:companyId/users/:userId',
|
||||
requireAdmin,
|
||||
validateParams(z.object({
|
||||
companyId: z.string().uuid(),
|
||||
userId: z.string().uuid()
|
||||
})),
|
||||
validateBody(z.object({
|
||||
role: z.string().optional(),
|
||||
})),
|
||||
companyController.updateUserRoleOnCompany
|
||||
);
|
||||
|
||||
router.delete(
|
||||
'/:companyId/users/:userId',
|
||||
requireAdmin,
|
||||
validateParams(z.object({
|
||||
companyId: z.string().uuid(),
|
||||
userId: z.string().uuid()
|
||||
})),
|
||||
companyController.removeUserFromCompany
|
||||
);
|
||||
|
||||
export default router;
|
||||
|
||||
@@ -2,6 +2,7 @@ import express from 'express';
|
||||
import * as projectController from '../controllers/project.controller.js';
|
||||
import { authenticate } from '../middlewares/auth/authMiddleware.js';
|
||||
import { requireAdmin } from '../middlewares/auth/roleMiddleware.js';
|
||||
import { checkProjectAccess } from '../middlewares/auth/resourceAccessMiddleware.js';
|
||||
import { validateBody, validateParams } from '../middlewares/security/validateInput.js';
|
||||
import { createProjectSchema, updateProjectSchema } from '../validators/crm.validators.js';
|
||||
import { z } from 'zod';
|
||||
@@ -22,6 +23,7 @@ router.get('/', projectController.getAllProjects);
|
||||
router.get(
|
||||
'/:projectId',
|
||||
validateParams(z.object({ projectId: z.string().uuid() })),
|
||||
checkProjectAccess,
|
||||
projectController.getProjectById
|
||||
);
|
||||
|
||||
@@ -54,6 +56,7 @@ router.delete(
|
||||
router.get(
|
||||
'/:projectId/notes',
|
||||
validateParams(z.object({ projectId: z.string().uuid() })),
|
||||
checkProjectAccess,
|
||||
projectController.getProjectNotes
|
||||
);
|
||||
|
||||
@@ -96,6 +99,7 @@ router.delete(
|
||||
router.get(
|
||||
'/:projectId/users',
|
||||
validateParams(z.object({ projectId: z.string().uuid() })),
|
||||
checkProjectAccess,
|
||||
projectController.getProjectUsers
|
||||
);
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import express from 'express';
|
||||
import * as todoController from '../controllers/todo.controller.js';
|
||||
import { authenticate } from '../middlewares/auth/authMiddleware.js';
|
||||
import { requireAdmin } from '../middlewares/auth/roleMiddleware.js';
|
||||
import { checkTodoAccess } from '../middlewares/auth/resourceAccessMiddleware.js';
|
||||
import { validateBody, validateParams } from '../middlewares/security/validateInput.js';
|
||||
import { createTodoSchema, updateTodoSchema } from '../validators/crm.validators.js';
|
||||
import { z } from 'zod';
|
||||
@@ -21,27 +23,31 @@ router.get('/', todoController.getAllTodos);
|
||||
router.get(
|
||||
'/:todoId',
|
||||
validateParams(z.object({ todoId: z.string().uuid() })),
|
||||
checkTodoAccess,
|
||||
todoController.getTodoById
|
||||
);
|
||||
|
||||
// Create new todo
|
||||
// Create new todo (admin only)
|
||||
router.post(
|
||||
'/',
|
||||
requireAdmin,
|
||||
validateBody(createTodoSchema),
|
||||
todoController.createTodo
|
||||
);
|
||||
|
||||
// Update todo
|
||||
// Update todo (admin only)
|
||||
router.patch(
|
||||
'/:todoId',
|
||||
requireAdmin,
|
||||
validateParams(z.object({ todoId: z.string().uuid() })),
|
||||
validateBody(updateTodoSchema),
|
||||
todoController.updateTodo
|
||||
);
|
||||
|
||||
// Delete todo
|
||||
// Delete todo (admin only)
|
||||
router.delete(
|
||||
'/:todoId',
|
||||
requireAdmin,
|
||||
validateParams(z.object({ todoId: z.string().uuid() })),
|
||||
todoController.deleteTodo
|
||||
);
|
||||
@@ -50,6 +56,7 @@ router.delete(
|
||||
router.patch(
|
||||
'/:todoId/toggle',
|
||||
validateParams(z.object({ todoId: z.string().uuid() })),
|
||||
checkTodoAccess,
|
||||
todoController.toggleTodo
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user