Blizzard
|
883540bd7e
|
feat(auth): 微信扫码登录改为「带参二维码 + 关注/扫码事件」(登录即涨粉)
上一版做成了网页授权(OAuth 允许页),方向错了。改成用户要的流程:
扫码 → 弹公众号关注页 → 关注即登录,服务号顺带涨粉。
流程:PC 建票 → 后端用 access_token 调「带参数二维码」接口(scene=ticket) →
展示微信二维码图 → 用户扫码关注 → 微信推 subscribe/SCAN 事件到 /wx/mp/callback →
按 openid 找/建用户 → ticket 置 authorized → PC 轮询拿 JWT。
明文模式(消息加解密):回调只验签名 sha1(sort(token,ts,nonce)),不做 AES。
关键实现点:
- access_token 缓存进 Redis(跨实例共享,避免重复拉取互相失效)+ 进程内锁双检;
- 事件同时处理 subscribe(未关注,EventKey 带 qrscene_ 前缀)与 SCAN(已关注,不带);
- 事件回调必须验签——否则任何人 POST 一个 openid 就能登录别人;
- 回调无论如何回 "success",否则微信重试并给用户弹"公众号故障";
- User.wechat_openid 用部分唯一索引(WHERE <> ''),避开存量空串互撞。
配置(appid/secret/token)后台可改、secret AES 加密入库。管理端「运维 → 登录设置」
列出还需在公众平台做的事(服务器 URL / Token 一致 / 明文模式 / IP 白名单)。
本地验证(真流程,非 mock):验签回 echostr 与微信算法一致;模拟 subscribe 事件
→ 建号 + 置票 → PC 轮询拿到 token+user → 库里确有该 openid 用户。真微信推真事件
留待部署后扫码。前端 web 登录页加「微信扫码/邮箱」双 tab,默认微信。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-07-21 08:58:31 +08:00 |
|
Blizzard
|
f8f7359723
|
feat(admin): 订阅管理页 + 修「余额列为 NULL 导致充值永不到账」
管理端「支付 → 订阅」:套餐配置 + 全平台订阅观测。配置时直接算出「一个周期
发几次、合计多少积分」,时长不能被间隔整除时橙字提示到期前会有空档 —— 让人在
配的时候就看见后果,而不是上线后才发现只发了一次。
顺带修了个真 bug,是拿真库验订阅时撞出来的(本地 42 个租户里 11 个中招):
credit_balance_micro 是后加的列,早于它创建的租户行值为 NULL。而入账语句是
「余额 + N」—— SQL 里 NULL + N 仍是 NULL,于是这些租户**充值永远不到账**:
分录照写、余额不动、不报错。这条路径是充值/兑换码/退款/扣费/订阅发放共用的,
不是订阅引入的问题。
三处修:
- 5 处余额增减一律改 coalesce(credit_balance_micro, 0),新写入自愈;
- 启动迁移回填存量 NULL(按账本求和,让「余额 = SUM(ledger)」重新成立);
- 模型只加 default:0,**刻意不加 not null** —— 存量库有 NULL 行,AutoMigrate
尝试 SET NOT NULL 会直接失败,而且它在回填之前跑,等于把部署搞挂。
回归测试先证明能失败(去掉 coalesce → 余额 0)再确认修复。第一版测试因为我给
模型加了 not null 而无法造出 NULL,恰好暴露了上面那个部署风险。
真库验证:回填后 42 个租户 0 个 NULL;那个"有分录但余额 NULL"的租户余额
2981 = 账本合计 2981.34。管理端页面显示真实订阅(已发放 3 次 = 首笔 + 补发 2 笔)。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-07-20 16:28:32 +08:00 |
|
Blizzard
|
79b110afd0
|
feat(admin): 数据源页转 RAG 运维台 + 支付/模型菜单重组 + 概览升级为仪表盘
后端:
- 新增 POST /admin/kb/search:管理端跨租户检索,支持 mode 指定单路
(vector/fulltext/graph/hybrid),不走 scopedKB(否则会被强制锁到调用者
自己的 space,跨租户排障就没法做了)
- KB 清单补 space_id(检索键是 <space_id>/<name>,缺它前端拼不出 key)
前端:
- 数据源&RAG 页补「检索试验台」:同一 query 并排跑生产链路 + 四路诊断,
召回不准时能直接定位是向量/分词/图谱哪一环挂了
- 支付拆成「配置 / 订单与对账」两个子页,挂到运维 > 支付 下;
导航支持二级菜单(NavParent 命中子路由自动展开)
- SettingsPage → ModelConfigPage「模型配置」,模型参数与计费规则合一
- 概览 → 仪表盘:并入计费与用量(UsagePage → UsageSection),
去掉系统健康拓扑(与服务状态页重复,同一份 /admin/status 数据)
- 全局隐藏滚动条(保留滚动)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-07-20 11:17:54 +08:00 |
|
Blizzard
|
c3151d1078
|
refactor(admin): 配置按域收口到「系统配置」页,Usage 只留用量观测
原本模型配置在「模型」页、计费规则与支付渠道却塞在「分析 > 计费&用量」观测页里(该页
~1290 行,首屏全是表单、真正的用量观测在第四屏)。按「域」重组:
- 新建「系统配置」页,两个 Tab:
· 模型 = 模型登记/激活/连通性测试 + 计费规则(汇率/硬拦截/按模型定价与权重)
· 支付 = 支付渠道配置(兑换码/积分包/微信参数) + 订单流水(订单流/对账/人工退款)
配了什么就在同处看它的规则与数据,不用来回跳。三块直接复用原组件,零重写。
- 「计费 & 用量」瘦成纯用量观测(消耗趋势/租户排行/发放积分)。
- 导航「模型」页并入系统配置(12 页 → 11),侧栏图标换齿轮。
- 顺带修残留 bug:数据源页「前往模型管理」原为 href=#/models + onClick 改 hash,
既指向已废弃路径、又是 hash 写法(早已换 BrowserRouter,点了不跳),改正规 <Link to=/admin/settings>。
tsc + build + vitest 41 过。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-07-20 10:19:32 +08:00 |
|
Blizzard
|
6de1b3f6b2
|
feat(admin): 官网落地页融进 admin —— / 是官网、/admin 是运维后台
用户要 agent.sundynix.cn/ 打开是营销官网、/admin 是后台,且只用一个前端。
把 sundynix-site/web 的营销落地页融进 sundynix-admin 这一个 Vite 工程(不挂两份 embed):
- 拷官网到 src/site/:home(hero/功能/架构/快速上手/下载)+layout(header/footer)
+terminal-demo/logo/reveal 等 + content/site.ts(文案本就是本产品)。去掉博客/posts/埋点/RSS
(营销 only,零后端改动);use-release 改纯静态版本号。public/ 加 brand logo+favicon。
- Tailwind v4→v3 对齐:site 的 ink/ground/accent/term 等 token 加进 tailwind.config(var 引用)
+ :root/.dark 变量+keyframes 进 index.css;bg-ground/85 用 color-mix 还原。admin 自身用默认
gray/violet 调色板,不冲突;landing 的 bg-ground 只作用在 SiteLayout 容器、不改 body。
- 路由重构:App.tsx 换 BrowserRouter —— / 官网(公开)、/admin/* 后台(AdminGate 内做 me/Login/AppShell)。
routes.tsx path 改相对、AppShell 链接加 /admin 前缀。@ 别名指向 src/site。
- gateway/Dockerfile/nginx 零改动:单份 dist 挂根 + NoRoute SPA 兜底已支持 BrowserRouter 深链。
验证:tsc + vite build(Tailwind 编译过)+ vitest 41 过;gateway 二进制冒烟打真 serve——
/ 返回官网 index.html、/admin 与 /admin/tasks SPA 兜底 200、/brand/*.webp 200、/api/v1 走 API 401;
dist 里确认落地页文案已进 bundle。(注:MCP 浏览器当前断开,视觉渲染待部署后线上看。)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-07-18 17:36:43 +08:00 |
|
Blizzard
|
373167b705
|
feat(admin): 补全平台任务观测 + 空间管理 + 基建加 MinIO/实时探针
对照已实现系统功能补 admin 缺失模块(feat/site):
- 全平台任务/运行观测:GET /admin/tasks(跨租户查 sundynix_task,join 租户名/提交人邮箱/评测,
按状态/租户筛 + 状态计数;含 HITL 待审批=筛 waiting)+ TasksPage(状态卡+筛+表)。
- 空间(Space)管理:GET /admin/spaces(跨租户列 Space + 成员数子查询 + kind/归档态)+ SpacesPage。
- 基建观测:infra 加 MinIO(126 对象存储);postgres/redis/minio 从启动标志升级为实时 ping
(blob.Ping/Postgres.Ping/Redis.Ping),能反映中途掉线。StatusPage 加 minio 标签、6 个依赖。
- 模型健康/熔断:确认 DashboardPage 已有「运行时链路态」渲染 m.health,无需重做。
验证:admin tsc + vitest 41 过、gateway build/vet/test 过;两新页浏览器实测渲染+优雅错误处理;
两新端点起临时 gateway 打真 PG 实测——tasks(counts+3路join)、spaces(成员数子查询)均返真数据。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-07-18 17:06:25 +08:00 |
|
Blizzard
|
a1c35852ef
|
chore: 删死代码 —— OpenReport/ReadLocalFile/isDesktop/openReport + admin Soon (P2)
完成度审计确认全链零生产调用:
- app.go OpenReport(仅被死包装引用)、ReadLocalFile(仅测试引用);
desktop.ts openReport 包装、isDesktop 导出(实际用 isMacDesktop)——全删。
绑定重新生成(OpenReport/ReadLocalFile 归零,PrintReportPage/SaveReportAs/
Notify 保留)。删对应的 app_test TestReadLocalFile。
- admin Soon.tsx(规划中占位组件)已成未引用死组件——routes.tsx 9 条路由全
ready:true,import 未用。删组件+import。
openInSystem/filepath/os 仍被 PrintReportPage/download 使用,不孤立。
desktop go test + tsc + 68 vitest、admin tsc + 41 vitest 全绿。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-07-18 11:56:51 +08:00 |
|
Blizzard
|
11d321f218
|
feat(admin): 计费 & 用量合成一页 —— 顶部配规则、下方看结果(闭环)
按"配置和观测放一个页面"收口:删掉重复的「计价 & 预算」页(其预算区块是 mock),
把真·计价配置并入「计费 & 用量」,形成 规则→扣费→观测 一页闭环。
- 新组件 BillingRules:全局 token→积分汇率 + 每模型 单价/币种/积分权重(读写
/admin/pricing + /admin/billing-config),改完对后续任务实时生效。
- UsagePage:顶部「计费规则」(配置端) + 下方「用量观测」(按规则折算后的实际消耗)。
- 删 PricingPage + /pricing 路由;api 加 credit_weight / getBillingConfig / saveBillingConfig。
live 验证(preview):改汇率保存→持久化→新任务按新汇率扣→用量观测反映;
tsc + 41 vitest 全过;无 PricingPage 残引。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-07-07 13:26:33 +08:00 |
|
Blizzard
|
54de95aa53
|
feat(admin): 用量 & 计费页 —— SaaS P2 计量观测面(读 /admin/usage)
管理端「分析」组新增页:全平台 / 单租户的 token · 积分 · 成本口径。
- api.adminUsage():拉 /admin/usage(含 trend / totals / tenants 排行 / 单租户余额);
微单位(×10⁻⁶)前端 ÷1e6 展示。
- UsagePage:租户下拉 + 近7/30天切换;KPI 卡(积分/Token/成本/余额或活跃租户);
积分消耗按天条形趋势(补零连续);全平台口径下各租户排行表(点名下钻单租户)。
- routes 注册 /usage(HashRouter)。
live 验证(preview):全平台两租户排行 + KPI + 趋势条渲染正确;点租户下钻→
单租户口径 + 当前余额卡;数值与后端自洽;无 console 错误;tsc + 41 vitest 全过。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-07-07 12:38:33 +08:00 |
|
Blizzard
|
a830ae2a04
|
feat(admin): 审计 & 安全事件页(T4.B 收尾)
- 新增「审计 & 安全」页(/audit,运维组):接 /admin/audit + /admin/guardrail-events
- 安全事件:护栏拦截/灰区放行(kind 徽标 + 原因 + method/path + actor/ip/时间)
- 操作审计:变更操作(方法配色徽标 + 路径 + 状态码着色 + actor/ip/时间)
- 顶栏统计(操作留痕/护栏拦截/灰区) + 30s 自刷 + 手动刷新
- api.ts 增 listAudit / listGuardrailEvents + 类型
- 风格对齐重做后的服务状态页(中性克制)
- T4.B 整组完成(剩 HITL 审批明细可选小项)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-07-02 09:43:41 +08:00 |
|
Blizzard
|
30e80c0eed
|
feat(admin): 提示词控制面页 + 概览/状态页重做 + 接入 vitest
- 新增「提示词」页(/prompts):接 /api/v1/prompts,建版本/激活热下发/
对比激活版行级 diff/撤销,挂到配置组
- 概览页重做为系统控制塔:吃 admin/overview(全平台口径)——平台任务/
评测/用户规模/服务在线 + 模型路由态 + 提示词覆盖态 + 健康拓扑 + 30s自刷
- 服务状态页重做:中性克制风 + 请求链路做成深色实时数据管道(流动光点/
节点辉光) + MCP 工具改能力域配色小卡片
- 接入 vitest(此前零测试):41 单测(api 控制面/lib diff/路由派生)
- api.ts 增 statsOverview/adminOverview/prompt 控制面四接口 + groupPrompts
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-07-02 08:59:40 +08:00 |
|
Blizzard
|
2d9695e940
|
feat: admin端UI
|
2026-06-27 12:06:29 +08:00 |
|
Blizzard
|
8bcb90cdb2
|
feat(admin): 服务状态面板(基建/服务探活 + MCP 工具注册)+ mcp-go 工具注册表
管理端新增「运维 › 服务状态」:总览横幅 + 摘要数字 + 请求链路拓扑
(客户端→网关→NATS→调度→MCP,按健康三态着色)+ 应用服务卡(含探针
延迟)+ 基建磁贴 + MCP 工具按能力域分组(中文名/作用)。
探活机制(全走 NATS,无 HTTP):
- mcp-go/mcp-py 新增 list_tools 自省工具,能应答=在线 + 上报工具清单
- dispatcher 无端点 → 新增 NATS 心跳主题 sundynix.health.dispatcher
(ServeHealth 应答 model/ready/uptime),网关用 bus.Ping 探
- 网关 GET /api/v1/admin/status 并发聚合四探针 + 各项延迟
mcp-go 重构:switch → map 注册表(buildRegistry),dispatch 与 list_tools
共用单一事实源,杜绝漂移;每个工具带中文名 + 作用描述。mcp-py 同样补元信息。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-06-22 16:38:10 +08:00 |
|
Blizzard
|
597665f3c8
|
feat(admin): 计价配置(按模型·分输入/输出单价)—— 计费比率配置落地
计费需 token↔真钱比率,配置归管理端。本次落地"按模型·分输入/输出"粒度:
后端(gateway):
- store.Pricing 模型(BaseModel + model_id 唯一 + input_per_1k/output_per_1k + currency),
AutoMigrate 建 sundynix_pricing;ListPricing/UpsertPricing(OnConflict model_id 覆盖)。
- admin handler:GET /admin/pricing 列表、PUT /admin/pricing 设置(校验非负,币种默认 CNY),
挂在 RequireAdmin 组下。
前端(admin):
- api:listPricing/savePricing(带 Bearer)。
- PricingPage:列出所有已登记模型(chat+embedding),每行可编辑 输入/输出每1K单价 + 币种,逐行保存。
- routes 新增「计价」页(配置组)。
实测:PUT→ok;GET 返回正确行;重复 PUT 同 model_id 仍 1 行且值更新(upsert 生效);表自动迁移。
前端 tsc 干净。下一步可做用量计量 × 单价折算(真正计费)。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-19 11:25:24 +08:00 |
|
Blizzard
|
3b54e59ecf
|
feat: embedding 配置搬上控制面 — 数据源页可视化配置 + 热更新
embedding 从 env 改为控制面驱动(持久化+可视化),复用 chat 模型同套范式:
配置控制面泛化为按 kind(chat/embedding),加 embedding kind。
- shared: 配置 subjects 泛化 sundynix.config.<kind>.get/.updated;bus 方法改 kind 参数
(RequestConfig/ServeConfig/PublishConfigUpdated/SubscribeConfigUpdated)
- gateway: sundynix_model 加 kind 列(每 kind 唯一激活)+旧行回填 chat;admin 按 kind
增删改/激活/列表,测试连接 embedding 走 POST /embeddings;main 按 kind ServeConfig;
变更广播各 kind
- dispatcher: 取 chat 配置(kind 化)
- mcp-go: rag.Engine.SetEmbedding 热更新(RWMutex);main 取/订阅 embedding 控制面配置
(覆盖 env)
- admin 控制台: api 按 kind;抽出复用 ModelManager;ModelsPage(chat)+新 DatasourcesPage
(embedding + 向量/图库占位);routes 数据源页就绪
- 验证: 全模块 build✓ + e2e PASS + 控制台 npm build✓;live 全跑通——chat(DeepSeek 回填
kind 仍工作);mcp-go 不带 EMBED env 启动→控制台配 embedding(百炼)→测试连接✓→激活
→NATS 热更新 mcp-go→入库+语义检索'存向量的数据库'→Milvus;浏览器数据源页拉到激活配置
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-10 17:25:54 +08:00 |
|
Blizzard
|
f6a669070d
|
refactor(admin): 控制台改为路由表驱动的动态路由 (react-router)
控制台从 useState 切 tab + 硬编码条件渲染,改为路由注册表驱动 + 真实 URL 路由,
加页面只需在 routes.tsx 加一条,不动外壳。
- 依赖 react-router-dom v7;App=HashRouter(静态托管/桌面内嵌都能深链)
- routes.tsx:路由注册表(单一事实源,导航+内容都派生);real 页面 lazy 懒加载(代码分割)
- shell/AppShell:NavLink 分组导航(配置/平台) + Routes + Suspense + 健康灯,全从注册表派生
- 页面归入 pages/(ModelsPage 移入),components/Soon 占位复用
- 验证:npm build✓(ModelsPage 独立 chunk=懒加载生效);真实浏览器——默认重定向 #/models、
nav 切换改 URL hash、深链 #/guardrails 直达、浏览器后退回 #/datasources、active 高亮
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-10 16:09:07 +08:00 |
|