Clean up
This commit is contained in:
212
docs/plans/sprint_5_story_15.md
Normal file
212
docs/plans/sprint_5_story_15.md
Normal file
@@ -0,0 +1,212 @@
|
||||
---
|
||||
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
|
||||
Reference in New Issue
Block a user