File size: 9,640 Bytes
3dd5c9a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using TaskTrackingSystem.Database.AppDbContextModels;
using TaskTrackingSystem.Shared;
using TaskTrackingSystem.Shared.Models.AuditLog;
using TaskTrackingSystem.WebApi.Infrastructure;

namespace TaskTrackingSystem.WebApi.Features.Audit
{
    [Route("api/[controller]")]
    [ApiController]
    [Authorize]
    public class AuditLogController : ControllerBase
    {
        private readonly AppDbContext _db;
        private readonly PermissionAuthorizationService _permissionAuthorizationService;

        public AuditLogController(AppDbContext db, PermissionAuthorizationService permissionAuthorizationService)
        {
            _db = db;
            _permissionAuthorizationService = permissionAuthorizationService;
        }

        [HttpGet]
        [ProducesResponseType(typeof(PagedResult<AuditLogDto>), StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status401Unauthorized)]
        public async Task<ActionResult> GetAuditLogs(
            [FromQuery] string? search,
            [FromQuery] PaginationQuery? paging = null)
        {
            if (!await _permissionAuthorizationService.CanAccessAsync(User, "api/AuditLog", "List"))
            {
                return Forbid();
            }

            var query = _db.AuditLogs
                .Include(a => a.User)
                .AsQueryable();

            if (!string.IsNullOrWhiteSpace(search))
            {
                var searchTerm = search.Trim();
                var searchPattern = $"%{searchTerm}%";
                var normalizedSearch = searchTerm.Replace(" ", string.Empty, StringComparison.Ordinal)
                    .ToLowerInvariant();
                var searchModuleLabel = normalizedSearch is "module" or "အပိုင်း";
                var searchActionLabel = normalizedSearch is "actions" or "လုပ်ဆောင်ချက်များ";
                var searchRoleModule = normalizedSearch.Contains("role", StringComparison.Ordinal) ||
                                       searchTerm.Contains("အခန်းကဏ္ဍ", StringComparison.Ordinal);
                var searchProjectModule = normalizedSearch.Contains("project", StringComparison.Ordinal) ||
                                          searchTerm.Contains("စီမံကိန်း", StringComparison.Ordinal);
                var searchTaskModule = normalizedSearch.Contains("task", StringComparison.Ordinal) ||
                                       searchTerm.Contains("လုပ်ငန်း", StringComparison.Ordinal);
                var searchUserModule = normalizedSearch.Contains("user", StringComparison.Ordinal) ||
                                       searchTerm.Contains("အသုံးပြုသူ", StringComparison.Ordinal);
                var searchIssueModule = normalizedSearch.Contains("issue", StringComparison.Ordinal) ||
                                        searchTerm.Contains("ပြဿနာ", StringComparison.Ordinal);
                var searchAuditModule = normalizedSearch.Contains("audit", StringComparison.Ordinal) ||
                                        searchTerm.Contains("မှတ်တမ်း", StringComparison.Ordinal);
                var searchDashboardModule = normalizedSearch.Contains("dashboard", StringComparison.Ordinal) ||
                                            searchTerm.Contains("ပင်မစာမျက်နှာ", StringComparison.Ordinal);
                var searchReportModule = normalizedSearch.Contains("report", StringComparison.Ordinal) ||
                                         searchTerm.Contains("အစီရင်ခံစာ", StringComparison.Ordinal);
                var searchCreateAction = normalizedSearch is "create" or "created" or "add" or "added" ||
                                         searchTerm.Contains("ဖန်တီး", StringComparison.Ordinal);
                var searchUpdateAction = normalizedSearch is "update" or "updated" or "edit" or "edited" ||
                                         searchTerm.Contains("အပ်ဒိတ်", StringComparison.Ordinal);
                var searchDeleteAction = normalizedSearch is "delete" or "deleted" ||
                                         searchTerm.Contains("ဖျက်", StringComparison.Ordinal);
                var searchAssignAction = normalizedSearch is "assign" or "assigned" or "assignaccess" ||
                                         searchTerm.Contains("ခွဲဝေ", StringComparison.Ordinal);
                query = query.Where(a => 
                    EF.Functions.ILike(a.Action ?? string.Empty, searchPattern) ||
                    EF.Functions.ILike(a.Module ?? string.Empty, searchPattern) ||
                    EF.Functions.ILike(a.Description ?? string.Empty, searchPattern) ||
                    (searchModuleLabel && a.Module != null) ||
                    (searchActionLabel && a.Action != null) ||
                    (searchRoleModule && EF.Functions.ILike(a.Module ?? string.Empty, "%role%")) ||
                    (searchProjectModule && EF.Functions.ILike(a.Module ?? string.Empty, "%project%")) ||
                    (searchTaskModule && EF.Functions.ILike(a.Module ?? string.Empty, "%task%")) ||
                    (searchUserModule && EF.Functions.ILike(a.Module ?? string.Empty, "%user%")) ||
                    (searchIssueModule && EF.Functions.ILike(a.Module ?? string.Empty, "%issue%")) ||
                    (searchAuditModule && EF.Functions.ILike(a.Module ?? string.Empty, "%audit%")) ||
                    (searchDashboardModule && EF.Functions.ILike(a.Module ?? string.Empty, "%dashboard%")) ||
                    (searchReportModule && EF.Functions.ILike(a.Module ?? string.Empty, "%report%")) ||
                    (searchCreateAction && EF.Functions.ILike(a.Action ?? string.Empty, "%create%")) ||
                    (searchUpdateAction && EF.Functions.ILike(a.Action ?? string.Empty, "%update%")) ||
                    (searchDeleteAction && EF.Functions.ILike(a.Action ?? string.Empty, "%delete%")) ||
                    (searchAssignAction && EF.Functions.ILike(a.Action ?? string.Empty, "%assign%")) ||
                    (a.User != null &&
                        (EF.Functions.ILike(a.User.Username ?? string.Empty, searchPattern) ||
                         EF.Functions.ILike(a.User.FirstName ?? string.Empty, searchPattern) ||
                         EF.Functions.ILike(a.User.LastName ?? string.Empty, searchPattern) ||
                         EF.Functions.ILike((a.User.FirstName ?? string.Empty) + " " + (a.User.LastName ?? string.Empty), searchPattern) ||
                         EF.Functions.ILike((a.User.FirstName ?? string.Empty) + (a.User.LastName ?? string.Empty), searchPattern) ||
                         EF.Functions.ILike(a.User.FirstNameMy ?? string.Empty, searchPattern) ||
                         EF.Functions.ILike(a.User.LastNameMy ?? string.Empty, searchPattern) ||
                         EF.Functions.ILike((a.User.FirstNameMy ?? string.Empty) + " " + (a.User.LastNameMy ?? string.Empty), searchPattern) ||
                         EF.Functions.ILike((a.User.FirstNameMy ?? string.Empty) + (a.User.LastNameMy ?? string.Empty), searchPattern))) ||
                    EF.Functions.ILike(a.IpAddress ?? string.Empty, searchPattern)
                );
            }

            if (paging == null || (!paging.Page.HasValue && !paging.Limit.HasValue))
            {
                var fullLogs = await query
                    .OrderByDescending(a => a.CreatedAt)
                    .Select(a => new AuditLogDto
                    {
                        Id = a.Id,
                        UserId = a.UserId,
                        Username = a.User != null ? a.User.Username : "System",
                        UserFullName = a.User != null ? $"{a.User.FirstName} {a.User.LastName}" : "System",
                        UserFullNameMy = a.User != null ? $"{a.User.FirstNameMy} {a.User.LastNameMy}" : null,
                        Action = a.Action,
                        Module = a.Module,
                        Description = a.Description,
                        IpAddress = a.IpAddress,
                        CreatedAt = a.CreatedAt ?? System.DateTime.UtcNow
                    })
                    .ToListAsync();

                return Ok(fullLogs);
            }

            var page = PaginationExtensions.NormalizePage(paging.Page);
            var limit = PaginationExtensions.NormalizePageSize(paging.Limit ?? 0);

            var pagedLogs = await query
                .OrderByDescending(a => a.CreatedAt)
                .Select(a => new AuditLogDto
                {
                    Id = a.Id,
                    UserId = a.UserId,
                    Username = a.User != null ? a.User.Username : "System",
                    UserFullName = a.User != null ? $"{a.User.FirstName} {a.User.LastName}" : "System",
                    UserFullNameMy = a.User != null ? $"{a.User.FirstNameMy} {a.User.LastNameMy}" : null,
                    Action = a.Action,
                    Module = a.Module,
                    Description = a.Description,
                    IpAddress = a.IpAddress,
                    CreatedAt = a.CreatedAt ?? System.DateTime.UtcNow
                })
                .ToPagedResultAsync(page, limit);

            return Ok(pagedLogs);
        }
    }
}