167 lines
4.2 KiB
Go
167 lines
4.2 KiB
Go
package mysql
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"gorm.io/gorm"
|
|
|
|
"wucher/internal/domain/audit"
|
|
)
|
|
|
|
type AuditRepository struct {
|
|
db *gorm.DB
|
|
}
|
|
|
|
func NewAuditRepository(db *gorm.DB) *AuditRepository {
|
|
return &AuditRepository{db: db}
|
|
}
|
|
|
|
func (r *AuditRepository) Create(ctx context.Context, entry *audit.AuditLog) error {
|
|
return r.db.WithContext(ctx).Create(entry).Error
|
|
}
|
|
|
|
func (r *AuditRepository) List(ctx context.Context, filter string, methods []string, modules []string, actions []string, sort string, limit, offset int) ([]audit.AuditLog, int64, error) {
|
|
q := r.db.WithContext(ctx).Model(&audit.AuditLog{})
|
|
filter = strings.TrimSpace(filter)
|
|
if filter != "" {
|
|
like := "%" + strings.ToLower(filter) + "%"
|
|
q = q.Where(
|
|
`LOWER(request_id) LIKE ? OR LOWER(layer) LIKE ? OR LOWER(action) LIKE ? OR LOWER(method) LIKE ? OR LOWER(path) LIKE ? OR LOWER(message) LIKE ?`,
|
|
like, like, like, like, like, like,
|
|
)
|
|
}
|
|
if len(methods) > 0 {
|
|
q = q.Where("UPPER(method) IN ?", methods)
|
|
}
|
|
if len(modules) > 0 {
|
|
pathPrefixes := modulePathPrefixes(modules)
|
|
if len(pathPrefixes) == 0 {
|
|
q = q.Where("LOWER(module) IN ?", modules)
|
|
} else {
|
|
pathConds := make([]string, 0, len(pathPrefixes))
|
|
pathArgs := make([]any, 0, len(pathPrefixes))
|
|
for _, prefix := range pathPrefixes {
|
|
pathConds = append(pathConds, "LOWER(path) LIKE ?")
|
|
pathArgs = append(pathArgs, strings.ToLower(prefix)+"%")
|
|
}
|
|
cond := fmt.Sprintf("(LOWER(module) IN ? OR ((module IS NULL OR module = '') AND (%s)))", strings.Join(pathConds, " OR "))
|
|
args := make([]any, 0, 2+len(pathArgs))
|
|
args = append(args, modules)
|
|
args = append(args, pathArgs...)
|
|
q = q.Where(cond, args...)
|
|
}
|
|
}
|
|
if len(actions) > 0 {
|
|
q = q.Where("LOWER(action) IN ?", actions)
|
|
}
|
|
|
|
var total int64
|
|
if err := q.Count(&total).Error; err != nil {
|
|
return nil, 0, err
|
|
}
|
|
|
|
if strings.TrimSpace(sort) == "" {
|
|
sort = "created_at DESC"
|
|
}
|
|
if limit < 0 {
|
|
limit = 0
|
|
}
|
|
if limit > 200 {
|
|
limit = 200
|
|
}
|
|
if offset < 0 {
|
|
offset = 0
|
|
}
|
|
|
|
var out []audit.AuditLog
|
|
query := q.Order(sort)
|
|
if limit > 0 {
|
|
query = query.Limit(limit).Offset(offset)
|
|
}
|
|
if err := query.Find(&out).Error; err != nil {
|
|
return nil, 0, err
|
|
}
|
|
return out, total, nil
|
|
}
|
|
|
|
func modulePathPrefixes(modules []string) []string {
|
|
seen := map[string]struct{}{}
|
|
out := make([]string, 0, len(modules))
|
|
for _, module := range modules {
|
|
var prefix string
|
|
switch strings.ToLower(strings.TrimSpace(module)) {
|
|
case "air_rescuer_checklist":
|
|
prefix = "/api/v1/air-rescuer-checklist/"
|
|
case "audit_log":
|
|
prefix = "/api/v1/audit-logs/"
|
|
case "auth":
|
|
prefix = "/api/v1/auth/"
|
|
case "base":
|
|
prefix = "/api/v1/bases/"
|
|
case "branding":
|
|
prefix = "/api/v1/branding/"
|
|
case "contact":
|
|
prefix = "/api/v1/contacts/"
|
|
case "duty_roster":
|
|
prefix = "/api/v1/duty-roster/"
|
|
case "dul":
|
|
prefix = "/api/v1/dul/"
|
|
case "facility":
|
|
prefix = "/api/v1/facilities/"
|
|
case "federal_state":
|
|
prefix = "/api/v1/federal-state/"
|
|
case "file_manager":
|
|
prefix = "/api/v1/file-manager/"
|
|
case "flight_data":
|
|
prefix = "/api/v1/flight-data/"
|
|
case "flight":
|
|
prefix = "/api/v1/flights/"
|
|
case "forces_present":
|
|
prefix = "/api/v1/forces-present/"
|
|
case "health_insurance_company":
|
|
prefix = "/api/v1/health-insurance-companies/"
|
|
case "helicopter_file":
|
|
prefix = "/api/v1/helicopter-files/"
|
|
case "helicopter":
|
|
prefix = "/api/v1/helicopters/"
|
|
case "hospital":
|
|
prefix = "/api/v1/hospital/"
|
|
case "icao":
|
|
prefix = "/api/v1/icao/"
|
|
case "insurance_patient_data":
|
|
prefix = "/api/v1/insurance-patient-data/"
|
|
case "land":
|
|
prefix = "/api/v1/land/"
|
|
case "master_setting":
|
|
prefix = "/api/v1/master-settings/"
|
|
case "medicine":
|
|
prefix = "/api/v1/medicine/"
|
|
case "mission":
|
|
prefix = "/api/v1/mission/"
|
|
case "opc":
|
|
prefix = "/api/v1/opc/"
|
|
case "patient_data":
|
|
prefix = "/api/v1/patient-data/"
|
|
case "reserve_ac":
|
|
prefix = "/api/v1/reserve-acs/"
|
|
case "role":
|
|
prefix = "/api/v1/roles/"
|
|
case "user":
|
|
prefix = "/api/v1/users/"
|
|
case "vocation":
|
|
prefix = "/api/v1/vocation/"
|
|
}
|
|
if prefix == "" {
|
|
continue
|
|
}
|
|
if _, ok := seen[prefix]; ok {
|
|
continue
|
|
}
|
|
seen[prefix] = struct{}{}
|
|
out = append(out, prefix)
|
|
}
|
|
return out
|
|
}
|