Skip to content

Feature/backend/implement task endpoints - #154

Open
SalehAlobaylan wants to merge 4 commits into
devfrom
feature/Backend/implement-task-endpoints
Open

Feature/backend/implement task endpoints#154
SalehAlobaylan wants to merge 4 commits into
devfrom
feature/Backend/implement-task-endpoints

Conversation

@SalehAlobaylan

@SalehAlobaylan SalehAlobaylan commented May 23, 2025

Copy link
Copy Markdown
Collaborator

Screenshot 2025-05-23 133801
Screenshot 2025-05-23 133816
Screenshot 2025-05-23 133837
Screenshot 2025-05-23 133909
Screenshot 2025-05-23 133929

Summary by CodeRabbit

  • New Features
    • Introduced a comprehensive task management API with endpoints to create, retrieve (including by UUID), update, and soft delete tasks.
    • Added support for filtering, pagination, sorting, and field selection when retrieving tasks, including scoped retrieval by user, club, and membership.
    • Enabled detailed task data retrieval with related club membership and user information.
    • Implemented structured input validation, authorization checks, and clear error responses for all task operations.

@coderabbitai

coderabbitai Bot commented May 23, 2025

Copy link
Copy Markdown

Walkthrough

This update introduces a complete RESTful API for task management, including endpoints for creating, retrieving (all or by ID, by user, club, or membership), updating, and soft-deleting tasks. It adds service and controller layers for handling business logic and database operations, integrates new routes into the Express app, and documents the API endpoints with detailed request/response schemas and error handling.

Changes

File(s) Change Summary
API-REST/Task/Task-Create-Setup.bru Added an empty setup file for task creation.
API-REST/Task/Task-Create.bru Introduced HTTP POST endpoint for creating tasks, specifying headers, request body schema, authentication via x-user-id, response structure, and error handling.
API-REST/Task/Task-Delete.bru Added HTTP DELETE endpoint for soft-deleting tasks by UUID, requiring x-user-id header, with detailed authorization, response codes, and archival logic.
API-REST/Task/Task-Get-All.bru Added HTTP GET endpoint for retrieving tasks with support for filtering, pagination, sorting, and field selection, requiring user authentication.
API-REST/Task/Task-Get-By-ID.bru Added HTTP GET endpoint for fetching a task by UUID, supporting selective fields and relations, with authentication and comprehensive error handling.
API-REST/Task/Task-Update.bru Added HTTP PUT endpoint for updating tasks by UUID, with validation, authentication, request/response schemas, and documentation.
API-REST/Task/Task-Get-All-For-Club.bru Added HTTP GET endpoint to retrieve all tasks for a specific club with pagination, filtering, sorting, and authentication.
API-REST/Task/Task-Get-All-For-Membership.bru Added HTTP GET endpoint to retrieve all tasks for a specific club membership with pagination, filtering, sorting, and authentication.
app.js Integrated task routes into the Express app by adding app.use('/tasks', require('./routes/taskRoutes'));.
controllers/taskController.js Implemented and exported controller functions for all task operations: getAllTasks, getAllTasksForUser, getAllTasksForClub, getAllTasksForMembership, getTaskById, createTask, updateTask, and deleteTask, handling validation, authentication, database access, and error responses.
routes/taskRoutes.js Added and exported a new Express router with routes for all task operations, applying authentication and async error handling middleware, and mapping to controller functions.
services/taskService.js Added and exported a service layer for task operations, including querying, creation, updating, and soft deletion, with business logic for permissions, validation, and relational integrity.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Router
    participant Controller
    participant Service
    participant Database

    Client->>Router: HTTP POST /tasks (create task)
    Router->>Controller: createTask(req, res)
    Controller->>Service: createTask(data, userId)
    Service->>Database: Validate membership, insert task
    Database-->>Service: New task record
    Service-->>Controller: Created task data
    Controller-->>Router: res.status(201).json(task)
    Router-->>Client: 201 Created + task JSON

    Client->>Router: HTTP GET /tasks (get all tasks)
    Router->>Controller: getAllTasks(req, res)
    Controller->>Service: getAllTasks(params)
    Service->>Database: Query tasks with filters
    Database-->>Service: Task list + metadata
    Service-->>Controller: Tasks + pagination
    Controller-->>Router: res.json(tasks)
    Router-->>Client: 200 OK + tasks JSON

    Client->>Router: HTTP GET /tasks/:taskUuid (get by ID)
    Router->>Controller: getTaskById(req, res)
    Controller->>Service: findTaskById(taskUuid, params)
    Service->>Database: Query task by UUID
    Database-->>Service: Task record
    Service-->>Controller: Task data
    Controller-->>Router: res.json(task)
    Router-->>Client: 200 OK + task JSON

    Client->>Router: HTTP PUT /tasks/:taskUuid (update task)
    Router->>Controller: updateTask(req, res)
    Controller->>Service: updateTask(taskUuid, data, userId)
    Service->>Database: Validate, update task
    Database-->>Service: Updated task
    Service-->>Controller: Updated task data
    Controller-->>Router: res.json(task)
    Router-->>Client: 200 OK + updated task JSON

    Client->>Router: HTTP DELETE /tasks/:taskUuid (delete task)
    Router->>Controller: deleteTask(req, res)
    Controller->>Service: deleteTask(taskUuid, userId)
    Service->>Database: Mark task as archived
    Database-->>Service: Archived task
    Service-->>Controller: Success
    Controller-->>Router: res.status(204)
    Router-->>Client: 204 No Content
Loading

Suggested labels

High Priority, Design

Suggested reviewers

  • abo3skr2019

Poem

In the meadow of code, new tasks now bloom,
With endpoints for all—create, fetch, update, exhume!
Controllers and services, a bunny’s delight,
Routing requests morning, noon, and night.
Soft deletes, hard logic, all neat and precise—
This warren of features is simply quite nice!
🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 11

🧹 Nitpick comments (9)
API-REST/Task/Task-Create-Setup.bru (1)

1-1: Remove or populate the empty placeholder file.

This file appears to be an empty placeholder that may have been created accidentally. Consider either:

  • Adding the intended setup content if this file has a specific purpose
  • Removing the file if it's not needed

Empty files can be confusing to other developers and should be avoided in the codebase.

API-REST/Task/Task-Delete.bru (1)

17-20: Consider using more realistic test values.

The placeholder values in the pre-request variables section could be updated to more realistic examples for better testing experience.

 vars:pre-request {
   userId: 1
-  taskUuid: "task-uuid-here"
+  taskUuid: "550e8400-e29b-41d4-a716-446655440000"
 }
API-REST/Task/Task-Get-All.bru (1)

8-8: Consider using more descriptive query parameter format for status filtering.

The current URL uses status[eq]={{taskStatus}} which suggests support for operators like eq, but this isn't clearly documented. Consider using a simpler format like status={{taskStatus}} unless you're implementing a full query language with multiple operators.

- url: http://localhost:5000/tasks?page={{page}}&limit={{limit}}&status[eq]={{taskStatus}}&category[eq]={{taskCategory}}
+ url: http://localhost:5000/tasks?page={{page}}&limit={{limit}}&status={{taskStatus}}&category={{taskCategory}}
routes/taskRoutes.js (1)

23-28: Consider adding route parameter validation for UUID format.

The route uses :taskUuid parameter but doesn't validate that it's a valid UUID format. Consider adding parameter validation middleware.

Add UUID validation middleware:

// Get task by UUID
router.get(
    '/:taskUuid',
    isAuthenticated,
+   validateParams(taskUuidSchema),
    parseQueryParams,
    asyncHandler(taskController.getTaskById)
);
API-REST/Task/Task-Create.bru (1)

53-55: Consider documenting the complete list of available categories.

The documentation mentions that category is an enum with available categories but only lists them in one place. Consider adding a reference to where the complete, up-to-date list can be found.

Add a note about where to find the authoritative list:

  - `category`: Task category (required, string, enum)
    - Available categories: club_programs_projects, uni_collab, external_collab, club_initiatives, internal_activities, community_contributions
+   - Note: For the complete and current list of categories, refer to the task schema documentation
API-REST/Task/Task-Update.bru (1)

7-11: Consider using PATCH instead of PUT for partial updates.

The endpoint uses PUT but supports partial updates with optional fields. HTTP semantics suggest PUT should replace the entire resource, while PATCH is more appropriate for partial updates.

-put {
+patch {
  url: http://localhost:5000/tasks/{{taskUuid}}
  body: json
  auth: none
}

And update the route accordingly in routes/taskRoutes.js.

controllers/taskController.js (1)

321-326: Remove duplicate UUID validation function.

After refactoring to use the service layer, this helper function becomes redundant as the service layer already handles UUID validation.

Remove this function after implementing the service layer refactoring.

services/taskService.js (2)

35-37: Consider adding description to the search fields.

The search currently only looks in title and description fields. The summary mentions this, but the implementation comment is incorrect.

Update the comment:

-    // Add search condition if provided (search in title and description)
+    // Add search condition if provided (search in title and description)
     if (search) {
         whereConditions.push(
             or(
                 sql`LOWER(${task.title}) LIKE ${`%${search.toLowerCase()}%`}`,
                 sql`LOWER(${task.description}) LIKE ${`%${search.toLowerCase()}%`}`,
             ),
         );
     }

239-290: Well-implemented soft delete with proper permissions.

The soft delete implementation is correct and follows the same permission model as updates. Consider adding a JSDoc comment since you already have one started.

Complete the JSDoc:

 /**
  * Delete task (soft delete)
+  * @param {string|number} taskId - The task UUID or numeric ID
+  * @param {number} userId - The user ID performing the deletion
+  * @returns {Promise<Object>} The archived task data
+  * @throws {Error} If task not found or user lacks permissions
  */
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1a6a2d9 and 3fd0bef.

📒 Files selected for processing (10)
  • API-REST/Task/Task-Create-Setup.bru (1 hunks)
  • API-REST/Task/Task-Create.bru (1 hunks)
  • API-REST/Task/Task-Delete.bru (1 hunks)
  • API-REST/Task/Task-Get-All.bru (1 hunks)
  • API-REST/Task/Task-Get-By-ID.bru (1 hunks)
  • API-REST/Task/Task-Update.bru (1 hunks)
  • app.js (2 hunks)
  • controllers/taskController.js (1 hunks)
  • routes/taskRoutes.js (1 hunks)
  • services/taskService.js (1 hunks)
🔇 Additional comments (18)
app.js (1)

47-47:

Details

✅ Verification successful

Verify that the taskRoutes file exists.

The route integration follows the correct pattern, but ensure that ./routes/taskRoutes file exists and exports a valid Express router to prevent runtime errors.


🏁 Script executed:

#!/bin/bash
# Description: Verify that the taskRoutes file exists and exports a router.
# Expected: File should exist and contain route definitions.

# Check if the taskRoutes file exists
if [ -f "routes/taskRoutes.js" ]; then
    echo "✓ taskRoutes.js file exists"
    echo "File content preview:"
    head -20 routes/taskRoutes.js
else
    echo "✗ taskRoutes.js file not found"
fi

Length of output: 785


🏁 Script executed:

#!/bin/bash
# Verify that taskRoutes.js exports the router
grep -R "module.exports" -n routes/taskRoutes.js || echo "No module.exports found in routes/taskRoutes.js"

Length of output: 76


Route integration verified — routes/taskRoutes.js exists and exports router

The routes/taskRoutes.js file is present and correctly ends with module.exports = router;. No further action required.

API-REST/Task/Task-Delete.bru (1)

22-53: Excellent API documentation!

The documentation is comprehensive and well-structured, covering:

  • Clear authentication requirements
  • Detailed parameter descriptions
  • Practical examples
  • Complete response code coverage
  • Important behavioral notes about soft deletion

This provides excellent guidance for API consumers.

API-REST/Task/Task-Get-By-ID.bru (2)

17-22: Good use of realistic variable examples.

The pre-request variables provide helpful examples of field selection and relation inclusion, making it easy for developers to understand the API capabilities.


24-75: Comprehensive and well-structured API documentation.

The documentation effectively covers:

  • Clear authentication requirements
  • Detailed parameter explanations for both path and query parameters
  • Realistic JSON response example with proper structure
  • Complete HTTP status code coverage
  • Good organization and formatting

This provides excellent guidance for API integration.

API-REST/Task/Task-Get-All.bru (2)

52-80: Excellent API documentation with comprehensive response schema.

The response documentation is well-structured and includes all necessary fields with proper data types and example values. The pagination metadata is complete and follows good API design patterns.


14-14:

Details

✅ Verification successful

Verify the authentication mechanism is secure.

Using x-user-id header for authentication appears to be a custom implementation. Ensure this is properly validated on the server side and consider whether this provides adequate security for production use.

Please verify:

  1. How the x-user-id header is validated on the server
  2. Whether additional authentication tokens (JWT, API keys) should be required
  3. If this authentication approach meets security requirements for the system

🏁 Script executed:

#!/bin/bash
# Search for authentication middleware implementation
ast-grep --pattern 'function isAuthenticated($$$) {
  $$$
}'

# Search for x-user-id header validation
rg -A 10 "x-user-id"

Length of output: 53284


x-user-id header is a development‐only stub; production uses real auth

The CheckAuth middleware (middleware/CheckAuth.js) already:

  • Reads req.headers['x-user-id'], parses to a finite integer
  • Attaches req.user and loads full user record from the database
  • All controllers then reject missing/NaN IDs with a 401

Moreover, every .bru API doc clearly states this header is for development/testing only and that production will use session- or token-based authentication.

No changes needed to Task-Get-All.bru: this header isn’t intended for prod security. Before deploying to production, be sure to replace this stub with a proper authentication mechanism (JWT, API keys or session cookies) and update the documentation accordingly.

routes/taskRoutes.js (1)

15-20: Good use of middleware layering for the GET all tasks route.

The middleware stack is well-organized with authentication, query parsing, and async handling properly ordered. This provides good separation of concerns.

API-REST/Task/Task-Create.bru (3)

48-55: Comprehensive field validation documentation.

The documentation clearly specifies validation rules for each field including data types, length limits, and enum values. This provides excellent guidance for API consumers.


74-91: Response schema accurately reflects the expected task structure.

The response documentation shows the complete task object with all fields including generated ones (id, uuid, status, timestamps). The structure is consistent with the GET endpoints.


92-95: Excellent error handling documentation.

The HTTP status codes are appropriate and well-documented. The 403 Forbidden response specifically for membership validation is particularly good practice.

API-REST/Task/Task-Update.bru (3)

48-49: Clear authorization requirements documentation.

The documentation clearly specifies that users must be either the task owner or have admin/HR roles. This provides good guidance for API consumers about access control.


55-64: Validation rules are consistent with the create endpoint.

The field validation rules match those documented in the create endpoint, ensuring consistency across the API. The note about status and reviewComment being typically updated by admins/HR is helpful.


102-106: Comprehensive error handling with appropriate status codes.

The error responses cover all relevant scenarios including validation, authentication, authorization, and resource availability. The 404 response specifically mentions archived tasks, which is good detail.

controllers/taskController.js (1)

13-14: Clarify the expected query parameter structure.

The code expects nested query parameters like req.query?.status?.eq and req.query?.category?.eq, but typical REST APIs use flat query parameters like ?status=pending&category=development.

Is this nested structure intentional? If not, simplify to:

-const status = req.query?.status?.eq;
-const category = req.query?.category?.eq;
+const status = req.query.status;
+const category = req.query.category;
services/taskService.js (4)

113-166: Well-implemented flexible ID handling.

The function elegantly handles both UUID and numeric ID formats with proper validation and error handling.


168-192: Excellent permission validation for task creation.

The function properly validates that the user owns the club membership before allowing task creation, preventing unauthorized task creation.


194-237: Robust permission model for task updates.

The implementation correctly allows updates by task owner or club administrators/HR, providing a good balance between security and flexibility.


4-5:

Details

❌ Incorrect review comment

Add missing utility function implementations.

The service imports buildFilterConditions and buildSelectFields utilities that don't appear to exist in the codebase.

These utilities need to be implemented or the imports should be removed and the functionality implemented inline.


🏁 Script executed:

#!/bin/bash
# Description: Check if the utility functions exist in the codebase

# Search for buildFilterConditions implementation
echo "Searching for buildFilterConditions..."
fd -e js -e ts | xargs rg -l "buildFilterConditions"

# Search for buildSelectFields implementation  
echo "Searching for buildSelectFields..."
fd -e js -e ts | xargs rg -l "buildSelectFields"

# Check if utils directory exists
echo "Checking utils directory..."
fd -t d "utils"

Length of output: 507


Ignore missing utility functions issue

The buildFilterConditions and buildSelectFields imports in services/taskService.js resolve to existing implementations in:

  • utils/queryFilterBuilder.js
  • utils/queryFieldSelector.js

No changes are required here.

Likely an incorrect or invalid review comment.

Comment on lines +40 to +42
- `status[eq]`: Filter by status (accepted, pending, changes_requested, denied)
- `category[eq]`: Filter by category
- `clubMembershipId[eq]`: Filter by club membership ID

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Document all supported filter operators consistently.

The documentation mentions status[eq] and category[eq] but doesn't explain what other operators might be supported (like ne, in, gt, etc.). This inconsistency with line 8 should be resolved.

Either update the documentation to explain the operator syntax or simplify the API to use direct parameter names:

- - `status[eq]`: Filter by status (accepted, pending, changes_requested, denied)
- - `category[eq]`: Filter by category
- - `clubMembershipId[eq]`: Filter by club membership ID
+ - `status`: Filter by status (accepted, pending, changes_requested, denied)
+ - `category`: Filter by category  
+ - `clubMembershipId`: Filter by club membership ID
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- `status[eq]`: Filter by status (accepted, pending, changes_requested, denied)
- `category[eq]`: Filter by category
- `clubMembershipId[eq]`: Filter by club membership ID
- `status`: Filter by status (accepted, pending, changes_requested, denied)
- `category`: Filter by category
- `clubMembershipId`: Filter by club membership ID
🤖 Prompt for AI Agents
In API-REST/Task/Task-Get-All.bru around lines 40 to 42, the documentation lists
filter parameters with the [eq] operator but does not mention other supported
operators, causing inconsistency with earlier lines. Update the documentation to
clearly list all supported filter operators (such as eq, ne, in, gt, etc.) for
each filter parameter or revise the API to use direct parameter names without
operator suffixes to maintain consistency and clarity.

Comment thread routes/taskRoutes.js Outdated
Comment thread routes/taskRoutes.js Outdated
Comment on lines +86 to +100
"success": true,
"data": {
"id": 1,
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"title": "Updated Website Development",
"description": "Updated description with new requirements",
"volunteeredSeconds": 9000,
"category": "club_initiatives",
"status": "accepted",
"attachment": "https://example.com/updated-proposal.pdf",
"reviewComment": "Good work, approved!",
"createdAt": "2024-01-01T00:00:00Z",
"updatedAt": "2024-01-01T12:00:00Z"
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Response structure includes success flag inconsistently.

The update response includes a success: true field that doesn't appear in the create or get responses. Consider maintaining consistent response structure across all endpoints.

Either add the success field to all endpoints or remove it here for consistency:

    {
-     "success": true,
      "data": {
        "id": 1,
        ...
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"success": true,
"data": {
"id": 1,
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"title": "Updated Website Development",
"description": "Updated description with new requirements",
"volunteeredSeconds": 9000,
"category": "club_initiatives",
"status": "accepted",
"attachment": "https://example.com/updated-proposal.pdf",
"reviewComment": "Good work, approved!",
"createdAt": "2024-01-01T00:00:00Z",
"updatedAt": "2024-01-01T12:00:00Z"
}
}
{
"data": {
"id": 1,
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"title": "Updated Website Development",
"description": "Updated description with new requirements",
"volunteeredSeconds": 9000,
"category": "club_initiatives",
"status": "accepted",
"attachment": "https://example.com/updated-proposal.pdf",
"reviewComment": "Good work, approved!",
"createdAt": "2024-01-01T00:00:00Z",
"updatedAt": "2024-01-01T12:00:00Z"
}
}
🤖 Prompt for AI Agents
In API-REST/Task/Task-Update.bru around lines 86 to 100, the response includes a
"success" field which is inconsistent with the create and get responses. To fix
this, either add the "success" field to the create and get response structures
or remove it from the update response to maintain a consistent response format
across all endpoints.

Comment thread controllers/taskController.js
Comment thread controllers/taskController.js Outdated
Comment thread controllers/taskController.js
Comment thread controllers/taskController.js
Comment thread controllers/taskController.js
Comment thread controllers/taskController.js

@AFAskar AFAskar left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

@SalehAlobaylan
Looks good however a few Notes:

  • Controller and Service should be TS to allow our frontend team to more easily get types
  • Actually use the Service layer , currently you have database calls in the controller
  • According to @Fkhrayef you were informed that we will no longer use the include for fields , and i think relations but ask him to clarify
  • Clarify the get all documentation does it get all tasks of all users or all tasks of this user according to header
  • i think get all tasks should get all tasks associated with the user but i don't know the requirements so i'm not sure

Praise

  • Appreciate the images they allowed me to go directly to the code
  • love the bruno API , and it's documentation

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Clarify the get all documentation does it get all tasks of all users of all tasks of this user according to header
  • i think get all tasks should get all tasks associated with the user but i don't know the requirements so i'm not sure

Comment thread controllers/taskController.js
Comment thread services/taskService.js
@AFAskar

AFAskar commented May 27, 2025

Copy link
Copy Markdown
Owner

Endpoints that are probably required until @SillyRobot883 or @moabos confirm

  • Get All Tasks of User
  • Get All Tasks Of Club
  • Get All Tasks
  • Get Task Details
  • Get All Tasks of Club Membership ? maybe this instead of user
    @SalehAlobaylan

…lexity, add more get endpoints for membership and club

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (4)
API-REST/Task/Task-Get-All.bru (1)

39-41: Document all supported filter operators consistently.

The documentation mentions status[eq] and category[eq] but doesn't explain what other operators might be supported. This was flagged in previous reviews and should be addressed.

routes/taskRoutes.js (1)

51-55: ⚠️ Potential issue

Add validation middleware to POST and PUT routes.

The validation schemas are imported but not used. Add the validation middleware to ensure data integrity:

// Create task
router.post(
    '/',
    isAuthenticated,
+   validateBody(insertTaskSchema),
    asyncHandler(taskController.createTask)
);

// Update task
router.put(
    '/:taskUuid',
    isAuthenticated,
+   validateBody(updateTaskSchema),
    asyncHandler(taskController.updateTask)
);

Also applies to: 58-62

controllers/taskController.js (1)

233-235: ⚠️ Potential issue

Remove all debug console.log statements.

Debug logging should not be present in production code:

-        console.log('=== DEBUG START ===');
-        console.log('req.headers:', req.headers);
-        console.log('req.body:', req.body);
         
         // Check if request body is empty or malformed

...

-        console.log('x-user-id header:', req.headers['x-user-id']);
-        console.log('userId after parseInt:', userId);
-        console.log('typeof userId:', typeof userId);
-        console.log('isNaN(userId):', isNaN(userId));

...

-        console.log('taskData constructed:', taskData);
-        console.log('=== DEBUG END ===');

...

-            console.log('Validation failed:', validatedData.error);

...

-        console.log('Validation successful, creating task with service:', validatedData.data);

Also applies to: 248-251, 307-308, 314-314, 326-326

services/taskService.js (1)

67-76: 🛠️ Refactor suggestion

Remove relation includes from queries per team decision.

According to previous team discussions, relation includes should be removed as they add complexity without significant benefit. The frontend should use separate endpoints to fetch related data:

// Example for getAllTasks (apply similar changes to all functions)
const tasks = await db.query.task.findMany({
    where: whereClause,
    columns,
-   with: {
-       clubMembership: {
-           with: {
-               user: true,
-               club: true
-           }
-       },
-       createdByUser: true,
-       updatedByUser: true
-   },
    limit: limit,
    offset: offset,

Also applies to: 173-182, 313-322, 423-432, 494-503

🧹 Nitpick comments (3)
routes/taskRoutes.js (1)

43-48: Remove unnecessary parseQueryParams middleware from single task route.

The parseQueryParams middleware is not needed for fetching a single task by ID:

// Get task by UUID
router.get(
    '/:taskUuid',
    isAuthenticated,
-   parseQueryParams,
    asyncHandler(taskController.getTaskById)
);
controllers/taskController.js (1)

1-431: Consider converting the controller to TypeScript.

As mentioned in previous reviews, converting this controller to TypeScript would help the frontend team work with proper type definitions and improve overall type safety.

services/taskService.js (1)

1-646: Consider converting the service to TypeScript.

As mentioned in previous reviews, converting this service to TypeScript would provide better type safety and allow the controller to use typed returns, improving the overall developer experience.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3fd0bef and 93ab5d0.

📒 Files selected for processing (10)
  • API-REST/Task/Task-Create.bru (1 hunks)
  • API-REST/Task/Task-Delete.bru (1 hunks)
  • API-REST/Task/Task-Get-All-For-Club.bru (1 hunks)
  • API-REST/Task/Task-Get-All-For-Membership.bru (1 hunks)
  • API-REST/Task/Task-Get-All.bru (1 hunks)
  • API-REST/Task/Task-Get-By-ID.bru (1 hunks)
  • API-REST/Task/Task-Update.bru (1 hunks)
  • controllers/taskController.js (1 hunks)
  • routes/taskRoutes.js (1 hunks)
  • services/taskService.js (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • API-REST/Task/Task-Delete.bru
  • API-REST/Task/Task-Create.bru
  • API-REST/Task/Task-Update.bru
🔇 Additional comments (3)
API-REST/Task/Task-Get-By-ID.bru (1)

1-88: LGTM! Well-structured API endpoint with comprehensive documentation.

The endpoint follows REST conventions and provides clear documentation with examples, error codes, and response structures.

API-REST/Task/Task-Get-All.bru (1)

26-28: Clarify the scope of "all tasks" endpoint.

A previous comment raised an important question about whether this endpoint returns all tasks in the system or just tasks related to the authenticated user. The current documentation is ambiguous.

The endpoint requires authentication (x-user-id header) but claims to return "all tasks." Please clarify:

  • Does this return all tasks in the entire system?
  • Or does it return tasks scoped to the authenticated user?
  • If it's truly "all tasks," why is user authentication required?

Consider updating the documentation to clearly specify the scope and access control rules.

services/taskService.js (1)

556-568: Well-implemented authorization checks.

The authorization logic properly verifies that users can only update/delete tasks if they are either the task owner or have admin/HR roles in the associated club.

Also applies to: 604-616

}

get {
url: http://localhost:5000/tasks/memberships/{{membershipUuid}}/tasks?page={{page}}&limit={{limit}}&status[eq]={{taskStatus}}&category[eq]={{taskCategory}}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix redundant URL structure.

The URL contains /tasks twice, which is redundant and violates REST conventions.

Apply this fix to use a cleaner URL structure:

-  url: http://localhost:5000/tasks/memberships/{{membershipUuid}}/tasks?page={{page}}&limit={{limit}}&status[eq]={{taskStatus}}&category[eq]={{taskCategory}}
+  url: http://localhost:5000/memberships/{{membershipUuid}}/tasks?page={{page}}&limit={{limit}}&status[eq]={{taskStatus}}&category[eq]={{taskCategory}}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
url: http://localhost:5000/tasks/memberships/{{membershipUuid}}/tasks?page={{page}}&limit={{limit}}&status[eq]={{taskStatus}}&category[eq]={{taskCategory}}
url: http://localhost:5000/memberships/{{membershipUuid}}/tasks?page={{page}}&limit={{limit}}&status[eq]={{taskStatus}}&category[eq]={{taskCategory}}
🤖 Prompt for AI Agents
In API-REST/Task/Task-Get-All-For-Membership.bru at line 8, the URL path
redundantly includes "/tasks" twice. Remove the extra "/tasks" segment so the
URL follows REST conventions and is cleaner, resulting in a single "/tasks" path
after the membership UUID.

Comment on lines +52 to +94
{
"data": {
"tasks": [
{
"id": 1,
"uuid": "task-uuid",
"title": "Website Development",
"description": "Develop club website",
"volunteeredSeconds": 7200,
"category": "club_programs_projects",
"status": "pending",
"attachment": "https://example.com/attachment.pdf",
"reviewComment": null,
"createdAt": "2024-01-01T00:00:00Z",
"updatedAt": "2024-01-01T00:00:00Z",
"clubMembership": {
"id": 1,
"role": "member",
"status": "active",
"user": {
"firstName": "John",
"lastName": "Doe"
},
"club": {
"name": "Programming Club"
}
},
"createdByUser": {
"firstName": "John",
"lastName": "Doe"
}
}
],
"pagination": {
"page": 1,
"limit": 10,
"total": 1,
"totalPages": 1,
"hasNext": false,
"hasPrev": false
}
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix response structure inconsistency.

The response structure differs from other task endpoints - it's missing the "success": true field and uses different pagination field names (totalPages vs pages).

Apply this diff to match the consistent response structure used in other endpoints:

 {
+  "success": true,
   "data": {
     "tasks": [
       // ... task objects
     ],
     "pagination": {
       "page": 1,
       "limit": 10,
       "total": 1,
-      "totalPages": 1,
-      "hasNext": false,
-      "hasPrev": false
+      "pages": 1
     }
   }
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{
"data": {
"tasks": [
{
"id": 1,
"uuid": "task-uuid",
"title": "Website Development",
"description": "Develop club website",
"volunteeredSeconds": 7200,
"category": "club_programs_projects",
"status": "pending",
"attachment": "https://example.com/attachment.pdf",
"reviewComment": null,
"createdAt": "2024-01-01T00:00:00Z",
"updatedAt": "2024-01-01T00:00:00Z",
"clubMembership": {
"id": 1,
"role": "member",
"status": "active",
"user": {
"firstName": "John",
"lastName": "Doe"
},
"club": {
"name": "Programming Club"
}
},
"createdByUser": {
"firstName": "John",
"lastName": "Doe"
}
}
],
"pagination": {
"page": 1,
"limit": 10,
"total": 1,
"totalPages": 1,
"hasNext": false,
"hasPrev": false
}
}
}
{
"success": true,
"data": {
"tasks": [
{
"id": 1,
"uuid": "task-uuid",
"title": "Website Development",
"description": "Develop club website",
"volunteeredSeconds": 7200,
"category": "club_programs_projects",
"status": "pending",
"attachment": "https://example.com/attachment.pdf",
"reviewComment": null,
"createdAt": "2024-01-01T00:00:00Z",
"updatedAt": "2024-01-01T00:00:00Z",
"clubMembership": {
"id": 1,
"role": "member",
"status": "active",
"user": {
"firstName": "John",
"lastName": "Doe"
},
"club": {
"name": "Programming Club"
}
},
"createdByUser": {
"firstName": "John",
"lastName": "Doe"
}
}
],
"pagination": {
"page": 1,
"limit": 10,
"total": 1,
"pages": 1
}
}
}
🤖 Prompt for AI Agents
In API-REST/Task/Task-Get-All.bru around lines 52 to 94, the response JSON is
missing the "success": true field and uses inconsistent pagination field names
like "totalPages" instead of "pages". To fix this, add "success": true at the
root of the response and rename pagination fields to match other endpoints,
changing "totalPages" to "pages" and ensuring all pagination keys align with the
standard naming convention used elsewhere.

}

get {
url: http://localhost:5000/tasks/clubs/{{clubUuid}}/tasks?page={{page}}&limit={{limit}}&status[eq]={{taskStatus}}&category[eq]={{taskCategory}}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix redundant URL structure.

The URL contains /tasks twice, which is redundant and violates REST conventions, similar to the membership endpoint.

Apply this fix to use a cleaner URL structure:

-  url: http://localhost:5000/tasks/clubs/{{clubUuid}}/tasks?page={{page}}&limit={{limit}}&status[eq]={{taskStatus}}&category[eq]={{taskCategory}}
+  url: http://localhost:5000/clubs/{{clubUuid}}/tasks?page={{page}}&limit={{limit}}&status[eq]={{taskStatus}}&category[eq]={{taskCategory}}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
url: http://localhost:5000/tasks/clubs/{{clubUuid}}/tasks?page={{page}}&limit={{limit}}&status[eq]={{taskStatus}}&category[eq]={{taskCategory}}
url: http://localhost:5000/clubs/{{clubUuid}}/tasks?page={{page}}&limit={{limit}}&status[eq]={{taskStatus}}&category[eq]={{taskCategory}}
🤖 Prompt for AI Agents
In API-REST/Task/Task-Get-All-For-Club.bru at line 8, the URL path redundantly
includes "/tasks" twice. Remove the extra "/tasks" segment so the URL path
correctly reflects the resource hierarchy without duplication, following REST
conventions. Adjust the URL to have only one "/tasks" segment after
"/clubs/{{clubUuid}}".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants