KIM-JINO5 4 luni în urmă
părinte
comite
c0991e33b5
64 a modificat fișierele cu 727 adăugiri și 381 ștergeri
  1. 1 0
      Admin/Admin.csproj
  2. 11 12
      Admin/Pages/Config/Basic.cshtml.cs
  3. 17 22
      Admin/Pages/Config/Company.cshtml.cs
  4. 12 13
      Admin/Pages/Config/External.cshtml.cs
  5. 12 14
      Admin/Pages/Config/Images.cshtml.cs
  6. 12 15
      Admin/Pages/Config/Meta.cshtml.cs
  7. 11 12
      Admin/Pages/Config/Register.cshtml.cs
  8. 12 13
      Admin/Pages/Config/Template/Email.cshtml.cs
  9. 11 19
      Admin/Pages/Config/Test/Email.cshtml.cs
  10. 5 8
      Admin/Pages/Director/Role/Index.cshtml.cs
  11. 3 5
      Admin/Pages/Director/Role/Permission.cshtml.cs
  12. 5 7
      Admin/Pages/Director/User/Edit.cshtml.cs
  13. 3 4
      Admin/Pages/Director/User/Index.cshtml.cs
  14. 1 1
      Admin/Pages/Director/User/Roles.cshtml
  15. 3 5
      Admin/Pages/Director/User/Roles.cshtml.cs
  16. 12 0
      Admin/using.cs
  17. 1 1
      Application/Application.csproj
  18. 0 27
      Application/Features/Config/Commands/UpdateConfigCommand.cs
  19. 13 13
      Application/Features/Config/Get/Handler.cs
  20. 6 0
      Application/Features/Config/Get/Query.cs
  21. 2 67
      Application/Features/Config/Get/Response.cs
  22. 0 6
      Application/Features/Config/Queries/GetConfigQuery.cs
  23. 27 0
      Application/Features/Config/Update/Command.cs
  24. 6 6
      Application/Features/Config/Update/Handler.cs
  25. 432 0
      Application/Features/Config/Update/Request.cs
  26. 0 6
      Application/Features/Director/CreateRole/Command.cs
  27. 0 6
      Application/Features/Director/DeleteRole/Command.cs
  28. 0 6
      Application/Features/Director/GetRolePermissions/Query.cs
  29. 0 6
      Application/Features/Director/GetRoles/Query.cs
  30. 0 7
      Application/Features/Director/GetUser/Query.cs
  31. 0 6
      Application/Features/Director/GetUserRoles/Query.cs
  32. 0 6
      Application/Features/Director/GetUsers/Query.cs
  33. 6 0
      Application/Features/Director/Role/Create/Command.cs
  34. 3 3
      Application/Features/Director/Role/Create/Handler.cs
  35. 6 0
      Application/Features/Director/Role/Delete/Command.cs
  36. 3 3
      Application/Features/Director/Role/Delete/Handler.cs
  37. 3 3
      Application/Features/Director/Role/Permissions/Get/Handler.cs
  38. 6 0
      Application/Features/Director/Role/Permissions/Get/Query.cs
  39. 1 1
      Application/Features/Director/Role/Permissions/Get/Response.cs
  40. 2 2
      Application/Features/Director/Role/Permissions/Update/Command.cs
  41. 3 3
      Application/Features/Director/Role/Permissions/Update/Handler.cs
  42. 3 3
      Application/Features/Director/Roles/Get/Handler.cs
  43. 6 0
      Application/Features/Director/Roles/Get/Query.cs
  44. 1 1
      Application/Features/Director/Roles/Get/Response.cs
  45. 3 3
      Application/Features/Director/User/Get/Handler.cs
  46. 7 0
      Application/Features/Director/User/Get/Query.cs
  47. 1 1
      Application/Features/Director/User/Get/Response.cs
  48. 3 3
      Application/Features/Director/User/GetRoles/Handler.cs
  49. 6 0
      Application/Features/Director/User/GetRoles/Query.cs
  50. 1 1
      Application/Features/Director/User/GetRoles/Response.cs
  51. 2 2
      Application/Features/Director/User/Update/Command.cs
  52. 3 3
      Application/Features/Director/User/Update/Handler.cs
  53. 2 2
      Application/Features/Director/User/UpdateRoles/Command.cs
  54. 3 3
      Application/Features/Director/User/UpdateRoles/Handler.cs
  55. 3 3
      Application/Features/Director/Users/Get/Handler.cs
  56. 6 0
      Application/Features/Director/Users/Get/Query.cs
  57. 1 1
      Application/Features/Director/Users/Get/Response.cs
  58. 0 4
      Application/Features/ReferenceData/Dtos/BankCodeDto.cs
  59. 15 0
      Application/Features/ReferenceData/GetBank/Handler.cs
  60. 6 0
      Application/Features/ReferenceData/GetBank/Query.cs
  61. 4 0
      Application/Features/ReferenceData/GetBank/Response.cs
  62. 0 7
      Application/Features/ReferenceData/Queries/GetBankCodesQuery.cs
  63. 0 16
      Application/Features/ReferenceData/Queries/GetBankCodesQueryHandler.cs
  64. BIN
      tree.txt

+ 1 - 0
Admin/Admin.csproj

@@ -33,6 +33,7 @@
 
   <ItemGroup>
     <Folder Include="Middleware\" />
+    <Folder Include="Pages\Document\" />
     <Folder Include="wwwroot\uploads\basic\" />
   </ItemGroup>
 

+ 11 - 12
Admin/Pages/Config/Basic.cshtml.cs

@@ -1,7 +1,4 @@
-using Application.Features.Config;
-using Application.Features.Config.Commands;
-using Application.Features.Config.Queries;
-using MediatR;
+using MediatR;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.Mvc.RazorPages;
 
@@ -12,40 +9,42 @@ namespace Admin.Pages.Config
         [BindProperty]
         public InputModel Input { get; set; } = new();
 
-        public async Task OnGetAsync(CancellationToken cancellationToken)
+        public async Task OnGetAsync(CancellationToken ct)
         {
-            var config = await mediator.Send(new GetConfigQuery(), cancellationToken);
+            var config = await mediator.Send(new GetConfig.Query(), ct);
             if (config is not null)
             {
                 Input = InputModel.From(config);
             }
         }
 
-        public async Task<IActionResult> OnPostAsync(CancellationToken cancellationToken)
+        public async Task<IActionResult> OnPostAsync(CancellationToken ct)
         {
             if (!ModelState.IsValid)
             {
                 return Page();
             }
 
-            await mediator.Send(Input.ToCommand(), cancellationToken);
+            await mediator.Send(Input.ToCommand(), ct);
 
             return RedirectToPage();
         }
 
         public sealed class InputModel
         {
-            public ConfigDto.BasicConfigDto Basic { get; set; } = new();
+            public UpdateConfig.Request.BasicConfigDto Basic { get; set; } = new();
 
-            public static InputModel From(ConfigDto config)
+            public static InputModel From(GetConfig.Response config)
             {
+                var req = UpdateConfig.Request.From(config);
+
                 return new()
                 {
-                    Basic = config.Basic
+                    Basic = req.Basic
                 };
             }
 
-            public UpdateConfigCommand ToCommand()
+            public UpdateConfig.Command ToCommand()
             {
                 return new(
                     Basic

+ 17 - 22
Admin/Pages/Config/Company.cshtml.cs

@@ -1,8 +1,4 @@
-using Application.Features.Config;
-using Application.Features.Config.Commands;
-using Application.Features.Config.Queries;
-using Application.Features.ReferenceData.Dtos;
-using Application.Features.ReferenceData.Queries;
+using GetBank = Application.Features.ReferenceData.GetBank;
 using MediatR;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.Mvc.RazorPages;
@@ -14,57 +10,56 @@ namespace Admin.Pages.Config
         [BindProperty]
         public InputModel Input { get; set; } = new();
 
-        public IReadOnlyList<BankCodeDto> BankCodes { get; set; } = [];
+        public IReadOnlyList<GetBank.Response> BankCodes { get; set; } = [];
 
-        private async Task BindBankCodesAsync(CancellationToken cancellationToken)
+        private async Task BindBankCodesAsync(CancellationToken ct)
         {
-            BankCodes = await mediator.Send(new GetBankCodesQuery(), cancellationToken);
+            BankCodes = await mediator.Send(new GetBank.Query(), ct);
         }
 
-        public async Task OnGetAsync(CancellationToken cancellationToken)
+        public async Task OnGetAsync(CancellationToken ct)
         {
-            await BindBankCodesAsync(cancellationToken);
+            await BindBankCodesAsync(ct);
 
-            var config = await mediator.Send(new GetConfigQuery(), cancellationToken);
+            var config = await mediator.Send(new GetConfig.Query(), ct);
             if (config is not null)
             {
                 Input = InputModel.From(config);
             }
         }
 
-        public async Task<IActionResult> OnPostAsync(CancellationToken cancellationToken)
+        public async Task<IActionResult> OnPostAsync(CancellationToken ct)
         {
-            await BindBankCodesAsync(cancellationToken);
+            await BindBankCodesAsync(ct);
 
             if (!ModelState.IsValid)
             {
                 return Page();
             }
 
-            await mediator.Send(Input.ToCommand(), cancellationToken);
+            await mediator.Send(Input.ToCommand(), ct);
 
             return RedirectToPage();
         }
 
         public sealed class InputModel
         {
-            public ConfigDto.CompanyConfigDto Company { get; set; } = new();
+            public UpdateConfig.Request.CompanyConfigDto Company { get; set; } = new();
 
-            public static InputModel From(ConfigDto config)
+            public static InputModel From(GetConfig.Response config)
             {
+                var req = UpdateConfig.Request.From(config);
+
                 return new()
                 {
-                    Company = config.Company
+                    Company = req.Company
                 };
             }
 
-            public UpdateConfigCommand ToCommand()
+            public UpdateConfig.Command ToCommand()
             {
                 return new(
-                    null,
-                    null,
-                    null,
-                    Company
+                    Company: Company
                 );
             }
         }

+ 12 - 13
Admin/Pages/Config/External.cshtml.cs

@@ -1,7 +1,4 @@
-using Application.Features.Config;
-using Application.Features.Config.Commands;
-using Application.Features.Config.Queries;
-using MediatR;
+using MediatR;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.Mvc.RazorPages;
 
@@ -12,43 +9,45 @@ namespace Admin.Pages.Config
         [BindProperty]
         public InputModel Input { get; set; } = new();
 
-        public async Task OnGetAsync(CancellationToken cancellationToken)
+        public async Task OnGetAsync(CancellationToken ct)
         {
-            var config = await mediator.Send(new GetConfigQuery(), cancellationToken);
+            var config = await mediator.Send(new GetConfig.Query(), ct);
             if (config is not null)
             {
                 Input = InputModel.From(config);
             }
         }
 
-        public async Task<IActionResult> OnPostAsync(CancellationToken cancellationToken)
+        public async Task<IActionResult> OnPostAsync(CancellationToken ct)
         {
             if (!ModelState.IsValid)
             {
                 return Page();
             }
 
-            await mediator.Send(Input.ToCommand(), cancellationToken);
+            await mediator.Send(Input.ToCommand(), ct);
 
             return RedirectToPage();
         }
 
         public sealed class InputModel
         {
-            public ConfigDto.ExternalApiConfigDto External { get; set; } = new();
+            public UpdateConfig.Request.ExternalApiConfigDto External { get; set; } = new();
 
-            public static InputModel From(ConfigDto config)
+            public static InputModel From(GetConfig.Response config)
             {
+                var req = UpdateConfig.Request.From(config);
+
                 return new()
                 {
-                    External = config.External
+                    External = req.External
                 };
             }
 
-            public UpdateConfigCommand ToCommand()
+            public UpdateConfig.Command ToCommand()
             {
                 return new(
-                    External : External
+                    External: External
                 );
             }
         }

+ 12 - 14
Admin/Pages/Config/Images.cshtml.cs

@@ -1,6 +1,3 @@
-using Application.Features.Config.Commands;
-using Application.Features.Config.Queries;
-using Application.Features.Config;
 using MediatR;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.Mvc.RazorPages;
@@ -12,44 +9,46 @@ public sealed class ImagesModel(IMediator mediator) : PageModel
     [BindProperty]
     public InputModel Input { get; set; } = new();
 
-    public async Task OnGetAsync(CancellationToken cancellationToken)
+    public async Task OnGetAsync(CancellationToken ct)
     {
-        var config = await mediator.Send(new GetConfigQuery(), cancellationToken);
+        var config = await mediator.Send(new GetConfig.Query(), ct);
         if (config is not null)
         {
             Input = InputModel.From(config);
         }
     }
 
-    public async Task<IActionResult> OnPostAsync(CancellationToken cancellationToken)
+    public async Task<IActionResult> OnPostAsync(CancellationToken ct)
     {
         if (!ModelState.IsValid)
         {
             return Page();
         }
 
-        await mediator.Send(Input.ToCommand(Request), cancellationToken);
+        await mediator.Send(Input.ToCommand(Request), ct);
 
         return RedirectToPage();
     }
 
     public sealed class InputModel
     {
-        public ConfigDto.ImagesConfigDto Images { get; set; } = new();
+        public UpdateConfig.Request.ImagesConfigDto Images { get; set; } = new();
 
-        public static InputModel From(ConfigDto config)
+        public static InputModel From(GetConfig.Response config)
         {
+            var req = UpdateConfig.Request.From(config);
+
             return new()
             {
-                Images = config.Images
+                Images = req.Images
             };
         }
 
-        public UpdateConfigCommand ToCommand(HttpRequest request)
+        public UpdateConfig.Command ToCommand(HttpRequest request)
         {
             bool IsChecked(string key) => request.Form.TryGetValue(key, out var v) && v.Count > 0;
 
-            var delete = new UpdateConfigCommand.ImagesDeleteFlags(
+            var delete = new UpdateConfig.Command.ImagesDeleteFlags(
                 Favicon: IsChecked("delete_favicon"),
                 LogoSquare: IsChecked("delete_logo_square"),
                 LogoHorizontal: IsChecked("delete_logo_horizontal"),
@@ -61,8 +60,7 @@ public sealed class ImagesModel(IMediator mediator) : PageModel
             );
 
             return new(
-                null,
-                Images,
+                Images: Images,
                 ImagesDelete: delete
             );
         }

+ 12 - 15
Admin/Pages/Config/Meta.cshtml.cs

@@ -1,7 +1,4 @@
-using Application.Features.Config;
-using Application.Features.Config.Commands;
-using Application.Features.Config.Queries;
-using MediatR;
+using MediatR;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.Mvc.RazorPages;
 
@@ -12,45 +9,45 @@ namespace Admin.Pages.Config
         [BindProperty]
         public InputModel Input { get; set; } = new();
 
-        public async Task OnGetAsync(CancellationToken cancellationToken)
+        public async Task OnGetAsync(CancellationToken ct)
         {
-            var config = await mediator.Send(new GetConfigQuery(), cancellationToken);
+            var config = await mediator.Send(new GetConfig.Query(), ct);
             if (config is not null)
             {
                 Input = InputModel.From(config);
             }
         }
 
-        public async Task<IActionResult> OnPostAsync(CancellationToken cancellationToken)
+        public async Task<IActionResult> OnPostAsync(CancellationToken ct)
         {
             if (!ModelState.IsValid)
             {
                 return Page();
             }
 
-            await mediator.Send(Input.ToCommand(), cancellationToken);
+            await mediator.Send(Input.ToCommand(), ct);
 
             return RedirectToPage();
         }
 
         public sealed class InputModel
         {
-            public ConfigDto.MetaConfigDto Meta { get; set; } = new();
+            public UpdateConfig.Request.MetaConfigDto Meta { get; set; } = new();
 
-            public static InputModel From(ConfigDto config)
+            public static InputModel From(GetConfig.Response config)
             {
+                var req = UpdateConfig.Request.From(config);
+
                 return new()
                 {
-                    Meta = config.Meta
+                    Meta = req.Meta
                 };
             }
 
-            public UpdateConfigCommand ToCommand()
+            public UpdateConfig.Command ToCommand()
             {
                 return new(
-                    null,
-                    null,
-                    Meta
+                    Meta: Meta
                 );
             }
         }

+ 11 - 12
Admin/Pages/Config/Register.cshtml.cs

@@ -1,7 +1,4 @@
-using Application.Features.Config;
-using Application.Features.Config.Commands;
-using Application.Features.Config.Queries;
-using MediatR;
+using MediatR;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.Mvc.RazorPages;
 
@@ -12,40 +9,42 @@ namespace Admin.Pages.Config
         [BindProperty]
         public InputModel Input { get; set; } = new();
 
-        public async Task OnGetAsync(CancellationToken cancellationToken)
+        public async Task OnGetAsync(CancellationToken ct)
         {
-            var config = await mediator.Send(new GetConfigQuery(), cancellationToken);
+            var config = await mediator.Send(new GetConfig.Query(), ct);
             if (config is not null)
             {
                 Input = InputModel.From(config);
             }
         }
 
-        public async Task<IActionResult> OnPostAsync(CancellationToken cancellationToken)
+        public async Task<IActionResult> OnPostAsync(CancellationToken ct)
         {
             if (!ModelState.IsValid)
             {
                 return Page();
             }
 
-            await mediator.Send(Input.ToCommand(), cancellationToken);
+            await mediator.Send(Input.ToCommand(), ct);
 
             return RedirectToPage();
         }
 
         public sealed class InputModel
         {
-            public ConfigDto.AccountConfigDto Account { get; set; } = new();
+            public UpdateConfig.Request.AccountConfigDto Account { get; set; } = new();
 
-            public static InputModel From(ConfigDto config)
+            public static InputModel From(GetConfig.Response config)
             {
+                var req = UpdateConfig.Request.From(config);
+
                 return new()
                 {
-                    Account = config.Account
+                    Account = req.Account
                 };
             }
 
-            public UpdateConfigCommand ToCommand()
+            public UpdateConfig.Command ToCommand()
             {
                 return new(
                     Account: Account

+ 12 - 13
Admin/Pages/Config/Template/Email.cshtml.cs

@@ -1,7 +1,4 @@
-using Application.Features.Config;
-using Application.Features.Config.Commands;
-using Application.Features.Config.Queries;
-using MediatR;
+using MediatR;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.Mvc.RazorPages;
 
@@ -12,43 +9,45 @@ namespace Admin.Pages.Config.Template
         [BindProperty]
         public InputModel Input { get; set; } = new();
 
-        public async Task OnGetAsync(CancellationToken cancellationToken)
+        public async Task OnGetAsync(CancellationToken ct)
         {
-            var config = await mediator.Send(new GetConfigQuery(), cancellationToken);
+            var config = await mediator.Send(new GetConfig.Query(), ct);
             if (config is not null)
             {
                 Input = InputModel.From(config);
             }
         }
 
-        public async Task<IActionResult> OnPostAsync(CancellationToken cancellationToken)
+        public async Task<IActionResult> OnPostAsync(CancellationToken ct)
         {
             if (!ModelState.IsValid)
             {
                 return Page();
             }
 
-            await mediator.Send(Input.ToCommand(), cancellationToken);
+            await mediator.Send(Input.ToCommand(), ct);
 
             return RedirectToPage();
         }
 
         public sealed class InputModel
         {
-            public ConfigDto.EmailTemplateConfigDto EmailTemplate { get; set; } = new();
+            public UpdateConfig.Request.EmailTemplateConfigDto EmailTemplate { get; set; } = new();
 
-            public static InputModel From(ConfigDto config)
+            public static InputModel From(GetConfig.Response config)
             {
+                var req = UpdateConfig.Request.From(config);
+
                 return new()
                 {
-                    EmailTemplate = config.EmailTemplate
+                    EmailTemplate = req.EmailTemplate
                 };
             }
 
-            public UpdateConfigCommand ToCommand()
+            public UpdateConfig.Command ToCommand()
             {
                 return new(
-                    EmailTemplate : EmailTemplate
+                    EmailTemplate: EmailTemplate
                 );
             }
         }

+ 11 - 19
Admin/Pages/Config/Test/Email.cshtml.cs

@@ -1,12 +1,9 @@
-using Application.Features.Config;
-using Application.Features.Config.Commands;
-using Application.Features.Config.Queries;
-using Application.Abstractions.Messaging.Email;
+using Application.Abstractions.Messaging.Email;
+using SharedKernel;
 using MediatR;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.Mvc.RazorPages;
 using Microsoft.Extensions.Options;
-using SharedKernel;
 using System.ComponentModel;
 using System.ComponentModel.DataAnnotations;
 
@@ -25,16 +22,16 @@ namespace Admin.Pages.Config.Test
         [BindProperty]
         public InputModel Input { get; set; } = new();
 
-        public async Task OnGetAsync(CancellationToken cancellationToken)
+        public async Task OnGetAsync(CancellationToken ct)
         {
-            var config = await mediator.Send(new GetConfigQuery(), cancellationToken);
+            var config = await mediator.Send(new GetConfig.Query(), ct);
             if (config is not null)
             {
                 Input = InputModel.From(config);
             }
         }
 
-        public async Task<IActionResult> OnPostAsync(CancellationToken cancellationToken)
+        public async Task<IActionResult> OnPostAsync(CancellationToken ct)
         {
             if (!ModelState.IsValid)
             {
@@ -56,7 +53,7 @@ namespace Admin.Pages.Config.Test
                                  """,
                     MessageText: $"TEST MAIL\nFrom={Settings.SMTP.FromEmail}\nTo={ToAddress}\nHost={Settings.SMTP.Host}:{Settings.SMTP.Port}\nTLS={Settings.SMTP.UseStartTls}"
                 ),
-                cancellationToken
+                ct
             );
 
             TempData["SuccessMessage"] = "테스트 이메일을 발송했습니다.";
@@ -66,22 +63,17 @@ namespace Admin.Pages.Config.Test
 
         public sealed class InputModel
         {
-            public ConfigDto.BasicConfigDto Basic { get; set; } = new();
+            public UpdateConfig.Request.BasicConfigDto Basic { get; set; } = new();
 
-            public static InputModel From(ConfigDto config)
+            public static InputModel From(GetConfig.Response config)
             {
+                var req = UpdateConfig.Request.From(config);
+
                 return new()
                 {
-                    Basic = config.Basic
+                    Basic = req.Basic
                 };
             }
-
-            public UpdateConfigCommand ToCommand()
-            {
-                return new(
-                    Basic
-                );
-            }
         }
     }
 }

+ 5 - 8
Admin/Pages/Director/Role/Index.cshtml.cs

@@ -1,7 +1,4 @@
-using Application.Features.Director.CreateRole;
-using Application.Features.Director.DeleteRole;
-using Application.Features.Director.GetRoles;
-using MediatR;
+using MediatR;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.Mvc.RazorPages;
 using System.ComponentModel;
@@ -12,7 +9,7 @@ namespace Admin.Pages.Director.Role
     public class IndexModel(IMediator mediator) : PageModel
     {
         public int Total { get; set; } = 0;
-        public List<Response> List { get; set; } = [];
+        public List<GetRoles.Response> List { get; set; } = [];
 
         [Required]
         [DisplayName("역할(Role)")]
@@ -22,7 +19,7 @@ namespace Admin.Pages.Director.Role
 
         public async Task OnGetAsync(CancellationToken ct)
         {
-            List = await mediator.Send(new GetAllRolesQuery(), ct);
+            List = await mediator.Send(new GetRoles.Query(), ct);
             Total = List.Count;
         }
 
@@ -35,7 +32,7 @@ namespace Admin.Pages.Director.Role
                     throw new Exception("유효성 검사에 실패하였습니다.");
                 }
 
-                var command = new CreateRoleCommand(
+                var command = new CreateRole.Command(
                     RoleName: RoleName
                 );
 
@@ -57,7 +54,7 @@ namespace Admin.Pages.Director.Role
         {
             try
             {
-                await mediator.Send(new DeleteRoleCommand(id), ct);
+                await mediator.Send(new DeleteRole.Command(id), ct);
                 TempData["SuccessMessage"] = "정상적으로 삭제되었습니다.";
                 return RedirectToPage();
             }

+ 3 - 5
Admin/Pages/Director/Role/Permission.cshtml.cs

@@ -1,6 +1,4 @@
 using Application.Abstractions.Identity.Models;
-using Application.Features.Director.GetRolePermissions;
-using Application.Features.Director.UpdateRolePermissions;
 using MediatR;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.Mvc.RazorPages;
@@ -10,7 +8,7 @@ namespace Admin.Pages.Director.Role
     public class PermissionModel(IMediator mediator) : PageModel
     {
         [BindProperty]
-        public Response Role { get; set; } = new() { RoleID = string.Empty };
+        public GetRolePermissions.Response Role { get; set; } = new() { RoleID = string.Empty };
 
         public async Task<IActionResult> OnGetAsync(string id, CancellationToken ct)
         {
@@ -20,7 +18,7 @@ namespace Admin.Pages.Director.Role
                 return RedirectToPage("/Director/Role/Index");
             }
 
-            Role = await mediator.Send(new GetRoleClaimsQuery(id), ct);
+            Role = await mediator.Send(new GetRolePermissions.Query(id), ct);
 
             return Page();
         }
@@ -46,7 +44,7 @@ namespace Admin.Pages.Director.Role
                     })]
                 };
 
-                var command = new UpdateRolePermissionsCommand(
+                var command = new UpdateRolePermissions.Command(
                     Role.RoleID,
                     permissions
                 );

+ 5 - 7
Admin/Pages/Director/User/Edit.cshtml.cs

@@ -1,6 +1,4 @@
-using Application.Features.Director.GetUser;
-using Application.Features.Director.UpdateUser;
-using MediatR;
+using MediatR;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.Mvc.RazorPages;
 
@@ -9,15 +7,15 @@ namespace Admin.Pages.Director.User
     public class EditModel(IMediator mediator) : PageModel
     {
         [BindProperty]
-        public Response? Input { get; set; }
+        public GetUser.Response? Input { get; set; }
 
         public async Task OnGetAsync(string id, CancellationToken ct)
         {
-            var user = await mediator.Send(new GetUserQuery(id), ct);
+            var user = await mediator.Send(new GetUser.Query(id), ct);
 
             if (user != null)
             {
-                Input = new Response
+                Input = new GetUser.Response
                 {
                     ID = user.ID,
                     Name = user.FullName,
@@ -40,7 +38,7 @@ namespace Admin.Pages.Director.User
                     throw new Exception("유효성 검사에 실패하였습니다.");
                 }
 
-                var command = new UpdateUserCommand(
+                var command = new UpdateUser.Command(
                     ID: Input!.ID,
                     FullName: Input.Name,
                     Email: Input.Email,

+ 3 - 4
Admin/Pages/Director/User/Index.cshtml.cs

@@ -1,5 +1,4 @@
-using Application.Features.Director.GetUsers;
-using Microsoft.AspNetCore.Mvc.RazorPages;
+using Microsoft.AspNetCore.Mvc.RazorPages;
 using MediatR;
 
 namespace Admin.Pages.Director.User
@@ -7,11 +6,11 @@ namespace Admin.Pages.Director.User
     public class IndexModel(IMediator mediator) : PageModel
     {
         public int Total { get; set; } = 0;
-        public List<Response> List { get; set; } = [];
+        public List<GetUsers.Response> List { get; set; } = [];
 
         public async Task OnGetAsync(CancellationToken ct)
         {
-            List = await mediator.Send(new GetAllUserQuery(), ct);
+            List = await mediator.Send(new GetUsers.Query(), ct);
             Total = List.Count;
         }
     }

+ 1 - 1
Admin/Pages/Director/User/Roles.cshtml

@@ -26,7 +26,7 @@
         }
 
         <div class="form-check">
-            <input class="form-check-input" type="checkbox" value="1" id="allChecked" checked />
+            <input class="form-check-input" type="checkbox" value="1" id="allChecked" />
             <label class="form-check-label" for="allChecked">
                 모두 선택
             </label>

+ 3 - 5
Admin/Pages/Director/User/Roles.cshtml.cs

@@ -1,6 +1,4 @@
 using Application.Abstractions.Identity.Models;
-using Application.Features.Director.GetUserRoles;
-using Application.Features.Director.UpdateUserRoles;
 using MediatR;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.Mvc.RazorPages;
@@ -10,7 +8,7 @@ namespace Admin.Pages.Director.User
     public class RolesModel(IMediator mediator) : PageModel
     {
         [BindProperty]
-        public required Response Input { get; set; }
+        public required GetUserRoles.Response Input { get; set; }
 
         public async Task<IActionResult> OnGetAsync(string id, CancellationToken ct)
         {
@@ -20,7 +18,7 @@ namespace Admin.Pages.Director.User
                 return RedirectToPage("/Director/User/Index");
             }
 
-            Input = await mediator.Send(new GetUserRolesQuery(id), ct);
+            Input = await mediator.Send(new GetUserRoles.Query(id), ct);
 
             return Page();
         }
@@ -34,7 +32,7 @@ namespace Admin.Pages.Director.User
                     throw new Exception("유효성 검사에 실패하였습니다.");
                 }
 
-                var command = new UpdateUserRolesCommand(
+                var command = new UpdateUserRoles.Command(
                     Input!.User.ID,
                     new UserRolesDto
                     {

+ 12 - 0
Admin/using.cs

@@ -0,0 +1,12 @@
+global using GetConfig = Application.Features.Config.Get;
+global using UpdateConfig = Application.Features.Config.Update;
+global using GetUser = Application.Features.Director.User.Get;
+global using GetUserRoles = Application.Features.Director.User.GetRoles;
+global using UpdateUser = Application.Features.Director.User.Update;
+global using UpdateUserRoles = Application.Features.Director.User.UpdateRoles;
+global using GetUsers = Application.Features.Director.Users.Get;
+global using GetRoles = Application.Features.Director.Roles.Get;
+global using CreateRole = Application.Features.Director.Role.Create;
+global using DeleteRole = Application.Features.Director.Role.Delete;
+global using GetRolePermissions = Application.Features.Director.Role.Permissions.Get;
+global using UpdateRolePermissions = Application.Features.Director.Role.Permissions.Update;

+ 1 - 1
Application/Application.csproj

@@ -9,7 +9,7 @@
   <ItemGroup>
     <Folder Include="Authentication\" />
     <Folder Include="Behaviors\" />
-    <Folder Include="Features\ReferenceData\Commands\" />
+    <Folder Include="Features\ReferenceData\Dtos\" />
   </ItemGroup>
 
   <ItemGroup>

+ 0 - 27
Application/Features/Config/Commands/UpdateConfigCommand.cs

@@ -1,27 +0,0 @@
-using MediatR;
-
-namespace Application.Features.Config.Commands
-{
-    public sealed record UpdateConfigCommand(
-        ConfigDto.BasicConfigDto? Basic = null,
-        ConfigDto.ImagesConfigDto? Images = null,
-        ConfigDto.MetaConfigDto? Meta = null,
-        ConfigDto.CompanyConfigDto? Company = null,
-        ConfigDto.AccountConfigDto? Account = null,
-        ConfigDto.EmailTemplateConfigDto? EmailTemplate = null,
-        ConfigDto.ExternalApiConfigDto? External = null,
-        ConfigDto.PaymentConfigDto? Payment = null,
-        UpdateConfigCommand.ImagesDeleteFlags? ImagesDelete = null
-    ) : IRequest {
-        public sealed record ImagesDeleteFlags(
-            bool Favicon = false,
-            bool LogoSquare = false,
-            bool LogoHorizontal = false,
-            bool OgDefault = false,
-            bool TwitterImage = false,
-            bool AppleTouchIcon = false,
-            bool AppIcon192 = false,
-            bool AppIcon512 = false
-       );
-    }
-}

+ 13 - 13
Application/Features/Config/Queries/GetConfigQueryHandler.cs → Application/Features/Config/Get/Handler.cs

@@ -2,22 +2,22 @@ using Application.Abstractions.Data;
 using MediatR;
 using Microsoft.EntityFrameworkCore;
 
-namespace Application.Features.Config.Queries;
+namespace Application.Features.Config.Get;
 
-public sealed class GetConfigQueryHandler(IAppDbContext db) : IRequestHandler<GetConfigQuery, ConfigDto?>
+public sealed class Handler(IAppDbContext db) : IRequestHandler<Query, Response?>
 {
-    public async Task<ConfigDto?> Handle(GetConfigQuery request, CancellationToken cancellationToken)
+    public async Task<Response?> Handle(Query request, CancellationToken ct)
     {
-        var config = await db.Config.AsNoTracking().OrderByDescending(x => x.ID).FirstOrDefaultAsync(cancellationToken);
+        var config = await db.Config.AsNoTracking().OrderByDescending(x => x.ID).FirstOrDefaultAsync(ct);
         if (config is null)
         {
             return null;
         }
 
-        return new ConfigDto
+        return new Response
         {
             ID = config.ID,
-            Basic = new ConfigDto.BasicConfigDto
+            Basic = new Response.BasicConfigDto
             {
                 SiteName = config.Basic.SiteName,
                 SiteURL = config.Basic.SiteURL,
@@ -37,7 +37,7 @@ public sealed class GetConfigQueryHandler(IAppDbContext db) : IRequestHandler<Ge
                 MaintenanceContent = config.Basic.MaintenanceContent
             },
 
-            Images = new ConfigDto.ImagesConfigDto
+            Images = new Response.ImagesConfigDto
             {
                 FaviconPath = config.Images.Favicon,
                 LogoSquarePath = config.Images.LogoSquare,
@@ -49,7 +49,7 @@ public sealed class GetConfigQueryHandler(IAppDbContext db) : IRequestHandler<Ge
                 AppIcon512Path = config.Images.AppIcon_512
             },
 
-            Meta = new ConfigDto.MetaConfigDto
+            Meta = new Response.MetaConfigDto
             {
                 Keywords = config.Meta.Keywords,
                 Description = config.Meta.Description,
@@ -61,7 +61,7 @@ public sealed class GetConfigQueryHandler(IAppDbContext db) : IRequestHandler<Ge
                 Adds = config.Meta.Adds
             },
 
-            Company = new ConfigDto.CompanyConfigDto
+            Company = new Response.CompanyConfigDto
             {
                 Name = config.Company.Name,
                 RegNo = config.Company.RegNo,
@@ -81,7 +81,7 @@ public sealed class GetConfigQueryHandler(IAppDbContext db) : IRequestHandler<Ge
                 BankNumber = config.Company.BankNumber
             },
 
-            Account = new ConfigDto.AccountConfigDto
+            Account = new Response.AccountConfigDto
             {
                 IsRegisterBlock = config.Account.IsRegisterBlock,
                 IsRegisterEmailAuth = config.Account.IsRegisterEmailAuth,
@@ -100,7 +100,7 @@ public sealed class GetConfigQueryHandler(IAppDbContext db) : IRequestHandler<Ge
                 MaxLoginTryLimitSecond = config.Account.MaxLoginTryLimitSecond
             },
 
-            EmailTemplate = new ConfigDto.EmailTemplateConfigDto
+            EmailTemplate = new Response.EmailTemplateConfigDto
             {
                 RegisterEmailFormTitle = config.EmailTemplate.RegisterEmailFormTitle,
                 RegisterEmailFormContent = config.EmailTemplate.RegisterEmailFormContent,
@@ -118,7 +118,7 @@ public sealed class GetConfigQueryHandler(IAppDbContext db) : IRequestHandler<Ge
                 ChangedEmailFormContent = config.EmailTemplate.ChangedEmailFormContent
             },
 
-            External = new ConfigDto.ExternalApiConfigDto
+            External = new Response.ExternalApiConfigDto
             {
                 YouTubeApiKeyEnc = config.External.YouTubeApiKeyEnc,
                 YouTubeApiName = config.External.YouTubeApiName,
@@ -127,7 +127,7 @@ public sealed class GetConfigQueryHandler(IAppDbContext db) : IRequestHandler<Ge
                 GoogleAppId = config.External.GoogleAppId
             },
 
-            Payment = new ConfigDto.PaymentConfigDto
+            Payment = new Response.PaymentConfigDto
             {
 
             }

+ 6 - 0
Application/Features/Config/Get/Query.cs

@@ -0,0 +1,6 @@
+using MediatR;
+
+namespace Application.Features.Config.Get
+{
+    public sealed record Query : IRequest<Response?>;
+}

+ 2 - 67
Application/Features/Config/ConfigDto.cs → Application/Features/Config/Get/Response.cs

@@ -1,10 +1,9 @@
 using Microsoft.AspNetCore.Http;
 using System.ComponentModel;
-using System.ComponentModel.DataAnnotations;
 
-namespace Application.Features.Config;
+namespace Application.Features.Config.Get;
 
-public sealed class ConfigDto
+public sealed class Response
 {
     public int ID { get; init; }
 
@@ -19,71 +18,51 @@ public sealed class ConfigDto
 
     public sealed class BasicConfigDto
     {
-        [MaxLength(100)]
         [DisplayName("사이트 이름")]
         public string? SiteName { get; init; }
 
-        [MaxLength(100)]
-        [DataType(DataType.Url)]
         [DisplayName("사이트 주소")]
         public string? SiteURL { get; init; }
 
         [DisplayName("최고 관리자 ID")]
         public string? RootID { get; init; }
 
-        [MaxLength(100)]
-        [DataType(DataType.EmailAddress)]
         [DisplayName("송수신 이메일")]
         public string? FromEmail { get; init; }
 
-        [MaxLength(30)]
         [DisplayName("송수신자 이름")]
         public string? FromName { get; init; }
 
-        [MaxLength(200)]
         [DisplayName("SMTP Server")]
         public string? SmtpServer { get; init; }
 
-        [Range(1, 65535)]
         [DisplayName("SMTP Port")]
         public int? SmtpPort { get; set; }
 
         [DisplayName("SMTP Enable SSL")]
         public bool SmtpEnableSSL { get; init; } = false;
 
-        [MaxLength(100)]
         [DisplayName("SMTP Username")]
         public string? SmtpUsername { get; init; }
 
-        [MaxLength(200)]
-        [DataType(DataType.Password)]
         [DisplayName("SMTP Password")]
         public string? SmtpPassword { get; init; }
 
-        [MaxLength(200)]
-        [DataType(DataType.MultilineText)]
         [DisplayName("관리자단 접근 가능 IP")]
         public string? AdminWhiteIPList { get; init; }
 
-        [MaxLength(200)]
-        [DataType(DataType.MultilineText)]
         [DisplayName("사용자단 접근 가능 IP")]
         public string? FrontWhiteIPList { get; init; }
 
-        [MaxLength(200)]
         [DisplayName("차단 시 안내문 제목")]
         public string? BlockAlertTitle { get; init; }
 
-        [MaxLength(5000)]
-        [DataType(DataType.MultilineText)]
         [DisplayName("차단 시 안내문 내용")]
         public string? BlockAlertContent { get; init; }
 
         [DisplayName("점검 여부")]
         public bool IsMaintenance { get; init; } = false;
 
-        [MaxLength(5000)]
-        [DataType(DataType.MultilineText)]
         [DisplayName("점검 내용")]
         public string? MaintenanceContent { get; init; }
     }
@@ -91,174 +70,130 @@ public sealed class ConfigDto
     public sealed class ImagesConfigDto
     {
         // ====== DB에 저장/표시할 경로(문자열) ======
-        [MaxLength(255)]
         [DisplayName("Favicon")]
         public string? FaviconPath { get; init; }
 
-        [MaxLength(255)]
         [DisplayName("Logo-square")]
         public string? LogoSquarePath { get; init; }
 
-        [MaxLength(255)]
         [DisplayName("Logo-horizontal")]
         public string? LogoHorizontalPath { get; init; }
 
-        [MaxLength(255)]
         [DisplayName("og-default")]
         public string? OgDefaultPath { get; init; }
 
-        [MaxLength(255)]
         [DisplayName("Twitter-image")]
         public string? TwitterImagePath { get; init; }
 
-        [MaxLength(255)]
         [DisplayName("Apple-touch-icon")]
         public string? AppleTouchIconPath { get; init; }
 
-        [MaxLength(255)]
         [DisplayName("App-icon-192")]
         public string? AppIcon192Path { get; init; }
 
-        [MaxLength(255)]
         [DisplayName("App-icon-512")]
         public string? AppIcon512Path { get; init; }
 
         // ====== 업로드 입력(폼 바인딩용) ======
-        [DataType(DataType.Upload)]
         [DisplayName("Favicon 업로드")]
         public IFormFile? FaviconFile { get; init; }
 
-        [DataType(DataType.Upload)]
         [DisplayName("Logo-square 업로드")]
         public IFormFile? LogoSquareFile { get; init; }
 
-        [DataType(DataType.Upload)]
         [DisplayName("Logo-horizontal 업로드")]
         public IFormFile? LogoHorizontalFile { get; init; }
 
-        [DataType(DataType.Upload)]
         [DisplayName("og-default 업로드")]
         public IFormFile? OgDefaultFile { get; init; }
 
-        [DataType(DataType.Upload)]
         [DisplayName("Twitter-image 업로드")]
         public IFormFile? TwitterImageFile { get; init; }
 
-        [DataType(DataType.Upload)]
         [DisplayName("Apple-touch-icon 업로드")]
         public IFormFile? AppleTouchIconFile { get; init; }
 
-        [DataType(DataType.Upload)]
         [DisplayName("App-icon-192 업로드")]
         public IFormFile? AppIcon192File { get; init; }
 
-        [DataType(DataType.Upload)]
         [DisplayName("App-icon-512 업로드")]
         public IFormFile? AppIcon512File { get; init; }
     }
 
     public sealed class MetaConfigDto
     {
-        [MaxLength(255)]
         [DisplayName("Meta Keywords")]
         public string? Keywords { get; init; }
 
-        [MaxLength(255)]
         [DisplayName("Meta Description")]
         public string? Description { get; init; }
 
-        [MaxLength(255)]
         [DisplayName("Meta Author")]
         public string? Author { get; init; }
 
-        [MaxLength(255)]
         [DisplayName("Meta Viewport")]
         public string? Viewport { get; init; }
 
-        [MaxLength(255)]
         [DisplayName("Meta ApplicationName")]
         public string? ApplicationName { get; init; }
 
-        [MaxLength(255)]
         [DisplayName("Meta Generator")]
         public string? Generator { get; init; }
 
-        [MaxLength(255)]
         [DisplayName("Meta Robots")]
         public string? Robots { get; init; }
 
-        [MaxLength(3000)]
-        [DataType(DataType.MultilineText)]
         [DisplayName("Meta Adds")]
         public string? Adds { get; init; }
     }
 
     public sealed class CompanyConfigDto
     {
-        [MaxLength(70)]
         [DisplayName("상호 명")]
         public string? Name { get; init; }
 
-        [MaxLength(100)]
         [DisplayName("사업자 등록 번호")]
         public string? RegNo { get; init; }
 
-        [MaxLength(255)]
         [DisplayName("사업자 소재지")]
         public string? Address { get; init; }
 
-        [MaxLength(8)]
-        [DataType(DataType.PostalCode)]
         [DisplayName("우편번호")]
         public string? ZipCode { get; init; }
 
-        [MaxLength(50)]
         [DisplayName("대표자 명")]
         public string? Owner { get; init; }
 
-        [MaxLength(20)]
         [DisplayName("대표 전화번호")]
         public string? Tel { get; init; }
 
-        [MaxLength(20)]
         [DisplayName("FAX")]
         public string? Fax { get; init; }
 
-        [MaxLength(20)]
         [DisplayName("통신판매업 신고번호")]
         public string? RetailSaleNo { get; init; }
 
-        [MaxLength(20)]
         [DisplayName("부가통신 사업자번호")]
         public string? AddedSaleNo { get; init; }
 
-        [MaxLength(100)]
         [DisplayName("호스팅 서비스")]
         public string? Hosting { get; init; }
 
-        [MaxLength(70)]
         [DisplayName("정보관리책임자")]
         public string? AdminName { get; init; }
 
-        [MaxLength(100)]
-        [DataType(DataType.EmailAddress)]
         [DisplayName("정보관리책임자 이메일")]
         public string? AdminEmail { get; init; }
 
-        [MaxLength(200)]
-        [DataType(DataType.Url)]
         [DisplayName("사이트 주소")]
         public string? SiteUrl { get; init; }
 
-        [MaxLength(10)]
         [DisplayName("입금계좌 - 은행")]
         public string? BankCode { get; init; }
 
-        [MaxLength(70)]
         [DisplayName("입금계좌 - 예금주")]
         public string? BankOwner { get; init; }
 
-        [MaxLength(100)]
         [DisplayName("입금계좌 - 계좌번호")]
         public string? BankNumber { get; init; }
     }

+ 0 - 6
Application/Features/Config/Queries/GetConfigQuery.cs

@@ -1,6 +0,0 @@
-using MediatR;
-
-namespace Application.Features.Config.Queries
-{
-    public sealed record GetConfigQuery : IRequest<ConfigDto?>;
-}

+ 27 - 0
Application/Features/Config/Update/Command.cs

@@ -0,0 +1,27 @@
+using MediatR;
+
+namespace Application.Features.Config.Update
+{
+    public sealed record Command(
+        Request.BasicConfigDto? Basic = null,
+        Request.ImagesConfigDto? Images = null,
+        Request.MetaConfigDto? Meta = null,
+        Request.CompanyConfigDto? Company = null,
+        Request.AccountConfigDto? Account = null,
+        Request.EmailTemplateConfigDto? EmailTemplate = null,
+        Request.ExternalApiConfigDto? External = null,
+        Request.PaymentConfigDto? Payment = null,
+        Command.ImagesDeleteFlags? ImagesDelete = null
+    ) : IRequest {
+        public sealed record ImagesDeleteFlags(
+            bool Favicon = false,
+            bool LogoSquare = false,
+            bool LogoHorizontal = false,
+            bool OgDefault = false,
+            bool TwitterImage = false,
+            bool AppleTouchIcon = false,
+            bool AppIcon192 = false,
+            bool AppIcon512 = false
+       );
+    }
+}

+ 6 - 6
Application/Features/Config/Commands/UpdateConfigCommandHandler.cs → Application/Features/Config/Update/Handler.cs

@@ -1,21 +1,21 @@
 using Application.Abstractions.Data;
 using Domain.Entities.Common;
+using ConfigEntity = Domain.Entities.Common.Config;
 using MediatR;
 using Microsoft.AspNetCore.Http;
 using Microsoft.EntityFrameworkCore;
 using SharedKernel.Storage;
-using DomainConfig = Domain.Entities.Common.Config;
 
-namespace Application.Features.Config.Commands;
+namespace Application.Features.Config.Update;
 
-public sealed class UpdateConfigCommandHandler(IAppDbContext db, IFileStorage storage, IEditorImageService editorImage) : IRequestHandler<UpdateConfigCommand>
+public sealed class Handler(IAppDbContext db, IFileStorage storage, IEditorImageService editorImage) : IRequestHandler<Command>
 {
-    public async Task Handle(UpdateConfigCommand request, CancellationToken ct)
+    public async Task Handle(Command request, CancellationToken ct)
     {
         var config = await db.Config.OrderByDescending(x => x.ID).FirstOrDefaultAsync(ct);
         if (config is null)
         {
-            config = DomainConfig.Create();
+            config = ConfigEntity.Create();
             db.Config.Add(config);
         }
 
@@ -52,7 +52,7 @@ public sealed class UpdateConfigCommandHandler(IAppDbContext db, IFileStorage st
 
         if (request.Images != null)
         {
-            var del = request.ImagesDelete ?? new UpdateConfigCommand.ImagesDeleteFlags();
+            var del = request.ImagesDelete ?? new Command.ImagesDeleteFlags();
 
             images.Favicon = await ApplyImageAsync(del.Favicon, config.Images.Favicon, request.Images.FaviconFile, [".ico"], ct);
             images.LogoSquare = await ApplyImageAsync(del.LogoSquare, config.Images.LogoSquare, request.Images.LogoSquareFile, [".jpg", ".jpeg", ".png", ".gif", ".webp", ".svg"], ct);

+ 432 - 0
Application/Features/Config/Update/Request.cs

@@ -0,0 +1,432 @@
+using Microsoft.AspNetCore.Http;
+using System.ComponentModel;
+using System.ComponentModel.DataAnnotations;
+
+namespace Application.Features.Config.Update;
+
+public sealed class Request
+{
+    public int ID { get; init; }
+
+    public BasicConfigDto Basic { get; init; } = new();
+    public ImagesConfigDto Images { get; init; } = new();
+    public MetaConfigDto Meta { get; init; } = new();
+    public CompanyConfigDto Company { get; init; } = new();
+    public AccountConfigDto Account { get; init; } = new();
+    public EmailTemplateConfigDto EmailTemplate { get; init; } = new();
+    public ExternalApiConfigDto External { get; init; } = new();
+    public PaymentConfigDto Payment { get; init; } = new();
+
+    public sealed class BasicConfigDto
+    {
+        [MaxLength(100)]
+        [DisplayName("사이트 이름")]
+        public string? SiteName { get; init; }
+
+        [MaxLength(100)]
+        [DataType(DataType.Url)]
+        [DisplayName("사이트 주소")]
+        public string? SiteURL { get; init; }
+
+        [DisplayName("최고 관리자 ID")]
+        public string? RootID { get; init; }
+
+        [MaxLength(100)]
+        [DataType(DataType.EmailAddress)]
+        [DisplayName("송수신 이메일")]
+        public string? FromEmail { get; init; }
+
+        [MaxLength(30)]
+        [DisplayName("송수신자 이름")]
+        public string? FromName { get; init; }
+
+        [MaxLength(200)]
+        [DisplayName("SMTP Server")]
+        public string? SmtpServer { get; init; }
+
+        [Range(1, 65535)]
+        [DisplayName("SMTP Port")]
+        public int? SmtpPort { get; set; }
+
+        [DisplayName("SMTP Enable SSL")]
+        public bool SmtpEnableSSL { get; init; } = false;
+
+        [MaxLength(100)]
+        [DisplayName("SMTP Username")]
+        public string? SmtpUsername { get; init; }
+
+        [MaxLength(200)]
+        [DataType(DataType.Password)]
+        [DisplayName("SMTP Password")]
+        public string? SmtpPassword { get; init; }
+
+        [MaxLength(200)]
+        [DataType(DataType.MultilineText)]
+        [DisplayName("관리자단 접근 가능 IP")]
+        public string? AdminWhiteIPList { get; init; }
+
+        [MaxLength(200)]
+        [DataType(DataType.MultilineText)]
+        [DisplayName("사용자단 접근 가능 IP")]
+        public string? FrontWhiteIPList { get; init; }
+
+        [MaxLength(200)]
+        [DisplayName("차단 시 안내문 제목")]
+        public string? BlockAlertTitle { get; init; }
+
+        [MaxLength(5000)]
+        [DataType(DataType.MultilineText)]
+        [DisplayName("차단 시 안내문 내용")]
+        public string? BlockAlertContent { get; init; }
+
+        [DisplayName("점검 여부")]
+        public bool IsMaintenance { get; init; } = false;
+
+        [MaxLength(5000)]
+        [DataType(DataType.MultilineText)]
+        [DisplayName("점검 내용")]
+        public string? MaintenanceContent { get; init; }
+    }
+
+    public sealed class ImagesConfigDto
+    {
+        // ====== DB에 저장/표시할 경로(문자열) ======
+        [MaxLength(255)]
+        [DisplayName("Favicon")]
+        public string? FaviconPath { get; init; }
+
+        [MaxLength(255)]
+        [DisplayName("Logo-square")]
+        public string? LogoSquarePath { get; init; }
+
+        [MaxLength(255)]
+        [DisplayName("Logo-horizontal")]
+        public string? LogoHorizontalPath { get; init; }
+
+        [MaxLength(255)]
+        [DisplayName("og-default")]
+        public string? OgDefaultPath { get; init; }
+
+        [MaxLength(255)]
+        [DisplayName("Twitter-image")]
+        public string? TwitterImagePath { get; init; }
+
+        [MaxLength(255)]
+        [DisplayName("Apple-touch-icon")]
+        public string? AppleTouchIconPath { get; init; }
+
+        [MaxLength(255)]
+        [DisplayName("App-icon-192")]
+        public string? AppIcon192Path { get; init; }
+
+        [MaxLength(255)]
+        [DisplayName("App-icon-512")]
+        public string? AppIcon512Path { get; init; }
+
+        // ====== 업로드 입력(폼 바인딩용) ======
+        [DataType(DataType.Upload)]
+        [DisplayName("Favicon 업로드")]
+        public IFormFile? FaviconFile { get; init; }
+
+        [DataType(DataType.Upload)]
+        [DisplayName("Logo-square 업로드")]
+        public IFormFile? LogoSquareFile { get; init; }
+
+        [DataType(DataType.Upload)]
+        [DisplayName("Logo-horizontal 업로드")]
+        public IFormFile? LogoHorizontalFile { get; init; }
+
+        [DataType(DataType.Upload)]
+        [DisplayName("og-default 업로드")]
+        public IFormFile? OgDefaultFile { get; init; }
+
+        [DataType(DataType.Upload)]
+        [DisplayName("Twitter-image 업로드")]
+        public IFormFile? TwitterImageFile { get; init; }
+
+        [DataType(DataType.Upload)]
+        [DisplayName("Apple-touch-icon 업로드")]
+        public IFormFile? AppleTouchIconFile { get; init; }
+
+        [DataType(DataType.Upload)]
+        [DisplayName("App-icon-192 업로드")]
+        public IFormFile? AppIcon192File { get; init; }
+
+        [DataType(DataType.Upload)]
+        [DisplayName("App-icon-512 업로드")]
+        public IFormFile? AppIcon512File { get; init; }
+    }
+
+    public sealed class MetaConfigDto
+    {
+        [MaxLength(255)]
+        [DisplayName("Meta Keywords")]
+        public string? Keywords { get; init; }
+
+        [MaxLength(255)]
+        [DisplayName("Meta Description")]
+        public string? Description { get; init; }
+
+        [MaxLength(255)]
+        [DisplayName("Meta Author")]
+        public string? Author { get; init; }
+
+        [MaxLength(255)]
+        [DisplayName("Meta Viewport")]
+        public string? Viewport { get; init; }
+
+        [MaxLength(255)]
+        [DisplayName("Meta ApplicationName")]
+        public string? ApplicationName { get; init; }
+
+        [MaxLength(255)]
+        [DisplayName("Meta Generator")]
+        public string? Generator { get; init; }
+
+        [MaxLength(255)]
+        [DisplayName("Meta Robots")]
+        public string? Robots { get; init; }
+
+        [MaxLength(3000)]
+        [DataType(DataType.MultilineText)]
+        [DisplayName("Meta Adds")]
+        public string? Adds { get; init; }
+    }
+
+    public sealed class CompanyConfigDto
+    {
+        [MaxLength(70)]
+        [DisplayName("상호 명")]
+        public string? Name { get; init; }
+
+        [MaxLength(100)]
+        [DisplayName("사업자 등록 번호")]
+        public string? RegNo { get; init; }
+
+        [MaxLength(255)]
+        [DisplayName("사업자 소재지")]
+        public string? Address { get; init; }
+
+        [MaxLength(8)]
+        [DataType(DataType.PostalCode)]
+        [DisplayName("우편번호")]
+        public string? ZipCode { get; init; }
+
+        [MaxLength(50)]
+        [DisplayName("대표자 명")]
+        public string? Owner { get; init; }
+
+        [MaxLength(20)]
+        [DisplayName("대표 전화번호")]
+        public string? Tel { get; init; }
+
+        [MaxLength(20)]
+        [DisplayName("FAX")]
+        public string? Fax { get; init; }
+
+        [MaxLength(20)]
+        [DisplayName("통신판매업 신고번호")]
+        public string? RetailSaleNo { get; init; }
+
+        [MaxLength(20)]
+        [DisplayName("부가통신 사업자번호")]
+        public string? AddedSaleNo { get; init; }
+
+        [MaxLength(100)]
+        [DisplayName("호스팅 서비스")]
+        public string? Hosting { get; init; }
+
+        [MaxLength(70)]
+        [DisplayName("정보관리책임자")]
+        public string? AdminName { get; init; }
+
+        [MaxLength(100)]
+        [DataType(DataType.EmailAddress)]
+        [DisplayName("정보관리책임자 이메일")]
+        public string? AdminEmail { get; init; }
+
+        [MaxLength(200)]
+        [DataType(DataType.Url)]
+        [DisplayName("사이트 주소")]
+        public string? SiteUrl { get; init; }
+
+        [MaxLength(10)]
+        [DisplayName("입금계좌 - 은행")]
+        public string? BankCode { get; init; }
+
+        [MaxLength(70)]
+        [DisplayName("입금계좌 - 예금주")]
+        public string? BankOwner { get; init; }
+
+        [MaxLength(100)]
+        [DisplayName("입금계좌 - 계좌번호")]
+        public string? BankNumber { get; init; }
+    }
+
+    public sealed class AccountConfigDto
+    {
+        public bool IsRegisterBlock { get; init; }
+        public bool IsRegisterEmailAuth { get; init; }
+        public ushort? PasswordMinLength { get; init; }
+        public ushort? PasswordUppercaseLength { get; init; }
+        public ushort? PasswordNumbersLength { get; init; }
+        public ushort? PasswordSpecialcharsLength { get; init; }
+        public string? DeniedEmailList { get; init; }
+        public string? DeniedNameList { get; init; }
+        public ushort? ChangeEmailDay { get; init; }
+        public ushort? ChangeNameDay { get; init; }
+        public ushort? ChangeSummaryDay { get; init; }
+        public ushort? ChangeIntroDay { get; init; }
+        public ushort? ChangePasswordDay { get; init; }
+        public ushort? MaxLoginTryCount { get; init; }
+        public ushort? MaxLoginTryLimitSecond { get; init; }
+    }
+
+    public sealed class EmailTemplateConfigDto
+    {
+        public string? RegisterEmailFormTitle { get; init; }
+        public string? RegisterEmailFormContent { get; init; }
+        public string? RegistrationEmailFormTitle { get; init; }
+        public string? RegistrationEmailFormContent { get; init; }
+        public string? ResetPasswordEmailFormTitle { get; init; }
+        public string? ResetPasswordEmailFormContent { get; init; }
+        public string? ChangedPasswordEmailFormTitle { get; init; }
+        public string? ChangedPasswordEmailFormContent { get; init; }
+        public string? WithdrawEmailFormTitle { get; init; }
+        public string? WithdrawEmailFormContent { get; init; }
+        public string? EmailVerifyFormTitle { get; init; }
+        public string? EmailVerifyFormContent { get; init; }
+        public string? ChangedEmailFormTitle { get; init; }
+        public string? ChangedEmailFormContent { get; init; }
+    }
+
+    public sealed class ExternalApiConfigDto
+    {
+        public string? YouTubeApiKeyEnc { get; init; }
+        public string? YouTubeApiName { get; init; }
+        public string? GoogleClientId { get; init; }
+        public string? GoogleClientSecretEnc { get; init; }
+        public string? GoogleAppId { get; init; }
+    }
+
+    public sealed class PaymentConfigDto
+    {
+    }
+
+    public static Request From(Get.Response src) => new()
+    {
+        ID = src.ID,
+
+        Basic = new BasicConfigDto
+        {
+            SiteName = src.Basic.SiteName,
+            SiteURL = src.Basic.SiteURL,
+            RootID = src.Basic.RootID,
+            FromEmail = src.Basic.FromEmail,
+            FromName = src.Basic.FromName,
+            SmtpServer = src.Basic.SmtpServer,
+            SmtpPort = src.Basic.SmtpPort,
+            SmtpEnableSSL = src.Basic.SmtpEnableSSL,
+            SmtpUsername = src.Basic.SmtpUsername,
+            SmtpPassword = src.Basic.SmtpPassword,
+            AdminWhiteIPList = src.Basic.AdminWhiteIPList,
+            FrontWhiteIPList = src.Basic.FrontWhiteIPList,
+            BlockAlertTitle = src.Basic.BlockAlertTitle,
+            BlockAlertContent = src.Basic.BlockAlertContent,
+            IsMaintenance = src.Basic.IsMaintenance,
+            MaintenanceContent = src.Basic.MaintenanceContent
+        },
+
+        Images = new ImagesConfigDto
+        {
+            FaviconPath = src.Images.FaviconPath,
+            LogoSquarePath = src.Images.LogoSquarePath,
+            LogoHorizontalPath = src.Images.LogoHorizontalPath,
+            OgDefaultPath = src.Images.OgDefaultPath,
+            TwitterImagePath = src.Images.TwitterImagePath,
+            AppleTouchIconPath = src.Images.AppleTouchIconPath,
+            AppIcon192Path = src.Images.AppIcon192Path,
+            AppIcon512Path = src.Images.AppIcon512Path
+        },
+
+        Meta = new MetaConfigDto
+        {
+            Keywords = src.Meta.Keywords,
+            Description = src.Meta.Description,
+            Author = src.Meta.Author,
+            Viewport = src.Meta.Viewport,
+            ApplicationName = src.Meta.ApplicationName,
+            Generator = src.Meta.Generator,
+            Robots = src.Meta.Robots,
+            Adds = src.Meta.Adds
+        },
+
+        Company = new CompanyConfigDto
+        {
+            Name = src.Company.Name,
+            RegNo = src.Company.RegNo,
+            Address = src.Company.Address,
+            ZipCode = src.Company.ZipCode,
+            Owner = src.Company.Owner,
+            Tel = src.Company.Tel,
+            Fax = src.Company.Fax,
+            RetailSaleNo = src.Company.RetailSaleNo,
+            AddedSaleNo = src.Company.AddedSaleNo,
+            Hosting = src.Company.Hosting,
+            AdminName = src.Company.AdminName,
+            AdminEmail = src.Company.AdminEmail,
+            SiteUrl = src.Company.SiteUrl,
+            BankCode = src.Company.BankCode,
+            BankOwner = src.Company.BankOwner,
+            BankNumber = src.Company.BankNumber
+        },
+
+        Account = new AccountConfigDto
+        {
+            IsRegisterBlock = src.Account.IsRegisterBlock,
+            IsRegisterEmailAuth = src.Account.IsRegisterEmailAuth,
+            PasswordMinLength = src.Account.PasswordMinLength,
+            PasswordUppercaseLength = src.Account.PasswordUppercaseLength,
+            PasswordNumbersLength = src.Account.PasswordNumbersLength,
+            PasswordSpecialcharsLength = src.Account.PasswordSpecialcharsLength,
+            DeniedEmailList = src.Account.DeniedEmailList,
+            DeniedNameList = src.Account.DeniedNameList,
+            ChangeEmailDay = src.Account.ChangeEmailDay,
+            ChangeNameDay = src.Account.ChangeNameDay,
+            ChangeSummaryDay = src.Account.ChangeSummaryDay,
+            ChangeIntroDay = src.Account.ChangeIntroDay,
+            ChangePasswordDay = src.Account.ChangePasswordDay,
+            MaxLoginTryCount = src.Account.MaxLoginTryCount,
+            MaxLoginTryLimitSecond = src.Account.MaxLoginTryLimitSecond
+        },
+
+        EmailTemplate = new EmailTemplateConfigDto
+        {
+            RegisterEmailFormTitle = src.EmailTemplate.RegisterEmailFormTitle,
+            RegisterEmailFormContent = src.EmailTemplate.RegisterEmailFormContent,
+            RegistrationEmailFormTitle = src.EmailTemplate.RegistrationEmailFormTitle,
+            RegistrationEmailFormContent = src.EmailTemplate.RegistrationEmailFormContent,
+            ResetPasswordEmailFormTitle = src.EmailTemplate.ResetPasswordEmailFormTitle,
+            ResetPasswordEmailFormContent = src.EmailTemplate.ResetPasswordEmailFormContent,
+            ChangedPasswordEmailFormTitle = src.EmailTemplate.ChangedPasswordEmailFormTitle,
+            ChangedPasswordEmailFormContent = src.EmailTemplate.ChangedPasswordEmailFormContent,
+            WithdrawEmailFormTitle = src.EmailTemplate.WithdrawEmailFormTitle,
+            WithdrawEmailFormContent = src.EmailTemplate.WithdrawEmailFormContent,
+            EmailVerifyFormTitle = src.EmailTemplate.EmailVerifyFormTitle,
+            EmailVerifyFormContent = src.EmailTemplate.EmailVerifyFormContent,
+            ChangedEmailFormTitle = src.EmailTemplate.ChangedEmailFormTitle,
+            ChangedEmailFormContent = src.EmailTemplate.ChangedEmailFormContent
+        },
+
+        External = new ExternalApiConfigDto
+        {
+            YouTubeApiKeyEnc = src.External.YouTubeApiKeyEnc,
+            YouTubeApiName = src.External.YouTubeApiName,
+            GoogleClientId = src.External.GoogleClientId,
+            GoogleClientSecretEnc = src.External.GoogleClientSecretEnc,
+            GoogleAppId = src.External.GoogleAppId
+        },
+
+        Payment = new PaymentConfigDto()
+    };
+}

+ 0 - 6
Application/Features/Director/CreateRole/Command.cs

@@ -1,6 +0,0 @@
-using MediatR;
-
-namespace Application.Features.Director.CreateRole
-{
-    public sealed record CreateRoleCommand(string? RoleName) : IRequest;
-}

+ 0 - 6
Application/Features/Director/DeleteRole/Command.cs

@@ -1,6 +0,0 @@
-using MediatR;
-
-namespace Application.Features.Director.DeleteRole
-{
-    public sealed record DeleteRoleCommand(string? RoleID) : IRequest;
-}

+ 0 - 6
Application/Features/Director/GetRolePermissions/Query.cs

@@ -1,6 +0,0 @@
-using MediatR;
-
-namespace Application.Features.Director.GetRolePermissions
-{
-    public sealed record GetRoleClaimsQuery(string RoleID) : IRequest<Response>;
-}

+ 0 - 6
Application/Features/Director/GetRoles/Query.cs

@@ -1,6 +0,0 @@
-using MediatR;
-
-namespace Application.Features.Director.GetRoles
-{
-    public sealed record GetAllRolesQuery() : IRequest<List<Response>>;
-}

+ 0 - 7
Application/Features/Director/GetUser/Query.cs

@@ -1,7 +0,0 @@
-using Application.Abstractions.Identity.Models;
-using MediatR;
-
-namespace Application.Features.Director.GetUser
-{
-    public sealed record GetUserQuery(string ID) : IRequest<AspNetUserDto?>;
-}

+ 0 - 6
Application/Features/Director/GetUserRoles/Query.cs

@@ -1,6 +0,0 @@
-using MediatR;
-
-namespace Application.Features.Director.GetUserRoles
-{
-    public sealed record GetUserRolesQuery(string UserID) : IRequest<Response>;
-}

+ 0 - 6
Application/Features/Director/GetUsers/Query.cs

@@ -1,6 +0,0 @@
-using MediatR;
-
-namespace Application.Features.Director.GetUsers
-{
-    public sealed record GetAllUserQuery() : IRequest<List<Response>>;
-}

+ 6 - 0
Application/Features/Director/Role/Create/Command.cs

@@ -0,0 +1,6 @@
+using MediatR;
+
+namespace Application.Features.Director.Role.Create
+{
+    public sealed record Command(string? RoleName) : IRequest;
+}

+ 3 - 3
Application/Features/Director/CreateRole/Handler.cs → Application/Features/Director/Role/Create/Handler.cs

@@ -1,11 +1,11 @@
 using Application.Abstractions.Identity;
 using MediatR;
 
-namespace Application.Features.Director.CreateRole
+namespace Application.Features.Director.Role.Create
 {
-    public sealed class Handler(IIdentityRoleWriter roleWriter) : IRequestHandler<CreateRoleCommand>
+    public sealed class Handler(IIdentityRoleWriter roleWriter) : IRequestHandler<Command>
     {
-        public async Task Handle(CreateRoleCommand request, CancellationToken ct)
+        public async Task Handle(Command request, CancellationToken ct)
         {
             await roleWriter.CreateRoleAsync(request.RoleName ?? string.Empty, ct);
         }

+ 6 - 0
Application/Features/Director/Role/Delete/Command.cs

@@ -0,0 +1,6 @@
+using MediatR;
+
+namespace Application.Features.Director.Role.Delete
+{
+    public sealed record Command(string? RoleID) : IRequest;
+}

+ 3 - 3
Application/Features/Director/DeleteRole/Handler.cs → Application/Features/Director/Role/Delete/Handler.cs

@@ -1,11 +1,11 @@
 using Application.Abstractions.Identity;
 using MediatR;
 
-namespace Application.Features.Director.DeleteRole
+namespace Application.Features.Director.Role.Delete
 {
-    public sealed class Handler(IIdentityRoleWriter roleWriter) : IRequestHandler<DeleteRoleCommand>
+    public sealed class Handler(IIdentityRoleWriter roleWriter) : IRequestHandler<Command>
     {
-        public async Task Handle(DeleteRoleCommand request, CancellationToken ct)
+        public async Task Handle(Command request, CancellationToken ct)
         {
             await roleWriter.DeleteRoleAsync(request.RoleID ?? string.Empty, ct);
         }

+ 3 - 3
Application/Features/Director/GetRolePermissions/Handler.cs → Application/Features/Director/Role/Permissions/Get/Handler.cs

@@ -3,11 +3,11 @@ using SharedKernel.Constants;
 using MediatR;
 using System.Data;
 
-namespace Application.Features.Director.GetRolePermissions
+namespace Application.Features.Director.Role.Permissions.Get
 {
-    public sealed class Handler(IIdentityRoleReader roleReader) : IRequestHandler<GetRoleClaimsQuery, Response>
+    public sealed class Handler(IIdentityRoleReader roleReader) : IRequestHandler<Query, Response>
     {
-        public async Task<Response> Handle(GetRoleClaimsQuery request, CancellationToken ct)
+        public async Task<Response> Handle(Query request, CancellationToken ct)
         {
             var roleAndClaims = await roleReader.GetRoleAsync(request.RoleID, ct);
             if (roleAndClaims is null)

+ 6 - 0
Application/Features/Director/Role/Permissions/Get/Query.cs

@@ -0,0 +1,6 @@
+using MediatR;
+
+namespace Application.Features.Director.Role.Permissions.Get
+{
+    public sealed record Query(string RoleID) : IRequest<Response>;
+}

+ 1 - 1
Application/Features/Director/GetRolePermissions/Response.cs → Application/Features/Director/Role/Permissions/Get/Response.cs

@@ -1,4 +1,4 @@
-namespace Application.Features.Director.GetRolePermissions
+namespace Application.Features.Director.Role.Permissions.Get
 {
     public sealed class Response
     {

+ 2 - 2
Application/Features/Director/UpdateRolePermissions/Command.cs → Application/Features/Director/Role/Permissions/Update/Command.cs

@@ -1,9 +1,9 @@
 using Application.Abstractions.Identity.Models;
 using MediatR;
 
-namespace Application.Features.Director.UpdateRolePermissions
+namespace Application.Features.Director.Role.Permissions.Update
 {
-    public sealed record UpdateRolePermissionsCommand(
+    public sealed record Command(
         string RoleID,
         PermissionDto Permissions
     ) : IRequest;

+ 3 - 3
Application/Features/Director/UpdateRolePermissions/Handler.cs → Application/Features/Director/Role/Permissions/Update/Handler.cs

@@ -1,11 +1,11 @@
 using Application.Abstractions.Identity;
 using MediatR;
 
-namespace Application.Features.Director.UpdateRolePermissions
+namespace Application.Features.Director.Role.Permissions.Update
 {
-    public sealed class Handler(IIdentityRoleWriter roleWriter) : IRequestHandler<UpdateRolePermissionsCommand>
+    public sealed class Handler(IIdentityRoleWriter roleWriter) : IRequestHandler<Command>
     {
-        public async Task Handle(UpdateRolePermissionsCommand request, CancellationToken ct)
+        public async Task Handle(Command request, CancellationToken ct)
         {
             await roleWriter.UpdateRoleAsync(request.RoleID, request.Permissions, ct);
         }

+ 3 - 3
Application/Features/Director/GetRoles/Handler.cs → Application/Features/Director/Roles/Get/Handler.cs

@@ -1,11 +1,11 @@
 using Application.Abstractions.Identity;
 using MediatR;
 
-namespace Application.Features.Director.GetRoles
+namespace Application.Features.Director.Roles.Get
 {
-    public sealed class Handler(IIdentityRoleReader roleReader) : IRequestHandler<GetAllRolesQuery, List<Response>>
+    public sealed class Handler(IIdentityRoleReader roleReader) : IRequestHandler<Query, List<Response>>
     {
-        public async Task<List<Response>> Handle(GetAllRolesQuery request, CancellationToken ct)
+        public async Task<List<Response>> Handle(Query request, CancellationToken ct)
         {
             var roles = await roleReader.GetRolesAsync(ct);
 

+ 6 - 0
Application/Features/Director/Roles/Get/Query.cs

@@ -0,0 +1,6 @@
+using MediatR;
+
+namespace Application.Features.Director.Roles.Get
+{
+    public sealed record Query() : IRequest<List<Response>>;
+}

+ 1 - 1
Application/Features/Director/GetRoles/Response.cs → Application/Features/Director/Roles/Get/Response.cs

@@ -1,4 +1,4 @@
-namespace Application.Features.Director.GetRoles
+namespace Application.Features.Director.Roles.Get
 {
     public class Response
     {

+ 3 - 3
Application/Features/Director/GetUser/Handler.cs → Application/Features/Director/User/Get/Handler.cs

@@ -2,11 +2,11 @@
 using Application.Abstractions.Identity.Models;
 using MediatR;
 
-namespace Application.Features.Director.GetUser
+namespace Application.Features.Director.User.Get
 {
-    public sealed class Handler(IIdentityUserReader userReader) : IRequestHandler<GetUserQuery, AspNetUserDto?>
+    public sealed class Handler(IIdentityUserReader userReader) : IRequestHandler<Query, AspNetUserDto?>
     {
-        public async Task<AspNetUserDto?> Handle(GetUserQuery request, CancellationToken ct)
+        public async Task<AspNetUserDto?> Handle(Query request, CancellationToken ct)
         {
             return await userReader.GetUserAsync(request.ID, ct);
         }

+ 7 - 0
Application/Features/Director/User/Get/Query.cs

@@ -0,0 +1,7 @@
+using Application.Abstractions.Identity.Models;
+using MediatR;
+
+namespace Application.Features.Director.User.Get
+{
+    public sealed record Query(string ID) : IRequest<AspNetUserDto?>;
+}

+ 1 - 1
Application/Features/Director/GetUser/Response.cs → Application/Features/Director/User/Get/Response.cs

@@ -1,7 +1,7 @@
 using System.ComponentModel;
 using System.ComponentModel.DataAnnotations;
 
-namespace Application.Features.Director.GetUser
+namespace Application.Features.Director.User.Get
 {
     public class Response
     {

+ 3 - 3
Application/Features/Director/GetUserRoles/Handler.cs → Application/Features/Director/User/GetRoles/Handler.cs

@@ -1,11 +1,11 @@
 using Application.Abstractions.Identity;
 using MediatR;
 
-namespace Application.Features.Director.GetUserRoles
+namespace Application.Features.Director.User.GetRoles
 {
-    public sealed class Handler(IIdentityRoleReader roleReader, IIdentityUserReader userReader) : IRequestHandler<GetUserRolesQuery, Response?>
+    public sealed class Handler(IIdentityRoleReader roleReader, IIdentityUserReader userReader) : IRequestHandler<Query, Response?>
     {
-        public async Task<Response> Handle(GetUserRolesQuery request, CancellationToken ct)
+        public async Task<Response> Handle(Query request, CancellationToken ct)
         {
             var user = await userReader.GetUserAsync(request.UserID, ct);
             if (user == null)

+ 6 - 0
Application/Features/Director/User/GetRoles/Query.cs

@@ -0,0 +1,6 @@
+using MediatR;
+
+namespace Application.Features.Director.User.GetRoles
+{
+    public sealed record Query(string UserID) : IRequest<Response>;
+}

+ 1 - 1
Application/Features/Director/GetUserRoles/Response.cs → Application/Features/Director/User/GetRoles/Response.cs

@@ -1,7 +1,7 @@
 using Application.Abstractions.Identity.Models;
 using System.ComponentModel;
 
-namespace Application.Features.Director.GetUserRoles
+namespace Application.Features.Director.User.GetRoles
 {
     public class Response
     {

+ 2 - 2
Application/Features/Director/UpdateUser/Command.cs → Application/Features/Director/User/Update/Command.cs

@@ -1,8 +1,8 @@
 using MediatR;
 
-namespace Application.Features.Director.UpdateUser
+namespace Application.Features.Director.User.Update
 {
-    public sealed record UpdateUserCommand(
+    public sealed record Command(
         string ID,
         string? FullName,
         string? Email,

+ 3 - 3
Application/Features/Director/UpdateUser/Handler.cs → Application/Features/Director/User/Update/Handler.cs

@@ -2,11 +2,11 @@ using Application.Abstractions.Identity;
 using Application.Abstractions.Identity.Models;
 using MediatR;
 
-namespace Application.Features.Director.UpdateUser
+namespace Application.Features.Director.User.Update
 {
-    public sealed class Handler(IIdentityUserWriter userWriter) : IRequestHandler<UpdateUserCommand>
+    public sealed class Handler(IIdentityUserWriter userWriter) : IRequestHandler<Command>
     {
-        public async Task Handle(UpdateUserCommand request, CancellationToken ct)
+        public async Task Handle(Command request, CancellationToken ct)
         {
             await userWriter.UpdateUserAsync(new ApplicationUserDto
             {

+ 2 - 2
Application/Features/Director/UpdateUserRoles/Command.cs → Application/Features/Director/User/UpdateRoles/Command.cs

@@ -1,9 +1,9 @@
 using Application.Abstractions.Identity.Models;
 using MediatR;
 
-namespace Application.Features.Director.UpdateUserRoles
+namespace Application.Features.Director.User.UpdateRoles
 {
-    public sealed record UpdateUserRolesCommand
+    public sealed record Command
     (
         string UserID,
         UserRolesDto? Roles

+ 3 - 3
Application/Features/Director/UpdateUserRoles/Handler.cs → Application/Features/Director/User/UpdateRoles/Handler.cs

@@ -1,11 +1,11 @@
 using Application.Abstractions.Identity;
 using MediatR;
 
-namespace Application.Features.Director.UpdateUserRoles
+namespace Application.Features.Director.User.UpdateRoles
 {
-    public sealed class Handler(IIdentityUserWriter userWriter) : IRequestHandler<UpdateUserRolesCommand>
+    public sealed class Handler(IIdentityUserWriter userWriter) : IRequestHandler<Command>
     {
-        public async Task Handle(UpdateUserRolesCommand request, CancellationToken ct)
+        public async Task Handle(Command request, CancellationToken ct)
         {
             await userWriter.UpdateUserRolesAsync(request.UserID, request.Roles, ct);
         }

+ 3 - 3
Application/Features/Director/GetUsers/Handler.cs → Application/Features/Director/Users/Get/Handler.cs

@@ -1,11 +1,11 @@
 using Application.Abstractions.Identity;
 using MediatR;
 
-namespace Application.Features.Director.GetUsers
+namespace Application.Features.Director.Users.Get
 {
-    public sealed class Handler(IIdentityUserReader userReader) : IRequestHandler<GetAllUserQuery, List<Response>>
+    public sealed class Handler(IIdentityUserReader userReader) : IRequestHandler<Query, List<Response>>
     {
-        public async Task<List<Response>> Handle(GetAllUserQuery request, CancellationToken ct)
+        public async Task<List<Response>> Handle(Query request, CancellationToken ct)
         {
             var users = await userReader.GetAllUserAsync(ct);
 

+ 6 - 0
Application/Features/Director/Users/Get/Query.cs

@@ -0,0 +1,6 @@
+using MediatR;
+
+namespace Application.Features.Director.Users.Get
+{
+    public sealed record Query() : IRequest<List<Response>>;
+}

+ 1 - 1
Application/Features/Director/GetUsers/Response.cs → Application/Features/Director/Users/Get/Response.cs

@@ -1,4 +1,4 @@
-namespace Application.Features.Director.GetUsers
+namespace Application.Features.Director.Users.Get
 {
     public class Response
     {

+ 0 - 4
Application/Features/ReferenceData/Dtos/BankCodeDto.cs

@@ -1,4 +0,0 @@
-namespace Application.Features.ReferenceData.Dtos
-{
-    public sealed record BankCodeDto(string Value, string Text);
-}

+ 15 - 0
Application/Features/ReferenceData/GetBank/Handler.cs

@@ -0,0 +1,15 @@
+using Domain.Entities.Common.ValueObject;
+using MediatR;
+
+namespace Application.Features.ReferenceData.GetBank
+{
+    public sealed class Handler : IRequestHandler<Query, IReadOnlyList<Response>>
+    {
+        public Task<IReadOnlyList<Response>> Handle(Query request, CancellationToken _)
+        {
+            IReadOnlyList<Response> result = BankCode.List.Select(x => new Response(x.Value, x.Text)).ToList();
+
+            return Task.FromResult(result);
+        }
+    }
+}

+ 6 - 0
Application/Features/ReferenceData/GetBank/Query.cs

@@ -0,0 +1,6 @@
+using MediatR;
+
+namespace Application.Features.ReferenceData.GetBank
+{
+    public sealed record Query : IRequest<IReadOnlyList<Response>>;
+}

+ 4 - 0
Application/Features/ReferenceData/GetBank/Response.cs

@@ -0,0 +1,4 @@
+namespace Application.Features.ReferenceData.GetBank
+{
+    public sealed record Response(string Value, string Text);
+}

+ 0 - 7
Application/Features/ReferenceData/Queries/GetBankCodesQuery.cs

@@ -1,7 +0,0 @@
-using Application.Features.ReferenceData.Dtos;
-using MediatR;
-
-namespace Application.Features.ReferenceData.Queries
-{
-    public sealed record GetBankCodesQuery : IRequest<IReadOnlyList<BankCodeDto>>;
-}

+ 0 - 16
Application/Features/ReferenceData/Queries/GetBankCodesQueryHandler.cs

@@ -1,16 +0,0 @@
-using Application.Features.ReferenceData.Dtos;
-using Domain.Entities.Common.ValueObject;
-using MediatR;
-
-namespace Application.Features.ReferenceData.Queries
-{
-    public sealed class GetBankCodesQueryHandler : IRequestHandler<GetBankCodesQuery, IReadOnlyList<BankCodeDto>>
-    {
-        public Task<IReadOnlyList<BankCodeDto>> Handle(GetBankCodesQuery request, CancellationToken cancellationToken)
-        {
-            IReadOnlyList<BankCodeDto> result = BankCode.List.Select(x => new BankCodeDto(x.Value, x.Text)).ToList();
-
-            return Task.FromResult(result);
-        }
-    }
-}

BIN
tree.txt