feat(gateway): 敏感操作审计日志(T4.B)
- store.AuditLog 表(sundynix_audit_log) + AppendAudit/ListAudit - middleware.Audit(db):只审计变更类(POST/PUT/DELETE/PATCH),收尾 best-effort 落库(独立超时 ctx,失败静默不拖垮主流程);挂管理组 + prompt 激活/撤销 + HITL 审批 - GET /api/v1/admin/audit:倒序审计流(limit/offset 翻页) - live:PUT pricing / POST prompts/deactivate 留痕(actor/path/status/ip),GET 不记 - DEPTH_ROADMAP T4.B:overview✅ + audit✅ 打勾 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
package store
|
||||
|
||||
import "context"
|
||||
|
||||
// AppendAudit 追加一条审计留痕(best-effort:审计失败不应影响主流程,调用方忽略返回)。
|
||||
func (p *Postgres) AppendAudit(ctx context.Context, a *AuditLog) error {
|
||||
if p.db == nil || a == nil {
|
||||
return errStoreDisabled
|
||||
}
|
||||
return p.db.WithContext(ctx).Create(a).Error
|
||||
}
|
||||
|
||||
// ListAudit 倒序列出审计留痕(管理端审计流;limit 限流、offset 翻页)。
|
||||
func (p *Postgres) ListAudit(ctx context.Context, limit, offset int) ([]AuditLog, error) {
|
||||
if p.db == nil {
|
||||
return nil, errStoreDisabled
|
||||
}
|
||||
if limit <= 0 || limit > 200 {
|
||||
limit = 50
|
||||
}
|
||||
if offset < 0 {
|
||||
offset = 0
|
||||
}
|
||||
var out []AuditLog
|
||||
err := p.db.WithContext(ctx).Order("created_at desc").Limit(limit).Offset(offset).Find(&out).Error
|
||||
return out, err
|
||||
}
|
||||
@@ -42,3 +42,18 @@ type Eval struct {
|
||||
}
|
||||
|
||||
func (Eval) TableName() string { return "sundynix_eval" }
|
||||
|
||||
// AuditLog 是一条敏感操作留痕(改模型/密钥/激活 prompt/审批 等)。
|
||||
// 由 Audit 中间件在请求收尾时 best-effort 写入;只增不改,供运维溯源。
|
||||
type AuditLog struct {
|
||||
BaseModel
|
||||
Actor string `gorm:"size:64;index"` // 操作者 uid(未登录/系统留空)
|
||||
Action string `gorm:"size:8"` // HTTP 方法:POST / PUT / DELETE
|
||||
Route string `gorm:"size:128"` // 路由模式,如 /api/v1/admin/models/:id
|
||||
Path string `gorm:"size:256"` // 实际请求路径
|
||||
Status int // HTTP 响应状态码
|
||||
IP string `gorm:"size:64"`
|
||||
Detail string `gorm:"type:text"` // 备注(可选,如目标名/关键参数)
|
||||
}
|
||||
|
||||
func (AuditLog) TableName() string { return "sundynix_audit_log" }
|
||||
|
||||
@@ -66,7 +66,7 @@ func OpenPostgres(dsn string) *Postgres {
|
||||
migrateLegacyIntIDs(db)
|
||||
migrateDocLinkToID(db)
|
||||
|
||||
if err := db.AutoMigrate(&User{}, &Task{}, &Eval{}, &LLMModel{}, &KB{}, &Doc{}, &Agent{}, &DocLink{}, &Pricing{}, &Prompt{}); err != nil {
|
||||
if err := db.AutoMigrate(&User{}, &Task{}, &Eval{}, &LLMModel{}, &KB{}, &Doc{}, &Agent{}, &DocLink{}, &Pricing{}, &Prompt{}, &AuditLog{}); err != nil {
|
||||
log.Printf("[store] postgres AutoMigrate 失败,降级运行: %v", err)
|
||||
return &Postgres{}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user