🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
478 lines
14 KiB
Markdown
478 lines
14 KiB
Markdown
# 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) │
|
||
└─────────────────────────────────────┘
|
||
```
|
||
|
||
### 模块通信规则
|
||
|
||
1. **禁止直接引用其他模块的 Domain 实体**
|
||
2. **允许通过 MediatR 查询其他模块**(Application Service Integration)
|
||
3. **允许通过 Domain Events 解耦通信**(Event-Driven)
|
||
4. **使用 Contracts 项目定义模块对外接口**
|
||
|
||
### 架构测试
|
||
|
||
项目包含自动化架构测试,确保模块边界被严格遵守:
|
||
|
||
```bash
|
||
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. 安装依赖
|
||
|
||
```bash
|
||
cd colaflow-api
|
||
dotnet restore
|
||
```
|
||
|
||
### 2. 启动数据库(使用 Docker)
|
||
|
||
从项目根目录启动:
|
||
|
||
```bash
|
||
cd ..
|
||
docker-compose up -d postgres redis
|
||
```
|
||
|
||
### 3. 运行数据库迁移
|
||
|
||
```bash
|
||
# 创建迁移(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
|
||
|
||
```bash
|
||
cd src/ColaFlow.API
|
||
dotnet run
|
||
```
|
||
|
||
API 将运行在:
|
||
- HTTP: `http://localhost:5000`
|
||
- HTTPS: `https://localhost:5001`
|
||
- Swagger/Scalar: `https://localhost:5001/scalar/v1`
|
||
|
||
### 5. 运行测试
|
||
|
||
```bash
|
||
# 运行所有测试
|
||
dotnet test
|
||
|
||
# 运行单元测试
|
||
dotnet test --filter Category=Unit
|
||
|
||
# 运行集成测试
|
||
dotnet test --filter Category=Integration
|
||
|
||
# 生成覆盖率报告
|
||
dotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=opencover
|
||
```
|
||
|
||
## 开发指南
|
||
|
||
### Domain Layer 开发
|
||
|
||
**聚合根示例:**
|
||
|
||
```csharp
|
||
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 示例:**
|
||
|
||
```csharp
|
||
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 示例:**
|
||
|
||
```csharp
|
||
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 示例:**
|
||
|
||
```csharp
|
||
[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 测试** - 关键用户流程
|
||
|
||
### 单元测试示例
|
||
|
||
```csharp
|
||
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);
|
||
}
|
||
}
|
||
```
|
||
|
||
### 集成测试示例
|
||
|
||
```csharp
|
||
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`:
|
||
|
||
```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`
|
||
|
||
## 相关文档
|
||
|
||
- [完整架构设计](../docs/M1-Architecture-Design.md)
|
||
- [项目计划](../product.md)
|
||
- [Sprint 计划](../docs/Sprint-Plan.md)
|
||
- [Docker 使用指南](../DOCKER-README.md)
|
||
- [测试指南](tests/README.md)
|
||
|
||
## 下一步开发任务
|
||
|
||
### 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
|