Compare commits

...

2 Commits

Author SHA1 Message Date
movingsam
feb1a733cd fix: 修复 CI/CD Dockerfile 路径
Some checks failed
Build / build (push) Failing after 34s
Deploy to K8s / deploy (push) Failing after 2s
Build and Push Docker / build (push) Failing after 16s
- 修改 dockerfile 路径为 ./src/Dockerfile
2026-02-28 21:52:11 +08:00
movingsam
b8d2a93c9f docs: 添加代码库分析文档(中文)
- STACK.md - 技术栈和依赖
- INTEGRATIONS.md - 外部集成
- ARCHITECTURE.md - 架构设计
- STRUCTURE.md - 代码库结构
- CONVENTIONS.md - 编码规范
- TESTING.md - 测试模式
- CONCERNS.md - 技术债务和问题
2026-02-28 18:38:17 +08:00
8 changed files with 715 additions and 1 deletions

View File

@ -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 }}

View 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*

View 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*

View 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*

View 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)
- ORMEntity 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*

View 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.103rollForward: 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*

View 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*

View 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*