using Carter; using Knot.Modules.Auth.Application.Auth.DTOs; using Knot.Shared.Kernel; using Knot.Modules.Settings.Application.Settings.Abstractions; using Knot.Modules.Settings.Application.Settings.DTOs; using Knot.Modules.Auth.Application.Users.Register; using Knot.Shared.Kernel.Storage; using Knot.Modules.Auth.Infrastructure.Persistence; using MediatR; using Knot.Modules.Admin.Application.Admin.Queries; using Knot.Modules.Admin.Application.Admin.Commands; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Mvc; using Knot.Modules.Admin.Application.Admin.Commands.TestKlipy; namespace Knot.Host.Presentation.Endpoints; public sealed class AdminEndpoints : ICarterModule { public void AddRoutes(IEndpointRouteBuilder app) { var group = app.MapGroup("api/admin"); // Middleware handles auth group.MapGet("settings", async (ISender sender, CancellationToken ct) => { var result = await sender.Send(new GetSettingsQuery(), ct); return Results.Ok(result.Value); }); group.MapPut("settings", async ([FromBody] SystemSettingsDto settings, ISender sender, CancellationToken ct) => { var result = await sender.Send(new UpdateSettingsCommand(settings), ct); return Results.Ok(result.Value); }); group.MapPost("settings/test-klipy", async (ISender sender, CancellationToken ct) => { var result = await sender.Send(new TestKlipyConnectionCommand(), ct); return result.IsSuccess ? Results.Ok(new { success = true }) : Results.BadRequest(new { error = result.Error.Description }); }); group.MapGet("dashboard", async (ISender sender, CancellationToken ct) => { var result = await sender.Send(new GetDashboardStatsQuery(), ct); return Results.Ok(result.Value); }); group.MapPost("users", async ([FromBody] RegisterUserCommand command, ISender sender, CancellationToken ct) => { var result = await sender.Send(command, ct); if (result.IsFailure) return Results.BadRequest(new { error = result.Error.Description }); var userDetails = await sender.Send(new GetUserDetailsQuery(result.Value.User.Id), ct); return Results.Ok(userDetails.Value); }); group.MapPost("users/{userId:guid}/reset-password", async (Guid userId, [FromBody] ResetPasswordDto dto, ISender sender, CancellationToken ct) => { var result = await sender.Send(new ResetUserPasswordCommand(userId, dto.NewPassword), ct); if (result.IsFailure) { if (result.Error.Code == "User.NotFound") return Results.NotFound(new { error = "User not found" }); return Results.BadRequest(new { error = result.Error.Description }); } return Results.Ok(result.Value); }); group.MapGet("users", async (ISender sender, [FromQuery] string query = "", CancellationToken ct = default) => { var result = await sender.Send(new SearchUsersQuery(query), ct); return Results.Ok(result.Value); }); group.MapGet("users/{id:guid}", async (Guid id, ISender sender, CancellationToken ct) => { var result = await sender.Send(new GetUserDetailsQuery(id), ct); return result.IsSuccess ? Results.Ok(result.Value) : Results.NotFound("User not found"); }); group.MapGet("clean/dry-run", async (IFileStorageService fileStorage, AuthDbContext identityDb, ISender sender, CancellationToken ct) => { var result = await sender.Send(new CleanDryRunQuery(fileStorage, identityDb), ct); return Results.Ok(result.Value); }); group.MapPost("clean/run", async (IFileStorageService fileStorage, AuthDbContext identityDb, ISender sender, CancellationToken ct) => { var result = await sender.Send(new CleanRunCommand(fileStorage, identityDb), ct); return Results.Ok(result.Value); }); } }