# Bulk Actions Implementation

## Overview

This document describes the implementation of bulk action endpoints for the task management system. These endpoints allow coordinators and admins to perform batch operations on multiple tasks simultaneously.

## Endpoints

### 1. Bulk Status Update

**Endpoint:** `PUT /tasks/bulk/status`

**Request Body:**
```json
{
  "task_ids": [1, 2, 3],
  "status": "in_progress"
}
```

**Response:**
```json
{
  "success_count": 3,
  "failed_count": 0,
  "errors": null
}
```

**Permissions:**
- Coordinators and admins can update any tasks
- Artists can only update their own assigned tasks

**Features:**
- Atomic transaction handling - either all tasks update or none
- Permission validation for all tasks before making changes
- Detailed error reporting for failed tasks

### 2. Bulk Assignment

**Endpoint:** `PUT /tasks/bulk/assign`

**Request Body:**
```json
{
  "task_ids": [1, 2, 3],
  "assigned_user_id": 5
}
```

**Response:**
```json
{
  "success_count": 3,
  "failed_count": 0,
  "errors": null
}
```

**Permissions:**
- Only coordinators and admins can perform bulk assignments

**Features:**
- Atomic transaction handling
- Validates user is a member of all task projects
- Sends notifications to assigned user for each task
- Detailed error reporting for failed tasks

## Schemas

### BulkStatusUpdate
```python
class BulkStatusUpdate(BaseModel):
    task_ids: List[int] = Field(..., min_length=1)
    status: TaskStatus
```

### BulkAssignment
```python
class BulkAssignment(BaseModel):
    task_ids: List[int] = Field(..., min_length=1)
    assigned_user_id: int
```

### BulkActionResult
```python
class BulkActionResult(BaseModel):
    success_count: int
    failed_count: int
    errors: Optional[List[dict]] = None
```

## Atomicity

Both endpoints implement atomic transactions:

1. All tasks are fetched in a single query
2. All validations (permissions, project membership) are performed before any changes
3. If any validation fails, the transaction is rolled back and no changes are made
4. Only if all validations pass are the changes committed

This ensures that partial updates never occur - either all tasks are updated successfully or none are.

## Error Handling

Errors are returned in a structured format:

```json
{
  "success_count": 1,
  "failed_count": 2,
  "errors": [
    {
      "task_id": 99,
      "error": "Task not found"
    },
    {
      "task_id": 100,
      "error": "Not authorized to update this task"
    }
  ]
}
```

Common error scenarios:
- Task not found
- Insufficient permissions
- User not a project member (for assignments)

## Testing

A comprehensive test script is available at `backend/test_bulk_actions.py` that tests:

1. Successful bulk status updates
2. Successful bulk assignments
3. Error handling with invalid task IDs
4. Atomicity with mixed valid/invalid IDs
5. Permission validation

Run tests with:
```bash
python test_bulk_actions.py
```

## Implementation Notes

### Route Ordering

The bulk action endpoints are placed BEFORE the `/{task_id}` routes in the router to prevent FastAPI from trying to match "bulk" as a task_id parameter.

### Transaction Management

SQLAlchemy's session management is used for transactions:
- `db.commit()` commits all changes
- `db.rollback()` reverts all changes if errors occur

### Notifications

The bulk assignment endpoint sends individual notifications for each assigned task using the existing `notification_service.notify_task_assigned()` function.

## Requirements Validated

This implementation satisfies the following requirements from the spec:

- **4.2**: Bulk status update with atomic transaction handling
- **4.4**: Error handling and rollback on failure
- **5.3**: Bulk assignment with atomic transaction handling
- **5.5**: Error handling and rollback on failure
