Files
Hua.Todo/.trae/rules/项目/01-项目架构.md
T
ShaoHua 3213d4c718 feat: 完成v1.3.0架构对齐与Web端根路径托管全量开发
- 重构架构:抽离AddCloudSyncServer到扩展类,补全中间层文档对齐
- 修复根路径404与鉴权跳转:新增中间件处理浏览器请求302跳转
- 实现种子数据初始化:添加默认管理员账号自动创建逻辑
- 优化前端代理与构建:新增Vite代理配置与自动构建Target
- 补全测试与文档:新增集成测试,更新开发与部署文档
2026-08-08 07:33:44 +08:00

12 KiB
Raw Blame History

项目架构(Hua.Todo 专属)

适用范围:本规则属于 项目规则(仅 Hua.Todo 项目生效)。

描述当前仓库的项目划分、依赖方向、运行模式与跨平台策略,供智能体在做改动时快速对齐架构边界。 完整设计参见 docs/manual/05-技术栈与项目结构.md 与 docs/manual/07-技术架构设计.md。

一、项目清单(src/)

项目 类型 职责 平台
Hua.Todo.Core 类库 领域实体、仓储接口(TaskEntity、UserEntity、SecurityPolicyEntity、AuditLogEntity、ITaskRepository 等) netstandard / net
Hua.Todo.Application 类库(共享层) EF Core TodoDbContext、TaskService/TaskRepository、CloudSync 业务服务(Application/Services/CloudSync/)、动态 API 属性层、迁移 net
Hua.Todo.HttpApi.AspNetCore 类库(ASP.NET Core 专属 HTTP 层) 承载依赖 ASP.NET Core 的实现:DynamicApiMiddleware、Mcp Server 端点、云同步服务端 DI(SessionAuthenticationHandler、CloudSyncServerService) net(依赖 Microsoft.AspNetCore.App 共享框架)
Hua.Todo.Host ASP.NET 服务端 Host 双角色统一部署:(1) Web 端前端/后端同源部署(承载前端静态资源 + Dynamic API + Swagger + MCP);(2) 云同步权威服务端(供 MAUI/Avalonia 的 CloudSyncProxy 转发);不区分模式 Windows/Linux 等服务器
Hua.Todo.Maui MAUI 客户端 Windows / macOS / iOS / Android 入口;内嵌 WebServer + WebView 承载 Vue 前端 多端
Hua.Todo.Avalonia Avalonia 客户端 Linux / Windows 桌面入口;内嵌 WebServer + WebView.Avalonia 承载 Vue 前端 桌面(含 Linux)
Hua.Todo.Web Vite + Vue 3 前端 同一份前端构建产物,被多个宿主以静态资源形式承载 浏览器/WebView

二、依赖方向(必须保持单向)

本图为 2026-08-08 v1.3.0 工单 05 更新版(代码对齐时间戳)。后续修改架构章节时,必须更新本标记并走 Glob/Grep 校验(详见 v1.3.0 00-工单总览 §5「架构文档 ↔ 代码一致性强制策略」)。

Hua.Todo.Core                         (无依赖)
   ↑ 单向引用
Hua.Todo.Application                  (依赖 Core)
   ↑ 单向引用
Hua.Todo.HttpApi.AspNetCore           (依赖 Application;依赖 Microsoft.AspNetCore.App 共享框架)
   ↑ 单向引用
   ├── Hua.Todo.Host                  (注册 AddApplicationServices + AddCloudSyncServer + AddMcpServerServices)
   ├── Hua.Todo.Maui                  (仅引用 Application + HttpApi.AspNetCore 的 CloudSyncProxy 子模块;不引用 AddCloudSyncServer)
   └── Hua.Todo.Avalonia              (同上,仅嵌入式 + CloudSyncProxy)

Hua.Todo.Web (无 .NET 依赖;通过 HTTP/同源调用上述任一宿主)
  • 禁止反向依赖:Core 不得引用 Application;Application 不得引用 HttpApi.AspNetCore / 任何宿主;HttpApi.AspNetCore 不得引用宿主项目。
  • MAUI / Avalonia 不得注册 AddCloudSyncServer:只注册 AddApplicationServices() + AddCloudSyncProxy(),权威云同步端点只在 Host 暴露。
  • MAUI / Avalonia 跨层引用边界:只引用 HttpApi.AspNetCore 中与嵌入式相关的类型(CloudSyncProxyMiddleware、CloudSyncProxySettings 等),不引用 CloudSyncServerService 等 Host-only DI 扩展(实际通过命名空间自然隔离)。

三、两种运行模式

端口对照表(全局统一,禁止硬编码歧义值)

端口 用途 所属模式 说明
:5057 嵌入式 Kestrel WebServer(HTTP) 嵌入式 MAUI / Avalonia 内嵌;Vite proxy 默认 target
:5173 Web 端 ASP.NET(HTTP) Web 端 前端云同步默认填写的服务器地址;Host Program.cs.UseUrls 显式绑定
:7055 Web 端 ASP.NET(HTTPS) Web 端 开发环境可选;生产由反向代理(Nginx/Caddy)统一 TLS 终止
:5174 Vite dev server(开发) 两者均可 WebView / 浏览器开发调试入口;.env.development 使用

模式 A:嵌入式(MAUI / Avalonia + WebView)

桌面/移动原生客户端,数据先存本地 SQLite(本地缓存),再按需与 Web 端同步。

请求链路(前端 → 本地 → 远端):

WebView(Hua.Todo.Web)
  ├─ 本地 Todo 操作(增删改查) → 同源 /api/task* 等动态 API
  │     → EmbeddedWebServerService(:5057)
  │     → UseDynamicApi
  │     → ITaskService / TaskRepository
  │     → 本地 SQLite(Hua.Todo.db)
  └─ 云同步操作(探测 / 登录 / 拉取 / 推送 / 策略)
        → 同源 /api/auth、/api/tasks、/api/cloud-sync/*、/api/security/*
        → EmbeddedWebServerService(:5057)
        → UseCloudSyncProxy(CloudSyncProxyMiddleware)
        → 后端 HttpClient 转发到「用户配置的 Web 端地址」(例 http://localhost:5173)
        → Web 端 Hua.Todo.Host 的动态 API 做鉴权与同步

关键规则:

  • 启动内嵌 Kestrel WebServer(端口 :5057),生产托管 Vue 前端静态产物(wwwroot/),开发加载 Vite dev server(ForEndUrl=http://localhost:5174)
  • 注入:window.__API_BASE_URL__ = "${HostUrl}/api"(HostUrl=http://localhost:5057)、window.mauiInterop
  • DI 只注册 AddApplicationServices() + AddCloudSyncProxy(),不注册 AddCloudSyncServer():嵌入式端不做用户管理、不暴露云同步的权威端点
  • 默认 SQLite 路径:LocalApplicationData/Hua.Todo/Hua.Todo.db(避免安装目录无写权限)
  • 本地用户 ID 固定为 TodoUserIds.LocalUserId = "local",与云端用户隔离

模式 B:Web 端(Hua.Todo.Host,部署入口)= Host 双角色统一部署

⚠️ Host 部署时不区分模式:

  • 对外角色:用户浏览器直接访问 Host(http://host-address:5173/)→ 即"Web 端前端 + 后端同源部署"
  • 对内角色:同时承担"云同步权威服务端"职责,接受 MAUI/Avalonia 嵌入式客户端通过 CloudSyncProxy 转发 /api/* 过来的请求

因此 Hua.Todo.Host/Program.cs 必须同时注册:AddApplicationServices + AddCloudSyncServer + AddMcpServerServices。

独立部署的 ASP.NET 服务端,既是后端接口服务,也是前端静态站点托管,部署产物是单个 Hua.Todo.Host 进程。

端点划分(四个逻辑入口,同一进程):

URL 前缀 内容 来源
/(根路径及所有 SPA 路由) Hua.Todo.Web 用户前端(登录后 Todo 列表) src/Hua.Todo.Web 的 dist/ 构建产物复制到 Hua.Todo.Host/wwwroot/;若缺失则由 MinimalBootstrapPageMiddleware 返回最小引导页(中文错误提示 + 构建命令,不 404)
/api/* 动态 API(本地+云同步共用的一套接口) Hua.Todo.Application/DynamicApi 扫描所有 IDynamicApiService 自动暴露(task / auth / tasks / security / cloud-sync / admin / voice)。权限检查时,浏览器 HTML 直访 Accept:text/html → 302 跳 /(前端接管登录弹窗);其他 API 请求(JSON)→ 401/403 JSON 错误
/mcp MCP Server 端点(Streamable HTTP) McpEndpointExtensions.cs 映射,供 MCP 客户端调用
/swagger + /admin/* Swagger UI + 管理后台前端(用户管理、审计、策略) Swagger:开发环境启用;Admin:Hua.Todo.Host/wwwroot/admin/(当前占位,后续 Vue 3 构建产物填入)

关键规则:

  • 同时注册 AddApplicationServices() + AddCloudSyncServer()(后者额外注册 IPasswordHasher<UserEntity>、云同步动态 API、安全策略校验器等)
  • 中间件顺序必须严格遵守(见 00-工单总览.md §5):Swagger → MinimalBootstrapPageMiddleware → UseDefaultFiles/UseStaticFiles → CORS → Authentication → Authorization → UseDynamicApi → MapMcpServer → MapFallbackToFile → Run
  • 端口:HTTP :5173 + HTTPS :7055,Program.cs 显式 UseUrls 绑定
  • 开发环境不启用 UseHttpsRedirection(由反向代理统一做 TLS 终止),避免前端 axios 把 307 当错误
  • 数据库:开发/测试使用 src/Hua.Todo.Host/Hua.Todo.db(SQLite);生产可切换其他后端

四、跨平台原则

  • 业务逻辑统一在 Application 层,宿主项目只做 DI 装配与平台桥接
  • 平台差异通过接口 + 平台目录实现(例:IGlobalHotKeyService 在 MAUI 与 Avalonia 各有自己的 Platforms/ 子目录实现)
  • 前端只有一份:Vue 项目通过不同的 .env.* 文件区分模式(.env.development / .env.maui / .env.production)

五、关键扩展点

扩展点 位置
DI 注册总入口 Hua.Todo.Application/Common/ServiceCollectionExtensions.cs(AddApplicationServices)
云同步服务端 DI(Host 专用) Hua.Todo.HttpApi.AspNetCore/CloudSync/CloudSyncServiceCollectionExtensions.cs(AddCloudSyncServer)
云同步代理 DI / 中间件(嵌入式) Hua.Todo.Application/Services/CloudSync/Services/CloudSyncProxyService.cs(AddCloudSyncProxy / UseCloudSyncProxy)
云同步代理设置端点(嵌入式) Hua.Todo.Application/Services/CloudSync/Services/ICloudSyncProxySettingsService(继承 IDynamicApiService,由 DynamicApi 自动暴露;仅在 AddCloudSyncProxy 时注册 DI)
云同步接口(auth/tasks/security/admin/cloud-sync probe) Hua.Todo.Application/Services/CloudSync/Services/ICloud*Service 实现 IDynamicApiService,由 DynamicApi 自动暴露
动态 API 中间件 + 路由/权限 Hua.Todo.HttpApi.AspNetCore/DynamicApi/DynamicApiMiddleware.cs(含 DynamicApiRouteAttribute / RequirePermissionAttribute)
MCP Server(工具描述符自动生成 + 端点) Hua.Todo.HttpApi.AspNetCore/Mcp/DynamicMcpToolExtensions.cs + McpServiceCollectionExtensions.cs(DI 注册 AddMcpServerServices) + McpEndpointExtensions.cs(端点 MapMcpServer)
嵌入式 WebServer Hua.Todo.{Maui,Avalonia}/Services/EmbeddedWebServerService.cs
种子数据初始化器(Web 端 DB Migrate 后) Hua.Todo.Application/Services/DataSeeder/IDataSeeder(仅在 AddCloudSyncServer 时注册)
全局快捷键平台实现 Hua.Todo.{Maui,Avalonia}/Services/Platforms/*GlobalHotKeyService.cs

六、版本统一策略

七、测试项目架构

7.1 目录结构

test/                                     ← 项目根目录下的顶层测试目录
├── Hua.Todo.Host.Tests/                  ← 服务端/Application 层集成测试
│   ├── CloudSync/                        ← 云同步模块
│   ├── Meeting/                          ← 会议模块
│   └── Attachments/                      ← 附件模块
├── Hua.Todo.Maui.Tests/                  ← MAUI 平台测试(骨架)
└── Hua.Todo.Avalonia.Tests/              ← Avalonia 平台测试(骨架)

7.2 分层规则(严禁跨层)

测试项目 可引用的被测项目 不得引用
Hua.Todo.Host.Tests Hua.Todo.Host / Application / Core MAUI / Avalonia 宿主
Hua.Todo.Maui.Tests Hua.Todo.Maui / Application / Core Avalonia 宿主
Hua.Todo.Avalonia.Tests Hua.Todo.Avalonia / Application / Core MAUI 宿主

7.3 技术栈与规范

  • 框架:xUnit 2.9+,SQLite In-Memory 模拟 DB
  • 测试层次:直接测 Application 服务层(DI 测试),必要时用 WebApplicationFactory
  • 命名:类 {被测类}Tests、方法 {方法名}_{场景}_{预期结果}、命名空间 Hua.Todo.Host.Tests.{模块名}
  • 文件组织:每个模块新建子目录,模块级共用测试放根目录