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>
6.7 KiB
6.7 KiB
task_id, story_id, sprint_id, status, type, assignee, created_date, completion_date
| task_id | story_id | sprint_id | status | type | assignee | created_date | completion_date |
|---|---|---|---|---|---|---|---|
| task_6 | story_0 | sprint_4 | not_started | backend | backend | 2025-11-05 | 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.cscolaflow-api/tests/Modules/ProjectManagement/Domain.Tests/Aggregates/WorkTaskTests.cs
Integration Tests:
colaflow-api/tests/Modules/ProjectManagement/Application.Tests/Commands/CreateStoryCommandTests.cscolaflow-api/tests/Modules/ProjectManagement/Application.Tests/Commands/UpdateStoryCommandTests.cscolaflow-api/tests/Modules/ProjectManagement/Application.Tests/Commands/CreateTaskCommandTests.cscolaflow-api/tests/Modules/ProjectManagement/Application.Tests/Commands/ReorderTasksCommandTests.cs
API Tests:
colaflow-api/tests/API.Tests/Controllers/StoriesControllerTests.cscolaflow-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
[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
[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
[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
[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
[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