Created comprehensive integration test suite for Issue Management Module with 8 test cases covering all CRUD operations, status changes, assignments, and multi-tenant isolation. Test Cases (8/8): 1. Create Issue (Story type) 2. Create Issue (Task type) 3. Create Issue (Bug type) 4. Get Issue by ID 5. List Issues 6. Change Issue Status (Kanban workflow) 7. Assign Issue to User 8. Multi-Tenant Isolation (CRITICAL security test) Bug Fix: Multi-Tenant Data Leakage - Issue: IssueRepository did not filter by TenantId, allowing cross-tenant data access - Solution: Implemented TenantContext service and added TenantId filtering to all repository queries - Security Impact: CRITICAL - prevents unauthorized access to other tenants' issues Changes: - Added ColaFlow.Modules.IssueManagement.IntegrationTests project - Added IssueManagementWebApplicationFactory for test infrastructure - Added TestAuthHelper for JWT token generation in tests - Added 8 comprehensive integration tests - Added ITenantContext and TenantContext services for tenant isolation - Updated IssueRepository to filter all queries by current tenant ID - Registered TenantContext in module DI configuration Test Status: 7/8 passed initially, 8/8 expected after multi-tenant fix Test Framework: xUnit + FluentAssertions + WebApplicationFactory Database: In-Memory (for fast, isolated tests) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
ColaFlow API
ColaFlow 后端 API 服务 - 基于 .NET 9 的 Modular Monolith + Clean Architecture + DDD + CQRS 实现。
架构亮点
- Modular Monolith Architecture - 模块化单体架构,清晰的模块边界
- Clean Architecture - 四层架构设计(Domain → Application → Infrastructure → API)
- Domain-Driven Design (DDD) - 领域驱动设计(战术模式)
- CQRS - 命令查询职责分离(MediatR)
- Event Sourcing - 事件溯源(用于审计日志)
- Architecture Testing - 自动化架构测试(NetArchTest)
技术栈
- .NET 9 - 最新的 .NET 平台
- Entity Framework Core 9 - ORM
- PostgreSQL 16+ - 主数据库
- Redis 7+ - 缓存和会话管理
- MediatR - 中介者模式(CQRS 和模块间通信)
- xUnit - 单元测试框架
- NetArchTest.Rules - 架构测试
- Testcontainers - 集成测试
项目结构(模块化单体)
colaflow-api/
├── src/
│ ├── ColaFlow.API/ # API 层(统一入口)
│ │ └── Program.cs # 模块注册和启动
│ │
│ ├── Modules/ # 业务模块
│ │ ├── ProjectManagement/ # 项目管理模块
│ │ │ ├── ColaFlow.Modules.PM.Domain/
│ │ │ │ ├── Aggregates/ # Project, Epic, Story, Task
│ │ │ │ ├── ValueObjects/ # ProjectId, ProjectKey, etc.
│ │ │ │ ├── Events/ # Domain Events
│ │ │ │ └── Exceptions/ # Domain Exceptions
│ │ │ ├── ColaFlow.Modules.PM.Application/
│ │ │ │ ├── Commands/ # CQRS Commands
│ │ │ │ ├── Queries/ # CQRS Queries
│ │ │ │ └── DTOs/ # Data Transfer Objects
│ │ │ ├── ColaFlow.Modules.PM.Infrastructure/
│ │ │ │ ├── Persistence/ # EF Core Configurations
│ │ │ │ └── Repositories/ # Repository Implementations
│ │ │ └── ColaFlow.Modules.PM.Contracts/
│ │ │ └── Events/ # Integration Events
│ │ │
│ │ ├── Workflow/ # 工作流模块(待实现)
│ │ ├── UserManagement/ # 用户管理模块(待实现)
│ │ ├── Notifications/ # 通知模块(待实现)
│ │ ├── Audit/ # 审计模块(待实现)
│ │ └── AI/ # AI 模块(待实现)
│ │
│ ├── Shared/ # 共享内核
│ │ └── ColaFlow.Shared.Kernel/
│ │ ├── Common/ # Entity, ValueObject, AggregateRoot
│ │ ├── Events/ # DomainEvent
│ │ └── Modules/ # IModule 接口
│ │
│ └── [Legacy - To be removed] # 旧的单体结构(迁移中)
│ ├── ColaFlow.Domain/
│ ├── ColaFlow.Application/
│ └── ColaFlow.Infrastructure/
│
├── tests/
│ ├── ColaFlow.ArchitectureTests/ # 架构测试(模块边界)
│ ├── ColaFlow.Domain.Tests/ # 领域层单元测试
│ ├── ColaFlow.Application.Tests/ # 应用层单元测试
│ └── ColaFlow.IntegrationTests/ # 集成测试
└── ColaFlow.sln
Modular Monolith 架构
模块边界规则
┌────────────────────────────────────────────────────┐
│ ColaFlow.API (Entry Point) │
└─────────────────┬──────────────────────────────────┘
│
┌─────────────┴─────────────┐
│ │
▼ ▼
┌─────────────┐ ┌─────────────┐
│ PM │ │ Workflow │ ... (其他模块)
│ Module │◄─────────►│ Module │
└─────────────┘ └─────────────┘
│ │
▼ ▼
┌─────────────────────────────────────┐
│ Shared.Kernel (Common Base) │
└─────────────────────────────────────┘
模块通信规则
- 禁止直接引用其他模块的 Domain 实体
- 允许通过 MediatR 查询其他模块(Application Service Integration)
- 允许通过 Domain Events 解耦通信(Event-Driven)
- 使用 Contracts 项目定义模块对外接口
架构测试
项目包含自动化架构测试,确保模块边界被严格遵守:
dotnet test tests/ColaFlow.ArchitectureTests
测试内容:
- Domain 层不依赖 Application 和 Infrastructure
- Domain 层只依赖 Shared.Kernel
- 模块间不直接引用其他模块的 Domain 实体
- AggregateRoot 正确继承
- ValueObject 是不可变的(sealed)
Clean Architecture 层级依赖
每个模块内部仍然遵循 Clean Architecture:
Module Structure:
API/Controllers ──┐
├──> Application ──> Domain
Infrastructure ───┘
依赖规则:
- Domain 层:仅依赖 Shared.Kernel(无其他依赖)
- Application 层:依赖 Domain 和 Contracts
- Infrastructure 层:依赖 Domain 和 Application
- API 层:依赖所有层
快速开始
前置要求
- .NET 9 SDK
- Docker Desktop(用于 PostgreSQL 和 Redis)
- IDE:Visual Studio 2022 / JetBrains Rider / VS Code
1. 安装依赖
cd colaflow-api
dotnet restore
2. 启动数据库(使用 Docker)
从项目根目录启动:
cd ..
docker-compose up -d postgres redis
3. 运行数据库迁移
# 创建迁移(Infrastructure 层完成后)
dotnet ef migrations add InitialCreate --project src/ColaFlow.Infrastructure --startup-project src/ColaFlow.API
# 应用迁移
dotnet ef database update --project src/ColaFlow.Infrastructure --startup-project src/ColaFlow.API
4. 运行 API
cd src/ColaFlow.API
dotnet run
API 将运行在:
- HTTP:
http://localhost:5000 - HTTPS:
https://localhost:5001 - Swagger/Scalar:
https://localhost:5001/scalar/v1
5. 运行测试
# 运行所有测试
dotnet test
# 运行单元测试
dotnet test --filter Category=Unit
# 运行集成测试
dotnet test --filter Category=Integration
# 生成覆盖率报告
dotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=opencover
开发指南
Domain Layer 开发
聚合根示例:
public class Project : AggregateRoot
{
public ProjectId Id { get; private set; }
public string Name { get; private set; }
// 工厂方法
public static Project Create(string name, string description, UserId ownerId)
{
var project = new Project
{
Id = ProjectId.Create(),
Name = name,
OwnerId = ownerId
};
project.AddDomainEvent(new ProjectCreatedEvent(project.Id, project.Name));
return project;
}
// 业务方法
public void UpdateDetails(string name, string description)
{
Name = name;
Description = description;
AddDomainEvent(new ProjectUpdatedEvent(Id));
}
}
Application Layer 开发(CQRS)
Command 示例:
public sealed record CreateProjectCommand : IRequest<ProjectDto>
{
public string Name { get; init; }
public string Description { get; init; }
}
public sealed class CreateProjectCommandHandler : IRequestHandler<CreateProjectCommand, ProjectDto>
{
public async Task<ProjectDto> Handle(CreateProjectCommand request, CancellationToken cancellationToken)
{
// 1. 创建聚合
var project = Project.Create(request.Name, request.Description, currentUserId);
// 2. 保存
await _repository.AddAsync(project, cancellationToken);
await _unitOfWork.SaveChangesAsync(cancellationToken);
// 3. 返回 DTO
return _mapper.Map<ProjectDto>(project);
}
}
Query 示例:
public sealed record GetProjectByIdQuery : IRequest<ProjectDto>
{
public Guid ProjectId { get; init; }
}
public sealed class GetProjectByIdQueryHandler : IQueryHandler<GetProjectByIdQuery, ProjectDto>
{
public async Task<ProjectDto> Handle(GetProjectByIdQuery request, CancellationToken cancellationToken)
{
var project = await _context.Projects
.AsNoTracking()
.FirstOrDefaultAsync(p => p.Id == request.ProjectId, cancellationToken);
return _mapper.Map<ProjectDto>(project);
}
}
API Layer 开发
Controller 示例:
[ApiController]
[Route("api/v1/[controller]")]
public class ProjectsController : ControllerBase
{
private readonly IMediator _mediator;
[HttpPost]
[ProducesResponseType(typeof(ProjectDto), StatusCodes.Status201Created)]
public async Task<IActionResult> CreateProject([FromBody] CreateProjectCommand command)
{
var result = await _mediator.Send(command);
return CreatedAtAction(nameof(GetProject), new { id = result.Id }, result);
}
[HttpGet("{id}")]
[ProducesResponseType(typeof(ProjectDto), StatusCodes.Status200OK)]
public async Task<IActionResult> GetProject(Guid id)
{
var result = await _mediator.Send(new GetProjectByIdQuery { ProjectId = id });
return Ok(result);
}
}
测试策略
测试金字塔
- 70% 单元测试 - Domain 和 Application 层
- 20% 集成测试 - API 端点测试
- 10% E2E 测试 - 关键用户流程
单元测试示例
public class ProjectTests
{
[Fact]
public void Create_WithValidData_ShouldCreateProject()
{
// Arrange
var name = "Test Project";
var ownerId = UserId.Create();
// Act
var project = Project.Create(name, "Description", ownerId);
// Assert
project.Should().NotBeNull();
project.Name.Should().Be(name);
project.DomainEvents.Should().ContainSingle(e => e is ProjectCreatedEvent);
}
}
集成测试示例
public class ProjectsControllerTests : IntegrationTestBase
{
[Fact]
public async Task CreateProject_WithValidData_ShouldReturn201()
{
// Arrange
var command = new CreateProjectCommand { Name = "Test", Description = "Test" };
// Act
var response = await _client.PostAsJsonAsync("/api/v1/projects", command);
// Assert
response.StatusCode.Should().Be(HttpStatusCode.Created);
var project = await response.Content.ReadFromJsonAsync<ProjectDto>();
project.Should().NotBeNull();
}
}
代码质量
覆盖率要求
- 最低要求:80%
- 目标:90%+
- 关键路径:100%
代码规范
- 遵循 C# 编码规范
- 使用 private 构造函数 + 工厂方法
- 所有 public 方法必须有 XML 注释
- 所有业务逻辑必须有单元测试
NuGet 包版本
Domain Layer
- 无外部依赖
Application Layer
- MediatR 13.1.0
- FluentValidation 12.0.0
- AutoMapper 15.1.0
Infrastructure Layer
- Microsoft.EntityFrameworkCore 9.0.10
- Npgsql.EntityFrameworkCore.PostgreSQL 9.0.4
- StackExchange.Redis 2.9.32
API Layer
- Serilog.AspNetCore 9.0.0
- Scalar.AspNetCore 2.9.0
Test Projects
- xUnit 2.9.2
- FluentAssertions 8.8.0
- Moq 4.20.72
- Testcontainers 4.x
环境变量
创建 src/ColaFlow.API/appsettings.Development.json:
{
"ConnectionStrings": {
"DefaultConnection": "Host=localhost;Port=5432;Database=colaflow;Username=colaflow;Password=colaflow_password",
"Redis": "localhost:6379,password=colaflow_redis_password"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}
API 文档
启动应用后,访问:
- Scalar UI:
https://localhost:5001/scalar/v1 - OpenAPI JSON:
https://localhost:5001/openapi/v1.json
相关文档
下一步开发任务
Infrastructure Layer(进行中)
- 配置 EF Core DbContext
- 创建 Entity Configurations
- 生成数据库 Migrations
- 实现 Repository 和 Unit of Work
Application Layer(待开发)
- 实现 CQRS Commands
- 实现 CQRS Queries
- 配置 MediatR Pipeline Behaviors
- 实现 FluentValidation Validators
API Layer(待开发)
- 实现 REST API Controllers
- 配置 OpenAPI/Scalar
- 实现异常处理中间件
- 配置 JWT 认证
测试(待开发)
- 编写 Domain 单元测试(≥80% 覆盖率)
- 编写 Application 单元测试
- 编写 API 集成测试
License
MIT License
团队
ColaFlow Development Team
当前状态: 🟡 Domain Layer 完成,Infrastructure 和 Application 层开发中
最后更新: 2025-11-02