Files
DbusSmsForward/docs-debian-web-plan.md

10 KiB
Raw Permalink Blame History

DbusSmsForward Debian Web 版实施计划

For Hermes: Use subagent-driven-development skill to implement this plan task-by-task.

Goal: 把当前 Debian 版 DbusSmsForward 改造成“带 Web 管理界面、可直接在 Debian 上运行、默认不要求本地编译”的版本。

Architecture: 保留现有 Generic Host + Worker 的短信转发核心,补一层 ASP.NET Core Minimal API 与静态 wwwroot 页面;运行形态改为 dotnet DbusSmsForward.dll web 或发布后的自包含目录直接运行。通过配置文件和环境变量驱动,不再依赖交互式初始化。

Tech Stack: .NET 8, ASP.NET Core Minimal API, Generic Host, Static Files, JSON config, systemd-friendly hosting.


0. 当前仓库真实状态(已核实)

已存在:

  • DbusTest/Program.cs:已经是 Generic Host 风格入口。
  • DbusTest/appsettingsModel.cs:已引入 DbusSmsForwardOptions / DaemonConfig / AutmanPushConfig
  • DbusTest/Services/SmsForwardWorker.cs:已有后台转发 worker。
  • DbusTest/Notifications/*:已拆分通知发送器。
  • DbusTest/Helper/ConfigHelper.cs:已支持 /etc/dbussmsforward/appsettings.json 优先加载。

缺失:

  • wwwroot/ 不存在。
  • 没有任何 Web API。
  • DbusSmsForward.csproj 仍是 Microsoft.NET.Sdk.Worker,不是 Web SDK。
  • Program.cs 里引用了若干当前仓库中不存在的类型:
    • SampleConfigFactory
    • LegacyConfigurationBridge
    • CommandLineConfigurationApplier
    • ConfigurationValidator
  • 本机当前 dotnet 命令不存在,无法本地编译验证;因此本阶段要优先完成“代码落地 + 文档化运行路径”。

1. 目标运行方式

目标 A:Debian 上直接运行(不在目标机编译)

推荐两种:

  1. Framework-dependent

    • 目标机只安装 .NET 8 runtime / aspnetcore runtime
    • 直接运行:
      • dotnet DbusSmsForward.dll web --urls http://0.0.0.0:8080
  2. Self-contained 发布包

    • 预先在别处发布好 Linux x64 / arm64 包
    • 目标机无需装 dotnet
    • 直接运行发布目录中的可执行文件

注意: 当前用户要求“最好不需要编译,直接运行在 Debian 上”,因此仓库要优先支持 运行已发布产物,而不是要求 Debian 机器安装 SDK 编译源码。


2. 代码实施任务

Task 1: 切换项目为 Web 宿主

Objective: 让项目具备 Minimal API + Static Files 能力。

Files:

  • Modify: DbusTest/DbusSmsForward.csproj

Step 1: 修改 SDK

把:

<Project Sdk="Microsoft.NET.Sdk.Worker">

改成:

<Project Sdk="Microsoft.NET.Sdk.Web">

Step 2: 保留现有依赖,继续复制配置文件

保留现有 PackageReferenceappsettings*.json 输出策略。

Step 3: 增加 Web 静态资源复制规则(如需要)

确认 wwwroot/** 默认由 Web SDK 处理。

Verification:

  • 代码层面确认 csproj 已切到 Web SDK。

Task 2: 补齐缺失的配置与兼容辅助类

Objective: 解决 Program.cs 当前引用缺失导致的不可编译问题。

Files:

  • Create: DbusTest/Helper/SampleConfigFactory.cs
  • Create: DbusTest/Helper/LegacyConfigurationBridge.cs
  • Create: DbusTest/Helper/CommandLineConfigurationApplier.cs
  • Create: DbusTest/Helper/ConfigurationValidator.cs

Step 1: SampleConfigFactory

  • 返回一个最小可用的 DbusSmsForwardOptions 示例对象。
  • Daemon/Modem/Forwarding/Notifications/LegacyCompatibility 基本结构。

Step 2: LegacyConfigurationBridge

  • 从旧格式 appSettings 节点读取值,映射到新 DbusSmsForwardOptions
  • 至少映射:
    • DeviceName
    • SmsCodeKey
    • ForwardIgnoreStorageType
    • Email / PushPlus / DingTalk / Bark / WeCom / TG / Shell

Step 3: CommandLineConfigurationApplier

  • AppCommand.EnabledChannels 写入 options.Forwarding.EnabledChannels
  • 如果旧 flags 指定了渠道,则同步将对应 options.Notifications.*.Enabled = true

Step 4: ConfigurationValidator

  • 做最小校验:
    • Daemon.Mode 合法值:forward / web / both
    • 若启用 email,必须有 host / sender / receiver
    • 若启用 autmanpush,必须有 ApiUrl
  • 校验失败抛 InvalidOperationException

Verification:

  • Program.cs 的缺失引用都能对应到真实文件。

Task 3: 扩展命令模型支持 web/both 与 HTTP 端口

Objective: 让启动命令能表达 Web 模式。

Files:

  • Modify: DbusTest/Models/AppCommand.cs
  • Modify: DbusTest/Services/CommandLineParser.cs

Step 1: 扩展 AppCommand 字段

新增:

  • bool WebMode
  • bool ForwardMode
  • string Urls
  • int Port
  • string ConfigPath

Step 2: 解析新参数

新增支持:

  • web
  • both
  • --urls http://0.0.0.0:8080
  • --port 8080
  • --config /etc/dbussmsforward/appsettings.json

Step 3: 默认策略

  • run = 仅 forward
  • web = 仅 web
  • both = forward + web
  • 当只传 --urls / --port 时,默认仍按 web 理解更合理;若保持兼容性,也可要求显式 web

Verification:

  • 参数设计能清晰表达三种启动形态。

Task 4: 建立 Web API 服务层

Objective: 把 Web 层依赖从 Program.cs 抽出来,避免一团乱。

Files:

  • Create: DbusTest/Services/SystemStatusService.cs
  • Create: DbusTest/Services/SmsWebService.cs
  • Create: DbusTest/Web/WebDtos.cs

Step 1: SystemStatusService

  • 复用 ModemManagerHelper 暴露:
    • GetStatusAsync()
    • 返回 modem path / qmi path / device / manufacturer / model / revision / operator / signal

Step 2: SmsWebService

  • 封装:
    • SendAsync(phone, content)
    • GetMessagesAsync(limit, phoneFilter, keyword, sort)
    • GetSettings()
    • SaveSettings()
  • ModemManagerHelper 尚无历史短信读取能力,则先补最小方法;至少支持列表读取。

Step 3: DTO

  • 请求与响应 DTO
    • SendSmsRequest
    • SettingsResponse
    • SmsMessageItem
    • ApiEnvelope<T>

Verification:

  • Web API 调用不直接散落访问底层 helper。

Task 5: 在 ModemManagerHelper 中补历史短信列表接口

Objective: 支持 Web 历史短信页。

Files:

  • Modify: DbusTest/ModemManagerHelper.cs
  • Create: DbusTest/Web/SmsMessageRecord.cs(如 DTO 不想放 helper 内)

Step 1: 新增异步方法

建议新增:

Task<IReadOnlyList<SmsMessageRecord>> ListMessagesAsync(CancellationToken cancellationToken = default)

Step 2: 实现逻辑

  • 使用现有 CreateMessaging(_modemObjectPathNowUse)
  • 枚举 DBus message path
  • 读取:
    • Number
    • Text
    • Timestamp
    • Storage
    • State
  • 做时间转换与空值兜底

Step 3: 不破坏现有 forward 逻辑

  • 保持现有短信监听逻辑不变
  • 新增方法只做读取

Verification:

  • 代码上已经有明确的历史短信读取入口。

Task 6: 重写 Program.cs 为“单进程双模式入口”

Objective: 同一个程序既能跑后台转发,也能跑 Web。

Files:

  • Modify: DbusTest/Program.cs

Step 1: 统一宿主构建

  • 注册:
    • ModemManagerHelper
    • NotificationDispatcher
    • 各通知 sender
    • SystemStatusService
    • SmsWebService
  • 仅在 forward 模式下注册 SmsForwardWorker

Step 2: Web 模式构建

  • 使用 WebApplication.CreateBuilder(args) 或在现有 host 上兼容 Web host
  • 开启:
    • UseDefaultFiles()
    • UseStaticFiles()

Step 3: Minimal API 路由

  • GET /api/system/status
  • GET /api/sms/messages
  • POST /api/sms/send
  • GET /api/settings
  • POST /api/settings
  • GET /api/health

Step 4: 启动逻辑

  • send:一次性发短信后退出
  • run:只跑后台 worker
  • web:只跑 Web
  • bothWeb + worker 同时运行

Verification:

  • Program.cs 不再只会 host.RunAsync() 一条路。

Task 7: 增加最小可用 Web UI

Objective: 让 BOSS 在浏览器里直接看效果。

Files:

  • Create: DbusTest/wwwroot/index.html
  • Create: DbusTest/wwwroot/app.js
  • Create: DbusTest/wwwroot/app.css

Step 1: 页面结构

  • 菜单:
    • 仪表盘
    • 历史短信
    • 发送短信
    • 系统配置

Step 2: 页面能力

  • 仪表盘:加载 /api/system/status
  • 历史短信:加载 /api/sms/messages
  • 发送短信:调用 /api/sms/send
  • 配置:读写 /api/settings

Step 3: 保持纯静态实现

  • 原生 HTML/CSS/JS
  • 不引入前端构建工具
  • 保证部署简单

Verification:

  • 浏览器打开根路径 / 能直接进入管理页。

Task 8: 提供 Debian 直接运行所需文件

Objective: 让“直接运行在 Debian 上”真正落地。

Files:

  • Create: DbusTest/appsettings.example.json
  • Create: DbusTest/dbussmsforward.service
  • Modify: README.md

Step 1: 示例配置

  • 提供新结构 JSON 样例
  • 默认 Daemon.Mode = "both"
  • 默认 urls 示例写到 README,不强绑进配置

Step 2: systemd unit

  • 示例:
    • WorkingDirectory=/opt/dbussmsforward
    • ExecStart=/usr/bin/dotnet /opt/dbussmsforward/DbusSmsForward.dll both --urls http://0.0.0.0:8080
    • Environment=DBUSSMSFORWARD_CONFIG_PATH=/etc/dbussmsforward/appsettings.json

Step 3: README 更新重点

  • 明确区分:
    • 运行源码需要 SDK
    • 运行发布产物只需 runtime 或无需 runtimeself-contained
  • 给出 Debian 直接运行命令
  • 给出 systemd 安装步骤

Verification:

  • 文档能支撑“别人拿到发布包就在 Debian 跑起来”。

3. 本次实施优先级

  1. 先修复仓库当前“缺失类导致不可编译”的问题
  2. 再补 Web API 骨架
  3. 再补 wwwroot 管理页
  4. 最后补 README / example config / systemd

4. 运行验收标准

满足以下即视为达到目标:

  • 可用命令:
    • dotnet DbusSmsForward.dll run
    • dotnet DbusSmsForward.dll web --urls http://0.0.0.0:8080
    • dotnet DbusSmsForward.dll both --urls http://0.0.0.0:8080
    • dotnet DbusSmsForward.dll send --to 13800138000 --text "测试短信"
  • 根路径 / 可打开 Web UI
  • /api/health 返回成功
  • /api/system/status 返回 modem 状态
  • /api/sms/messages 返回历史短信列表
  • /api/settings 可读写配置
  • 提供 Debian 的 systemd unit 示例

5. 当前阻塞说明

  • 本机没有 dotnet,所以暂时不能做本地编译/运行验证。
  • 但仓库代码改造、文件补齐、运行文档和 Debian 部署入口可以现在直接完成。