# 项目架构(Hua.Todo 专属) > 适用范围:本规则属于 **项目规则**(仅 Hua.Todo 项目生效)。 > > 描述当前仓库的项目划分、依赖方向、运行模式与跨平台策略,供智能体在做改动时快速对齐架构边界。 > 完整设计参见 [docs/manual/05-技术栈与项目结构.md](../../../docs/manual/05-技术栈与项目结构.md) 与 [docs/manual/07-技术架构设计.md](../../../docs/manual/07-技术架构设计.md)。 ## 一、项目清单(src/) | 项目 | 类型 | 职责 | 平台 | |---|---|---|---| | [Hua.Todo.Core](file:///d:/Proj/6.Hua.Todo/src/Hua.Todo.Core) | 类库 | 领域实体、仓储接口(`TaskEntity`、`UserEntity`、`SecurityPolicyEntity`、`AuditLogEntity`、`ITaskRepository` 等) | netstandard / net | | [Hua.Todo.Application](file:///d:/Proj/6.Hua.Todo/src/Hua.Todo.Application) | 类库(共享层) | EF Core `TodoDbContext`、`TaskService`/`TaskRepository`、CloudSync 业务服务(`Application/Services/CloudSync/`)、动态 API 属性层、迁移 | net | | [Hua.Todo.HttpApi.AspNetCore](file:///d:/Proj/6.Hua.Todo/src/Hua.Todo.HttpApi.AspNetCore) | 类库(ASP.NET Core 专属 HTTP 层) | 承载依赖 ASP.NET Core 的实现:DynamicApiMiddleware、Mcp Server 端点、云同步服务端 DI(SessionAuthenticationHandler、CloudSyncServerService) | net(依赖 `Microsoft.AspNetCore.App` 共享框架) | | [Hua.Todo.Host](file:///d:/Proj/6.Hua.Todo/src/Hua.Todo.Host) | ASP.NET 服务端 | **Host 双角色统一部署**:(1) Web 端前端/后端同源部署(承载前端静态资源 + Dynamic API + Swagger + MCP);(2) 云同步权威服务端(供 MAUI/Avalonia 的 CloudSyncProxy 转发);不区分模式 | Windows/Linux 等服务器 | | [Hua.Todo.Maui](file:///d:/Proj/6.Hua.Todo/src/Hua.Todo.Maui) | MAUI 客户端 | Windows / macOS / iOS / Android 入口;内嵌 WebServer + WebView 承载 Vue 前端 | 多端 | | [Hua.Todo.Avalonia](file:///d:/Proj/6.Hua.Todo/src/Hua.Todo.Avalonia) | Avalonia 客户端 | Linux / Windows 桌面入口;内嵌 WebServer + `WebView.Avalonia` 承载 Vue 前端 | 桌面(含 Linux) | | [Hua.Todo.Web](file:///d:/Proj/6.Hua.Todo/src/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`、云同步动态 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` | ## 六、版本统一策略 - 全局版本号通过根目录 `Directory.Build.props` 集中管理(当前 `1.2.3`) - Inno Setup 安装包:`src/Hua.Todo.Maui/setup.iss`、`src/Hua.Todo.Avalonia/setup.iss` - Linux:`publish-linux.ps1` 产出 `.tar.gz`;`pack/linux/` 含 Flatpak 基础结构 - 详见 [docs/project/研发工单-v1.2.0/02.1-版本统一与打包方案.md](../../../docs/project/研发工单-v1.2.0/02.1-版本统一与打包方案.md) ## 七、测试项目架构 ### 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.{模块名}` - 文件组织:每个模块新建子目录,模块级共用测试放根目录