Files
ColaFlow/colaflow-api/README.md
Yaojia Wang 014d62bcc2 Project Init
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-02 23:55:18 +01:00

478 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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
- IDEVisual 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