Files
ColaFlow/colaflow-api/src/Modules/ProjectManagement/ProjectManagementModule.cs
Yaojia Wang 12a4248430 feat(backend): Day 15 Task 1&2 - Add TenantId to Epic/Story/WorkTask and implement TenantContext
This commit completes Day 15's primary objectives:
1. Database Migration - Add TenantId columns to Epic, Story, and WorkTask entities
2. TenantContext Service - Implement tenant context retrieval from JWT claims

Changes:
- Added TenantId property to Epic, Story, and WorkTask domain entities
- Updated entity factory methods to require TenantId parameter
- Modified Project.CreateEpic to pass TenantId from parent aggregate
- Modified Epic.CreateStory and Story.CreateTask to propagate TenantId
- Added EF Core configurations for TenantId mapping with proper indexes
- Created EF Core migration: AddTenantIdToEpicStoryTask
  * Adds tenant_id columns to Epics, Stories, and Tasks tables
  * Creates indexes: ix_epics_tenant_id, ix_stories_tenant_id, ix_tasks_tenant_id
  * Uses default Guid.Empty for existing data (backward compatible)
- Implemented ITenantContext interface in Application layer
- Implemented TenantContext service in Infrastructure layer
  * Retrieves tenant ID from JWT claims (tenant_id or tenantId)
  * Throws UnauthorizedAccessException if tenant context unavailable
- Registered TenantContext as scoped service in DI container
- Added Global Query Filters for Epic, Story, and WorkTask entities
  * Ensures automatic tenant isolation at database query level
  * Prevents cross-tenant data access

Architecture:
- Follows the same pattern as Issue Management Module (Day 14)
- Maintains consistency with Project entity multi-tenancy implementation
- Ensures data isolation through both domain logic and database filters

Note: Unit tests require updates to pass TenantId parameter - will be addressed in follow-up commits

Reference: Day 15 roadmap (DAY15-22-PROJECTMANAGEMENT-ROADMAP.md)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-04 16:44:09 +01:00

64 lines
2.4 KiB
C#

using ColaFlow.Shared.Kernel.Modules;
using Microsoft.AspNetCore.Builder;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using FluentValidation;
using MediatR;
using ColaFlow.Modules.ProjectManagement.Application.Behaviors;
using ColaFlow.Modules.ProjectManagement.Application.Commands.CreateProject;
using ColaFlow.Modules.ProjectManagement.Application.Common.Interfaces;
using ColaFlow.Modules.ProjectManagement.Domain.Repositories;
using ColaFlow.Modules.ProjectManagement.Infrastructure.Persistence;
using ColaFlow.Modules.ProjectManagement.Infrastructure.Repositories;
using ColaFlow.Modules.ProjectManagement.Infrastructure.Services;
namespace ColaFlow.Modules.ProjectManagement;
/// <summary>
/// Project Management Module
/// Responsible for managing projects, epics, stories, and tasks.
/// </summary>
public class ProjectManagementModule : IModule
{
public string Name => "ProjectManagement";
public void RegisterServices(IServiceCollection services, IConfiguration configuration)
{
// Register DbContext
var connectionString = configuration.GetConnectionString("PMDatabase");
services.AddDbContext<PMDbContext>(options =>
options.UseNpgsql(connectionString));
// Register repositories
services.AddScoped<IProjectRepository, ProjectRepository>();
services.AddScoped<IUnitOfWork, UnitOfWork>();
// Register tenant context service
services.AddScoped<ITenantContext, TenantContext>();
// Note: IProjectNotificationService is registered in the API layer (Program.cs)
// as it depends on IRealtimeNotificationService which is API-specific
// Register MediatR handlers from Application assembly
services.AddMediatR(cfg =>
{
cfg.RegisterServicesFromAssembly(typeof(CreateProjectCommand).Assembly);
});
// Register FluentValidation validators
services.AddValidatorsFromAssembly(typeof(CreateProjectCommand).Assembly);
// Register pipeline behaviors
services.AddTransient(typeof(IPipelineBehavior<,>), typeof(ValidationBehavior<,>));
Console.WriteLine($"[{Name}] Module services registered");
}
public void ConfigureApplication(IApplicationBuilder app)
{
// Configure module-specific middleware if needed
Console.WriteLine($"[{Name}] Module application configured");
}
}