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;