# 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
