feat(funnels): add task completion endpoint (M4-BE-011)#116
Merged
Conversation
added 2 commits
May 28, 2026 12:48
Adds PATCH /api/funnels/:funnelId/stages/:stageId/tasks/:taskId so users can mark a stage task complete or pending. Ownership is verified as a single funnel -> stage -> task chain that surfaces any break as a 404, parent-stage locked returns 403, and same-status requests are idempotent. The save path lets the StageTask @BeforeUpdate hook drive is_complete and completed_at instead of writing them directly.
…mpletion # Conflicts: # src/modules/funnels/actions/stage-task.action.ts
📝 WalkthroughWalkthroughThis PR adds a complete task status update feature to the funnels module. It introduces a new PATCH endpoint that allows users to update the status (pending/complete) of tasks within funnel stages, including request validation, ownership verification, stage-lock checks, idempotent behavior, and comprehensive error handling. ChangesTask Status Update Feature
Sequence DiagramsequenceDiagram
participant Client
participant Controller as FunnelsController
participant Service as FunnelsService
participant Action as StageTaskModelAction
participant Repo as Repository
Client->>Controller: PATCH /funnels/{funnelId}/stages/{stageId}/tasks/{taskId}
Controller->>Service: updateTaskStatus(userId, funnelId, stageId, taskId, status)
Service->>Action: findByFunnelAndUser(funnelId, userId)
Action-->>Service: Funnel or null
Service->>Action: findStageInFunnel(stageId)
Action-->>Service: FunnelStage or null
alt Stage is locked
Service-->>Controller: ForbiddenException with lock message
else Stage is not locked
Service->>Action: findOwnedTask(taskId, stageId)
Action-->>Service: StageTask or null
alt Task not found
Service-->>Controller: NotFoundException
else Task found
alt Status unchanged
Service-->>Controller: current TaskUpdateResult
else Status changed
Service->>Action: saveTask(updated task)
Repo-->>Action: persisted StageTask
Action-->>Service: saved entity
Service-->>Controller: new TaskUpdateResult
end
end
end
Controller-->>Client: { statusCode: 200, message, data: TaskUpdateResult }
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
|
Actionable comments posted: 0 |
elijaharhinful
approved these changes
May 28, 2026
sage-ali
approved these changes
May 28, 2026
9 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Adds
PATCH /api/funnels/:funnelId/stages/:stageId/tasks/:taskIdso a user can mark a stage task as complete or incomplete. Builds the write side of the stage task model that previously had only read paths, and unblocks M4-BE-012 dependencies that need a stage to be considered done.The endpoint:
Funnel task not found or not accessible.) to avoid leaking cross-user resource existence.FUNNEL_STAGE_LOCKED_MESSAGEwhen the parent stage is locked, naming the prior stage that still needs to be completed.repository.save(loadedEntity)via the newStageTaskModelAction.saveTaskso theStageTask.@BeforeUpdate syncCompletionState()hook keepsis_completeandcompleted_atin sync rather than the service writing those fields directly.Related Issue
Implements ticket M4-BE-011 (Milestone 4 - Profile, Notifications & Stage Execution).
Type of Change
How Has This Been Tested?
11 service tests cover every acceptance criterion (AC-01 through AC-09 plus an AC-09 mirror and a locked-stage fallback). Each was driven against the running API three times back to back; results were identical and matched the AC table.
Test Evidence
Documentation Screenshots (if applicable)
Checklist
Summary by CodeRabbit
New Features
Tests