feat(admin): 面板「存储」卡片接真数据(含 PG 增强状态)+ 契约 v0.60
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled

- 现状:overviewMetrics.ts:188 的「存储」卡是写死的 value:"SQLite",后端也没有对应读端点(/admin/system/* 只有 revoke-keys/rotate-jwt/backup/restore 四个动作端点)。

- 新增只读端点 GET /api/v1/admin/system/storage(ownerAuth):main{kind,path,fileBytes,walBytes,shmBytes,pageSize,pageCount,freelistPages,freeBytes} + documents{count,bytes} + vector{kind,enabled,ready};只读(SELECT/PRAGMA + os.Stat)、复用活连接不开新池、**绝不含凭据**(只回 kind,不回 host/DSN)、失败一律 500 storage_unavailable(不回全 0 假快照;表缺失也 500 而不是静默 0)。

- vector 真源 = 组合根 app.vectorState()(Configured = DB_PG_URL 非空;Live = 向量索引类型断言成功),零新探测 ⇒ 面板现在能区分「未启用(未配置 DB_PG_URL)/ 启用(pgvector·ready)/ 已配置但未就绪(连接失败,检索降级)」,正好解答主人对「面板只写 SQLite」的困惑。

- 前端:卡片显示真实体积 + WAL/页数/空闲页 + documents 件数与占用 + PG 那一行;取数走与已接线卡片同一条加载/错误态(失败显示 '—' + 端点报错,不静默显示 0)。

- 契约 v0.60(项目红线):api-client(版本段 + 端点表 + 存储状态契约小节 + changelog)与 api-reference(版本号 + 端点表 + 详情小节)同步;字段名三方(代码/Docs/前端)逐字对齐。

- 主会话独立验收:隔离 worktree(ST1 的 14 文件,排除 B1 在途的 chat_documents.go/documents_pdf_test.go)build/vet 绿、全树 59 包 0 FAIL、存储端点 7 用例 PASS、双平台交叉编译绿。

- ⚠️ 该切片自首一起事故:为通过 cmd/cyrene 类型检查跑了 go build ./cmd/cyrene/(单 main 包)⇒ 覆盖了仓库根 cyrene.exe(49,675,264 B / 19:32:19,脏树未 strip);上一个权威产物仍在 cyrene.exe~(39,507,968 B / 19:25:13)。运行中的 PID 477964 未受影响;主会话将在整树干净后重跑 ctrl.bat build 恢复权威产物。
This commit is contained in:
AskaEth committed 2026-10-04 19:44:53 +08:00
1 parent 137b3e9eaf
commit c4e09afd38
14 files changed
+751 -13

No files matched your search

+28
View File
@@ -1,6 +1,7 @@
package gateway
import (
"database/sql"
"io/fs"
"log/slog"
"net/http"
@@ -10,6 +11,23 @@ import (
"git.yeij.top/AskaEth/Cyrene_v2/internal/runtime/model"
)
// VectorState 是组合根报告的向量增强(pgvector)运行状态,供管理侧
// 「存储状态」端点回答「PG 到底有没有生效」(design/03 §3)。
//
// 它是**复用**而非探测:网关不读环境变量、不新开 PG 连接、不
// 自行 ping —— 真相只有组合根知道(DB_PG_URL 是否配置 + 活的向量
// 索引是哪个后端),因此由它注入,避免面板看到与运行时不一致的
// 第二个判断。
type VectorState struct {
// Configured 报告 DB_PG_URL 是否已配置(非空即算),即
// 增强开关在不在。
Configured bool
// Live 报告当前活的向量索引确实是 PostgreSQL+pgvector 后端。
// 配置了但连接/schema 准备失败时为 false —— 此时语义检索已降级,
// 面板必须显示「未就绪」而不是假装增强生效。
Live bool
}
// Deps 承载网关被注入的依赖。除 Auth 外每个字段都容忍
// nil,Auth 是必需的(认证支撑登录与每一个 RBAC
// 决策)。Registry/Loop 由具体的 *capability.Registry 与
@@ -91,6 +109,16 @@ type Deps struct {
// 图片上传存储(<DataDir>/uploads)及其静态路由。可选;
// 为空时上传 handler 回退到 cfg.DataDir。
DataDir string
// Database 是组合根已打开的活 SQLite 连接池。管理侧的
// 「存储状态」只读端点用它读页级统计与 documents 表 ——
// 复用既有池,端点自身不另开连接或连接池。可选;为 nil 时
// 该端点诚实作答(500 storage_unavailable),绝不假装
// 拿到了数据。
Database *sql.DB
// Vector 是组合根报告的向量增强(pgvector)运行时状态,
// 见 VectorState。网关只读它,绝不自行探测。可选;零值
// 表示「未配置」(kind:"none"),与未启用增强的部署一致。
Vector VectorState
// Streaming 标记注入的 Loop 具备流式能力(其 OnStream
// 已接线为发布 ws.stream_chunk)。设置后 hub 会跳过它自己的
// 单次最终 stream_chunk 发送,因为增量已通过 OnStream 流出。