Blizzard
|
b6a6875795
|
feat(gateway): 可观测性 —— Prometheus 指标 + 结构化日志 + 探针
往"生产可运维"推一步(网关前门):
- Prometheus /metrics:sundynix_http_requests_total{method,route,status}、
request_duration_seconds 直方图、requests_in_flight。route 用 c.FullPath()
路由模板(/tasks/:id/...)避免按真实路径高基数。
- 结构化访问日志:slog JSON 到 stderr(request_id/method/route/status/latency_ms/
ip/uid/bytes),替代 gin 默认文本日志;gin.New()+Recovery 自管中间件链。
- RequestID 中间件:生成/透传 X-Request-ID,写上下文+响应头,供日志关联。
- 探针:/healthz(liveness,不查依赖)、/readyz(readiness,DB+Redis 就绪才 200,
否则 503),供 k8s 等导流判断;/api/v1/health 深度聚合保留。
- 三个根端点不挂业务鉴权(/metrics 生产应由网络层限制抓取来源)。
验证:单测(计数 +1 / X-Request-ID 生成与透传);实跑 /healthz 200、/readyz 200
(db,redis ready)、/metrics 输出真实指标、访问日志 JSON 正常、X-Request-ID 回写。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-19 10:38:31 +08:00 |
|
Blizzard
|
149c35c21b
|
feat(gateway): 真实鉴权片1 —— JWT 注册/登录 + 校验中间件(后端核心)
替掉"裸 X-User-ID 头当身份"的临时方案,落地无状态 JWT 鉴权后端:
- internal/auth:JWT 签发/校验(HS256,密钥 env JWT_SECRET,仅接受 HMAC 防 alg 混淆)
+ bcrypt 密码哈希/校验。纯包,含单测。
- User 模型加 Name + PasswordHash(json:"-" 不外泄);store 加 CreateUser/GetUserByEmail/
GetUserByID(邮箱唯一冲突 → ErrUserExists)。
- handler/auth:POST /auth/register(建用户+签发)· POST /auth/login(校验+签发,
用户不存在与密码错同一文案防枚举)· GET /auth/me。
- middleware/auth:解析 Bearer JWT,校验通过把已验证 userID 注入上下文(非阻断)。
- userID(c) 改为优先取 JWT 注入的 uid,兜底 X-User-ID 头(前端尚未接登录,保持可用)。
验证:
- 单测:JWT 签发/解析往返、过期拒绝、篡改/非法拒绝、bcrypt 哈希校验。
- 实跑(nats+pg+gateway):注册→token+user(无密码)、重复注册 409、错密码 401、
/auth/me 带 token 200 / 无 token 401;owner 隔离改用已验证 uid —— 带 token 建的库
匿名/伪造 header 都看不到(JWT 用户数据归于雪花 id,header 无法臆测)。
片 2 待做:前端登录页 + 存令牌带 Bearer + 处理 401 + 去掉 header 兜底 + 保护路由。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-17 16:14:21 +08:00 |
|
Blizzard
|
f610d8d2da
|
feat(kb): 大文档正文存 MinIO(PG 只留元数据+预览+对象键)
超过阈值(8000 字)的正文落对象存储,彻底解决十几万字文件塞 PG 的问题。
- internal/blob:minio-go 封装 Store(Open/Put/Get/Delete + Ready 降级);连不上则降级内联。
- docker-compose:milvus-minio 暴露 9000 端口供网关用作文档对象存储(bucket sundynix-docs)。
- main/router/handler:注入 blob.Store(env MINIO_*,默认 localhost:9000 minioadmin)。
- runIngest:size>8000 且 MinIO 可用 → 正文 Put 到 owner/kb/name,PG content 置空仅存
object_key+preview+size;否则内联。SaveDoc 改为按全文显式传 preview(offload 后内联为空也有预览)。
- KbDoc:object_key 非空时从 MinIO 取回全文。
验证:入 12182 字笔记 → PG content_len=0、object_key=wt/default/超大文件测试、preview 非空、
size=12182;/kb/doc 取回完整 12182 字(来自 MinIO);6321 字的仍内联(object_key 空)。
列表只读元数据+预览。gateway build 通过。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-13 17:02:44 +08:00 |
|
Blizzard
|
4fd44380aa
|
refactor(store): DB 规约统一 —— 雪花字符串 id + created/updated/deleted_at 软删
所有数据库映射结构体收敛到统一基类,清理混乱。
- store/base.go:BaseModel{ID string(雪花,bwmarrin/snowflake) PK, CreatedAt, UpdatedAt,
DeletedAt gorm软删index} + BeforeCreate 生成 id + NewID()。
- 全模型嵌入 BaseModel:User/Task/LLMModel/KB/Doc/Agent(去掉各自 ID uint/CreatedAt);
Task 业务 id(task_xxx)挪到 TaskID 唯一列,主键统一雪花。
- 模型 id uint→string:admin :id 路由、SetActiveModel/DeleteModel/SaveModel、modelBody.ID。
- 一次性迁移 migrateLegacyIntIDs:检测旧整型 id(AutoMigrate 不改主键类型)→ 备份
sundynix_model 行(唯一不可再生的 API 密钥)→ 删旧表 → 按新规约重建 → 回灌模型(新雪花 id)。
其它表(User/Task/KB/Doc/Agent)为可重建测试数据,重置。
- Doc 预埋 Size/Preview/ObjectKey 字段,DocLink 表(为后续 B/C)。
验证:重启 gateway → 日志"回灌 2 条模型配置";PG sundynix_model.id=varchar、有
created_at/updated_at/deleted_at;DeepSeek/百炼 密钥保留(keylen 35);admin 列表返回
雪花 string id + 脱敏 key;健康五灯全绿。gateway build 通过。
注:mcp-go 的 sundynix_user_profile(Profile) 模型尚未套同规约,待跟进对齐。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-13 16:45:52 +08:00 |
|
Blizzard
|
21e5f6620d
|
chore: fresh-clone 可直接运行审查与修复
确保 git clone 后零配置(除 LLM key)即可跑通后端链路。
- go.work: 移出 sundynix-desktop(Wails,//go:embed frontend/dist 需先 npm build,
且 main 为桩),避免污染后端工作区构建;保留后端 4 模块
- mcp-py pyproject: 注释未 import 的 mcp/docker 重依赖(对应功能仍为桩),
fresh pip install 只装实际用到的 nats-py + docx/openpyxl/pypdf,更快更稳
- README: 完整环境改为 fresh-clone 零配置运行指引(infra→4后端→2前端→控制台配模型)
- 审查结论: 无硬编码绝对路径; 各服务 env 默认全对齐 docker-compose; go.sum/
package-lock 齐全; /tmp clone 实测: 4 后端模块 go build ✓、admin npm ci+build ✓、
mcp-py 全新 venv 安装+导入 ✓; e2e PASS
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-11 17:13:55 +08:00 |
|
Blizzard
|
e5fa0ae36c
|
feat: Gateway store 桩换真实 GORM/Postgres + go-redis (含自动迁移与优雅降级)
第 2 层网关持久层落地,遵守 sundynix_ 表名前缀 + AutoMigrate 约定。
- store: GORM(NamingStrategy 前缀 sundynix_/单数) → User=sundynix_user, Task=sundynix_task
启动 AutoMigrate;go-redis/v9 滑动窗口限流(Incr+Expire,按 IP)
- 优雅降级:连不上库则 warn 继续(不 fatal),保证无 Docker 的 make demo 仍跑通
- handler: SubmitTask 持久化任务(best-effort),Billing 真实读库返回 tasks_submitted
- main: OpenPostgres/OpenRedis 读 POSTGRES_DSN/REDIS_ADDR 环境变量
- 验证: 4 模块 build ✓;e2e 3 测试 PASS;live 双路径(真实库持久化 + 坏DSN降级)实测通过
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
2026-06-10 11:43:53 +08:00 |
|
Blizzard
|
c7a02c3905
|
feat: 初始化 sundynix-agentix 分层式 AI Agent 平台脚手架
5 层 + 1 条 NATS 零拷贝消息总线的 monorepo(Monolith First → Microservices Morph B)。
纵向主干(任务流 + Token 流回流)已真实跑通,横向各层能力为带注释的桩。
已贯通(real code):
- sundynix-shared: 共享契约 + JetStream/core NATS 真实收发(bus) + 内嵌 NATS(devnats) + e2e 测试
- sundynix-gateway: Gin 接入 + DSL 解析组装 + NATS Publish + SSE 流式输出
- sundynix-dispatcher: NATS 消费 + Eino Orchestrator 流式回流 + 熔断器 + LLM Pool 占位流式
- 链路: HTTP POST → DSL → sundynix.tasks.* → Dispatcher → Token 经 sundynix.streams.<id> 回流 → SSE
- 基础设施: docker-compose(nats/postgres/redis/neo4j/milvus) + Makefile(make demo/e2e)
待填(桩):
- Eino 图编排 compose.NewGraph、LLM Pool 接 vLLM/Ollama
- Gateway store 换真实 pgx/redis
- sundynix-mcp-go: Bleve+Milvus+Neo4j 混合检索 / UniOffice / 外部 API
- sundynix-mcp-py: gVisor 沙箱 / MinerU(PaddleOCR) / Docker 解释器
- sundynix-desktop: React Flow 画布 → DSL 导出 → SSE 展示
|
2026-06-10 11:00:29 +08:00 |
|