feat(gateway): D3 审查读侧/revert 端点 + 语音用户可见面(L45)
(a) 记忆入库前审查的两条 admin 端点(主人判「有必要就做」):
GET /api/v1/admin/memories/reviews?limit= (留痕读侧,不含记忆正文)
POST /api/v1/admin/memories/{id}/revert (回滚软合并,落审计 memory.review.revert)
两条 writeAuth(裁定 DECISIONS #10:留痕属私有面,不给 viewer)
(b) 语音用户可见面:DTO voice(含服务端派生 url)+ GET /api/v1/media/{name}
(200/206/304/416/HEAD、Accept-Ranges、非法名/穿越统一 404 media_not_found)
+ documents.Store.SaveAudio(内容寻址、$DATA_DIR 0600)+ history voice 列读写与引用计数差动
缺口(如实):message_persisted/握手回放仍不带 voice(文件面外,需给 history.Message 加字段);
AMR 需一行 VoiceTranscoder 注入(DECISIONS #11 已排)。4 个变异自检(含一条自认的等价变异)。
This commit is contained in:
1 parent
4a937bd269
commit
1420e8aaa6
15 files changed
+2202
-5
No files matched your search
@@ -93,6 +93,13 @@ func (s *Server) registerUserRoutes(
|
||||
// 「随机名即凭据」的免鉴权读法,也不会放开内联服务 HTML/SVG 的口子。
|
||||
mux.Handle("POST /api/v1/documents", writeAuth(http.HandlerFunc(s.handleDocumentUpload)))
|
||||
mux.Handle("GET /api/v1/documents/{name}", writeAuth(http.HandlerFunc(s.handleDocumentFile)))
|
||||
|
||||
// 语音副本回放(design/24 §10.11;契约 v0.67 登记、本片落地):与文档读侧**同一
|
||||
// 道门**(owner|admin,必须 Bearer)—— 语音是私密内容,刻意**不**走图片那套
|
||||
// 「随机名即凭据」的免鉴权读法(客户端带 token 取字节 → `blob:` 播放)。音频副本
|
||||
// 与文档共用 `<DataDir>/uploads/documents` 目录,但下发类型恒为 `audio/*` 且内联,
|
||||
// 理由见 media.go。
|
||||
mux.Handle("GET /api/v1/media/{name}", writeAuth(http.HandlerFunc(s.handleMediaFile)))
|
||||
}
|
||||
|
||||
// registerHistoryRoutes 挂载持久化聊天历史表面(design/16)
|
||||
@@ -214,6 +221,16 @@ func (s *Server) registerAdminRoutes(
|
||||
// 语义、同样**不审计**。结果只活在进程内存(TTL 30 分钟),进程重启后旧 runId
|
||||
// 如实 404。
|
||||
mux.Handle("GET /api/v1/admin/memories/tidy/dry-run/{runId}", writeAuth(http.HandlerFunc(s.adminMemoryTidyDryRunStatus)))
|
||||
// 入库前审查(D3)的管理面(design/23 §15 D3-8「面板可查」+ §8「回滚」;切片 L45):
|
||||
// - GET .../memories/reviews —— 审查留痕列表(谁被审 / 四态 / 依据 / 合并去向 /
|
||||
// 是否降级 / 时间),**不含记忆正文**。只读、不审计,走 writeAuth(owner|admin):
|
||||
// 留痕带 itemId/personaId/projectId/sessionId,属私有记忆面,与同族的
|
||||
// GET /admin/memories 同档,**不给 viewer**(design/23 §11 的既有取向 + design/11 §7
|
||||
// 对 viewer 的定义是「只读监控投影」)。
|
||||
// - POST .../memories/{id}/revert —— 撤销一次软合并(无损可逆,行永不物理删除)。
|
||||
// 它是**写**,因此落审计(动作名 memory.review.revert,见 admin_memory_review.go)。
|
||||
mux.Handle("GET /api/v1/admin/memories/reviews", writeAuth(http.HandlerFunc(s.adminMemoryReviews)))
|
||||
mux.Handle("POST /api/v1/admin/memories/{id}/revert", writeAuth(http.HandlerFunc(s.adminMemoryRevert)))
|
||||
mux.Handle("GET /api/v1/admin/observability/audit", writeAuth(http.HandlerFunc(s.adminObservabilityAudit)))
|
||||
mux.Handle("GET /api/v1/admin/sessions/{id}/export", writeAuth(http.HandlerFunc(s.adminExportSession)))
|
||||
mux.Handle("POST /api/v1/admin/rag/query", writeAuth(http.HandlerFunc(s.adminSearchRag)))
|
||||
@@ -325,6 +342,9 @@ func (s *Server) withMiddleware(mux http.Handler) http.Handler {
|
||||
// 文档路径的同类防护(design/24 §3.2「路径穿越」):`..` 形态必须在 ServeMux
|
||||
// 清理路径并重定向之前被拦下,否则穿越请求会变成一个非文档路径的重定向。
|
||||
h = guardDocumentPaths(h)
|
||||
// 语音副本的同类防护(design/24 §10.11):三条读侧路(files/documents/media)
|
||||
// 各自的名字形态与错误码,因此各有一道门。
|
||||
h = guardMediaPaths(h)
|
||||
if s.frontend != nil {
|
||||
h = s.spa(h)
|
||||
// 安全入口(裁决 1.6 / 16.4.7,design/07 §0.2):管理面板前端按 .env 的
|
||||
|
||||
Reference in new issue
Block a user