Files
ColaFlow/docs/plans/sprint_5_story_15.md
Yaojia Wang 34a379750f
Some checks failed
Code Coverage / Generate Coverage Report (push) Has been cancelled
Tests / Run Tests (9.0.x) (push) Has been cancelled
Tests / Docker Build Test (push) Has been cancelled
Tests / Test Summary (push) Has been cancelled
Clean up
2025-11-15 08:58:48 +01:00

213 lines
6.1 KiB
Markdown

---
story_id: story_15
sprint_id: sprint_5
parent_story_id: story_0
status: not_started
priority: P0
assignee: backend
created_date: 2025-11-09
estimated_days: 5
phase: 3
---
# Story 15: Resource Migration to SDK Attributes
**Parent Epic**: [Story 0](sprint_5_story_0.md) - Integrate Microsoft .NET MCP SDK
**Phase**: 3 - Resource Migration (Week 5)
**Priority**: P0 - Critical
**Estimated Effort**: 5 days (1 week)
**Dependencies**: Story 14 (Tool migration complete)
## User Story
**As** a backend developer,
**I want** to migrate all 11 MCP Resources from custom implementation to SDK attribute-based registration,
**So that** we reduce boilerplate code while preserving multi-tenant isolation and Redis caching.
## Business Value
- **Code Reduction**: Remove 200-250 lines of custom Resource infrastructure
- **Performance**: SDK optimizations improve query speed by 30-40%
- **Caching**: Preserve Redis caching with minimal changes
- **Multi-Tenant**: Maintain 100% tenant isolation
## Resources to Migrate (11 Total)
### Core Resources (P0)
1. `projects.list` - List all projects
2. `projects.get/{id}` - Get project details
3. `issues.search` - Search issues with filters
4. `issues.get/{id}` - Get issue details
5. `sprints.current` - Get active Sprint
### Supporting Resources (P1)
6. `sprints.list` - List all Sprints
7. `users.list` - List team members
8. `docs.prd/{projectId}` - Get PRD document
### Advanced Resources (P2)
9. `reports.daily/{date}` - Daily status report
10. `reports.velocity` - Sprint velocity report
11. `audit.history/{entityId}` - Audit log history
## Migration Pattern
### Before (Custom Implementation)
```csharp
public class ProjectsListResource : IMcpResource
{
public string Uri => "colaflow://projects.list";
public string Name => "Projects List";
public string Description => "List all projects";
public string MimeType => "application/json";
private readonly IProjectRepository _repo;
private readonly ITenantContext _tenant;
public async Task<McpResourceContent> GetContentAsync(
McpResourceRequest request,
CancellationToken ct)
{
var projects = await _repo.GetAllAsync(_tenant.CurrentTenantId);
return new McpResourceContent
{
Uri = Uri,
MimeType = MimeType,
Text = JsonSerializer.Serialize(new { projects })
};
}
}
```
### After (SDK Attributes)
```csharp
[McpResource(
Uri = "colaflow://projects.list",
Name = "Projects List",
Description = "List all projects in current tenant",
MimeType = "application/json"
)]
public class ProjectsListResource
{
private readonly IProjectRepository _repo;
private readonly ITenantContext _tenant;
private readonly IDistributedCache _cache; // Redis preserved
public ProjectsListResource(
IProjectRepository repo,
ITenantContext tenant,
IDistributedCache cache)
{
_repo = repo;
_tenant = tenant;
_cache = cache;
}
public async Task<McpResourceContent> GetContentAsync(
McpContext context,
CancellationToken cancellationToken)
{
// Preserve Redis caching
var cacheKey = $"mcp:projects:list:{_tenant.CurrentTenantId}";
var cached = await _cache.GetStringAsync(cacheKey, cancellationToken);
if (cached != null)
{
return McpResourceContent.Json(cached);
}
// Preserve multi-tenant filtering
var projects = await _repo.GetAllAsync(
_tenant.CurrentTenantId,
cancellationToken);
var json = JsonSerializer.Serialize(new { projects });
// Cache for 5 minutes
await _cache.SetStringAsync(
cacheKey,
json,
new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5)
},
cancellationToken);
return McpResourceContent.Json(json);
}
}
```
## Key Changes
### What Changes
- ✅ Resource registration (custom → SDK attributes)
- ✅ URI declaration (property → attribute)
- ✅ Metadata (Name, Description in attribute)
### What Stays the Same
- ✅ TenantContext filtering (preserved)
- ✅ Redis caching logic (preserved)
- ✅ Query logic (unchanged)
- ✅ Response format (unchanged)
## Acceptance Criteria
- [ ] All 11 Resources migrated to `[McpResource]` attributes
- [ ] Multi-tenant isolation 100% verified
- [ ] Redis cache hit rate >80% maintained
- [ ] Response time <200ms (P95)
- [ ] Integration tests pass
- [ ] Claude Desktop can query all Resources
- [ ] Zero breaking changes for MCP clients
## Tasks Breakdown
- [ ] [Task 1](sprint_5_story_15_task_1.md) - Migrate P0 Resources (projects, issues, sprints.current) - 2 days
- [ ] [Task 2](sprint_5_story_15_task_2.md) - Migrate P1 Resources (sprints.list, users, docs) - 1 day
- [ ] [Task 3](sprint_5_story_15_task_3.md) - Migrate P2 Resources (reports, audit) - 1 day
- [ ] [Task 4](sprint_5_story_15_task_4.md) - Multi-tenant isolation testing and cache verification - 1 day
**Progress**: 0/4 tasks completed (0%)
## Testing Strategy
### Multi-Tenant Isolation Tests
- Verify TenantContext extraction from McpContext
- Test cross-tenant access attempts (should return 404)
- Validate Global Query Filters applied
### Cache Performance Tests
- Measure cache hit rate (target: >80%)
- Verify cache invalidation on data changes
- Test TTL expiration
### Integration Tests
- Claude Desktop resource queries
- Query parameter handling
- Error responses (404, 403, 500)
## Success Metrics
- **Code Reduction**: -200 lines (Resource infrastructure)
- **Performance**: +30-40% faster queries
- **Cache Hit Rate**: Maintain >80%
- **Multi-Tenant**: 100% isolation verified
## Definition of Done
- [ ] All 11 Resources migrated to SDK attributes
- [ ] Multi-tenant isolation 100% verified
- [ ] Redis caching verified (>80% hit rate)
- [ ] Performance benchmarks show ≥30% improvement
- [ ] Integration tests pass
- [ ] Code reviewed and approved
---
**Created**: 2025-11-09 by Product Manager Agent
**Owner**: Backend Team
**Start Date**: 2025-12-23 (Week 5)
**Target Date**: 2025-12-27 (End of Week 5)
**Status**: Not Started