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:
254
docs/plans/sprint_4_story_0_task_6.md
Normal file
254
docs/plans/sprint_4_story_0_task_6.md
Normal 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
|
||||
Reference in New Issue
Block a user