feat: Member permissions, optional phone, public users endpoint

- Allow members to create todos, companies, projects
- Auto-assign creator to resources (companyUsers, projectUsers, todoUsers)
- Add public /api/users endpoint for all authenticated users
- Make phone field optional in personal contacts (schema + validation)
- Update todo routes to use checkTodoAccess for updates

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
richardtekula
2026-01-16 07:08:42 +01:00
parent 3e8cd7b6ce
commit 47b68e672b
11 changed files with 70 additions and 11 deletions

View File

@@ -44,10 +44,9 @@ router.get(
companyController.getCompanyById
);
// Create new company (admin only)
// Create new company (any authenticated user)
router.post(
'/',
requireAdmin,
validateBody(createCompanySchema),
companyController.createCompany
);

View File

@@ -9,7 +9,7 @@ const router = express.Router()
const createContactSchema = z.object({
firstName: z.string().min(1, 'Meno je povinné'),
lastName: z.string().optional(),
phone: z.string().min(3, 'Telefón je povinný'),
phone: z.string().optional().nullable(),
email: z.string().email('Neplatný email'),
secondaryEmail: z.union([z.string().email('Neplatný email'), z.literal('')]).optional(),
companyId: z.union([z.string().uuid(), z.literal(''), z.null()]).optional(),

View File

@@ -27,10 +27,9 @@ router.get(
projectController.getProjectById
);
// Create new project (admin only)
// Create new project (any authenticated user)
router.post(
'/',
requireAdmin,
validateBody(createProjectSchema),
projectController.createProject
);

View File

@@ -27,19 +27,18 @@ router.get(
todoController.getTodoById
);
// Create new todo (admin only)
// Create new todo (any authenticated user)
router.post(
'/',
requireAdmin,
validateBody(createTodoSchema),
todoController.createTodo
);
// Update todo (admin only)
// Update todo (user must have access to the todo)
router.patch(
'/:todoId',
requireAdmin,
validateParams(z.object({ todoId: z.string().uuid() })),
checkTodoAccess,
validateBody(updateTodoSchema),
todoController.updateTodo
);

34
src/routes/user.routes.js Normal file
View File

@@ -0,0 +1,34 @@
import express from 'express';
import { authenticate } from '../middlewares/auth/authMiddleware.js';
import { db } from '../config/database.js';
import { users } from '../db/schema.js';
const router = express.Router();
// All user routes require authentication
router.use(authenticate);
/**
* Get all users (basic info only - for dropdowns, assignment, etc.)
* Available to all authenticated users
*/
router.get('/', async (req, res, next) => {
try {
const allUsers = await db
.select({
id: users.id,
username: users.username,
firstName: users.firstName,
lastName: users.lastName,
role: users.role,
})
.from(users)
.orderBy(users.username);
res.json(allUsers);
} catch (error) {
next(error);
}
});
export default router;