Files
lijiaoqiao/supply-api/internal/audit/audit.go
Your Name ed0961d486 fix(supply-api): 修复编译错误和测试问题
- 添加 ErrNotFound 和 ErrConcurrencyConflict 错误定义
- 修复 pgx.NullTime 替换为 *time.Time
- 修复 db.go 事务类型 (pgx.Tx vs pgxpool.Tx)
- 移除未使用的导入和变量
- 修复 NewSupplyAPI 调用参数
- 修复中间件链路 handler 类型问题
- 修复适配器类型引用 (storage.InMemoryAccountStore 等)
- 所有测试通过

Test: go test ./...
2026-04-01 13:03:44 +08:00

96 lines
2.2 KiB
Go

package audit
import (
"context"
"sync"
"time"
)
// 审计事件
type Event struct {
EventID string `json:"event_id,omitempty"`
TenantID int64 `json:"tenant_id"`
ObjectType string `json:"object_type"`
ObjectID int64 `json:"object_id"`
Action string `json:"action"`
BeforeState map[string]any `json:"before_state,omitempty"`
AfterState map[string]any `json:"after_state,omitempty"`
RequestID string `json:"request_id,omitempty"`
ResultCode string `json:"result_code"`
ClientIP string `json:"client_ip,omitempty"`
CreatedAt time.Time `json:"created_at"`
}
// 审计存储接口
type AuditStore interface {
Emit(ctx context.Context, event Event)
Query(ctx context.Context, filter EventFilter) ([]Event, error)
}
// 事件过滤器
type EventFilter struct {
TenantID int64
ObjectType string
ObjectID int64
Action string
StartDate string
EndDate string
Limit int
}
// 内存审计存储
type MemoryAuditStore struct {
mu sync.RWMutex
events []Event
nextID int64
}
func NewMemoryAuditStore() *MemoryAuditStore {
return &MemoryAuditStore{
events: make([]Event, 0),
nextID: 1,
}
}
func (s *MemoryAuditStore) Emit(ctx context.Context, event Event) {
s.mu.Lock()
defer s.mu.Unlock()
event.EventID = generateEventID()
event.CreatedAt = time.Now()
s.events = append(s.events, event)
}
func (s *MemoryAuditStore) Query(ctx context.Context, filter EventFilter) ([]Event, error) {
s.mu.RLock()
defer s.mu.RUnlock()
var result []Event
for _, event := range s.events {
if filter.TenantID > 0 && event.TenantID != filter.TenantID {
continue
}
if filter.ObjectType != "" && event.ObjectType != filter.ObjectType {
continue
}
if filter.ObjectID > 0 && event.ObjectID != filter.ObjectID {
continue
}
if filter.Action != "" && event.Action != filter.Action {
continue
}
result = append(result, event)
}
// 限制返回数量
if filter.Limit > 0 && len(result) > filter.Limit {
result = result[:filter.Limit]
}
return result, nil
}
func generateEventID() string {
return time.Now().Format("20060102150405") + "-evt"
}