package db import ( "context" "encoding/json" "fmt" "time" "github.com/pkg/errors" "github.com/uptrace/bun" ) // LogSuccess logs a successful permission-protected action func LogSuccess( ctx context.Context, tx bun.Tx, meta *AuditMeta, info *AuditInfo, ) error { return log(ctx, tx, meta, info, "success", nil) } // LogError logs a failed action due to an error func LogError( ctx context.Context, tx bun.Tx, meta *AuditMeta, info *AuditInfo, err error, ) error { errMsg := err.Error() return log(ctx, tx, meta, info, "error", &errMsg) } func log( ctx context.Context, tx bun.Tx, meta *AuditMeta, info *AuditInfo, result string, errorMessage *string, ) error { if meta == nil { return errors.New("audit meta cannot be nil for audit logging") } if info == nil { return errors.New("audit info cannot be nil for audit logging") } if meta.u == nil { return errors.New("user cannot be nil for audit logging") } if meta.r == nil { return errors.New("request cannot be nil for audit logging") } // Convert resourceID to string var resourceIDStr *string if info.ResourceID != nil { idStr := fmt.Sprintf("%v", info.ResourceID) resourceIDStr = &idStr } // Marshal details to JSON var detailsJSON json.RawMessage if info.Details != nil { jsonBytes, err := json.Marshal(info.Details) if err != nil { return errors.Wrap(err, "json.Marshal details") } detailsJSON = jsonBytes } // Extract IP and User-Agent from request ipAddress := meta.r.RemoteAddr userAgent := meta.r.UserAgent() log := &AuditLog{ UserID: meta.u.ID, Action: info.Action, ResourceType: info.ResourceType, ResourceID: resourceIDStr, Details: detailsJSON, IPAddress: ipAddress, UserAgent: userAgent, Result: result, ErrorMessage: errorMessage, CreatedAt: time.Now().Unix(), } return CreateAuditLog(ctx, tx, log) }