HaniBlindBox/.kiro/specs/advanced-features/design.md
2026-01-03 12:44:56 +08:00

9.8 KiB
Raw Blame History

Design Document: 高级功能迁移

Overview

本设计文档描述阶段8高级功能的实现方案包括API文档完善、集成测试覆盖和缓存预热机制。这些功能将确保迁移后的系统具备完整的文档、可靠的测试覆盖和良好的启动性能。

Architecture

整体架构

┌─────────────────────────────────────────────────────────────┐
│                      HoneyBox.Api                           │
├─────────────────────────────────────────────────────────────┤
│  ┌─────────────────┐  ┌─────────────────┐  ┌─────────────┐ │
│  │  Swagger/OpenAPI │  │  Controllers    │  │  Startup    │ │
│  │  Documentation   │  │  (XML Comments) │  │  Services   │ │
│  └─────────────────┘  └─────────────────┘  └─────────────┘ │
│                                                   │         │
│                                          ┌────────▼───────┐ │
│                                          │ CacheWarmup    │ │
│                                          │ HostedService  │ │
│                                          └────────────────┘ │
└─────────────────────────────────────────────────────────────┘
                              │
┌─────────────────────────────▼───────────────────────────────┐
│                    HoneyBox.Tests                           │
├─────────────────────────────────────────────────────────────┤
│  ┌─────────────────┐  ┌─────────────────┐  ┌─────────────┐ │
│  │  Integration    │  │  WebApplication │  │  Test       │ │
│  │  Tests          │  │  Factory        │  │  Database   │ │
│  └─────────────────┘  └─────────────────┘  └─────────────┘ │
└─────────────────────────────────────────────────────────────┘

Components and Interfaces

1. API文档组件

OpenAPI配置扩展

// 扩展OpenAPI配置添加JWT认证和中文描述
public static class OpenApiExtensions
{
    public static IServiceCollection AddHoneyBoxOpenApi(this IServiceCollection services)
    {
        services.AddOpenApi(options =>
        {
            options.AddDocumentTransformer((document, context, ct) =>
            {
                document.Info.Title = "HoneyBox API";
                document.Info.Version = "v1";
                document.Info.Description = "友达赏抽奖系统API文档";
                return Task.CompletedTask;
            });
        });
        return services;
    }
}

XML注释配置

// 在csproj中启用XML文档生成
<PropertyGroup>
    <GenerateDocumentationFile>true</GenerateDocumentationFile>
    <NoWarn>$(NoWarn);1591</NoWarn>
</PropertyGroup>

2. 集成测试组件

WebApplicationFactory配置

public class HoneyBoxWebApplicationFactory : WebApplicationFactory<Program>
{
    protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
        builder.ConfigureServices(services =>
        {
            // 移除生产数据库配置
            var descriptor = services.SingleOrDefault(
                d => d.ServiceType == typeof(DbContextOptions<HoneyBoxDbContext>));
            if (descriptor != null)
                services.Remove(descriptor);

            // 使用内存数据库
            services.AddDbContext<HoneyBoxDbContext>(options =>
            {
                options.UseInMemoryDatabase("TestDb");
            });
        });
    }
}

集成测试基类

public abstract class IntegrationTestBase : IClassFixture<HoneyBoxWebApplicationFactory>
{
    protected readonly HttpClient Client;
    protected readonly HoneyBoxWebApplicationFactory Factory;

    protected IntegrationTestBase(HoneyBoxWebApplicationFactory factory)
    {
        Factory = factory;
        Client = factory.CreateClient();
    }

    protected async Task<string> GetAuthTokenAsync(int userId = 1)
    {
        // 生成测试用JWT Token
    }
}

3. 缓存预热组件

缓存预热服务接口

public interface ICacheWarmupService
{
    Task WarmupAsync(CancellationToken cancellationToken = default);
    Task WarmupHotGoodsAsync(int count, CancellationToken cancellationToken = default);
    Task WarmupSystemConfigAsync(CancellationToken cancellationToken = default);
}

缓存预热后台服务

public class CacheWarmupHostedService : BackgroundService
{
    private readonly IServiceProvider _serviceProvider;
    private readonly ILogger<CacheWarmupHostedService> _logger;
    private readonly CacheWarmupOptions _options;

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        _logger.LogInformation("开始缓存预热...");
        
        using var scope = _serviceProvider.CreateScope();
        var warmupService = scope.ServiceProvider.GetRequiredService<ICacheWarmupService>();
        
        try
        {
            await warmupService.WarmupAsync(stoppingToken);
            _logger.LogInformation("缓存预热完成");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "缓存预热过程中发生错误,但不影响系统启动");
        }
    }
}

缓存预热配置

public class CacheWarmupOptions
{
    public int HotGoodsCount { get; set; } = 100;
    public bool EnableWarmup { get; set; } = true;
    public int WarmupDelaySeconds { get; set; } = 5;
}

Data Models

缓存预热配置模型

public class CacheWarmupOptions
{
    /// <summary>
    /// 热门商品预热数量
    /// </summary>
    public int HotGoodsCount { get; set; } = 100;
    
    /// <summary>
    /// 是否启用预热
    /// </summary>
    public bool EnableWarmup { get; set; } = true;
    
    /// <summary>
    /// 预热延迟秒数(等待系统完全启动)
    /// </summary>
    public int WarmupDelaySeconds { get; set; } = 5;
}

预热结果模型

public class WarmupResult
{
    public bool Success { get; set; }
    public int ItemsWarmed { get; set; }
    public TimeSpan Duration { get; set; }
    public string? ErrorMessage { get; set; }
}

Correctness Properties

A property is a characteristic or behavior that should hold true across all valid executions of a system-essentially, a formal statement about what the system should do. Properties serve as the bridge between human-readable specifications and machine-verifiable correctness guarantees.

Property 1: API文档完整性

For any 已迁移的控制器端点OpenAPI规范中应该包含该端点的定义包括路径、方法、参数和响应类型。 Validates: Requirements 1.1, 1.5

Property 2: API文档中文描述

For any OpenAPI规范中的端点定义应该包含非空的summary或description字段。 Validates: Requirements 1.3

Property 3: 集成测试响应格式一致性

For any API响应其JSON结构应该包含status、msg、data三个字段且status为整数类型。 Validates: Requirements 2.6

Property 4: 缓存预热异步性

For any 系统启动过程,缓存预热应该在后台异步执行,系统启动时间不应因预热数据量增加而显著增长。 Validates: Requirements 3.3

Error Handling

API文档错误处理

  • 如果XML注释文件不存在系统应该正常启动但记录警告日志
  • 如果OpenAPI配置失败应该记录错误但不影响API正常运行

集成测试错误处理

  • 测试数据库初始化失败时,应该提供清晰的错误信息
  • 测试超时时,应该记录详细的执行状态

缓存预热错误处理

  • 数据库连接失败时,记录错误但继续系统启动
  • 单个数据项预热失败时,跳过该项继续预热其他数据
  • Redis连接失败时记录警告并跳过预热

Testing Strategy

单元测试

  • 测试缓存预热服务的各个方法
  • 测试配置选项的默认值和边界值

集成测试

使用xUnit和WebApplicationFactory进行集成测试

[Fact]
public async Task GetGoodsList_ShouldReturnSuccess()
{
    // Arrange
    var client = _factory.CreateClient();
    
    // Act
    var response = await client.GetAsync("/api/goods_list?type=1");
    
    // Assert
    response.EnsureSuccessStatusCode();
    var content = await response.Content.ReadAsStringAsync();
    var result = JsonSerializer.Deserialize<ApiResponse<object>>(content);
    Assert.Equal(1, result.Status);
}

属性测试

使用FsCheck进行属性测试验证

  • API响应格式一致性
  • 缓存预热的异步性

测试配置

  • 最小100次迭代用于属性测试
  • 使用内存数据库进行集成测试
  • 测试标签格式: Feature: advanced-features, Property {number}: {property_text}