fix: Add type reference info and remove query paged.
This commit is contained in:
parent
d2041ea5e4
commit
621d9f4318
2
Flawless-Version-Control.sln.DotSettings
Normal file
2
Flawless-Version-Control.sln.DotSettings
Normal file
@ -0,0 +1,2 @@
|
||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:Boolean x:Key="/Default/CodeEditing/SuppressUninitializedWarningFix/Enabled/@EntryValue">False</s:Boolean></wpf:ResourceDictionary>
|
||||
@ -1,17 +0,0 @@
|
||||
namespace Flawless.Communication.Request;
|
||||
|
||||
public class QueryPagesRequest<T>
|
||||
{
|
||||
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; }
|
||||
}
|
||||
3
Flawless.Communication/Response/CommitSuccessResponse.cs
Normal file
3
Flawless.Communication/Response/CommitSuccessResponse.cs
Normal file
@ -0,0 +1,3 @@
|
||||
namespace Flawless.Communication.Response;
|
||||
|
||||
public record CommitSuccessResponse(DateTime CommittedOn, Guid CommitId);
|
||||
3
Flawless.Communication/Response/ListingResponse.cs
Normal file
3
Flawless.Communication/Response/ListingResponse.cs
Normal file
@ -0,0 +1,3 @@
|
||||
namespace Flawless.Communication.Response;
|
||||
|
||||
public record ListingResponse<T>(T[] Result);
|
||||
@ -1,25 +0,0 @@
|
||||
namespace Flawless.Communication.Response;
|
||||
|
||||
public record PagedResponse<T>
|
||||
{
|
||||
public required int Offset { get; init; }
|
||||
|
||||
public required int Length { get; init; }
|
||||
|
||||
public int? Total { get; init; }
|
||||
|
||||
public IEnumerable<T>? Data { get; init; }
|
||||
}
|
||||
|
||||
public record PagedResponse<TData, TMetadata>
|
||||
{
|
||||
public required int Offset { get; init; }
|
||||
|
||||
public required int Length { get; init; }
|
||||
|
||||
public int? Total { get; init; }
|
||||
|
||||
public IEnumerable<TData>? Data { get; init; }
|
||||
|
||||
public TMetadata? Metadata { get; init; }
|
||||
}
|
||||
3
Flawless.Communication/Response/PeekResponse.cs
Normal file
3
Flawless.Communication/Response/PeekResponse.cs
Normal file
@ -0,0 +1,3 @@
|
||||
namespace Flawless.Communication.Response;
|
||||
|
||||
public record PeekResponse<T>(T Result);
|
||||
@ -0,0 +1,4 @@
|
||||
namespace Flawless.Communication.Response;
|
||||
|
||||
public record RepositoryCommitResponse(
|
||||
Guid Id, string Author, DateTime CommitedOn, string Message, Guid MainDepotId);
|
||||
@ -2,5 +2,7 @@
|
||||
|
||||
public record ServerStatusResponse
|
||||
{
|
||||
public required string? FriendlyName { get; init; }
|
||||
|
||||
public required bool AllowPublicRegister { get; set; }
|
||||
}
|
||||
3
Flawless.Communication/Shared/LockFileInfo.cs
Normal file
3
Flawless.Communication/Shared/LockFileInfo.cs
Normal file
@ -0,0 +1,3 @@
|
||||
namespace Flawless.Communication.Shared;
|
||||
|
||||
public record LockFileInfo(string Path, string Owner);
|
||||
@ -27,7 +27,8 @@ public class AuthenticationController(
|
||||
{
|
||||
return Task.FromResult<ActionResult<ServerStatusResponse>>(Ok(new ServerStatusResponse()
|
||||
{
|
||||
AllowPublicRegister = true
|
||||
AllowPublicRegister = true,
|
||||
FriendlyName = "Ca2didi Server"
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
@ -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<IActionResult> GetUsersAsync(string repositoryName, QueryPagesRequest r)
|
||||
public async Task<ActionResult<ListingResponse<RepoUserRole>>> 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<RepoUserRole>
|
||||
{
|
||||
Length = r.Length,
|
||||
Offset = r.Offset,
|
||||
Total = rp.Members.Count,
|
||||
Data = rp.Members.Select(pm => new RepoUserRole
|
||||
return Ok(new ListingResponse<RepoUserRole>(rp.Members.Select(pm => new RepoUserRole
|
||||
{
|
||||
Username = pm.User.UserName!,
|
||||
Role = pm.Role
|
||||
})
|
||||
});
|
||||
}).ToArray()));
|
||||
}
|
||||
|
||||
[HttpPost("update_user")]
|
||||
@ -230,6 +225,7 @@ public class RepositoryInnieController(
|
||||
|
||||
|
||||
[HttpGet("fetch_manifest")]
|
||||
[ProducesResponseType<FileStreamResult>(200)]
|
||||
public async Task<IActionResult> 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<FileStreamResult>(200)]
|
||||
public async Task<IActionResult> 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<IActionResult> ListCommitsAsync(string userName, string repositoryName)
|
||||
public async Task<ActionResult<ListingResponse<RepositoryCommitResponse>>> 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<RepositoryCommitResponse> 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<RepositoryCommitResponse>(r.ToArray()));
|
||||
}
|
||||
|
||||
[HttpGet("list_locked_files")]
|
||||
public async Task<IActionResult> ListLocksAsync(string userName, string repositoryName)
|
||||
public async Task<ActionResult<ListingResponse<LockFileInfo>>> 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<LockFileInfo>(lockers));
|
||||
}
|
||||
|
||||
[HttpGet("peek_commit")]
|
||||
public async Task<IActionResult> PeekCommitAsync(string userName, string repositoryName)
|
||||
public async Task<ActionResult<PeekResponse<Guid>>> 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<Guid>(commit?.Id ?? Guid.Empty));
|
||||
}
|
||||
|
||||
|
||||
@ -394,6 +387,7 @@ public class RepositoryInnieController(
|
||||
}
|
||||
|
||||
[HttpPost("create_commit")]
|
||||
[ProducesResponseType<CommitSuccessResponse>(200)]
|
||||
public async Task<IActionResult> 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<WorkspaceFile> unresolved)
|
||||
|
||||
@ -14,34 +14,30 @@ namespace Flawless.Server.Controllers;
|
||||
[ApiController, Authorize, Route("api")]
|
||||
public class RepositoryOutieController(AppDbContext dbContext, UserManager<AppUser> userManager) : ControllerBase
|
||||
{
|
||||
|
||||
[HttpGet("repo_list")]
|
||||
public async Task<IActionResult> ListAllAvailableRepositoriesAsync([FromQuery] QueryPagesRequest r)
|
||||
public async Task<ActionResult<ListingResponse<RepositoryInfoResponse>>> 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();
|
||||
|
||||
return Ok(new PagedResponse<RepositoryInfoResponse>
|
||||
{
|
||||
Length = r.Length,
|
||||
Offset = r.Offset,
|
||||
Data = query.Select(rp => new RepositoryInfoResponse
|
||||
.Select(rp => new RepositoryInfoResponse
|
||||
{
|
||||
RepositoryName = rp.Name,
|
||||
OwnerUsername = rp.Owner.UserName!,
|
||||
LatestCommitId = rp.Commits.OrderByDescending(cm => cm.CommittedOn).FirstOrDefault()?.Id ?? Guid.Empty,
|
||||
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 ListingResponse<RepositoryInfoResponse>(query));
|
||||
}
|
||||
|
||||
[HttpPost("repo_create")]
|
||||
|
||||
@ -94,22 +94,15 @@ public class UserController(
|
||||
}
|
||||
|
||||
[HttpGet("query_info")]
|
||||
public async Task<ActionResult<PagedResponse<UserInfoResponse>>> GetUserInfoAsync(QueryPagesRequest r, [FromQuery] string keyword)
|
||||
public async Task<ActionResult<ListingResponse<UserInfoResponse>>> 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<UserInfoResponse>
|
||||
{
|
||||
Offset = r.Offset,
|
||||
Length = r.Length,
|
||||
Data = payload
|
||||
});
|
||||
return Ok(new ListingResponse<UserInfoResponse>(payload));
|
||||
}
|
||||
|
||||
[HttpGet("delete")]
|
||||
|
||||
@ -37,4 +37,8 @@
|
||||
<Compile Remove="Migrations\20250322194407_InitialCreate.Designer.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Exceptions\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user