Skip to content

Conversation

@Achintya-Chatterjee
Copy link
Contributor

@Achintya-Chatterjee Achintya-Chatterjee commented Dec 9, 2025

Date: 10th December, 2025

Developer Name: @Achintya-Chatterjee


Issue Ticket Number

Description

  • extend fetch serializer and OpenAPI docs to accept repeated assigneeId parameters
  • validate assignee membership in TaskListView and forward normalised IDs to TaskService
  • teach TaskRepository list/count to intersect team and assignee scopes correctly while honouring creator visibility
  • add unit coverage across serializer, view, service, and repository for new filtering paths

Documentation Updated?

  • Yes
  • No

Under Feature Flag

  • Yes
  • No

Database Changes

  • Yes
  • No

Breaking Changes

  • Yes
  • No

Development Tested?

  • Yes
  • No

Screenshots

Screenshot 1
Screen.Recording.2025-12-10.at.02.24.38.mp4
Screen.Recording.2025-12-10.at.03.00.51.mov

Test Coverage

Screenshot 1 Screenshot 2025-12-10 at 01 18 20

Additional Notes

- extend fetch serializer and OpenAPI docs to accept repeated assigneeId parameters
- validate assignee membership in TaskListView and forward normalized IDs to TaskService
- teach TaskRepository list/count to intersect team and assignee scopes correctly while honoring creator visibility
- add unit coverage across serializer, view, service, and repository for new filtering paths
- document curl verification of /v1/tasks with team-scoped assignee filters
@Achintya-Chatterjee Achintya-Chatterjee self-assigned this Dec 9, 2025
@coderabbitai
Copy link

coderabbitai bot commented Dec 9, 2025

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

This PR implements assignee filtering for the GET /tasks endpoint. A new assigneeId query parameter is parsed, validated to ensure assignees belong to the specified team, and threaded through the service and repository layers to filter tasks by matching task assignments in MongoDB.

Changes

Cohort / File(s) Summary
Repository filtering logic
todo/repositories/task_repository.py
Added _get_task_ids_for_assignees helper method to resolve task IDs from TaskAssignmentRepository for given assignee IDs (optionally scoped to team). Extended list and count methods with assignee_ids parameter to filter tasks via $in query on resolved task IDs; consolidated filtering logic to handle assignee, team, and user filters with proper $or conditions.
Serializer and query parameter extraction
todo/serializers/get_tasks_serializer.py
Introduced QueryParameterListField custom field to parse repeated query parameters from QueryDict. Added assigneeId field to GetTaskQueryParamsSerializer and updated validation to deduplicate and map assigneeId into assignee_ids in validated data.
Service layer
todo/services/task_service.py
Added assignee_ids parameter to TaskService.get_tasks method and threaded it through to TaskRepository.list and count calls.
View and validation
todo/views/task.py
Added assigneeIds query parameter with validation: requires teamId when assigneeId is provided; validates each assignee ID is a member of the specified team using UserTeamDetailsRepository. Passes validated assignee_ids to TaskService.get_tasks. Extended API schema documentation.
Repository tests
todo/tests/unit/repositories/test_task_repository.py
Added 11 new test cases covering: empty results and early return when assignee filter has no matches; filtering by assignee IDs with $in query; inclusion of user-created tasks when no assignments exist; team+assignee interaction; team filter skipping user filter; helper method _get_task_ids_for_assignees ObjectId conversion and team scoping.
Serializer tests
todo/tests/unit/serializers/test_get_tasks_serializer.py
Added tests for QueryDict parsing of repeated assigneeId parameters and deduplication in validated data.
Service tests
todo/tests/unit/services/test_task_service.py
Updated existing tests to expect assignee_ids parameter in repository method calls.
View tests
todo/tests/unit/views/test_task.py
Added tests for: rejecting assigneeId without teamId; rejecting assignee IDs not in team; successful filtering with valid team+assignee combination. Updated existing tests to pass assignee_ids=None for backward compatibility.

Sequence Diagram

sequenceDiagram
    participant Client
    participant TaskListView
    participant UserTeamDetailsRepository
    participant TaskService
    participant TaskRepository
    participant TaskAssignmentRepository
    participant MongoDB

    Client->>TaskListView: GET /tasks?teamId=X&assigneeId=Y
    TaskListView->>UserTeamDetailsRepository: get_users_by_team_id(teamId=X)
    UserTeamDetailsRepository-->>TaskListView: team members list
    TaskListView->>TaskListView: validate assigneeId in team members
    alt assigneeId not in team
        TaskListView-->>Client: 400 USER_NOT_TEAM_MEMBER
    else valid
        TaskListView->>TaskService: get_tasks(..., assignee_ids=[Y])
        TaskService->>TaskRepository: list(..., assignee_ids=[Y])
        TaskRepository->>TaskAssignmentRepository: _get_task_ids_for_assignees([Y], team_id=X)
        TaskAssignmentRepository->>MongoDB: query task_assignments by assignee_id & team_id
        MongoDB-->>TaskAssignmentRepository: task IDs
        TaskAssignmentRepository-->>TaskRepository: resolved task IDs
        TaskRepository->>MongoDB: query tasks where _id in [task_ids]
        MongoDB-->>TaskRepository: filtered tasks
        TaskRepository-->>TaskService: task list
        TaskService->>TaskRepository: count(..., assignee_ids=[Y])
        TaskRepository-->>TaskService: count (same filter logic)
        TaskService-->>TaskListView: GetTasksResponse
        TaskListView-->>Client: 200 tasks with pagination
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Filter logic in _get_task_ids_for_assignees and repository methods: Verify ObjectId conversion, team scoping, and proper $in/$or query construction for filtering accuracy.
  • View validation: Ensure team membership check is called correctly and error responses include proper field attribution.
  • Test coverage: Review comprehensive test scenarios for edge cases (empty results, team+assignee combinations, user-created task inclusion).
  • Parameter threading: Verify assignee_ids is correctly propagated from view through service to repository without unintended side effects.

Possibly related issues

Possibly related PRs

Suggested labels

tests

Suggested reviewers

  • iamitprakash
  • shobhan-sundar-goutam
  • Hariom01010

Poem

🐰 A filter for assignees hops into place,
Tasks grouped by team, none left out of grace.
Validation checks leap through the queue,
Parameters thread from view to repository true.
Tests blossom forth in gardens anew,
Filtering dreams now finally through! 🌱

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.28% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main feature being added: assignee filtering support in team task listings, directly corresponding to the PR's primary objective.
Linked Issues check ✅ Passed The PR implements all core requirements from issue #291: accept assigneeId query parameter [#291], validate assignee membership in TaskListView [#291], update TaskService.get_tasks with assignee_ids [#291], implement filtering in TaskRepository using TaskAssignmentRepository [#291], and add unit test coverage [#291].
Out of Scope Changes check ✅ Passed All changes directly support the assignee filtering feature objective. No unrelated modifications to other functionality, database schemas, or external systems are present beyond the scope of issue #291.
Description check ✅ Passed The PR description clearly relates to the changeset, detailing support for assignee filtering in team task listings with specific implementation steps matching the file changes.

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

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai bot added the tests Adds or updates tests label Dec 9, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
todo/services/task_service.py (1)

67-78: Remove the redundant inner TeamRepository import for clarity and easier mocking

The module-level import of TeamRepository at line 29 already makes the class available throughout the file. The inner import at line 84 is unnecessary and complicates test mocking. Remove it and rely on the top-level import:

        if team_id:
-            from todo.repositories.team_repository import TeamRepository
-
             if not TeamRepository.is_user_team_member(team_id, user_id):

This keeps behavior identical but allows tests to cleanly patch todo.services.task_service.TeamRepository.is_user_team_member without dealing with runtime imports. The assignee_ids parameter threading through TaskRepository.list and count is correct and maintains backward compatibility when None.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 92ad665 and 11f5f86.

📒 Files selected for processing (8)
  • todo/repositories/task_repository.py (3 hunks)
  • todo/serializers/get_tasks_serializer.py (3 hunks)
  • todo/services/task_service.py (2 hunks)
  • todo/tests/unit/repositories/test_task_repository.py (2 hunks)
  • todo/tests/unit/serializers/test_get_tasks_serializer.py (2 hunks)
  • todo/tests/unit/services/test_task_service.py (8 hunks)
  • todo/tests/unit/views/test_task.py (12 hunks)
  • todo/views/task.py (4 hunks)
🧰 Additional context used
🧠 Learnings (7)
📓 Common learnings
Learnt from: Achintya-Chatterjee
Repo: Real-Dev-Squad/todo-backend PR: 231
File: todo/repositories/task_repository.py:93-109
Timestamp: 2025-07-25T20:12:36.483Z
Learning: Issue #215 in the Real-Dev-Squad/todo-backend repository addresses the problem where tasks assigned to team members disappear from the team's todo list. The expected behavior is that tasks assigned to individual team members should still be visible in the team's todo list, which is implemented by aggregating both direct team assignments and member assignments in the _get_assigned_task_ids_for_team method.
Learnt from: Achintya-Chatterjee
Repo: Real-Dev-Squad/todo-backend PR: 231
File: todo/repositories/task_repository.py:93-109
Timestamp: 2025-07-25T20:12:36.483Z
Learning: In the todo-backend project, tasks can only be assigned to either a team (user_type = "team") or an individual user (user_type = "user"), never both simultaneously. When a POC reassigns a task from a team to an individual team member, the old team assignment is deactivated and a new user assignment is created, ensuring no overlapping assignments exist.
Learnt from: Achintya-Chatterjee
Repo: Real-Dev-Squad/todo-backend PR: 52
File: todo/views/task.py:106-106
Timestamp: 2025-05-29T21:36:27.694Z
Learning: Issue #26 in the Real-Dev-Squad/todo-backend repository comprehensively tracks user authentication implementation including registration, login, JWT tokens, and making task APIs require authentication. This covers replacing hardcoded user ID placeholders like "system_patch_user" with actual user ID extraction from authenticated requests.
Learnt from: Achintya-Chatterjee
Repo: Real-Dev-Squad/todo-backend PR: 52
File: todo/views/task.py:106-106
Timestamp: 2025-05-29T21:36:27.694Z
Learning: Issue #26 tracks the implementation of user authentication in the todo-backend project, which includes extracting user ID from request context to replace hardcoded placeholders like "system_patch_user" in todo/views/task.py.
📚 Learning: 2025-07-25T20:12:36.483Z
Learnt from: Achintya-Chatterjee
Repo: Real-Dev-Squad/todo-backend PR: 231
File: todo/repositories/task_repository.py:93-109
Timestamp: 2025-07-25T20:12:36.483Z
Learning: Issue #215 in the Real-Dev-Squad/todo-backend repository addresses the problem where tasks assigned to team members disappear from the team's todo list. The expected behavior is that tasks assigned to individual team members should still be visible in the team's todo list, which is implemented by aggregating both direct team assignments and member assignments in the _get_assigned_task_ids_for_team method.

Applied to files:

  • todo/services/task_service.py
  • todo/views/task.py
  • todo/tests/unit/views/test_task.py
  • todo/tests/unit/repositories/test_task_repository.py
  • todo/repositories/task_repository.py
  • todo/tests/unit/services/test_task_service.py
📚 Learning: 2025-07-23T19:26:43.747Z
Learnt from: Achintya-Chatterjee
Repo: Real-Dev-Squad/todo-backend PR: 227
File: todo/repositories/task_repository.py:0-0
Timestamp: 2025-07-23T19:26:43.747Z
Learning: In the todo-backend project, the get_tasks_for_user method in TaskRepository is intentionally designed to return only tasks assigned to the user (not tasks created by them), while the count method includes both tasks created by and assigned to the user. This behavioral difference is by design to serve different use cases.

Applied to files:

  • todo/services/task_service.py
  • todo/views/task.py
  • todo/tests/unit/repositories/test_task_repository.py
  • todo/repositories/task_repository.py
  • todo/tests/unit/services/test_task_service.py
📚 Learning: 2025-07-09T19:59:31.694Z
Learnt from: AnujChhikara
Repo: Real-Dev-Squad/todo-backend PR: 119
File: todo/repositories/task_repository.py:149-154
Timestamp: 2025-07-09T19:59:31.694Z
Learning: In the todo-backend project, per product requirements, tasks marked as deleted (isDeleted=True) should still be returned in user task queries. The get_tasks_for_user method in TaskRepository should not filter out deleted tasks, unlike typical soft deletion patterns.

Applied to files:

  • todo/services/task_service.py
  • todo/views/task.py
  • todo/tests/unit/repositories/test_task_repository.py
  • todo/repositories/task_repository.py
  • todo/tests/unit/services/test_task_service.py
📚 Learning: 2025-07-25T20:12:36.483Z
Learnt from: Achintya-Chatterjee
Repo: Real-Dev-Squad/todo-backend PR: 231
File: todo/repositories/task_repository.py:93-109
Timestamp: 2025-07-25T20:12:36.483Z
Learning: In the todo-backend project, tasks can only be assigned to either a team (user_type = "team") or an individual user (user_type = "user"), never both simultaneously. When a POC reassigns a task from a team to an individual team member, the old team assignment is deactivated and a new user assignment is created, ensuring no overlapping assignments exist.

Applied to files:

  • todo/views/task.py
  • todo/repositories/task_repository.py
📚 Learning: 2025-09-22T15:34:24.054Z
Learnt from: Hariom01010
Repo: Real-Dev-Squad/todo-backend PR: 279
File: todo/management/commands/migrate_add_roles_to_teams.py:3-3
Timestamp: 2025-09-22T15:34:24.054Z
Learning: In the todo-backend repository, UserTeamDetailsRepository is defined in todo/repositories/team_repository.py and should be imported from there, not from a separate module.

Applied to files:

  • todo/views/task.py
  • todo/repositories/task_repository.py
📚 Learning: 2025-07-25T20:12:36.483Z
Learnt from: Achintya-Chatterjee
Repo: Real-Dev-Squad/todo-backend PR: 231
File: todo/repositories/task_repository.py:93-109
Timestamp: 2025-07-25T20:12:36.483Z
Learning: In the todo-backend project's TaskAssignmentRepository, the update_assignment method ensures exclusive task assignments by deactivating all current active assignments for a task before creating a new assignment. This prevents any task from being simultaneously assigned to both a team and individual team members.

Applied to files:

  • todo/views/task.py
  • todo/tests/unit/repositories/test_task_repository.py
  • todo/repositories/task_repository.py
🧬 Code graph analysis (7)
todo/services/task_service.py (1)
todo/repositories/task_repository.py (1)
  • count (219-260)
todo/tests/unit/serializers/test_get_tasks_serializer.py (1)
todo/serializers/get_tasks_serializer.py (1)
  • GetTaskQueryParamsSerializer (27-88)
todo/views/task.py (2)
todo/repositories/team_repository.py (2)
  • UserTeamDetailsRepository (126-387)
  • get_users_by_team_id (223-232)
todo/constants/messages.py (1)
  • ValidationErrors (62-88)
todo/tests/unit/views/test_task.py (3)
todo/views/task.py (2)
  • get (83-140)
  • get (242-248)
todo/constants/messages.py (1)
  • ValidationErrors (62-88)
todo/dto/responses/get_tasks_response.py (1)
  • GetTasksResponse (7-8)
todo/tests/unit/repositories/test_task_repository.py (1)
todo/repositories/task_repository.py (2)
  • _get_task_ids_for_assignees (33-75)
  • count (219-260)
todo/repositories/task_repository.py (5)
todo/repositories/task_assignment_repository.py (1)
  • TaskAssignmentRepository (14-523)
todo/repositories/common/mongo_repository.py (1)
  • get_collection (17-20)
todo/models/task.py (1)
  • TaskModel (23-43)
todo/repositories/abstract_repository.py (1)
  • count (40-42)
todo/repositories/postgres_repository.py (1)
  • count (74-81)
todo/tests/unit/services/test_task_service.py (1)
todo/services/task_service.py (1)
  • get_tasks (68-134)
🪛 GitHub Actions: Tests
todo/tests/unit/services/test_task_service.py

[error] 151-151: AssertionError: Expected 'list' to be called once. Called 0 times.


[error] 1-1: Test suite failing due to mocks not being invoked as expected (get_tasks/list calls).

🔇 Additional comments (4)
todo/tests/unit/serializers/test_get_tasks_serializer.py (1)

3-4: Serializer assigneeId tests accurately cover QueryDict + dedup behavior

The new tests correctly verify that assigneeId is pulled from a QueryDict into validated_data["assignee_ids"] and that duplicates are removed while preserving order; using DRF’s ValidationError here is also appropriate for the existing assertions.

Also applies to: 75-89

todo/tests/unit/views/test_task.py (1)

48-57: View tests correctly exercise assignee filtering, validation, and default wiring

The updated assertions that TaskService.get_tasks is always called with assignee_ids=None in the non-filtered paths keep the contract tight, and the three new tests around assigneeId (missing teamId, non‑member rejection, and successful pass‑through of IDs) match the view logic and error‑handling expectations. Patching UserTeamDetailsRepository.get_users_by_team_id and verifying both error sources and the final assignee_ids argument gives solid coverage for the new behavior.

Also applies to: 106-147, 223-251, 292-348, 363-444

todo/repositories/task_repository.py (1)

32-76: Assignee‑based filtering in list/count is consistent and efficient

_get_task_ids_for_assignees correctly resolves active user assignments (optionally scoped by team_id), handling both string and ObjectId representations of IDs, and returning a unique set of ObjectId task IDs. The updates to list and count sensibly:

  • Start from the existing status filter.
  • Constrain by assignee IDs (with early return when there are no matching assignments).
  • Fall back to team‑wide task IDs when only team_id is provided.
  • Preserve the “createdBy OR assigned to user” semantics when no team scope is active, while skipping that user filter once a team scope (either via team_id or assignee_ids+team_id) is applied.

This matches the documented behavior around team vs user visibility and avoids unnecessary collection operations when filters produce an empty task set.

Also applies to: 110-155, 219-260

todo/tests/unit/repositories/test_task_repository.py (1)

94-204: Repository tests thoroughly cover new assignee and team scoping logic

The added unit tests for TaskRepository.list/count and _get_task_ids_for_assignees do a good job of pinning down the new behavior:

  • Verifying early exits when assignee filters yield no task IDs.
  • Asserting that _id $in filters appear inside the $and query for both list and count.
  • Ensuring team+assignee combinations rely exclusively on _get_task_ids_for_assignees(team_id=...) and skip _get_team_task_ids, and that team scoping suppresses the user createdBy/assigned OR clause.

The helper tests that inspect the generated assignment filter (including mixed string/ObjectId forms for assignee_id and team_id) are especially useful for catching regressions in how assignments are resolved.

Also applies to: 236-317

- accept repeated assigneeId query params and normalize them
- require valid team membership before passing assignee filters downstream
- thread assignee_ids through TaskService and TaskRepository list/count
- add coverage for team-scoped filtering paths across view/service/repo
- centralize the teamId missing validation message for consistency
- ensure GetTaskQueryParamsSerializer surfaces invalid assigneeId values
- rename repository helper set to assignee_lookup_values for readability
* test(tasks): cover team + assignee filtering scenarios

- add serializer, view, service, and repository specs for multi-assignee queries
- exercise team-scoped assignee resolution and list/count symmetry
- protect regressions where team filters should bypass user-level fallbacks

* test(tasks): cover team + assignee filtering scenarios

- add serializer, view, service, and repository specs for multi-assignee queries
- exercise team-scoped assignee resolution and list/count symmetry
- protect regressions where team filters should bypass user-level fallbacks

* test(tasks): cover team + assignee filtering scenarios

- add serializer, view, service, and repository specs for multi-assignee queries
- exercise team-scoped assignee resolution and list/count symmetry
- protect regressions where team filters should bypass user-level fallbacks

* fix: By stubbing is_user_team_member before asserting the repository calls, the test no longer bails out with a “FORBIDDEN” response; the mocked list/count methods are hit, and the assertions succeed.

* fix:failing test

* fix: formatting

* test(tasks): update assignee filtering tests for objectid validation

- use valid ObjectId strings in serializer and view tests
- ensure team membership mock aligns with validated assignee ids
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

tests Adds or updates tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feat: Implement Assignee Filtering in GET /tasks Endpoint

3 participants