Yimaru-BackEnd/internal/repository/activity_logs.go

148 lines
4.0 KiB
Go

package repository
import (
dbgen "Yimaru-Backend/gen/db"
"Yimaru-Backend/internal/domain"
"context"
"encoding/json"
"github.com/jackc/pgx/v5/pgtype"
)
func (s *Store) CreateActivityLog(ctx context.Context, log domain.ActivityLog) (domain.ActivityLog, error) {
var actorID, resourceID pgtype.Int8
var actorRole, message, ipAddress, userAgent pgtype.Text
if log.ActorID != nil {
actorID = pgtype.Int8{Int64: *log.ActorID, Valid: true}
}
if log.ResourceID != nil {
resourceID = pgtype.Int8{Int64: *log.ResourceID, Valid: true}
}
if log.ActorRole != nil {
actorRole = pgtype.Text{String: *log.ActorRole, Valid: true}
}
if log.Message != nil {
message = pgtype.Text{String: *log.Message, Valid: true}
}
if log.IPAddress != nil {
ipAddress = pgtype.Text{String: *log.IPAddress, Valid: true}
}
if log.UserAgent != nil {
userAgent = pgtype.Text{String: *log.UserAgent, Valid: true}
}
var metadata interface{}
if log.Metadata != nil {
metadata = log.Metadata
}
row, err := s.queries.CreateActivityLog(ctx, dbgen.CreateActivityLogParams{
ActorID: actorID,
ActorRole: actorRole,
Action: log.Action,
ResourceType: log.ResourceType,
ResourceID: resourceID,
Message: message,
Metadata: metadata,
IpAddress: ipAddress,
UserAgent: userAgent,
})
if err != nil {
return domain.ActivityLog{}, err
}
return mapActivityLogRow(row), nil
}
func (s *Store) ListActivityLogs(ctx context.Context, filter domain.ActivityLogFilter) ([]domain.ActivityLog, int64, error) {
var filterActorID, filterResourceID pgtype.Int8
var filterAction, filterResourceType pgtype.Text
var filterAfter, filterBefore pgtype.Timestamptz
if filter.ActorID != nil {
filterActorID = pgtype.Int8{Int64: *filter.ActorID, Valid: true}
}
if filter.ResourceID != nil {
filterResourceID = pgtype.Int8{Int64: *filter.ResourceID, Valid: true}
}
if filter.Action != nil {
filterAction = pgtype.Text{String: *filter.Action, Valid: true}
}
if filter.ResourceType != nil {
filterResourceType = pgtype.Text{String: *filter.ResourceType, Valid: true}
}
if filter.After != nil {
filterAfter = pgtype.Timestamptz{Time: *filter.After, Valid: true}
}
if filter.Before != nil {
filterBefore = pgtype.Timestamptz{Time: *filter.Before, Valid: true}
}
rows, err := s.queries.ListActivityLogs(ctx, dbgen.ListActivityLogsParams{
FilterActorID: filterActorID,
FilterAction: filterAction,
FilterResourceType: filterResourceType,
FilterResourceID: filterResourceID,
FilterAfter: filterAfter,
FilterBefore: filterBefore,
LogOffset: filter.Offset,
LogLimit: filter.Limit,
})
if err != nil {
return nil, 0, err
}
var (
logs []domain.ActivityLog
totalCount int64
)
for i, row := range rows {
if i == 0 {
totalCount = row.TotalCount
}
logs = append(logs, domain.ActivityLog{
ID: row.ID,
ActorID: ptrInt64(row.ActorID),
ActorRole: ptrString(row.ActorRole),
Action: row.Action,
ResourceType: row.ResourceType,
ResourceID: ptrInt64(row.ResourceID),
Message: ptrString(row.Message),
Metadata: json.RawMessage(row.Metadata),
IPAddress: ptrString(row.IpAddress),
UserAgent: ptrString(row.UserAgent),
CreatedAt: row.CreatedAt.Time,
})
}
return logs, totalCount, nil
}
func (s *Store) GetActivityLogByID(ctx context.Context, id int64) (domain.ActivityLog, error) {
row, err := s.queries.GetActivityLogByID(ctx, id)
if err != nil {
return domain.ActivityLog{}, err
}
return mapActivityLogRow(row), nil
}
func mapActivityLogRow(row dbgen.ActivityLog) domain.ActivityLog {
return domain.ActivityLog{
ID: row.ID,
ActorID: ptrInt64(row.ActorID),
ActorRole: ptrString(row.ActorRole),
Action: row.Action,
ResourceType: row.ResourceType,
ResourceID: ptrInt64(row.ResourceID),
Message: ptrString(row.Message),
Metadata: json.RawMessage(row.Metadata),
IPAddress: ptrString(row.IpAddress),
UserAgent: ptrString(row.UserAgent),
CreatedAt: row.CreatedAt.Time,
}
}