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:
richardtekula
2025-12-12 07:41:57 +01:00
parent 918af3a843
commit 8656fb1db0
14 changed files with 2175 additions and 125 deletions

View File

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