🗂️ Day 3: (Building in public: OpsFlow - Authorization - The Part Most Developers Get Wrong)
Built the task management core today. Projects, tasks, members. Standard CRUD stuff.
Except it's not.
The Real Challenge:
Not "can users create tasks?" but "can THIS user modify THIS specific task?"
Here's where most apps fail:
❌ Authorization in middleware: `app.use('/tasks', verifyToken, taskRoutes)`
Problem: Every task route needs different rules. Update = different from delete.
✅ Authorization in service layer:
```typescript
async deleteTask(taskId: string, userId: string) {
const task = await Task.findById(taskId);
const project = await Project.findById(task.project);
// Resource-level check, not route-level
if (!project.hasAccess(userId)) {
throw new AuthorizationError();
}
// Action-level check
if (task.createdBy !== userId && !project.isOwner(userId)) {
throw new AuthorizationError("Only creator or owner can delete");
}
}
```
Why this scales:
1. Business rules stay in one place
2. Can be tested independently
3. Flexible per-resource rules
4. Clear error messages
The pattern I followed:
• Project owners can do everything
• Members can view + create tasks
• Task creators can edit their tasks
• Owners override all permissions
Also added:
• Pagination (page, limit, total) for list endpoints
• Filtering (status, priority, assignee)
• MongoDB indexes on query fields
• Proper population of related data
What I learned:
Security isn't a feature you add. It's a constraint you design around from day one.
Middleware is for "who are you?"
Service layer is for "what can you do?"
For juniors: Start with "deny by default" - explicitly allow what's needed, not the reverse.
How do you handle resource-level authorization in your stack?
#SoftwareArchitecture #Authorization #NodeJS #APIDesign #Security