feat: 初始化Webhook中继系统项目

- 添加FastAPI应用基础结构,包括主入口、路由和模型定义
- 实现Webhook接收端点(/webhook/{namespace})和健康检查(/health)
- 添加管理后台路由和模板,支持端点、目标、渠道和模板管理
- 包含SQLite数据库模型定义和初始化逻辑
- 添加日志记录和统计服务
- 包含Dockerfile和配置示例文件
- 添加项目文档,包括设计、流程图和验收标准
This commit is contained in:
2025-12-21 18:43:12 +08:00
commit 2bc7460f1f
42 changed files with 3177 additions and 0 deletions
@@ -0,0 +1,32 @@
# Webhook中继系统 - Admin后台升级计划
## 1. 核心变更:数据库驱动配置
- 引入 **SQLite + SQLAlchemy** 替代静态 `config.yml`
- 存储模型:
- `Target`:转发目标Webhook(名称、URL、超时)。
- `RemarkRule`:remark值到目标列表的映射(imcgcd03 -> [Target A, Target B])。
- `EventTemplate`:事件模板(event_define_no -> 模板文本)。
- `NotificationChannel`:通知渠道(类型feishu/wecom、Webhook URL、名称)。
- `EventChannelBinding`:事件到渠道的绑定(pay.ali_scaned -> [Channel A, Channel B])。
## 2. Admin后台界面
- 基于 **FastAPI + Jinja2 + Bootstrap** 提供简易管理UI。
- 功能页面:
- **目标管理**:增删改查转发目标。
- **路由规则**:配置 `remark` 对应的目标列表。
- **通知模板**:编辑不同事件的通知文案。
- **通知渠道**:添加飞书/企业微信机器人链接。
- **通知绑定**:将事件与通知渠道关联。
## 3. 系统架构调整
- `app/db.py`:数据库连接与模型定义。
- `app/admin.py`:管理后台路由与CRUD逻辑。
- `app/config.py`:改为混合模式,优先从DB加载动态配置,保留文件配置作为默认值/种子数据。
- `app/services/relay.py` & `notify.py`:适配新的DB驱动配置查询。
## 4. 实施步骤
1. **依赖更新**:添加 `sqlalchemy``jinja2``python-multipart`
2. **数据层实现**:定义ORM模型与初始化脚本(支持从现有yaml导入种子数据)。
3. **后台UI实现**:创建HTML模板与FastAPI路由。
4. **配置适配**:改造 `load_config` 逻辑,支持热重载或每次请求查询DB。
5. **构建与部署**:更新Dockerfile,重新构建并运行,验证后台配置生效。
@@ -0,0 +1,47 @@
# Webhook中继系统 - 增强功能实施计划
## 1. 核心变更:日志审计与多端点管理
为了满足多Webhook接收管理、系统状态监控及日志审计需求,将进行以下数据库与逻辑扩展:
### 1.1 数据库模型扩展 (`app/db.py`)
- **`WebhookEndpoint`**:管理接收端点(Namespace)。
- 字段:`namespace` (唯一标识), `description` (备注), `created_at`, `is_active`
- **`RequestLog`**:记录入站请求。
- 字段:`id`, `namespace`, `remark`, `event_no`, `raw_body` (JSON), `received_at`, `status` (success/error)。
- **`DeliveryLog`**:记录出站转发与推送结果。
- 字段:`request_id` (FK), `target_name` (目标/渠道名), `type` (relay/notify), `status`, `response_summary`, `created_at`
### 1.2 业务逻辑增强 (`app/main.py`)
- **端点校验**`POST /webhook/{namespace}` 将校验 namespace 是否在 `WebhookEndpoint` 表中注册(未注册的可选拒绝或标记为匿名)。
- **日志持久化**:请求处理完成后,将入站数据与出站结果(routed/notified)异步写入 SQLite 数据库。
- **状态统计**:内存记录系统启动时间,实时计算运行耗时;从 DB 统计今日接收量。
## 2. Admin后台功能升级
### 2.1 界面改造 (`templates/admin/*.html`)
- **顶部状态栏 (`base.html`)**:增加系统运行状态指示器(运行时间、今日请求数、最新一条日志时间)。
- **端点管理 (`endpoints.html`)**:新增页面,支持创建、启用/禁用接收端点(Namespace)。
- **日志审计 (`logs.html`)**
- 请求列表:按时间倒序展示,显示 namespace, remark, event。
- 详情视图:点击查看完整 JSON 负载及对应的所有分发记录(目标+渠道)。
- 清理功能:一键清空历史日志。
### 2.2 后台逻辑 (`app/admin.py`)
- 新增 `/admin/endpoints` 路由:CRUD 操作。
- 新增 `/admin/logs` 路由:分页查询日志。
- 新增 `/admin/stats` 接口(或模板上下文):提供状态栏数据。
## 3. 实施步骤
1. **更新 DB 模型**:修改 `app/db.py` 添加新表。
2. **实现日志与端点逻辑**
- 更新 `app/main.py` 接入日志记录。
- 创建 `app/services/stats.py` 简单的统计服务。
3. **开发前端页面**
- 修改 `base.html` 添加状态栏与菜单。
- 创建 `endpoints.html``logs.html`
4. **开发后台路由**:在 `app/admin.py` 实现对应视图。
5. **验证**
- 创建新 Endpoint `demo_input`
- 发送测试数据,确认日志生成且状态栏更新。
- 验证“日志详情”能清晰展示接收到的 JSON 和分发结果。
此方案在保留现有轻量级架构的同时,补全了运维监控与多入口管理能力。
@@ -0,0 +1,53 @@
# Webhook 中继系统 - 核心逻辑重构计划
## 1. 核心设计理念变更
响应您的需求,我们将系统从“基于固定字段(remark)的路由”升级为**“基于端点的自定义规则引擎”**。
- **以端点为中心**:每个接收端点(Endpoint)拥有独立的配置页面,绑定属于自己的处理流程。
- **通用规则引擎**:不再硬编码检测 `remark``event_define_no`
- **变量自定义**:您可以指定检测 JSON 中的任意字段(如 `body.status``data.order_id`)。
- **条件匹配**:当指定字段的值等于设定值时,触发动作。
- **统一动作(Action)**:将“转发”和“通知”统一为规则命中的“动作”。
- 动作 A:转发给目标 X(原 Target)。
- 动作 B:使用模板 Y 发送给渠道 Z(原 Notification)。
## 2. 数据库模型重构 (`app/db.py`)
我们需要调整表结构以支持这种灵活关系(建议重置数据库):
1. **保留**`WebhookEndpoint`, `Target`, `NotificationChannel`, `RequestLog`, `DeliveryLog`
2. **移除**`RemarkRule`, 旧的 `EventTemplate` 关联逻辑。
3. **新增/修改**
* **`MessageTemplate`** (原 EventTemplate):仅存储模板文本,不再绑定特定事件ID,作为纯资源库。
* **`ProcessingRule`** (处理规则):绑定到 `WebhookEndpoint`
* 字段:`match_field` (匹配键,如 `trans_order_info.remark`), `match_value` (匹配值)。
* **`RuleAction`** (规则动作):绑定到 `ProcessingRule`
* 字段:`action_type` (forward/notify), `target_id` (关联Target), `channel_id` (关联Channel), `template_id` (关联Template)。
## 3. 业务逻辑升级 (`app/services/engine.py`)
创建新的规则引擎服务:
- **动态取值**:支持点号索引(如 `data.user.id`)从深层 JSON 中提取变量。
- **流程执行**
1. 接收 Webhook -> 查找 Endpoint。
2. 遍历 Endpoint 下的所有 `ProcessingRule`
3. 提取 `match_field` 对应的值与 `match_value` 比对。
4. 命中则执行该规则下的所有 `RuleAction`(并行执行转发或通知)。
## 4. Admin UI 交互大改版
- **资源库模式**`目标管理``通知渠道``消息模板` 变为纯粹的基础资源维护页面。
- **端点编排页**(核心):
- 点击某个端点,进入**“流程配置”**详情页。
- **可视化规则编辑器**
- "当 `[输入框: 字段路径]` 等于 `[输入框: 值]` 时:"
- ➕ 添加动作:[转发] -> 选择目标。
- ➕ 添加动作:[通知] -> 选择渠道 + 选择模板。
- **体验优化**:在同一个页面完成逻辑闭环,无需在不同菜单间跳转。
## 5. 实施步骤
1. **重构 DB**:更新 `app/db.py` 模型定义。
2. **实现引擎**:编写 `app/services/engine.py` 实现动态匹配与分发。
3. **更新 API**:修改 `app/main.py` 调用新引擎。
4. **重写 UI**
- 改造 `admin.py` 路由。
- 新增 `templates/admin/endpoint_detail.html` 作为核心配置页。
- 简化其他资源页面。
5. **迁移/重置**:删除旧 DB文件,重新构建运行。
@@ -0,0 +1,30 @@
# 系统功能增强计划
针对您提出的两个问题,我们将进行以下改进:
## 1. 解决 "pay.wx_scaned" 等代码的显示问题
**方案**:在配置“通知动作”时,允许您定义**自定义模板变量**。
* **原理**
* 当规则匹配到 `pay.wx_scaned` 时,您在动作中设置变量 `pay_type_name` = "微信支付"。
* 当规则匹配到 `pay.ali_scaned` 时,您在动作中设置变量 `pay_type_name` = "支付宝"。
* **模板写法**`收到{pay_type_name}付款{trans_amt}元`
* 这样同一个模板可以根据不同的规则,显示不同的中文名称,完美解决代码转义问题。
## 2. 补全 "修改" 功能
**方案**:为所有资源管理页面添加编辑功能。
* **目标管理**:添加编辑按钮。
* **通知渠道**:添加编辑按钮。
* **消息模板**:添加编辑按钮。
* **实现方式**:点击编辑弹出模态框(复用添加框),回显数据,保存时调用更新接口。
## 实施步骤
1. **数据库升级**
* `RuleAction` 表新增 `template_vars` 字段(JSON类型),用于存储自定义变量。
2. **后端开发**
* 更新 `RuleEngine`,在渲染模板前将 `template_vars` 合并到数据上下文中。
*`admin.py` 中新增 `update_target`, `update_channel`, `update_template` 等路由。
3. **前端开发**
* **端点详情页**:在添加/编辑动作时,增加“模板变量”输入框(JSON格式)。
* **资源列表页**:增加“编辑”按钮及相应的 JS 逻辑来回显数据。
4. **部署**
* 由于涉及数据库字段变更,需要再次重置数据库。
@@ -0,0 +1,42 @@
# 系统修复与全链路优化计划
针对“弹窗失效”的紧急Bug和您对系统的长远期望,我制定了以下全方位的优化方案:
## 1. 紧急修复:UI 交互失效 (Priority 0)
**问题根源**:页面脚本(Script)在 Bootstrap 库加载之前执行了,导致 `bootstrap` 对象未定义。
**修复方案**
* 调整 `base.html` 结构,在底部引入 Bootstrap JS 之后新增 `{% block scripts %}` 插槽。
* 将所有管理页面的 JS 代码移动到 `block scripts` 中,确保执行顺序正确。
## 2. 核心增强:规则引擎升级 (Priority 1)
目前的规则仅支持“等于”,无法满足复杂业务(如匹配特定前缀的订单号)。
**优化方案**
* **数据库变更**`ProcessingRule` 表新增 `operator` 字段(默认为 `eq`)。
* **支持操作符**
* `eq` (等于)
* `neq` (不等于)
* `contains` (包含)
* `startswith` (以...开头)
* `regex` (正则表达式)
* **UI 适配**:在端点详情页的添加规则弹窗中,增加“操作符”下拉选择。
## 3. 运维增强:日志重试 (Replay) (Priority 2)
Webhook 系统最常见的问题是下游服务暂时不可用,导致消息丢失。
**优化方案**
* **后端**:新增 `/admin/logs/{id}/replay` 接口,读取历史日志的 `raw_body` 重新注入规则引擎。
* **前端**:在“系统日志”列表的失败记录旁,添加“重试”按钮。
## 4. 体验优化:首页仪表盘 (Priority 3)
目前的首页直接跳转到列表,缺乏全局视野。
**优化方案**
* 重写 `/admin/` 首页,展示:
* 今日请求总量 / 成功率
* 各端点 (Endpoint) 的流量占比
* 最近 10 条失败记录(方便快速排查)
## 实施路线图
1. **UI 架构调整**:修复 `base.html` 及所有子页面(解决弹窗问题)。
2. **数据模型迁移**:更新 DB,添加 `operator` 字段。
3. **业务逻辑升级**:更新 `engine.py` 支持新操作符,实现重试逻辑。
4. **界面功能补全**:更新前端页面适配新功能。
5. **部署**:重置数据库并重启服务。
@@ -0,0 +1,50 @@
# 规则引擎逻辑重构计划:支持多级条件与流程编排
您说得非常对。目前的扁平化规则(单层 `if-match-then-action`)在处理“组合条件”时会导致规则数量爆炸,配置极其繁琐且难以维护。
**核心问题**:现在的结构是“单层匹配”,无法表达“先判断A,再判断B”的逻辑。
**您的需求**
1. **第一层(事件分类)**:先根据 `event_define_no` 判断业务类型(微信支付/退款/投诉),决定用哪个**模板**。
2. **第二层(渠道分发)**:再根据 `remark` 判断归属(门店002/003),决定推给哪个**渠道**。
为此,我将对系统进行深度的逻辑重构,引入**“规则组(Rule Group)”**和**“条件链(Condition Chain)”**的概念,但为了保持用户界面的直观性,我设计了更符合您直觉的 **“流程树(Flow Tree)”** 方案。
## 方案设计:嵌套式规则引擎
### 1. 数据模型升级 (DB)
* **ProcessingRule 表变更**
* 新增 `parent_rule_id` (Integer, nullable): 允许规则嵌套。子规则只有在父规则匹配成功后才会执行。
* 此变更实现了“树状结构”。
### 2. 核心逻辑升级 (Engine)
* **递归匹配**
* 引擎首先查找所有 `parent_id` 为空的**根规则**。
* 如果根规则匹配成功(例如 `event_define_no == pay.wx_scaned`):
* 执行根规则挂载的动作(例如:设置模板变量 `pay_method="微信"`)。
* **继续检查其子规则**
* 子规则(例如 `remark == imcgcd03`)匹配成功:
* 执行子规则挂载的动作(例如:推送到 `渠道003`)。
* 动作执行时,会**继承**父规则上下文中设置的变量(如模板ID或变量)。
### 3. 用户界面重构 (UI)
* **端点详情页**
* 不再是扁平列表,而是**树形展示**。
* 在每个规则卡片内部,增加“**添加子规则**”按钮。
* 视觉上通过缩进或连线表示层级关系。
* 支持**拖拽排序**(优先级调整)。
## 实施步骤
1. **数据库迁移**:为 `ProcessingRule` 添加 `parent_rule_id` 字段。
2. **后端逻辑**:重写 `engine.py``process` 方法,改为递归处理。
3. **前端交互**:重写 `endpoint_detail.html`,使用递归模板渲染规则树。
4. **无损更新**:编写 SQL 脚本或逻辑,确保现有数据平滑迁移到新结构(现有规则都视为根规则)。
这样,您的配置流程将变为:
1. **根规则**`event_define_no == pay.wx_scaned`
* 动作:设置变量 `pay_type="微信"`**不需要指定渠道**
* **子规则 A**`remark == imcgcd02`
* 动作:推送到 `渠道002`**复用父级的模板设置**
* **子规则 B**`remark == imcgcd03`
* 动作:推送到 `渠道003`
这完美符合您的思维模型。