docs(backend): Add Sprint 4 backend API verification and optional enhancement story

Backend APIs are 100% ready for Sprint 4 frontend implementation. Created comprehensive verification report and optional enhancement story for advanced UX fields.

Changes:
- Created backend_api_verification.md (detailed API analysis)
- Created Story 0: Backend API Enhancements (optional P2)
- Created 6 tasks for Story 0 implementation
- Updated Sprint 4 to include backend verification status
- Verified Story/Task CRUD APIs are complete
- Documented missing optional fields (AcceptanceCriteria, Tags, StoryPoints, Order)
- Provided workarounds for Sprint 4 MVP

Backend Status:
- Story API: 100% complete (8 endpoints)
- Task API: 100% complete (9 endpoints)
- Security: Multi-tenant isolation verified
- Missing optional fields: Can be deferred to future sprint

Frontend can proceed with P0/P1 Stories without blockers.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Yaojia Wang
2025-11-05 21:45:09 +01:00
parent 8ce89c11e9
commit b3c92042ed
8 changed files with 1758 additions and 0 deletions

View File

@@ -0,0 +1,254 @@
---
task_id: task_6
story_id: story_0
sprint_id: sprint_4
status: not_started
type: backend
assignee: backend
created_date: 2025-11-05
completion_date: null
---
# Task 6: Write Tests and Update Documentation
## What to do
Write comprehensive unit and integration tests for the new fields. Update API documentation and create example requests/responses.
## Files to create/modify
**Unit Tests**:
- `colaflow-api/tests/Modules/ProjectManagement/Domain.Tests/Aggregates/StoryTests.cs`
- `colaflow-api/tests/Modules/ProjectManagement/Domain.Tests/Aggregates/WorkTaskTests.cs`
**Integration Tests**:
- `colaflow-api/tests/Modules/ProjectManagement/Application.Tests/Commands/CreateStoryCommandTests.cs`
- `colaflow-api/tests/Modules/ProjectManagement/Application.Tests/Commands/UpdateStoryCommandTests.cs`
- `colaflow-api/tests/Modules/ProjectManagement/Application.Tests/Commands/CreateTaskCommandTests.cs`
- `colaflow-api/tests/Modules/ProjectManagement/Application.Tests/Commands/ReorderTasksCommandTests.cs`
**API Tests**:
- `colaflow-api/tests/API.Tests/Controllers/StoriesControllerTests.cs`
- `colaflow-api/tests/API.Tests/Controllers/TasksControllerTests.cs`
**Documentation**:
- `docs/sprints/sprint_4/backend_api_verification.md` (update)
- API Swagger annotations
## Implementation
### Unit Tests - StoryTests.cs
```csharp
[Fact]
public void UpdateAcceptanceCriteria_WithValidCriteria_ShouldUpdateList()
{
// Arrange
var story = Story.Create(tenantId, "Title", "Desc", epicId, priority, userId);
var criteria = new List<string> { "Criterion 1", "Criterion 2" };
// Act
story.UpdateAcceptanceCriteria(criteria);
// Assert
story.AcceptanceCriteria.Should().HaveCount(2);
story.AcceptanceCriteria.Should().Contain("Criterion 1");
}
[Fact]
public void UpdateAcceptanceCriteria_WithTooMany_ShouldThrowException()
{
// Arrange
var story = Story.Create(tenantId, "Title", "Desc", epicId, priority, userId);
var criteria = Enumerable.Range(1, 21).Select(i => $"Criterion {i}").ToList();
// Act & Assert
var act = () => story.UpdateAcceptanceCriteria(criteria);
act.Should().Throw<DomainException>().WithMessage("*more than 20*");
}
[Fact]
public void UpdateTags_WithValidTags_ShouldUpdateList()
{
// Arrange & Act & Assert
}
[Fact]
public void UpdateTags_WithInvalidCharacters_ShouldThrowException()
{
// Arrange & Act & Assert
}
[Fact]
public void UpdateStoryPoints_WithValidPoints_ShouldUpdatePoints()
{
// Arrange & Act & Assert
}
[Fact]
public void UpdateStoryPoints_WithNegativePoints_ShouldThrowException()
{
// Arrange & Act & Assert
}
```
### Unit Tests - WorkTaskTests.cs
```csharp
[Fact]
public void UpdateOrder_WithValidOrder_ShouldUpdateOrder()
{
// Arrange
var task = WorkTask.Create(tenantId, "Title", "Desc", storyId, priority, userId);
// Act
task.UpdateOrder(5);
// Assert
task.Order.Should().Be(5);
}
[Fact]
public void UpdateOrder_WithNegativeOrder_ShouldThrowException()
{
// Arrange
var task = WorkTask.Create(tenantId, "Title", "Desc", storyId, priority, userId);
// Act & Assert
var act = () => task.UpdateOrder(-1);
act.Should().Throw<DomainException>().WithMessage("*cannot be negative*");
}
```
### Integration Tests - CreateStoryCommandTests.cs
```csharp
[Fact]
public async Task Handle_WithAcceptanceCriteria_ShouldCreateStoryWithCriteria()
{
// Arrange
var command = new CreateStoryCommand
{
Title = "Test Story",
Description = "Description",
EpicId = epicId,
Priority = "High",
AcceptanceCriteria = new List<string> { "AC1", "AC2" },
Tags = new List<string> { "tag1", "tag2" },
StoryPoints = 5,
CreatedBy = userId
};
// Act
var result = await _handler.Handle(command, CancellationToken.None);
// Assert
result.Should().NotBeNull();
result.AcceptanceCriteria.Should().HaveCount(2);
result.Tags.Should().HaveCount(2);
result.StoryPoints.Should().Be(5);
}
```
### API Tests - StoriesControllerTests.cs
```csharp
[Fact]
public async Task CreateStory_WithNewFields_ShouldReturn201WithFields()
{
// Arrange
var request = new CreateStoryRequest
{
Title = "Story with new fields",
Description = "Description",
Priority = "High",
AcceptanceCriteria = new List<string> { "AC1", "AC2" },
Tags = new List<string> { "backend", "api" },
StoryPoints = 8,
CreatedBy = _userId
};
// Act
var response = await _client.PostAsJsonAsync($"/api/v1/epics/{_epicId}/stories", request);
// Assert
response.StatusCode.Should().Be(HttpStatusCode.Created);
var story = await response.Content.ReadFromJsonAsync<StoryDto>();
story.AcceptanceCriteria.Should().HaveCount(2);
story.Tags.Should().Contain("backend");
story.StoryPoints.Should().Be(8);
}
[Fact]
public async Task UpdateStory_WithNewFields_ShouldReturn200WithUpdatedFields()
{
// Arrange, Act, Assert
}
[Fact]
public async Task GetStory_ShouldReturnNewFields()
{
// Arrange, Act, Assert
}
```
### API Tests - TasksControllerTests.cs
```csharp
[Fact]
public async Task ReorderTasks_WithValidOrders_ShouldReturn204()
{
// Arrange
var task1 = await CreateTask("Task 1");
var task2 = await CreateTask("Task 2");
var task3 = await CreateTask("Task 3");
var request = new ReorderTasksRequest
{
Tasks = new List<TaskOrderDto>
{
new() { TaskId = task3.Id, Order = 0 },
new() { TaskId = task1.Id, Order = 1 },
new() { TaskId = task2.Id, Order = 2 }
}
};
// Act
var response = await _client.PutAsJsonAsync($"/api/v1/stories/{_storyId}/tasks/reorder", request);
// Assert
response.StatusCode.Should().Be(HttpStatusCode.NoContent);
var tasks = await _client.GetFromJsonAsync<List<TaskDto>>($"/api/v1/stories/{_storyId}/tasks");
tasks[0].Id.Should().Be(task3.Id);
tasks[1].Id.Should().Be(task1.Id);
}
```
### Documentation Updates
Update `backend_api_verification.md`:
- Add new fields to Story/Task data models
- Add example requests with new fields
- Update API endpoint list with ReorderTasks
- Remove "Missing Optional Fields" sections
- Update "Feature Gap Analysis" to 100% complete
## Test Coverage Requirements
- [ ] Domain validation: 100% coverage
- [ ] Command handlers: >80% coverage
- [ ] API endpoints: >80% coverage
- [ ] Edge cases tested (null, empty, invalid)
## Acceptance
- [ ] All unit tests written and passing
- [ ] All integration tests written and passing
- [ ] All API tests written and passing
- [ ] Test coverage meets requirements (>80%)
- [ ] API documentation updated
- [ ] Swagger annotations added
- [ ] Example requests/responses documented
- [ ] No test failures in CI/CD pipeline
- [ ] Code review completed