Commit Graph

1561 Commits

Author SHA1 Message Date
ryan 4ecec2cf1b forcetypeassert 6→0(缓存 list 断言、relay/flared 中间件契约断言、图片压缩 flight 断言,全部带检查+安全失败路径);errname 1→0;prealloc 2 处(另 1 处与 repo mnd 冲突,用命名常量解决)。nilnil 保留(not-found/可选结果惯例,含接口契约注释)。
Result: {"status":"keep","total_issues":15,"golint_canonicalheader":0,"golint_errname":0,"golint_errorlint":1,"golint_forcetypeassert":0,"golint_gosec":0,"golint_intrange":0,"golint_modernize":3,"golint_nilnil":3,"golint_perfsprint":0,"golint_prealloc":0,"golint_recvcheck":7,"golint_usestdlibvars":0,"golint_wastedassign":0,"golint_total":14,"eslint_problems":1,"eslint_errors":0,"eslint_warnings":1,"tsc_errors":0,"measure_s":43}
2026-08-16 17:58:03 +08:00
ryan 86fad02c41 errorlint 12→1:3 处 cmd 入口 err!=context.Canceled→errors.Is(防御性,当前 runner 不 wrap 语义不变);2 处 strconv.NumError 断言、1 处 viper 断言、2 处 ==io.EOF、2 处 ==redis.Nil、1 处 ==gorm.ErrRecordNotFound→errors.As/Is;8 处 %v→%w 保留错误链。刻意保留 telegram.go 单处 %v(原始错误仅作上下文文本,wrap 会改变 errors.Is 匹配语义)。
Result: {"status":"keep","total_issues":22,"golint_canonicalheader":0,"golint_errname":1,"golint_errorlint":1,"golint_forcetypeassert":3,"golint_gosec":0,"golint_intrange":0,"golint_modernize":3,"golint_nilnil":3,"golint_perfsprint":0,"golint_prealloc":3,"golint_recvcheck":7,"golint_usestdlibvars":0,"golint_wastedassign":0,"golint_total":21,"eslint_problems":1,"eslint_errors":0,"eslint_warnings":1,"tsc_errors":0,"measure_s":46}
2026-08-16 17:52:03 +08:00
ryan 600a7acdfb docs: 核查并润色文档,对齐项目实际实现
- 删除未经验证的环境要求(Docker 版本号、浏览器条目)与括号废话
- 故障排查改为真实处理路径(升级→重新发布→强制同步→重建 Agent→提交 issue),删除仅开发时用的排障章节
- 删除设计文档中的测试与验收、实现检查清单、贡献者阅读建议等开发内容
- 修正与代码不符的事实:reset-passwd 命令名、证书续签窗口 7 天、Pages 检查间隔 1440 分钟、Relay vhost 端口 8080、SSO 仅支持 OIDC 等
- 去除口语化表述与无意义括号,改写「不是…而是…」句式
- 同步修正文档站链接锚点,构建验证通过
2026-08-16 17:49:57 +08:00
ryan 288b74d104 intrange 3→0 + modernize 5→3:for i:=0;i<len/N;i++ → range len/N(8 处);time.Time 字段 omitempty→omitzero(wire 输出一致);SplitSeq;min() 简化。刻意保留 lark.go omitzero(会改变 wire 行为)。
Result: {"status":"keep","total_issues":33,"golint_canonicalheader":0,"golint_errname":1,"golint_errorlint":12,"golint_forcetypeassert":3,"golint_gosec":0,"golint_intrange":0,"golint_modernize":3,"golint_nilnil":3,"golint_perfsprint":0,"golint_prealloc":3,"golint_recvcheck":7,"golint_usestdlibvars":0,"golint_wastedassign":0,"golint_total":32,"eslint_problems":1,"eslint_errors":0,"eslint_warnings":1,"tsc_errors":0,"measure_s":45}
2026-08-16 17:47:09 +08:00
ryan ce28f63659 wastedassign 7→0:删除 7 处死初始化(snapshot.go 三连、push 三件套 content、format.go numStr),改 var 声明,零行为变化。
Result: {"status":"keep","total_issues":38,"golint_canonicalheader":0,"golint_errname":1,"golint_errorlint":12,"golint_forcetypeassert":3,"golint_gosec":0,"golint_intrange":3,"golint_modernize":5,"golint_nilnil":3,"golint_perfsprint":0,"golint_prealloc":3,"golint_recvcheck":7,"golint_usestdlibvars":0,"golint_wastedassign":0,"golint_total":37,"eslint_problems":1,"eslint_errors":0,"eslint_warnings":1,"tsc_errors":0,"measure_s":47}
2026-08-16 17:44:45 +08:00
ryan d0414b402a canonicalheader 8→0 + usestdlibvars 3→0:header key 改为 Go 规范大小写(wire 格式本就如此,纯代码修正)、HTTP 方法常量替代字符串字面量。
Result: {"status":"keep","total_issues":45,"golint_canonicalheader":0,"golint_errname":1,"golint_errorlint":12,"golint_forcetypeassert":3,"golint_gosec":0,"golint_intrange":3,"golint_modernize":5,"golint_nilnil":3,"golint_perfsprint":0,"golint_prealloc":3,"golint_recvcheck":7,"golint_usestdlibvars":0,"golint_wastedassign":7,"golint_total":44,"eslint_problems":1,"eslint_errors":0,"eslint_warnings":1,"tsc_errors":0,"measure_s":38}
2026-08-16 17:38:18 +08:00
ryan 699e95f12c perfsprint 18→0:strconv.Itoa/FormatInt/FormatUint/FormatBool 替代 fmt.Sprintf、无动词 fmt.Errorf→errors.New、纯字符串拼接。全部语义等价(已核对 diff)。修正 fixer 遗留的 import 问题(引入 goimports 统一整理)。
Result: {"status":"keep","total_issues":56,"golint_canonicalheader":8,"golint_errname":1,"golint_errorlint":12,"golint_forcetypeassert":3,"golint_gosec":0,"golint_intrange":3,"golint_modernize":5,"golint_nilnil":3,"golint_perfsprint":0,"golint_prealloc":3,"golint_recvcheck":7,"golint_usestdlibvars":3,"golint_wastedassign":7,"golint_total":55,"eslint_problems":1,"eslint_errors":0,"eslint_warnings":1,"tsc_errors":0,"measure_s":47}
2026-08-16 17:34:44 +08:00
ryan 4e3d79c001 fix(frontend): 修复 useEffect 缺失依赖导致 code-check 失败 2026-08-16 17:29:14 +08:00
ryan 5aaaf8f197 fix(frontend): 修复静态导出下切换语言无效的问题 2026-08-16 17:29:14 +08:00
ryan b76f707c8b modernize 37→5(-32):interface{}→any、内置 max/min、slices/maps 辅助、strings.Cut/SplitSeq、strings.Builder(修复 mail.go O(n²) 拼接)。逐 hunk 核对语义等价;omitzero 冲突修复被自动跳过(wire 格式不变);手动清 4 处遗留 sort import + 2 处 QF1012。
Result: {"status":"keep","total_issues":74,"golint_canonicalheader":8,"golint_errname":1,"golint_errorlint":12,"golint_forcetypeassert":3,"golint_gosec":0,"golint_intrange":3,"golint_modernize":5,"golint_nilnil":3,"golint_perfsprint":18,"golint_prealloc":3,"golint_recvcheck":7,"golint_usestdlibvars":3,"golint_wastedassign":7,"golint_total":73,"eslint_problems":1,"eslint_errors":0,"eslint_warnings":1,"tsc_errors":0,"measure_s":38}
2026-08-16 17:28:22 +08:00
ryan f1f6bb858a 修复 internal/apps/edge/observability/linux.go 的 2 个 gosec G115 整数溢出转换:helper 改为接收 int64 b,用 gosec 认可的饱和乘法模式(uint64 域乘积 + 上界比较),去掉原 //nolint:gosec,语义不变(Bsize 恒为正)。repo 自带 gate 首次全绿。
Result: {"status":"keep","total_issues":106,"golint_canonicalheader":8,"golint_errname":1,"golint_errorlint":12,"golint_forcetypeassert":3,"golint_gosec":0,"golint_intrange":3,"golint_modernize":37,"golint_nilnil":3,"golint_perfsprint":18,"golint_prealloc":3,"golint_recvcheck":7,"golint_usestdlibvars":3,"golint_wastedassign":7,"golint_total":105,"eslint_problems":1,"eslint_errors":0,"eslint_warnings":1,"tsc_errors":0,"measure_s":38}
2026-08-16 17:21:04 +08:00
ryan 305d609d0d chore(quality): 启动代码质量 autoresearch 会话
- .auto/ 会话文件(prompt/measure/checks/ideas)
- pnpm-workspace.yaml 认可 @parcel/watcher 与 @swc/core 构建脚本,
  修复 pnpm 11 下 make code-check 无法运行的问题
2026-08-16 17:10:28 +08:00
ryan 5a8722ff07 feat(frontend): 控制台 next-intl 中英双语
接入无 URL 前缀的 zh-CN/en,顶栏与外观设置可切换语言;选择写入 cookie 后刷新生效。
2026-08-16 16:49:16 +08:00
ryan b66cf3ae9c feat(log): PG 分区清理与 logstore import-lint
CleanupExpired 先按月 DROP 过期分区,再删边界行并清理空分区;apps 禁止直连 analytics。
2026-08-16 16:48:15 +08:00
ryan a8fcf6087a chore(message-gateway): swagger and format 2026-08-16 12:27:03 +08:00
ryan 30acdb91e8 feat(message-gateway): add profile bot pairing card 2026-08-16 12:23:44 +08:00
ryan 124ce9bebb feat(message-gateway): add admin channel cards and per-type forms 2026-08-16 12:22:28 +08:00
ryan 635c1760ad feat(message-gateway): add user bind and unbind APIs 2026-08-16 12:19:32 +08:00
ryan 69d39d906f feat(message-gateway): add admin channel CRUD APIs 2026-08-16 12:17:05 +08:00
ryan 09ec9d0af3 feat(message-gateway): run adapters on worker and handle pairing inbound 2026-08-16 12:14:17 +08:00
ryan 7ca6dbe272 feat(message-gateway): add QQ official C2C botgo adapter
Pin github.com/tencent-connect/botgo v0.2.1. Connect uses C2C intent
only via the official WebSocket session manager.
2026-08-16 12:10:15 +08:00
ryan ef97ca5c7e feat(message-gateway): add Telegram private-chat telebot adapter 2026-08-16 12:06:03 +08:00
ryan cc86370e50 feat(message-gateway): emit message_gateway.inbound domain events 2026-08-16 12:04:55 +08:00
ryan 60afdf7c7b feat(message-gateway): add channel, binding, and pairing repositories 2026-08-16 12:04:14 +08:00
ryan 9b1ef1cf7f feat(message-gateway): add w_message_* models and goose migrations 2026-08-16 12:03:23 +08:00
ryan 8ea4c7e13e feat(message-gateway): add channel types, registry, and pairing codes 2026-08-16 12:01:52 +08:00
ryan a4db79e9bd chore: ignore local git worktrees directory 2026-08-16 12:00:42 +08:00
ryan 8b1eb9ca0d docs(message-gateway): add Wavelet message gateway implementation plan 2026-08-16 11:59:59 +08:00
ryan e36db8a56c docs(message-gateway): add Wavelet inbound channel gateway design spec 2026-08-16 11:55:57 +08:00
ryan 37d5a87c9b chore: docs 2026-08-16 11:32:46 +08:00
ryan 64fbaa7ef1 chore: docs 2026-08-16 11:32:13 +08:00
ryan e52592b16d feat(log): 解耦用户访问日志存储,支持切换日志主库
用户访问日志可在 ClickHouse、PostgreSQL、SQLite 之间切换。
关闭 ClickHouse 时由主库承接写入与查询;切换任务会冻结写入、复制数据后翻转主库。
启动时校验日志主库与运行配置一致,定期清理按各库保留天数删除过期记录。
2026-08-16 11:17:55 +08:00
ryan 6a53619dd2 feat(framework): 回灌 OpenFlare 分层、安全与运行时改进
将平台域持久化收敛为 repository 唯一入口,model 去掉 IO。
邮件头写入前清除 CR/LF,防止 header 注入。
httppool 支持可配置 Transport;batchwriter 增加 MinBatchSize/Stats,flush 失败交回批次;任务 PermanentError 作为 SkipRetry 终态。
设置与推送页的确认改为 AlertDialog;axios 去尾斜杠并按 Gin 数组序列化查询参数。
升级共享 Go 依赖(Gin、Asynq、OTel、GORM、Redis 等)。
2026-08-16 11:07:20 +08:00
ryan fa689aedbc feat(sync): 同步 Wavelet 推送审计、OTel schema 与前端字体
自定义 Webhook 在 HTTP 200 但业务 errcode 非零时记为失败,任务日志记录上游响应。
OTel Resource 改为 NewSchemaless,避免 semconv 与 SDK 版本冲突。
前端用 next/font 自托管 Inter,并忽略浏览器扩展改写 body 引起的 hydration 警告。
2026-08-16 11:06:54 +08:00
ryan b9b42e3174 ci: make canary 2026-08-16 10:13:39 +08:00
ryan 20830d31bd chore: guideline 2026-08-16 10:01:56 +08:00
ryan f960511cc0 chore(release): v3.5.3
### 新增
- 访问日志「日志明细」支持按 HTTP 状态码筛选,可直接输入任意状态码。
- 访问日志「日志明细」支持自定义时间范围筛选,可按起止时间检索日志。
- 首页看板改版:24 小时请求趋势拆分展示请求总量与 2xx/4xx/5xx 状态码类请求量并独占一行;移除宿主机磁盘指标,24 小时容量趋势(CPU/内存)并入业务流量卡片展示。

### 🛠 修复
- 修复首页「来源分布」卡片在 PostgreSQL/SQLite 日志库下无数据的问题。
- 修复源站错误页「仅针对 GET 请求」未真正透传非 GET 响应的问题:POST/PUT 等非 GET 请求现可完整看到源站原始报错内容。
v3.5.3
2026-08-13 11:44:08 +08:00
ryan 465440fa5b fix(access-logs): 修复状态码自定义 2026-08-13 11:33:12 +08:00
ryan a4dd5ca9e1 feat(dashboard): 首页请求趋势拆分状态码并合并容量到业务流量
- 24 小时请求趋势拆分展示请求总量与 200/400/500 状态码请求量,独占一行;
  时间桶聚合新增 status_200/400/500_count(CH countIf、PG FILTER),
  请求趋势改为基于原始桶聚合(小时 rollup 无状态码口径)
- 首页移除宿主机磁盘指标,容量趋势(CPU/内存)并入业务流量卡片展示
- 压缩协议 traffic_24h 扩展为 7 元组,前端归一化同步更新
2026-08-13 11:10:37 +08:00
ryan a9e4237bbf feat(access-logs): 状态码支持手动输入,新增时间范围筛选
- 状态码筛选支持预设快捷选项 + 手动输入任意 100-599 状态码(数字校验)
- 新增时间范围筛选:shadcn 日期+时间选择器(Popover+Calendar+时分 Select),
  起止时间以 RFC3339 成对传入,后端校验格式与先后关系,非法值返回 400
- 默认显示来源 IP/访问域名/状态码,节点 ID/请求路径/时间范围折叠进「更多筛选」
2026-08-13 10:27:40 +08:00
ryan 75d1fcf345 feat(access-logs): 日志明细支持按状态码筛选并折叠次要搜索项,修复首页来源分布无数据
- 修复 PostgreSQL/SQLite 日志库下首页「来源分布」卡片无数据:RegionCounts 对空
  节点 ID 误拼 node_id = '' 恒空条件,改为空节点 ID 表示全节点聚合(对齐 CH 语义),
  并过滤空白归属地
- /access-logs?tab=list 新增状态码筛选:状态码下拉含常用 2xx/3xx/4xx/5xx 选项,
  校验 100-599,非法值返回 400;ClickHouse 与 PostgreSQL/SQLite 日志库均支持
- 搜索框折叠:默认仅显示来源 IP 与状态码,节点 ID/访问域名/请求路径折叠进
  「更多筛选」
2026-08-13 09:59:32 +08:00
ryan 284eec54f7 chore: guideline 2026-08-12 12:40:06 +08:00
ryan a3ad0d2c97 chore: rename .agent to .agents and update skill path references 2026-08-12 12:39:15 +08:00
ryan 92322c7a22 feat(push): log upstream webhook response in task history
Pusher.Send now returns the upstream response body alongside the error,
so the push task handler can print what the webhook actually replied
(custom channel e.g. {"errcode":0,"errmsg":"ok"} or a rejection
like {"errcode":93000,...}) into the task log on both success and
failure. Other pushers (lark/telegram/email) return an empty string,
keeping their behavior unchanged.

fix(push): surface webhook business errors in custom channel audit

CustomPusher.Send only checked the HTTP status code. WeChat Work /
DingTalk webhooks return HTTP 200 with a non-zero errcode in the body
even when the message is rejected (e.g. template_card requires
card_action.url when type=1), so rejected pushes were recorded as
'success' in the notification history. Parse the response body and
return an error when errcode is non-zero, matching the Lark pusher.
2026-08-12 12:32:23 +08:00
ryan f499645cdc chore: guideline 2026-08-12 12:02:14 +08:00
ryan f1577bf092 fix(openresty): 修复源站错误页「仅针对 GET 请求」覆盖非 GET 原始报错数据
proxy_intercept_errors 会在 Lua 判断前丢弃源站错误响应体,POST/PUT 等
请求收到 503 时被 OpenResty 自带错误页覆盖原始报错数据。现改为在代理
location 内用 Lua header/body 过滤器仅对 GET 请求替换错误页,非 GET
请求完整透传源站原始状态码与响应体;非仅 GET 模式继续使用命名 location
承载错误页。
2026-08-09 19:38:44 +08:00
ryan 01ed2c5e36 chore(release): v3.5.2
修复几个遗漏bug
v3.5.2
2026-08-09 14:08:04 +08:00
ryan 80696c12fa fix: lint 2026-08-09 13:47:40 +08:00
ryan 3d4d99081e fix(log): PG 日志库批量写入为零 ID 行生成雪花 ID
PostgreSQL 日志表 id 为 NOT NULL 且无默认值,而 GORM 将零值 uint64
主键视为自增并省略 id 列,导致 node access log / 可观测指标等批量
落库持续报 "null value in column id violates not-null constraint"。
在 BatchInsert* 落库前为零 ID 行生成雪花 ID(与 ClickHouse 写入路径
一致),并新增单元回归与 PG 集成回归测试覆盖六张日志表。
2026-08-09 13:47:13 +08:00
ryan 0639855653 fix(openresty): 修复源站错误页「仅针对 GET 请求」未生效
error_page 的 URI 内部重定向会把请求方法改写成 GET,导致内部
Lua 中 ngx.req.get_method() 恒为 GET,get_only 判断永不命中,
POST/PUT 等请求仍返回自定义错误页。

改为命名 location(@__openflare_origin_error)承载错误页:
命名 location 保留原始请求方法与原始错误状态码,非 GET 请求
直接以原状态码退出、不再注入自定义 HTML。附带回归断言,禁止
回退到 URI 内部重定向形式。
2026-08-09 13:42:38 +08:00