From 621d9f4318ffffaa29deda7b72f7b2a14d8a6d5f Mon Sep 17 00:00:00 2001 From: Cardidi Date: Sun, 30 Mar 2025 20:58:15 +0800 Subject: [PATCH] fix: Add type reference info and remove query paged. --- Flawless-Version-Control.sln.DotSettings | 2 + .../Request/QueryPagesRequest.cs | 17 ----- .../Response/CommitSuccessResponse.cs | 3 + .../Response/ListingResponse.cs | 3 + .../Response/PagedResponse.cs | 25 ------- .../Response/PeekResponse.cs | 3 + .../Response/RepositoryCommitResponse.cs | 4 ++ .../Response/ServerStatusResponse.cs | 2 + Flawless.Communication/Shared/LockFileInfo.cs | 3 + .../Controllers/AuthenticationController.cs | 3 +- .../Controllers/RepositoryInnieController.cs | 66 ++++++++----------- .../Controllers/RepositoryOutieController.cs | 34 +++++----- Flawless.Server/Controllers/UserController.cs | 11 +--- Flawless.Server/Flawless.Server.csproj | 4 ++ .../ExceptionTransformMiddleware.cs | 5 +- 15 files changed, 75 insertions(+), 110 deletions(-) create mode 100644 Flawless-Version-Control.sln.DotSettings delete mode 100644 Flawless.Communication/Request/QueryPagesRequest.cs create mode 100644 Flawless.Communication/Response/CommitSuccessResponse.cs create mode 100644 Flawless.Communication/Response/ListingResponse.cs delete mode 100644 Flawless.Communication/Response/PagedResponse.cs create mode 100644 Flawless.Communication/Response/PeekResponse.cs create mode 100644 Flawless.Communication/Response/RepositoryCommitResponse.cs create mode 100644 Flawless.Communication/Shared/LockFileInfo.cs diff --git a/Flawless-Version-Control.sln.DotSettings b/Flawless-Version-Control.sln.DotSettings new file mode 100644 index 0000000..06b71d5 --- /dev/null +++ b/Flawless-Version-Control.sln.DotSettings @@ -0,0 +1,2 @@ + + False \ No newline at end of file diff --git a/Flawless.Communication/Request/QueryPagesRequest.cs b/Flawless.Communication/Request/QueryPagesRequest.cs deleted file mode 100644 index f2d9249..0000000 --- a/Flawless.Communication/Request/QueryPagesRequest.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace Flawless.Communication.Request; - -public class QueryPagesRequest -{ - public required int Offset { get; init; } - - public required int Length { get; init; } - - public T? Parameter { get; init; } -} - -public class QueryPagesRequest -{ - public required int Offset { get; init; } - - public required int Length { get; init; } -} \ No newline at end of file diff --git a/Flawless.Communication/Response/CommitSuccessResponse.cs b/Flawless.Communication/Response/CommitSuccessResponse.cs new file mode 100644 index 0000000..a3dd975 --- /dev/null +++ b/Flawless.Communication/Response/CommitSuccessResponse.cs @@ -0,0 +1,3 @@ +namespace Flawless.Communication.Response; + +public record CommitSuccessResponse(DateTime CommittedOn, Guid CommitId); \ No newline at end of file diff --git a/Flawless.Communication/Response/ListingResponse.cs b/Flawless.Communication/Response/ListingResponse.cs new file mode 100644 index 0000000..8697556 --- /dev/null +++ b/Flawless.Communication/Response/ListingResponse.cs @@ -0,0 +1,3 @@ +namespace Flawless.Communication.Response; + +public record ListingResponse(T[] Result); \ No newline at end of file diff --git a/Flawless.Communication/Response/PagedResponse.cs b/Flawless.Communication/Response/PagedResponse.cs deleted file mode 100644 index 5be4a86..0000000 --- a/Flawless.Communication/Response/PagedResponse.cs +++ /dev/null @@ -1,25 +0,0 @@ -namespace Flawless.Communication.Response; - -public record PagedResponse -{ - public required int Offset { get; init; } - - public required int Length { get; init; } - - public int? Total { get; init; } - - public IEnumerable? Data { get; init; } -} - -public record PagedResponse -{ - public required int Offset { get; init; } - - public required int Length { get; init; } - - public int? Total { get; init; } - - public IEnumerable? Data { get; init; } - - public TMetadata? Metadata { get; init; } -} \ No newline at end of file diff --git a/Flawless.Communication/Response/PeekResponse.cs b/Flawless.Communication/Response/PeekResponse.cs new file mode 100644 index 0000000..ba536b6 --- /dev/null +++ b/Flawless.Communication/Response/PeekResponse.cs @@ -0,0 +1,3 @@ +namespace Flawless.Communication.Response; + +public record PeekResponse(T Result); \ No newline at end of file diff --git a/Flawless.Communication/Response/RepositoryCommitResponse.cs b/Flawless.Communication/Response/RepositoryCommitResponse.cs new file mode 100644 index 0000000..a034cb8 --- /dev/null +++ b/Flawless.Communication/Response/RepositoryCommitResponse.cs @@ -0,0 +1,4 @@ +namespace Flawless.Communication.Response; + +public record RepositoryCommitResponse( + Guid Id, string Author, DateTime CommitedOn, string Message, Guid MainDepotId); \ No newline at end of file diff --git a/Flawless.Communication/Response/ServerStatusResponse.cs b/Flawless.Communication/Response/ServerStatusResponse.cs index b0991c8..4b08e9d 100644 --- a/Flawless.Communication/Response/ServerStatusResponse.cs +++ b/Flawless.Communication/Response/ServerStatusResponse.cs @@ -2,5 +2,7 @@ public record ServerStatusResponse { + public required string? FriendlyName { get; init; } + public required bool AllowPublicRegister { get; set; } } \ No newline at end of file diff --git a/Flawless.Communication/Shared/LockFileInfo.cs b/Flawless.Communication/Shared/LockFileInfo.cs new file mode 100644 index 0000000..26d3eac --- /dev/null +++ b/Flawless.Communication/Shared/LockFileInfo.cs @@ -0,0 +1,3 @@ +namespace Flawless.Communication.Shared; + +public record LockFileInfo(string Path, string Owner); \ No newline at end of file diff --git a/Flawless.Server/Controllers/AuthenticationController.cs b/Flawless.Server/Controllers/AuthenticationController.cs index 69558a3..27de4fd 100644 --- a/Flawless.Server/Controllers/AuthenticationController.cs +++ b/Flawless.Server/Controllers/AuthenticationController.cs @@ -27,7 +27,8 @@ public class AuthenticationController( { return Task.FromResult>(Ok(new ServerStatusResponse() { - AllowPublicRegister = true + AllowPublicRegister = true, + FriendlyName = "Ca2didi Server" })); } diff --git a/Flawless.Server/Controllers/RepositoryInnieController.cs b/Flawless.Server/Controllers/RepositoryInnieController.cs index 2abad88..eadc4da 100644 --- a/Flawless.Server/Controllers/RepositoryInnieController.cs +++ b/Flawless.Server/Controllers/RepositoryInnieController.cs @@ -13,6 +13,7 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; +using Microsoft.OpenApi.Validations.Rules; namespace Flawless.Server.Controllers; @@ -108,7 +109,7 @@ public class RepositoryInnieController( } [HttpGet("get_users")] - public async Task GetUsersAsync(string repositoryName, QueryPagesRequest r) + public async Task>> GetUsersAsync(string repositoryName) { if (string.IsNullOrWhiteSpace(repositoryName) || repositoryName.Length <= 3) return BadRequest(new FailedResponse("Repository name is empty or too short!")); @@ -122,17 +123,11 @@ public class RepositoryInnieController( if (rp == null) return BadRequest(new FailedResponse("Repository not found!")); - return Ok(new PagedResponse + return Ok(new ListingResponse(rp.Members.Select(pm => new RepoUserRole { - Length = r.Length, - Offset = r.Offset, - Total = rp.Members.Count, - Data = rp.Members.Select(pm => new RepoUserRole - { - Username = pm.User.UserName!, - Role = pm.Role - }) - }); + Username = pm.User.UserName!, + Role = pm.Role + }).ToArray())); } [HttpPost("update_user")] @@ -230,6 +225,7 @@ public class RepositoryInnieController( [HttpGet("fetch_manifest")] + [ProducesResponseType(200)] public async Task DownloadManifestAsync(string userName, string repositoryName, [FromQuery] string commitId) { if (!Guid.TryParse(commitId, out var commitGuid)) return BadRequest(new FailedResponse("Invalid commit id")); @@ -245,6 +241,7 @@ public class RepositoryInnieController( [HttpGet("fetch_depot")] + [ProducesResponseType(200)] public async Task DownloadDepotAsync(string userName, string repositoryName, [FromQuery] string depotId) { if (!Guid.TryParse(depotId, out var depotGuid)) return BadRequest(new FailedResponse("Invalid depot id")); @@ -260,50 +257,49 @@ public class RepositoryInnieController( } [HttpGet("list_commit")] - public async Task ListCommitsAsync(string userName, string repositoryName) + public async Task>> ListCommitsAsync(string userName, string repositoryName) { var user = (await userManager.GetUserAsync(HttpContext.User))!; var grantIssue = await ValidateRepositoryAsync(userName, repositoryName, user, RepositoryRole.Guest); - if (grantIssue is not Repository) return (IActionResult) grantIssue; + if (grantIssue is not Repository) return (ActionResult) grantIssue; - var commit = await dbContext.Repositories + var commit = dbContext.Repositories .Where(r => r.Owner.UserName == userName && r.Name == repositoryName) .SelectMany(r => r.Commits) - .Include(r => r.Author) + .Include(r => r.Author).Include(repositoryCommit => repositoryCommit.MainDepot) .OrderByDescending(r => r.CommittedOn) - .ToArrayAsync(); + .AsAsyncEnumerable(); - return Ok(new - { - Commits = commit - }); + List r = new(); + await foreach (var cm in commit) + r.Add(new RepositoryCommitResponse( + cm.Id, cm.Author.UserName!, cm.CommittedOn, cm.Message, cm.MainDepot.DepotId)); + + return Ok(new ListingResponse(r.ToArray())); } [HttpGet("list_locked_files")] - public async Task ListLocksAsync(string userName, string repositoryName) + public async Task>> ListLocksAsync(string userName, string repositoryName) { var user = (await userManager.GetUserAsync(HttpContext.User))!; var grantIssue = await ValidateRepositoryAsync(userName, repositoryName, user, RepositoryRole.Developer); - if (grantIssue is not Repository) return (IActionResult) grantIssue; + if (grantIssue is not Repository) return (ActionResult) grantIssue; var lockers = await dbContext.Repositories .Where(r => r.Owner.UserName == userName && r.Name == repositoryName) .SelectMany(r => r.Locked) - .Select(l => new { Path = l.Path, Owner = l.LockDownUser.UserName}) + .Select(l => new LockFileInfo(l.Path, l.LockDownUser.UserName)) .ToArrayAsync(); - return Ok(new - { - Lockers = lockers - }); + return Ok(new ListingResponse(lockers)); } [HttpGet("peek_commit")] - public async Task PeekCommitAsync(string userName, string repositoryName) + public async Task>> PeekCommitAsync(string userName, string repositoryName) { var user = (await userManager.GetUserAsync(HttpContext.User))!; var grantIssue = await ValidateRepositoryAsync(userName, repositoryName, user, RepositoryRole.Guest); - if (grantIssue is not Repository rp) return (IActionResult) grantIssue; + if (grantIssue is not Repository rp) return (ActionResult) grantIssue; var commit = await dbContext.Repositories .Where(r => r.Owner.UserName == userName && r.Name == repositoryName) @@ -312,10 +308,7 @@ public class RepositoryInnieController( .OrderByDescending(r => r.CommittedOn) .FirstOrDefaultAsync(); - return Ok(new - { - Commit = commit?.Id.ToString() ?? string.Empty - }); + return Ok(new PeekResponse(commit?.Id ?? Guid.Empty)); } @@ -394,6 +387,7 @@ public class RepositoryInnieController( } [HttpPost("create_commit")] + [ProducesResponseType(200)] public async Task CommitAsync(string userName, string repositoryName, [FromForm] FormCommitRequest req) { var user = (await userManager.GetUserAsync(HttpContext.User))!; @@ -538,11 +532,7 @@ public class RepositoryInnieController( throw; } - return Ok(new - { - CreatedAt = commit.CommittedOn, - CommitId = commit.Id - }); + return Ok(new CommitSuccessResponse(commit.CommittedOn, commit.Id)); } private static async ValueTask StencilWorkspaceSnapshotAsync(Stream depotStream, HashSet unresolved) diff --git a/Flawless.Server/Controllers/RepositoryOutieController.cs b/Flawless.Server/Controllers/RepositoryOutieController.cs index eb425ac..fcf0f4d 100644 --- a/Flawless.Server/Controllers/RepositoryOutieController.cs +++ b/Flawless.Server/Controllers/RepositoryOutieController.cs @@ -14,34 +14,30 @@ namespace Flawless.Server.Controllers; [ApiController, Authorize, Route("api")] public class RepositoryOutieController(AppDbContext dbContext, UserManager userManager) : ControllerBase { + [HttpGet("repo_list")] - public async Task ListAllAvailableRepositoriesAsync([FromQuery] QueryPagesRequest r) + public async Task>> ListAllAvailableRepositoriesAsync() { var u = (await userManager.GetUserAsync(HttpContext.User))!; - var query = await dbContext.Repositories + var query = dbContext.Repositories .Include(repository => repository.Owner) .Include(repository => repository.Commits) .Include(repository => repository.Members) .ThenInclude(repositoryMember => repositoryMember.User) .Where(rp => rp.Members.Any(m => m.User == u)) - .Skip(r.Offset) - .Take(r.Length) - .ToArrayAsync(); + .Select(rp => new RepositoryInfoResponse + { + RepositoryName = rp.Name, + OwnerUsername = rp.Owner.UserName!, + LatestCommitId = rp.Commits.OrderByDescending(cm => cm.CommittedOn) + .Select(cm => cm.Id).FirstOrDefault(), + Description = rp.Description, + IsArchived = rp.IsArchived, + Role = rp.Members.First(m => m.User == u).Role + }) + .ToArray(); - return Ok(new PagedResponse - { - Length = r.Length, - Offset = r.Offset, - Data = query.Select(rp => new RepositoryInfoResponse - { - RepositoryName = rp.Name, - OwnerUsername = rp.Owner.UserName!, - LatestCommitId = rp.Commits.OrderByDescending(cm => cm.CommittedOn).FirstOrDefault()?.Id ?? Guid.Empty, - Description = rp.Description, - IsArchived = rp.IsArchived, - Role = rp.Members.First(m => m.User == u).Role - }), - }); + return Ok(new ListingResponse(query)); } [HttpPost("repo_create")] diff --git a/Flawless.Server/Controllers/UserController.cs b/Flawless.Server/Controllers/UserController.cs index 5dc08b2..2981f27 100644 --- a/Flawless.Server/Controllers/UserController.cs +++ b/Flawless.Server/Controllers/UserController.cs @@ -94,22 +94,15 @@ public class UserController( } [HttpGet("query_info")] - public async Task>> GetUserInfoAsync(QueryPagesRequest r, [FromQuery] string keyword) + public async Task>> QueryUserInfoAsync([FromQuery] string keyword) { var payload = await userManager.Users .Where(u => u.UserName!.Contains(keyword) || (u.NickName != null && u.NickName.Contains(keyword))) - .Skip(r.Offset) - .Take(r.Length) .Select(u => GetUserInfoInternal(u, null)) .ToArrayAsync(); // Return self as default - return Ok(new PagedResponse - { - Offset = r.Offset, - Length = r.Length, - Data = payload - }); + return Ok(new ListingResponse(payload)); } [HttpGet("delete")] diff --git a/Flawless.Server/Flawless.Server.csproj b/Flawless.Server/Flawless.Server.csproj index e5322e7..a8990ac 100644 --- a/Flawless.Server/Flawless.Server.csproj +++ b/Flawless.Server/Flawless.Server.csproj @@ -37,4 +37,8 @@ + + + + diff --git a/Flawless.Server/Middlewares/ExceptionTransformMiddleware.cs b/Flawless.Server/Middlewares/ExceptionTransformMiddleware.cs index 6d26f2c..1f2ef19 100644 --- a/Flawless.Server/Middlewares/ExceptionTransformMiddleware.cs +++ b/Flawless.Server/Middlewares/ExceptionTransformMiddleware.cs @@ -6,7 +6,10 @@ public class ExceptionTransformMiddleware(RequestDelegate next) { public async Task InvokeAsync(HttpContext context) { - try { await next(context); } + try + { + await next(context); + } catch (Exception e) { context.Response.StatusCode = 500;