Files
task-list/docs/feature-subtasks-and-multi-assignees.md

4.5 KiB

Feature Update: Sub-tasks and Multi-Person Assignment

This document outlines the implementation of two major features: the ability to break down tasks into sub-tasks and the functionality to assign a single task to multiple users with specific workload allocations.

1. Feature Overview

Sub-tasks

  • Goal: To allow complex tasks to be broken down into a checklist of smaller, actionable items.
  • Functionality:
    • Users can create, edit, and delete sub-tasks directly on the parent task's detail page.
    • Each sub-task has a completion status (done/todo) that can be toggled with a checkbox.
    • The parent task displays a progress bar and a completion count (e.g., "3 of 5 completed") that updates in real-time.

Multi-Person Assignment

  • Goal: To support team collaboration by allowing a task to be assigned to more than one person.
  • Functionality:
    • The task form now allows selecting multiple assignees.
    • For each assignee, a workload percentage can be specified.
    • The form validates that the total workload for all assignees on a task sums to 100%.
    • The task detail page now displays all assignees and their corresponding workload percentages.

2. Technical Implementation

A. Database Schema (prisma/schema.prisma)

To support these features, the database schema was updated with two key changes:

  1. Self-referencing Relation for Sub-tasks: A one-to-many relationship was added to the Task model itself to create a parent-child hierarchy.

    • A parentId field was added to the Task model.
    • A parent and subTasks relation field established the hierarchy.
    • onDelete: Cascade ensures that deleting a parent task automatically deletes all of its sub-tasks.
  2. Many-to-Many Relation for Assignees: The direct assigneeId field on the Task model was removed and replaced with a new join table, TaskAssignee, to manage the many-to-many relationship between Task and User.

    • The TaskAssignee model includes taskId, userId, and a workloadPercentage field.

B. Backend API (src/app/api/)

The backend API routes were refactored to handle the new data structures:

  • GET /api/tasks/[id]: The Prisma query was updated to include the new assignees (with user data) and subTasks relations, providing the frontend with all necessary data for the task detail page.
  • PUT /api/tasks/[id]: The update logic now runs within a prisma.$transaction to ensure data integrity. When assignees are updated, it first deletes all existing TaskAssignee records for the task and then creates new ones based on the incoming data.
  • POST /api/tasks: The creation logic was also wrapped in a transaction to create the Task, its TaskAssignee records, and its TaskTag associations atomically.
  • GET /api/tasks: The filtering logic was updated to allow searching for tasks based on the new assignees relation.

C. Frontend Components (src/components/)

Several new components were created, and existing ones were modified:

  • SubTaskItem.tsx: A new component to render a single sub-task. It manages its own state for editing and handles status updates and deletion.
  • SubTaskList.tsx: A new component that lists all SubTaskItems and includes a form for creating new sub-tasks for a given parent.
  • TaskForm.tsx: This component underwent a major refactoring.
    • The state (FormData) was updated to manage an array of assignees objects instead of a single assigneeId.
    • The UI was completely overhauled, replacing the simple assignee dropdown with an interactive list that allows adding/removing users and setting their workload percentages.
    • Real-time validation was added to ensure the total workload percentage sums to 100%.
  • page.tsx (src/app/tasks/[id]): The task detail page was updated to integrate the SubTaskList component and to correctly display the list of multiple assignees.

D. Type Definitions (src/types/task.ts)

All relevant TypeScript types, including Task, TaskWithRelations, CreateTaskInput, and UpdateTaskInput, were updated to reflect the new database schema, ensuring type safety across the application.

E. Data Converters (src/lib/taskConverters.ts)

The data converter functions, which map data between the Prisma client response and the frontend's expected types, were rewritten to handle the new assignees and subTasks arrays recursively, ensuring a consistent data shape throughout the app.