added admin page and audit log viewing

This commit is contained in:
2026-02-11 19:07:40 +11:00
parent c05ecb66fe
commit 000eac44bb
22 changed files with 1298 additions and 155 deletions

View File

@@ -41,29 +41,48 @@ func CreateAuditLog(ctx context.Context, tx bun.Tx, log *AuditLog) error {
type AuditLogFilter struct {
*ListFilter
customWhere []whereClause
}
type whereClause struct {
query string
args []any
}
func NewAuditLogFilter() *AuditLogFilter {
return &AuditLogFilter{NewListFilter()}
return &AuditLogFilter{
ListFilter: NewListFilter(),
customWhere: []whereClause{},
}
}
func (a *AuditLogFilter) UserID(id int) *AuditLogFilter {
a.Add("al.user_id", id)
a.Add("al.user_id", "=", id)
return a
}
func (a *AuditLogFilter) Action(action string) *AuditLogFilter {
a.Add("al.action", action)
a.Add("al.action", "=", action)
return a
}
func (a *AuditLogFilter) ResourceType(resourceType string) *AuditLogFilter {
a.Add("al.resource_type", resourceType)
a.Add("al.resource_type", "=", resourceType)
return a
}
func (a *AuditLogFilter) Result(result string) *AuditLogFilter {
a.Add("al.result", result)
a.Add("al.result", "=", result)
return a
}
func (a *AuditLogFilter) DateRange(start, end int64) *AuditLogFilter {
if start > 0 {
a.Add("al.created_at", ">=", start)
}
if end > 0 {
a.Add("al.created_at", "<=", end)
}
return a
}
@@ -75,10 +94,17 @@ func GetAuditLogs(ctx context.Context, tx bun.Tx, pageOpts *PageOpts, filters *A
Order: bun.OrderDesc,
OrderBy: "created_at",
}
return GetList[AuditLog](tx).
lg := GetList[AuditLog](tx).
Relation("User").
Filter(filters.filters...).
GetPaged(ctx, pageOpts, defaultPageOpts)
Filter(filters.filters...)
// Apply custom where clauses (e.g., date range)
for _, clause := range filters.customWhere {
lg = lg.Where(clause.query, clause.args...)
}
return lg.GetPaged(ctx, pageOpts, defaultPageOpts)
}
// GetAuditLogsByUser retrieves audit logs for a specific user
@@ -101,6 +127,57 @@ func GetAuditLogsByAction(ctx context.Context, tx bun.Tx, action string, pageOpt
return GetAuditLogs(ctx, tx, pageOpts, filters)
}
// GetAuditLogByID retrieves a single audit log by ID
func GetAuditLogByID(ctx context.Context, tx bun.Tx, id int) (*AuditLog, error) {
if id <= 0 {
return nil, errors.New("id must be positive")
}
log := new(AuditLog)
err := tx.NewSelect().
Model(log).
Relation("User").
Where("al.id = ?", id).
Scan(ctx)
if err != nil {
if err.Error() == "sql: no rows in result set" {
return nil, nil
}
return nil, errors.Wrap(err, "tx.NewSelect")
}
return log, nil
}
// GetUniqueActions retrieves a list of all unique actions in the audit log
func GetUniqueActions(ctx context.Context, tx bun.Tx) ([]string, error) {
var actions []string
err := tx.NewSelect().
Model((*AuditLog)(nil)).
Column("action").
Distinct().
Order("action ASC").
Scan(ctx, &actions)
if err != nil {
return nil, errors.Wrap(err, "tx.NewSelect")
}
return actions, nil
}
// GetUniqueResourceTypes retrieves a list of all unique resource types in the audit log
func GetUniqueResourceTypes(ctx context.Context, tx bun.Tx) ([]string, error) {
var resourceTypes []string
err := tx.NewSelect().
Model((*AuditLog)(nil)).
Column("resource_type").
Distinct().
Order("resource_type ASC").
Scan(ctx, &resourceTypes)
if err != nil {
return nil, errors.Wrap(err, "tx.NewSelect")
}
return resourceTypes, nil
}
// CleanupOldAuditLogs deletes audit logs older than the specified timestamp
func CleanupOldAuditLogs(ctx context.Context, tx bun.Tx, olderThan int64) (int, error) {
result, err := tx.NewDelete().