Compare commits
2 Commits
7bf4c41e41
...
feb1a733cd
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
feb1a733cd | ||
|
|
b8d2a93c9f |
@ -50,7 +50,7 @@ jobs:
|
|||||||
uses: docker/build-push-action@v5
|
uses: docker/build-push-action@v5
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: src/Dockerfile
|
dockerfile: ./src/Dockerfile
|
||||||
push: true
|
push: true
|
||||||
tags: ${{ steps.meta.outputs.tags }}
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
labels: ${{ steps.meta.outputs.labels }}
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
|||||||
109
.planning/codebase/ARCHITECTURE.md
Normal file
109
.planning/codebase/ARCHITECTURE.md
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
# 架构
|
||||||
|
|
||||||
|
**分析日期:** 2026-02-28
|
||||||
|
|
||||||
|
## 模式概述
|
||||||
|
|
||||||
|
**整体:** 分层架构 + 领域驱动设计 (DDD)
|
||||||
|
|
||||||
|
**关键特性:**
|
||||||
|
- **控制器层 (Controllers)** - 处理 HTTP 请求,返回 API 响应
|
||||||
|
- **服务层 (Services)** - 业务逻辑实现,使用依赖注入
|
||||||
|
- **数据访问层** - 通过 Entity Framework Core 访问数据库
|
||||||
|
- **领域模型** - 来自外部 Domain 程序集 (Fengling.Platform.Domain)
|
||||||
|
|
||||||
|
## 层次
|
||||||
|
|
||||||
|
**控制器层 (Controllers):**
|
||||||
|
- 位置:`src/Controllers/`
|
||||||
|
- 包含:`UsersController.cs`, `RolesController.cs`, `TenantsController.cs`, `OAuthClientsController.cs`, `GatewayController.cs`
|
||||||
|
- 职责:处理 HTTP 请求、参数验证、返回响应
|
||||||
|
- 依赖:Service 层接口
|
||||||
|
|
||||||
|
**服务层 (Services):**
|
||||||
|
- 位置:`src/Services/`
|
||||||
|
- 包含:`UserService.cs`, `RoleService.cs`, `TenantService.cs`, `OAuthClientService.cs`, `GatewayService.cs`, `H5LinkService.cs`
|
||||||
|
- 职责:业务逻辑实现、数据转换、事务管理
|
||||||
|
- 依赖:Domain 模型、DbContext、UserManager、RoleManager
|
||||||
|
|
||||||
|
**数据层 (Data/Infrastructure):**
|
||||||
|
- PlatformDbContext - 平台业务数据
|
||||||
|
- GatewayDbContext - 网关配置数据
|
||||||
|
- 仓储模式:通过 NetCorePal.Extensions.Repository
|
||||||
|
|
||||||
|
**领域层 (Domain - 外部引用):**
|
||||||
|
- Fengling.Platform.Domain.AggregatesModel.UserAggregate
|
||||||
|
- Fengling.Platform.Domain.AggregatesModel.RoleAggregate
|
||||||
|
- Fengling.Platform.Domain.AggregatesModel.TenantAggregate
|
||||||
|
|
||||||
|
## 数据流
|
||||||
|
|
||||||
|
**典型请求流程:**
|
||||||
|
|
||||||
|
1. **HTTP 请求** → Controller 接收
|
||||||
|
2. **参数验证** → DTO 绑定
|
||||||
|
3. **业务处理** → Service 层执行
|
||||||
|
4. **数据持久化** → EF Core 保存
|
||||||
|
5. **响应返回** → Controller 返回结果
|
||||||
|
|
||||||
|
**状态管理:**
|
||||||
|
- 无状态 API 设计
|
||||||
|
- 状态存储在 PostgreSQL 数据库
|
||||||
|
- 认证状态通过 JWT Token 传递
|
||||||
|
|
||||||
|
## 关键抽象
|
||||||
|
|
||||||
|
**服务接口:**
|
||||||
|
- `IUserService` - 用户管理
|
||||||
|
- `IRoleService` - 角色管理
|
||||||
|
- `ITenantService` - 租户管理
|
||||||
|
- `IOAuthClientService` - OAuth 客户端管理
|
||||||
|
- `IGatewayService` - 网关配置
|
||||||
|
- `IH5LinkService` - H5 链接服务
|
||||||
|
|
||||||
|
**数据传输对象 (DTO):**
|
||||||
|
- 位置:`src/Models/Dtos/`
|
||||||
|
- 模式:CreateXxxDto, UpdateXxxDto, XxxDto, XxxQueryDto
|
||||||
|
- 用途:API 请求/响应数据结构
|
||||||
|
|
||||||
|
## 入口点
|
||||||
|
|
||||||
|
**主入口:**
|
||||||
|
- 位置:`src/Program.cs`
|
||||||
|
- 触发:应用启动时执行
|
||||||
|
- 职责:服务注册、中间件配置、管道构建
|
||||||
|
|
||||||
|
**API 端点:**
|
||||||
|
- `/api/console/[controller]` - RESTful API 前缀
|
||||||
|
- `/swagger` - API 文档
|
||||||
|
|
||||||
|
## 错误处理
|
||||||
|
|
||||||
|
**策略:**
|
||||||
|
- 异常捕获 + 日志记录
|
||||||
|
- 返回标准 HTTP 状态码
|
||||||
|
- 错误详情通过响应体返回
|
||||||
|
|
||||||
|
**模式:**
|
||||||
|
```csharp
|
||||||
|
try {
|
||||||
|
// 业务逻辑
|
||||||
|
} catch (KeyNotFoundException ex) {
|
||||||
|
return NotFound();
|
||||||
|
} catch (InvalidOperationException ex) {
|
||||||
|
return BadRequest();
|
||||||
|
} catch (Exception ex) {
|
||||||
|
_logger.LogError(ex, "...");
|
||||||
|
return StatusCode(500);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 跨领域关注
|
||||||
|
|
||||||
|
**日志:** Microsoft.Extensions.Logging + ILogger<T>
|
||||||
|
**验证:** ASP.NET Core Model Validation + FluentValidation (已引用)
|
||||||
|
**认证:** OpenIddict + JWT Bearer
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*架构分析:2026-02-28*
|
||||||
75
.planning/codebase/CONCERNS.md
Normal file
75
.planning/codebase/CONCERNS.md
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
# 代码库问题
|
||||||
|
|
||||||
|
**分析日期:** 2026-02-28
|
||||||
|
|
||||||
|
## 技术债务
|
||||||
|
|
||||||
|
**硬编码密钥:**
|
||||||
|
- 问题:`src/Program.cs:62` 包含硬编码的 OAuth 客户端密钥
|
||||||
|
- 影响:安全风险,不适合生产环境
|
||||||
|
- 修复:使用环境变量或密钥管理服务
|
||||||
|
|
||||||
|
**缺少测试项目:**
|
||||||
|
- 问题:当前项目没有测试目录
|
||||||
|
- 影响:无法进行自动化测试,难以保证代码质量
|
||||||
|
- 修复:添加 xUnit/MSTest 测试项目
|
||||||
|
|
||||||
|
## 已知问题
|
||||||
|
|
||||||
|
**当前未发现严重 Bug:**
|
||||||
|
- 代码结构清晰,异常处理完善
|
||||||
|
|
||||||
|
## 安全考虑
|
||||||
|
|
||||||
|
**OAuth 密钥硬编码:**
|
||||||
|
- 风险:生产环境密钥泄露风险
|
||||||
|
- 当前缓解:仅在开发环境使用
|
||||||
|
- 建议:使用环境变量或密钥 vault
|
||||||
|
|
||||||
|
**CORS 允许所有:**
|
||||||
|
- 风险:`policy.AllowAnyOrigin()` 存在安全风险
|
||||||
|
- 当前缓解:仅开发环境使用
|
||||||
|
- 建议:生产环境限制具体域名
|
||||||
|
|
||||||
|
## 性能问题
|
||||||
|
|
||||||
|
**当前未发现明显性能瓶颈:**
|
||||||
|
- 使用 Entity Framework Core 进行数据库查询
|
||||||
|
- 支持分页查询,避免大数据量返回
|
||||||
|
|
||||||
|
## 脆弱区域
|
||||||
|
|
||||||
|
**审计日志记录:**
|
||||||
|
- 每次操作都写入审计日志
|
||||||
|
- 高并发场景可能成为瓶颈
|
||||||
|
- 建议:考虑异步写入或批量处理
|
||||||
|
|
||||||
|
## 扩展限制
|
||||||
|
|
||||||
|
**当前架构支持:**
|
||||||
|
- 水平扩展:通过 Docker 容器化易于扩展
|
||||||
|
- 功能扩展:分层架构便于添加新模块
|
||||||
|
|
||||||
|
## 依赖风险
|
||||||
|
|
||||||
|
**外部依赖:**
|
||||||
|
- NetCorePal.Extensions - 自定义扩展库
|
||||||
|
- OpenIddict - 社区维护的开源库
|
||||||
|
- 建议:关注版本更新,及时升级
|
||||||
|
|
||||||
|
## 缺失功能
|
||||||
|
|
||||||
|
**缺失测试覆盖:**
|
||||||
|
- 无单元测试
|
||||||
|
- 无集成测试
|
||||||
|
- 无 API 测试
|
||||||
|
- 优先级:高
|
||||||
|
|
||||||
|
**缺失功能:**
|
||||||
|
- 无缓存层(Redis 已引用但未使用)
|
||||||
|
- 无消息队列集成
|
||||||
|
- 无后台任务系统
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*问题审计:2026-02-28*
|
||||||
118
.planning/codebase/CONVENTIONS.md
Normal file
118
.planning/codebase/CONVENTIONS.md
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
# 编码规范
|
||||||
|
|
||||||
|
**分析日期:** 2026-02-28
|
||||||
|
|
||||||
|
## 命名模式
|
||||||
|
|
||||||
|
**文件:**
|
||||||
|
- PascalCase:`UserService.cs`、`UsersController.cs`
|
||||||
|
|
||||||
|
**类/接口:**
|
||||||
|
- PascalCase:`UserService`、`IUserService`
|
||||||
|
|
||||||
|
**方法:**
|
||||||
|
- PascalCase:`GetUsersAsync`、`CreateUserAsync`
|
||||||
|
|
||||||
|
**变量:**
|
||||||
|
- camelCase:`userService`、`userName`
|
||||||
|
|
||||||
|
## 代码风格
|
||||||
|
|
||||||
|
**格式化:**
|
||||||
|
- 使用 .editorconfig 或 Rider/VS 默认格式化
|
||||||
|
- 花括号风格:K&R
|
||||||
|
|
||||||
|
**命名空间:**
|
||||||
|
- 层级式:`Fengling.Console.Controllers`
|
||||||
|
|
||||||
|
## 导入组织
|
||||||
|
|
||||||
|
**顺序:**
|
||||||
|
1. System 命名空间
|
||||||
|
2. 项目内部命名空间
|
||||||
|
3. 第三方库
|
||||||
|
|
||||||
|
**示例:**
|
||||||
|
```csharp
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Fengling.Console.Services;
|
||||||
|
using Fengling.Platform.Domain;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
```
|
||||||
|
|
||||||
|
## 错误处理
|
||||||
|
|
||||||
|
**模式:**
|
||||||
|
- 使用 try-catch 捕获异常
|
||||||
|
- 按异常类型返回不同 HTTP 状态码
|
||||||
|
- 记录日志:`_logger.LogError(ex, "...")`
|
||||||
|
|
||||||
|
**示例:**
|
||||||
|
```csharp
|
||||||
|
try {
|
||||||
|
await _userService.CreateUserAsync(dto);
|
||||||
|
} catch (InvalidOperationException ex) {
|
||||||
|
return BadRequest(new { message = ex.Message });
|
||||||
|
} catch (Exception ex) {
|
||||||
|
_logger.LogError(ex, "Error creating user");
|
||||||
|
return StatusCode(500, new { message = ex.Message });
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 日志
|
||||||
|
|
||||||
|
**框架:** Microsoft.Extensions.Logging + ILogger<T>
|
||||||
|
|
||||||
|
**模式:**
|
||||||
|
```csharp
|
||||||
|
private readonly ILogger<UsersController> _logger;
|
||||||
|
|
||||||
|
_logger.LogError(ex, "Error message");
|
||||||
|
_logger.LogWarning(ex, "Warning message");
|
||||||
|
```
|
||||||
|
|
||||||
|
## 注释
|
||||||
|
|
||||||
|
**何时注释:**
|
||||||
|
- 公开 API 方法使用 XML 文档注释
|
||||||
|
- 复杂业务逻辑添加说明
|
||||||
|
|
||||||
|
**XML 注释示例:**
|
||||||
|
```csharp
|
||||||
|
/// <summary>
|
||||||
|
/// 获取用户列表
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="query">分页查询参数</param>
|
||||||
|
/// <returns>分页的用户列表</returns>
|
||||||
|
[HttpGet]
|
||||||
|
public async Task<ActionResult<PagedResultDto<UserDto>>> GetUsers(...)
|
||||||
|
```
|
||||||
|
|
||||||
|
## 函数设计
|
||||||
|
|
||||||
|
**大小:**
|
||||||
|
- 保持方法简洁,单一职责
|
||||||
|
- 复杂逻辑拆分到私有方法
|
||||||
|
|
||||||
|
**参数:**
|
||||||
|
- 使用 DTO 进行参数分组
|
||||||
|
- 异步方法使用 Async 后缀
|
||||||
|
|
||||||
|
**返回值:**
|
||||||
|
- 使用 Task<T> 返回异步结果
|
||||||
|
- 集合使用 IEnumerable<T>
|
||||||
|
|
||||||
|
## 模块设计
|
||||||
|
|
||||||
|
**导出:**
|
||||||
|
- 公开接口:I[Xxx]Service
|
||||||
|
- 实现类:XxxService
|
||||||
|
|
||||||
|
**依赖注入:**
|
||||||
|
- 构造函数注入
|
||||||
|
- 接口+实现配对
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*规范分析:2026-02-28*
|
||||||
86
.planning/codebase/INTEGRATIONS.md
Normal file
86
.planning/codebase/INTEGRATIONS.md
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
# 外部集成
|
||||||
|
|
||||||
|
**分析日期:** 2026-02-28
|
||||||
|
|
||||||
|
## APIs & 外部服务
|
||||||
|
|
||||||
|
**身份认证:**
|
||||||
|
- **OpenIddict** - OAuth 2.0 / OpenID Connect 身份提供商
|
||||||
|
- 实现:内置 OpenIddict 认证服务器
|
||||||
|
- 客户端:fengling-api
|
||||||
|
- 密钥:fengling-api-secret(硬编码,见 `src/Program.cs:62`)
|
||||||
|
- 发行者:http://localhost:5132/
|
||||||
|
|
||||||
|
**反向代理:**
|
||||||
|
- **YARP (YarpGateway)** - 反向代理网关
|
||||||
|
- 项目引用:`../../fengling-gateway/src/YarpGateway.csproj`
|
||||||
|
- 用于 API 网关和请求转发
|
||||||
|
|
||||||
|
## 数据存储
|
||||||
|
|
||||||
|
**数据库:**
|
||||||
|
- **PostgreSQL** - 主数据库
|
||||||
|
- 连接:`DefaultConnection` (PlatformDbContext)
|
||||||
|
- 连接:`GatewayConnection` (GatewayDbContext)
|
||||||
|
- ORM:Entity Framework Core + Npgsql
|
||||||
|
|
||||||
|
**表结构:**
|
||||||
|
- 用户表 (ApplicationUser)
|
||||||
|
- 角色表 (ApplicationRole)
|
||||||
|
- 租户表 (Tenant)
|
||||||
|
- OAuth 客户端表
|
||||||
|
- 审计日志表 (AuditLog)
|
||||||
|
- 网关配置表
|
||||||
|
|
||||||
|
## 身份认证
|
||||||
|
|
||||||
|
**认证方案:**
|
||||||
|
- OpenIddict Validation (Bearer Token)
|
||||||
|
- JWT Bearer 认证
|
||||||
|
- ASP.NET Core Identity
|
||||||
|
|
||||||
|
**用户管理:**
|
||||||
|
- ASP.NET Core Identity
|
||||||
|
- 支持租户隔离 (TenantInfo)
|
||||||
|
|
||||||
|
## 监控与可观测性
|
||||||
|
|
||||||
|
**日志:**
|
||||||
|
- 使用 Microsoft.Extensions.Logging
|
||||||
|
- 通过 ILogger<T> 注入
|
||||||
|
- 开发环境启用敏感数据日志
|
||||||
|
|
||||||
|
**API 文档:**
|
||||||
|
- Swagger / OpenAPI
|
||||||
|
- 端点:`/swagger/v1/swagger.json`
|
||||||
|
|
||||||
|
## CI/CD & 部署
|
||||||
|
|
||||||
|
**主机:**
|
||||||
|
- Docker 容器化
|
||||||
|
- Dockerfile 位于 `src/Dockerfile`
|
||||||
|
|
||||||
|
**CI/CD 流水线:**
|
||||||
|
- Gitea Actions (`.gitea/workflows/`)
|
||||||
|
- `deploy.yml` - 部署流水线
|
||||||
|
- `docker.yml` - Docker 构建
|
||||||
|
- `build.yml` - 构建流水线
|
||||||
|
|
||||||
|
## 环境配置
|
||||||
|
|
||||||
|
**必需环境变量:**
|
||||||
|
- `ConnectionStrings:DefaultConnection` - 平台数据库连接
|
||||||
|
- `ConnectionStrings:GatewayConnection` - 网关数据库连接
|
||||||
|
|
||||||
|
**配置文件:**
|
||||||
|
- `appsettings.json` - 应用配置
|
||||||
|
- `appsettings.Development.json` - 开发配置
|
||||||
|
|
||||||
|
## Webhooks & 回调
|
||||||
|
|
||||||
|
**无外部 Webhooks:**
|
||||||
|
- 当前无外部系统回调集成
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*集成审计:2026-02-28*
|
||||||
86
.planning/codebase/STACK.md
Normal file
86
.planning/codebase/STACK.md
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
# 技术栈
|
||||||
|
|
||||||
|
**分析日期:** 2026-02-28
|
||||||
|
|
||||||
|
## 语言
|
||||||
|
|
||||||
|
**主要:**
|
||||||
|
- **C#** (.NET 10.0) - 后端 API 开发
|
||||||
|
|
||||||
|
**次要:**
|
||||||
|
- **JSON** - 配置文件和数据交换格式
|
||||||
|
|
||||||
|
## 运行时
|
||||||
|
|
||||||
|
**环境:**
|
||||||
|
- .NET 10.0.103 SDK
|
||||||
|
- ASP.NET Core 10.0 Web 应用
|
||||||
|
|
||||||
|
**包管理:**
|
||||||
|
- NuGet
|
||||||
|
- `global.json` 指定 SDK 版本 10.0.103,rollForward: latestMinor
|
||||||
|
|
||||||
|
## 框架
|
||||||
|
|
||||||
|
**核心:**
|
||||||
|
- **ASP.NET Core 10.0** - Web 框架
|
||||||
|
- **Entity Framework Core** - ORM,用于数据访问
|
||||||
|
- **Npgsql.EntityFrameworkCore.PostgreSQL** - PostgreSQL 数据库驱动
|
||||||
|
|
||||||
|
**身份认证:**
|
||||||
|
- **OpenIddict** - OAuth 2.0 / OIDC 身份提供商
|
||||||
|
- **Microsoft.AspNetCore.Authentication.JwtBearer** - JWT 令牌认证
|
||||||
|
|
||||||
|
**其他:**
|
||||||
|
- **Swashbuckle.AspNetCore** - Swagger/OpenAPI 文档
|
||||||
|
- **QRCoder** + **SkiaSharp** - 二维码生成
|
||||||
|
- **NetCorePal.Extensions** - 扩展库集合
|
||||||
|
|
||||||
|
## 关键依赖
|
||||||
|
|
||||||
|
**核心业务:**
|
||||||
|
- `Npgsql.EntityFrameworkCore.PostgreSQL` - PostgreSQL 数据库访问
|
||||||
|
- `OpenIddict.*` - 身份认证和授权
|
||||||
|
- `Microsoft.AspNetCore.Identity.EntityFrameworkCore` - 用户身份管理
|
||||||
|
|
||||||
|
**扩展库:**
|
||||||
|
- `NetCorePal.Extensions.AspNetCore` - ASP.NET Core 扩展
|
||||||
|
- `NetCorePal.Extensions.DistributedLocks.Redis` - 分布式锁
|
||||||
|
- `NetCorePal.Extensions.Repository.EntityFrameworkCore` - 仓储模式
|
||||||
|
|
||||||
|
**工具库:**
|
||||||
|
- `Swashbuckle.AspNetCore` - API 文档
|
||||||
|
- `QRCoder` + `SkiaSharp` - 二维码生成
|
||||||
|
- `Microsoft.OpenApi` - OpenAPI 支持
|
||||||
|
|
||||||
|
## 项目引用
|
||||||
|
|
||||||
|
- `YarpGateway` - 反向代理网关
|
||||||
|
- `Fengling.Platform.Infrastructure` - 平台基础设施
|
||||||
|
|
||||||
|
## 配置
|
||||||
|
|
||||||
|
**环境配置:**
|
||||||
|
- `appsettings.json` - 默认配置
|
||||||
|
- `appsettings.Development.json` - 开发环境配置
|
||||||
|
- `launchSettings.json` - 启动配置
|
||||||
|
|
||||||
|
**数据库连接:**
|
||||||
|
- `DefaultConnection` - 平台数据库 (PlatformDbContext)
|
||||||
|
- `GatewayConnection` - 网关数据库 (GatewayDbContext)
|
||||||
|
|
||||||
|
## 平台要求
|
||||||
|
|
||||||
|
**开发:**
|
||||||
|
- .NET 10.0 SDK
|
||||||
|
- PostgreSQL 数据库
|
||||||
|
- Visual Studio Code / Rider / Visual Studio
|
||||||
|
|
||||||
|
**生产:**
|
||||||
|
- Docker 容器化部署
|
||||||
|
- Linux 服务器
|
||||||
|
- PostgreSQL 数据库
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*技术栈分析:2026-02-28*
|
||||||
96
.planning/codebase/STRUCTURE.md
Normal file
96
.planning/codebase/STRUCTURE.md
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
# 代码库结构
|
||||||
|
|
||||||
|
**分析日期:** 2026-02-28
|
||||||
|
|
||||||
|
## 目录布局
|
||||||
|
|
||||||
|
```
|
||||||
|
fengling-console/
|
||||||
|
├── global.json # .NET SDK 版本配置
|
||||||
|
├── Directory.Build.props # 项目共享属性
|
||||||
|
├── src/
|
||||||
|
│ ├── Fengling.Console.csproj # 主项目文件
|
||||||
|
│ ├── Program.cs # 应用入口
|
||||||
|
│ ├── Dockerfile # Docker 构建文件
|
||||||
|
│ ├── appsettings.json # 应用配置
|
||||||
|
│ ├── appsettings.Development.json # 开发环境配置
|
||||||
|
│ ├── Properties/
|
||||||
|
│ │ └── launchSettings.json # 启动配置
|
||||||
|
│ ├── Controllers/ # API 控制器
|
||||||
|
│ ├── Services/ # 业务服务层
|
||||||
|
│ ├── Models/
|
||||||
|
│ │ └── Dtos/ # 数据传输对象
|
||||||
|
│ └── bin/Debug/ # 编译输出
|
||||||
|
├── .gitea/workflows/ # CI/CD 流水线
|
||||||
|
```
|
||||||
|
|
||||||
|
## 目录用途
|
||||||
|
|
||||||
|
**src/Controllers/:**
|
||||||
|
- 用途:API 端点定义
|
||||||
|
- 包含文件:
|
||||||
|
- `UsersController.cs` - 用户管理 API
|
||||||
|
- `RolesController.cs` - 角色管理 API
|
||||||
|
- `TenantsController.cs` - 租户管理 API
|
||||||
|
- `OAuthClientsController.cs` - OAuth 客户端 API
|
||||||
|
- `GatewayController.cs` - 网关配置 API
|
||||||
|
- `GlobalUsing.cs` - 全局 using 指令
|
||||||
|
|
||||||
|
**src/Services/:**
|
||||||
|
- 用途:业务逻辑实现
|
||||||
|
- 包含文件:
|
||||||
|
- `UserService.cs` - 用户业务逻辑
|
||||||
|
- `RoleService.cs` - 角色业务逻辑
|
||||||
|
- `TenantService.cs` - 租户业务逻辑
|
||||||
|
- `OAuthClientService.cs` - OAuth 客户端逻辑
|
||||||
|
- `GatewayService.cs` - 网关配置逻辑
|
||||||
|
- `H5LinkService.cs` - H5 链接服务
|
||||||
|
|
||||||
|
**src/Models/Dtos/:**
|
||||||
|
- 用途:API 数据传输对象
|
||||||
|
- 包含文件:
|
||||||
|
- CreateXxxDto.cs (CreateUserDto, CreateRoleDto, CreateTenantDto, CreateClientDto)
|
||||||
|
- UpdateXxxDto.cs (UpdateUserDto, UpdateRoleDto, UpdateTenantDto, UpdateClientDto)
|
||||||
|
- XxxDto.cs (UserDto, RoleDto, TenantDto, OAuthClientDto, GatewayDto)
|
||||||
|
- XxxQueryDto.cs (UserQueryDto, RoleQueryDto, TenantQueryDto, OAuthClientQueryDto)
|
||||||
|
- `PaginationDto.cs` - 分页结果
|
||||||
|
- `ResetPasswordDto.cs` - 密码重置
|
||||||
|
- `TenantSettingsDto.cs` - 租户设置
|
||||||
|
|
||||||
|
## 关键文件位置
|
||||||
|
|
||||||
|
**入口点:**
|
||||||
|
- `src/Program.cs` - 应用启动配置和服务注册
|
||||||
|
|
||||||
|
**配置:**
|
||||||
|
- `src/appsettings.json` - 应用配置
|
||||||
|
- `src/appsettings.Development.json` - 开发环境配置
|
||||||
|
|
||||||
|
**核心逻辑:**
|
||||||
|
- `src/Services/UserService.cs` - 用户服务实现
|
||||||
|
- `src/Controllers/UsersController.cs` - 用户 API
|
||||||
|
|
||||||
|
## 命名约定
|
||||||
|
|
||||||
|
**文件:**
|
||||||
|
- PascalCase:`UserService.cs`、`UsersController.cs`
|
||||||
|
|
||||||
|
**目录:**
|
||||||
|
- PascalCase:`Controllers/`、`Services/`、`Models/Dtos/`
|
||||||
|
|
||||||
|
**类/接口:**
|
||||||
|
- PascalCase:`UserService`、`IUserService`
|
||||||
|
|
||||||
|
## 新增代码位置
|
||||||
|
|
||||||
|
**新增功能:**
|
||||||
|
- API 端点:`src/Controllers/`
|
||||||
|
- 业务逻辑:`src/Services/`
|
||||||
|
- DTO:`src/Models/Dtos/`
|
||||||
|
|
||||||
|
**新增测试:**
|
||||||
|
- 建议位置:单独的测试项目(如 `tests/` 目录)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*结构分析:2026-02-28*
|
||||||
144
.planning/codebase/TESTING.md
Normal file
144
.planning/codebase/TESTING.md
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
# 测试模式
|
||||||
|
|
||||||
|
**分析日期:** 2026-02-28
|
||||||
|
|
||||||
|
## 测试框架
|
||||||
|
|
||||||
|
**未检测到测试框架:**
|
||||||
|
- 当前项目未包含测试项目
|
||||||
|
- 建议添加 xUnit、NUnit 或 MSTest
|
||||||
|
|
||||||
|
**推荐配置:**
|
||||||
|
- 框架:xUnit
|
||||||
|
- Mock 库:Moq
|
||||||
|
- 集成测试:Microsoft.AspNetCore.Mvc.Testing
|
||||||
|
|
||||||
|
## 测试文件组织
|
||||||
|
|
||||||
|
**建议结构:**
|
||||||
|
```
|
||||||
|
tests/
|
||||||
|
├── Fengling.Console.Tests/
|
||||||
|
│ ├── Unit/
|
||||||
|
│ │ ├── Services/
|
||||||
|
│ │ └── Controllers/
|
||||||
|
│ └── Integration/
|
||||||
|
```
|
||||||
|
|
||||||
|
## 测试结构
|
||||||
|
|
||||||
|
**单元测试示例:**
|
||||||
|
```csharp
|
||||||
|
public class UserServiceTests
|
||||||
|
{
|
||||||
|
private readonly Mock<UserManager<ApplicationUser>> _userManagerMock;
|
||||||
|
private readonly UserService _userService;
|
||||||
|
|
||||||
|
public UserServiceTests()
|
||||||
|
{
|
||||||
|
_userManagerMock = new Mock<UserManager<ApplicationUser>>(...);
|
||||||
|
_userService = new UserService(...);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task GetUsersAsync_ReturnsPagedResults()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var expectedUsers = new List<UserDto> { ... };
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = await _userService.GetUsersAsync(1, 10);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(expectedUsers.Count, result.TotalCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 模拟 (Mocking)
|
||||||
|
|
||||||
|
**常用 Mock 库:**
|
||||||
|
- Moq - 主流 Mock 框架
|
||||||
|
|
||||||
|
**Mock 对象:**
|
||||||
|
```csharp
|
||||||
|
var mockUserManager = new Mock<UserManager<ApplicationUser>>(
|
||||||
|
store: mockStore.Object,
|
||||||
|
optionsAccessor: new Mock<IOptions<IdentityOptions>>().Object,
|
||||||
|
passwordHasher: new Mock<IPasswordHasher<ApplicationUser>>().Object,
|
||||||
|
validators: new List<IUserValidator<ApplicationUser>>(),
|
||||||
|
keyNormalizer: new Mock<ILookupNormalizer>().Object,
|
||||||
|
errors: new IdentityErrorDescriber(),
|
||||||
|
logger: new Mock<ILogger<UserManager<ApplicationUser>>>().Object,
|
||||||
|
services: new Mock<IServiceProvider>().Object);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Fixture 和工厂
|
||||||
|
|
||||||
|
**测试数据:**
|
||||||
|
- 使用静态工厂方法创建测试数据
|
||||||
|
- 每个测试方法独立,不共享状态
|
||||||
|
|
||||||
|
**示例:**
|
||||||
|
```csharp
|
||||||
|
public static class TestData
|
||||||
|
{
|
||||||
|
public static CreateUserDto CreateValidUserDto() => new CreateUserDto
|
||||||
|
{
|
||||||
|
UserName = "testuser",
|
||||||
|
Email = "test@example.com",
|
||||||
|
Password = "Test@123456",
|
||||||
|
RealName = "Test User"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 测试类型
|
||||||
|
|
||||||
|
**单元测试:**
|
||||||
|
- 范围:Service 层业务逻辑
|
||||||
|
- 重点:边界条件、异常处理
|
||||||
|
|
||||||
|
**集成测试:**
|
||||||
|
- 范围:Controller API 端点
|
||||||
|
- 使用:Microsoft.AspNetCore.Mvc.Testing
|
||||||
|
|
||||||
|
## 常见模式
|
||||||
|
|
||||||
|
**异步测试:**
|
||||||
|
```csharp
|
||||||
|
[Fact]
|
||||||
|
public async Task CreateUserAsync_ValidInput_ReturnsCreatedUser()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var dto = TestData.CreateValidUserDto();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = await _userService.CreateUserAsync(dto);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.NotNull(result);
|
||||||
|
Assert.Equal(dto.UserName, result.UserName);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**异常测试:**
|
||||||
|
```csharp
|
||||||
|
[Fact]
|
||||||
|
public async Task CreateUserAsync_DuplicateUser_ThrowsException()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var dto = TestData.CreateValidUserDto();
|
||||||
|
_userManagerMock
|
||||||
|
.Setup(x => x.CreateAsync(It.IsAny<ApplicationUser>(), It.IsAny<string>()))
|
||||||
|
.ReturnsAsync(IdentityResult.Failed(new IdentityError { Description = "Duplicate" }));
|
||||||
|
|
||||||
|
// Act & Assert
|
||||||
|
await Assert.ThrowsAsync<InvalidOperationException>(() =>
|
||||||
|
_userService.CreateUserAsync(dto));
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*测试分析:2026-02-28*
|
||||||
Loading…
Reference in New Issue
Block a user