181 Commits

Author SHA1 Message Date
win
8d0ef3d2ef chore: antigravity 瘦身,删除边缘文件保留核心 2026-05-12 12:19:22 +08:00
win
7347dfffc1 chore: merge upstream v0.1.124-125, keep Windsurf/Antigravity customizations
Upstream changes:
- feat: 邮箱 + GitHub + Google OAuth 快捷登录
- feat: Codex image bridge 开关
- feat: 内容审核 (content moderation) — 新增 contentModerationService/Handler
- feat: redeem code 返利、批量并发 API、markdown 页面渲染
- feat: 登录注册条款确认
- fix(security): pages API 加 JWT + 可见性校验
- fix: 修复 markdown 页面图片路径
- fix(gateway): 不再默认注入 redact thinking beta
- fix: 稳定 anthropic passthrough 超时错误
- chore: VERSION 升到 0.1.125 + golang:1.26.3-alpine

Conflict resolutions:
- Dockerfile/backend/Dockerfile: 取 upstream golang:1.26.3-alpine
- backend/go.mod: 取 upstream term v0.42.0,保留定制 protobuf v1.36.10
- frontend/src/api/admin/index.ts: 并集 (windsurf + riskControl)
- backend/cmd/server/wire_gen.go: 接 upstream contentModeration*,保留 windsurfHandler/windsurfGatewayService/billingCacheService/requestEventBus;并通过 wire 重生成
- frontend/src/views/admin/AccountsView.vue: 采用 upstream 双层布局 + OpenAI Meta,保留 is_enterprise prop 和 Windsurf tier badge

Note:
- WIP commit (de048fad) preserved Windsurf tier access service / NLU
  extractor / ops log stream / Google OAuth login modal et al before merge.
- 3 pre-existing go vet issues in test files (NewOpsHandler, RegisterGatewayRoutes,
  DefaultCLIProductVersion) are unrelated to this merge — leftover from local
  customization refactors; production code (go build ./...) passes.
2026-05-09 01:42:39 +08:00
win
de048fad25 chore(wip): save Windsurf/Antigravity/ops customizations before upstream merge
WIP commit保存以下定制工作以便后续合并 upstream v0.1.124-125:
- Windsurf: tier access service, NLU extractor, cold threshold, Google login
- Antigravity: client/oauth 调整
- Ops: log stream handler/broadcaster/middleware, OpsLogStreamView
- Frontend: WindsurfLoginModal Google, GoogleIcon, AccountsView, sidebar/router/i18n
2026-05-09 00:41:19 +08:00
shaw
fda1ed459d feat: 优化 OAuth 账号导入流程 2026-05-08 11:36:09 +08:00
Wesley Liddick
e69319e747
Merge pull request #2224 from lyen1688/feat-email-oauth-github-google
feat: 增加 GitHub 和 Google 邮箱快捷登录
2026-05-07 10:07:28 +08:00
Wesley Liddick
d52da45363
Merge pull request #2202 from Michael-Jetson/main
新增三大功能:兑换码邀请返利、批量修改用户并发数、Markdown页面渲染
2026-05-07 09:35:14 +08:00
shaw
fff4a300c6 feat(risk-control): add content moderation audit 2026-05-07 09:14:47 +08:00
lyen1688
af550fa64e feat: 增加 GitHub 和 Google 邮箱快捷登录 2026-05-06 16:06:11 +08:00
win
3fe228d143 chore: merge upstream v0.1.122-123, keep Windsurf/Antigravity customizations
New upstream features:
- feat: improve OpenAI messages compatibility for Claude Code
- feat: image generation stream & concurrency controls
- fix(rate-limit): remove 429 cooldown config option
- fix: skip previous_response_id recovery when payload has function_call_output
- feat: support select search in group/account views
- fix: ops cleanup settings
- chore: remove openspec and update axios

Conflict resolutions:
- config.go: kept AntigravityLSWorker+NodeTLSProxy AND added ImageConcurrency
- account_test_service.go: kept windsurf import AND added openai_compat import
- docker-compose.yml: kept Windsurf env vars AND added image concurrency env vars
2026-05-06 11:50:54 +08:00
Michael-Jetson
4cbd4932a0 feat: add redeem code affiliate rebate, batch concurrency API, and markdown page rendering
1. Redeem code affiliate rebate: balance-type redeem codes now trigger
   invite rebate for the inviter. Payment fulfillment uses context key
   to prevent double-rebate.

2. Batch concurrency update: new POST /admin/users/batch-concurrency
   endpoint supporting mode=set/add with all=true for all users.

3. Markdown page rendering: new GET /api/v1/pages/:slug API serves local
   .md files. Custom menu items with url="md:slug" render markdown with
   collapsible TOC sidebar, scroll spy, and copy buttons on code blocks.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-05 06:44:37 -07:00
Wesley Liddick
37f7c7128c
Merge pull request #2120 from gaoren002/fix/rate-limit-429-cooldown-config
fix(rate-limit): make 429 fallback cooldown configurable
2026-05-05 19:46:11 +08:00
lyen1688
6a41cf6a51 feat: add admin affiliate record pages 2026-05-03 20:33:13 +08:00
gaoren002
4b904c887c fix(rate-limit): make 429 fallback cooldown configurable 2026-04-30 03:01:39 +00:00
win
fdd2d08a4d feat: merge feat/omniroute-ideas — P2C scheduler, quota scoring, tier fallback 2026-04-29 15:42:37 +08:00
win
d1e2d39c26 feat(viewer): add real-time request stream WebSocket endpoint
Adds GET /api/v1/admin/ops/ws/requests — a fan-out WebSocket that pushes
per-request metadata (method, path, model, account_id, status, latency_ms)
to all connected admin clients the moment each gateway dispatch completes.

- service/request_event_bus.go: lock-free pub/sub with non-blocking drop
  when per-subscriber buffer (64 slots) is full; nil-safe Publish
- service/request_event_bus_test.go: 6 tests (basic, fanout, drop, nil, close)
- GatewayHandler: records reqStartTime at entry; defer emits RequestEvent on
  every return; sets status success/error/rate_limited in both Gemini and
  Anthropic dispatch paths
- OpsHandler: accepts *RequestEventBus; wires it to RequestStreamWSHandler
- ops_ws_requests_handler.go: subscribes to bus, pushes JSON per event,
  reuses existing upgrader/conn-limit/ping-pong infrastructure
- Route: ws.GET("/requests", ...) alongside existing /ws/qps
- wire_gen.go: requestEventBus shared between OpsHandler and GatewayHandler
2026-04-29 01:48:15 +08:00
win
110902ad4b feat(health): split liveness and readiness probes
Add HealthService with Liveness (no-op) and Readiness (DB+Redis ping
with per-component timeout) checks. Expose three endpoints:

- /healthz : new liveness endpoint, zero-dependency, always 200
- /ready   : new readiness endpoint, returns 503 with details on dep
             failure; suitable for K8s readinessProbe and load balancers
- /health  : preserved for backward compatibility, equivalent to
             /healthz

Switch primary docker-compose healthcheck to /ready so the container
is only marked healthy once DB+Redis are reachable. Standalone/dev/
local compose files keep /health to avoid disrupting existing setups.

Tests: unit tests cover liveness, readiness with both deps healthy,
each dep failing independently, and per-component timeout enforcement.
2026-04-28 23:39:50 +08:00
win
9da079a5ee x
Some checks failed
Security Scan / backend-security (push) Failing after 3s
Security Scan / frontend-security (push) Failing after 5s
CI / test (push) Failing after 3s
CI / frontend (push) Failing after 3s
CI / golangci-lint (push) Failing after 3s
CI / windsurf-platform (macos-latest) (push) Has been cancelled
CI / windsurf-platform (windows-latest) (push) Has been cancelled
2026-04-27 19:01:41 +08:00
win
898a65314c chore: 删除 Antigravity 订制代码,回退至上游 v0.1.118
Some checks failed
CI / test (push) Failing after 3s
CI / frontend (push) Failing after 4s
CI / golangci-lint (push) Failing after 6s
CI / windsurf-platform (macos-latest) (push) Has been cancelled
CI / windsurf-platform (windows-latest) (push) Has been cancelled
Security Scan / backend-security (push) Failing after 3s
Security Scan / frontend-security (push) Failing after 3s
- 删除自定义文件:gateway_attribution, gateway_claude_runtime_headers,
  identity_service_antigravity, language_server_service, lsrpc_handler,
  antigravity_http handler/routes, 所有 antigravity 专项测试
- 将 antigravity pkg/service 文件回退至上游版本(移除 IsEnterprise、
  claude_code_tool_map、dynamic fingerprint 等定制逻辑)
- 修复 gateway_service.go:移除 NormalizeSystemPromptEnv、
  generateSessionIDForAccount、applyClaudeRuntimeOptionalHeaders 调用,
  使用上游的 session-id 同步逻辑
- 恢复 language_server_pb gen 文件(Windsurf local_ls.go 依赖)
- 保留全部 Windsurf 集成代码不变
2026-04-25 22:35:48 +08:00
win
2064c1a19f chore: merge upstream Wei-Shaw/sub2api 至 v0.1.118
- 保留 Windsurf 订制代码
- 上游新增:Affiliate 邀返佣功能、OpenAI compact 支持、Claude Code 完整 mimicry
- 解决冲突:handler/wire.go、wire_gen.go、constants.go、gateway_service.go 等
2026-04-25 22:08:18 +08:00
shaw
4e1bb2b445 feat(affiliate): add feature toggle and per-user custom invite settings
- 在系统设置「功能开关」中新增邀请返利总开关,默认关闭;
  关闭态:菜单隐藏、注册忽略 aff、新充值不返利,但已有 quota 仍可转余额
- 支持管理员为指定用户设置专属邀请码(覆盖随机码,全局唯一)
- 支持管理员为指定用户设置专属返利比例(覆盖全局比例,可单条/批量调整)
- 在系统设置邀请返利卡片内嵌入专属用户管理表格(搜索/编辑/批量/删除),
  删除采用项目通用 ConfirmDialog,会同时清除专属比例并把邀请码重置为系统随机码
- /affiliate 用户页新增「我的返利比例」卡片与动态使用说明,让用户直观看到
  分享后能拿到多少(同源 resolveRebateRatePercent 计算,与实际充值一致)
- 新增数据库迁移 132 添加 aff_rebate_rate_percent 与 aff_code_custom 列
- 新增 admin 路由组 /api/v1/admin/affiliates/users/* 共 5 个端点
- AffiliateService 改为只依赖 *SettingService,去除冗余的 SettingRepository
- 邀请码格式校验放宽到 [A-Z0-9_-]{4,32},兼容旧 12 位系统码与新自定义码
- 补充单元测试与集成测试覆盖新方法、冲突路径与边界值
2026-04-25 20:22:07 +08:00
VpSanta33
f03de00cb9 feat: add affiliate invite rebate flow and admin rebate-rate setting 2026-04-24 22:22:26 +08:00
win
9156585a23 chore: gofmt/goimports 后处理
合并上游后统一运行 gofmt/goimports,消除排序差异与空行不一致。
2026-04-24 11:52:53 +08:00
win
2d2f677a64 chore: merge upstream Wei-Shaw/sub2api 至 v0.1.117
主要合并内容:
- feat(channel-monitor): admin 渠道监控 MVP + 日聚合/模板/用户端卡片
- feat(available-channels): 新增"可用渠道"聚合视图与平台聚合
- feat(settings): 功能开关联动到配置页
- refactor(channel-monitor): 事件驱动调度器 / runner 生命周期 + 单测
- fix(openai/codex): 图像生成桥接修复、支付 webhook 未知单号处理
- misc: i18n/UI polish, typing tightening

冲突已手动解决,保留本地订制:
- handler.Handlers / AdminHandlers 联合 windsurf + channel_monitor/available_channel 字段
- wire/wire_gen 清理步骤同时注册 WindsurfRefreshService 与 ChannelMonitorRunner
- routes/admin 同时注册 windsurf 与 channel-monitor 路由
- service/wire 合并 Windsurf* 与 ChannelMonitor* 的 provider
- frontend admin API barrel 取两侧并集
- 采纳上游对 migrationChecksumCompatibilityRule 字段的重命名(非订制代码)
2026-04-24 11:52:21 +08:00
Wesley Liddick
ff08f9d798
Merge pull request #1853 from gaoren002/fix/codex-image-generation-bridge
fix(openai): 完善 Codex 在 Responses 链路下的图片生成兼容性
2026-04-24 08:55:23 +08:00
win
2a4103298e Merge remote-tracking branch 'origin/main'
# Conflicts:
#	backend/cmd/server/wire_gen.go
2026-04-24 01:21:36 +08:00
gaoren002
5f41899705 fix: bridge codex image generation over responses 2026-04-23 15:13:57 +00:00
erio
5e060b2222 Merge remote-tracking branch 'upstream/main' into feat/channel-insights
# Conflicts:
#	backend/cmd/server/wire_gen.go
2026-04-23 22:30:45 +08:00
win
21325afb33 feat(windsurf): 补全ops日志记录与endpoint派生,对齐其他平台
Some checks failed
CI / test (push) Failing after 10s
CI / frontend (push) Failing after 8s
CI / golangci-lint (push) Failing after 5s
Security Scan / backend-security (push) Failing after 5s
Security Scan / frontend-security (push) Failing after 4s
- windsurf_gateway_service: 添加上游延迟/TTFT/错误上下文记录
- endpoint: DeriveUpstreamEndpoint 添加 PlatformWindsurf 分支
- ops_error_logger: guessPlatformFromPath 添加 /windsurf/ 识别
2026-04-23 20:46:27 +08:00
james-6-23
dc5d42addc feat(rpm): RPM 限流模块优化
P0:
- rpm_override 嵌入 Auth Cache Snapshot,消除每请求 DB 查询 (snapshot v6→v7)
- 429 RPM 响应返回 Retry-After 头(当前分钟剩余秒数)

P1:
- ClearAll 按钮直连 DELETE API,带 loading 防重复
- 新增 GET /admin/users/:id/rpm-status 管理员 RPM 用量查询端点

优化:
- checkRPM 从级联互斥改为并行取最严,user.rpm_limit 作为全局硬上限始终生效
- Override/Group 变更后自动失效 auth cache
- fail-open 语义不变,Redis 故障不阻塞业务
2026-04-23 16:34:37 +08:00
win
ff7eab0392 Merge remote-tracking branch 'origin/main'
# Conflicts:
#	backend/go.mod
#	backend/go.sum
#	backend/internal/repository/migrations_runner.go
2026-04-22 21:27:18 +08:00
IanShaw
0bc3a521b5
Merge branch 'Wei-Shaw:main' into rebuild/auth-identity-foundation 2026-04-22 17:24:38 +08:00
IanShaw027
ca4e38aa01 fix(profile): stabilize binding compatibility and frontend checks 2026-04-22 14:57:47 +08:00
lucas morgan
c548021921 feat(openai): 同步生图 API 支持并接入图片计费调度
- 同步 OpenAI 图片生成与编辑接口
- 接入图片请求解析、账号调度、转发与用量记录
- 接入图片计费与图片用量落库
- 限制 OAuth 生图仅支持无显式模型和尺寸的基础请求
2026-04-22 12:30:08 +08:00
IanShaw027
dd314c41e3 fix(payment): restore public resume and result flows 2026-04-22 11:17:23 +08:00
IanShaw027
c229f33e9e fix(review): harden payment, oauth, and migration paths 2026-04-22 10:26:22 +08:00
IanShaw027
d4c0a99114 feat(auth): support unbinding third-party identities 2026-04-22 00:54:38 +08:00
IanShaw027
d08757ce9e refactor(admin): remove auth migration reports 2026-04-21 17:34:18 +08:00
erio
59290e39f9 chore(channels): drop admin-side available channels view
Remove the admin-side "Available Channels" aggregate view — admins
already see full channel configuration (groups, pricing, model
mappings) in the channel edit dialog, making a read-only admin
aggregate view redundant. The user-side "可用渠道" remains.

Backend:
- Delete handler/admin/available_channel_handler.go (+ test)
- Drop AdminHandlers.AvailableChannel field and wire injection
- Remove /admin/channels/available route

Frontend:
- Delete views/admin/AvailableChannelsView.vue
- Drop /admin/available-channels router entry
- Strip AvailableChannel types + listAvailable from api/admin/channels.ts
2026-04-21 17:18:37 +08:00
IanShaw027
9742796ee7 fix: retire public payment verify and backfill trade no 2026-04-21 11:41:02 +08:00
IanShaw027
dcd5c43da4 feat: complete email binding and pending oauth verification flows 2026-04-21 10:00:06 +08:00
erio
654cfb6480 feat(channels): add "Available Channels" aggregate view
Add a read-only aggregate view per channel: its linked groups and a
deterministic wildcard-free supported-model list with pricing details.

Backend
- service.Channel.SupportedModels(): combine ModelMapping keys with
  same-platform ModelPricing.Models; trailing "*" keys expand via
  pricing prefix match; platforms without a mapping produce no
  entries (intentional "no mapping = not shown" rule).
- Extract splitWildcardSuffix() shared with toModelEntry.
- Build a per-call pricing lookup map (platform+lowerName -> *pricing)
  to avoid O(N*M) scans in SupportedModels.
- ChannelService.ListAvailable() aggregates channels + active groups;
  filters out group IDs no longer active.
- Admin route GET /api/v1/admin/channels/available returns the full
  DTO (id, status, billing_model_source, restrict_models, groups,
  supported_models).
- User route GET /api/v1/channels/available applies three filters:
  Status==active, visible-group intersection, and platform filter
  on supported_models (prevents cross-platform leak when a channel
  links to both a user-accessible group and an inaccessible one on
  another platform). Response is a plain array (matches the
  /groups/available sibling shape). Field whitelist omits
  billing_model_source, restrict_models, ids, status, sort_order.

Frontend
- New /admin/available-channels and /available-channels views backed
  by a shared AvailableChannelsTable component (admin adds status +
  billing-source columns via slots).
- PricingRow extracted to its own SFC; SupportedModelChip references
  shared billing-mode constants in constants/channel.ts.
- Sidebar: new entry above "渠道管理" for admin; matching entry in
  user nav.
- i18n: zh + en coverage for both namespaces.

Tests
- SupportedModels: wildcard-only pricing skipped, prefix-matches-
  nothing, cross-platform bleed, case-insensitive dedup, empty
  platform mapping.
- ListAvailable: nil groupRepo, inactive-group-ID dropped, stable
  case-insensitive name sort.
- User handler: 401 on unauthenticated, visible-group intersection,
  platform filter on supported_models, JSON whitelist.
- Admin handler: full DTO including default BillingModelSource
  fallback.

Refs: issue #1729
2026-04-21 00:27:10 +08:00
erio
6925ac25c4 feat(channel-monitor): apply template via subset picker; CC 2.1.114 baseline doc
Apply flow:
- POST /admin/channel-monitor-templates/:id/apply now requires monitor_ids
  (non-empty array). Service applies the template only to the selected
  subset, gated by AND template_id = :id (so users can't sneak in
  unrelated monitor IDs).
- New GET /admin/channel-monitor-templates/:id/monitors returns the
  associated monitor briefs (id/name/provider/enabled) for the picker.
- ApplyToMonitors signature gains monitorIDs []int64; empty list returns
  ErrChannelMonitorTemplateApplyEmpty.

Frontend:
- New MonitorTemplateApplyPickerDialog.vue: list of associated monitors
  with checkboxes (default all checked), 全选 / 全不选 shortcuts, live
  selected/total count. Submit calls apply(id, ids).
- MonitorTemplateManagerDialog replaces the old ConfirmDialog flow with
  the picker; onApplied refetches the list to refresh associated counts.

i18n: applyPicker* + common.selectAll keys.

chore: bump version to 0.1.114.33

The CC 2.1.114 (sdk-cli) UA / APIKeyBetaHeader / JSON metadata.user_id
baseline (already verified working via the in-process apply on prod
template id=1) is documented in internal/pkg/claude/constants.go and
is what the seed template in the manager UI should follow.
2026-04-21 14:39:19 +08:00
erio
a296425994 feat(channel-monitor): request templates with snapshot apply + headers/body override
Problem:
Upstream channels can reject monitor probes based on client fingerprint
(e.g. "only Claude Code clients allowed"). The monitor had no way to
customize the outgoing request to bypass such restrictions.

Solution:
Introduce reusable request templates that carry extra_headers plus an
optional body override; monitors reference a template and receive a
snapshot copy on apply. Template edits do NOT auto-propagate — users
must click "apply to associated monitors" to refresh snapshots, so a
bad template edit cannot instantly break all production monitors.

Data model (migration 112):
- channel_monitor_request_templates: id, name, provider, description,
  extra_headers jsonb, body_override_mode ('off'|'merge'|'replace'),
  body_override jsonb. Unique (provider, name).
- channel_monitors: +template_id (FK, ON DELETE SET NULL), +extra_headers,
  +body_override_mode, +body_override (the three runtime snapshot fields).

Checker (channel_monitor_checker.go):
- callProvider + runCheckForModel accept a CheckOptions carrying the
  snapshot fields. mergeHeaders applies user headers on top of adapter
  defaults (forbidden list: Host / Content-Length / Transfer-Encoding /
  Connection / Content-Encoding).
- buildRequestBody:
    off     -> adapter default body
    merge   -> shallow-merge over default; per-provider deny list
               (model/messages/contents) protects the challenge contract
    replace -> user body verbatim
- Replace mode skips challenge validation; instead HTTP 2xx + non-empty
  extracted response text = operational, empty = failed.
- 4 new unit tests cover all three modes + replace/empty-response case.

Admin API:
- /admin/channel-monitor-templates CRUD + /:id/apply (overwrite snapshot
  on all template_id=id monitors, returns affected count).
- channel_monitor request/response DTOs gain the 4 new fields.

Frontend:
- channelMonitorTemplate.ts API client.
- MonitorAdvancedRequestConfig.vue shared component for headers textarea
  + body mode radio + body JSON editor; used by both template and monitor
  forms.
- MonitorTemplateManagerDialog.vue: provider tabs, list/create/edit/
  delete/apply, live "associated monitors" count per row.
- MonitorFiltersBar: new 模板管理 button next to 新增监控.
- MonitorFormDialog: collapsible 高级 section with template dropdown
  (filtered by form.provider, clears on provider change) + embedded
  AdvancedRequestConfig. Picking a template copies its fields into the
  form (snapshot semantics mirrored on the client).
- i18n zh/en entries for all new copy.

chore: bump version to 0.1.114.32
2026-04-21 14:14:49 +08:00
IanShaw027
7ef7fd19e7 fix: restore wechat payment oauth and jsapi flow 2026-04-20 23:34:57 +08:00
IanShaw027
724f8e89a1 feat: resolve auth identity migration reports 2026-04-20 22:29:21 +08:00
IanShaw027
452e55a53c feat: add admin auth identity repair binding 2026-04-20 22:22:14 +08:00
IanShaw027
3bd3027251 feat: expose auth identity migration reports 2026-04-20 22:05:33 +08:00
IanShaw027
9bebf1c1a6 feat: resolve payment results by resume token 2026-04-20 20:53:46 +08:00
erio
20a4e41872 feat(monitor): admin channel monitor MVP with SSRF protection and batch aggregation
新增 admin「渠道监控」模块(参考 BingZi-233/check-cx),独立于现有 Channel 体系。
admin 配置 + 后台定时调用上游 LLM chat completions 健康检查 + 所有登录用户只读可见。

后端:
- ent: channel_monitor + channel_monitor_history(AES-256-GCM 加密 api_key)
- service 按职责拆分:service/aggregator/validate/checker/runner/ssrf
- provider strategy map 替代 switch(openai/anthropic/gemini)
- repository batch 聚合(ListLatestForMonitorIDs + ComputeAvailabilityForMonitors)消除 N+1
- runner: ticker(5s) + pond worker pool(5) + inFlight 防并发 + TrySubmit 防雪崩
  + 凌晨 3 点 cron 清理 30 天历史
- SSRF 防护:强制 https + 私网/loopback/云元数据 IP 拒绝(127/8、10/8、172.16/12、
  192.168/16、169.254/16、100.64/10、::1、fc00::/7、fe80::/10)+ DialContext
  在 socket 层防 DNS rebinding
- API key sanitize:擦除 url.Error 与上游响应 body 中的 sk-/sk-ant-/AIza/JWT 模式
- APIKeyDecryptFailed 标志位 + 单 monitor 路径检测,避免空 key 调用上游

handler:
- admin: CRUD + 手动触发 + 历史接口(api_key 脱敏)
- user: 只读列表 + 状态详情(去除 api_key/endpoint)
- ParseChannelMonitorID 共用 + dto.ChannelMonitorExtraModelStatus 共用

前端:
- 路由 /admin/channels/{pricing,monitor} + /monitor(用户只读)
- AppSidebar 父项 expandOnly 支持
- ChannelMonitorView 拆为 8 个子组件 + ChannelStatusView 拆出 detail dialog
- composables/useChannelMonitorFormat + constants/channelMonitor 共享
- i18n monitorCommon namespace 消除 admin/user 两 view 重复

合规:所有文件符合 CLAUDE.md(Go ≤ 500 行 / Vue ≤ 300 行 / 函数 ≤ 30 行)
CI: go build / gofmt / golangci-lint(0 issues) / make test-unit / pnpm build 全绿
2026-04-20 20:21:02 +08:00
IanShaw027
6a75bd77e3 feat: add pending oauth email onboarding flow 2026-04-20 19:30:09 +08:00