Skip to content

Commit 0b9cbb0

Browse files
authored
Removed dead endpoint and de-duplicated exam/plugin-version logic (#212)
1 parent 69a7fc4 commit 0b9cbb0

6 files changed

Lines changed: 42 additions & 53 deletions

File tree

src/Schuly.API/Controllers/AppController.cs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,5 @@ public async Task<IActionResult> GetSchoolSystems(CancellationToken cancellation
3131
var result = await mediator.Send(new GetSchoolSystemsQuery(), cancellationToken);
3232
return result.ToActionResult();
3333
}
34-
35-
[HttpGet("test", Name = "TestEndpointWithAuth")]
36-
[ProducesResponseType(StatusCodes.Status200OK)]
37-
public IActionResult Test()
38-
{
39-
return Ok();
40-
}
4134
}
4235
}

src/Schuly.API/Plugins/PluginManager.cs

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -96,20 +96,7 @@ public async Task RemoveAsync(string name, CancellationToken ct = default)
9696
private static RegistryPlugin? Resolve(IReadOnlyList<RegistryPlugin> index, string name, string? version)
9797
{
9898
var entry = index.FirstOrDefault(p => p.Name.Equals(name, StringComparison.OrdinalIgnoreCase));
99-
if (entry is null) return null;
100-
101-
if (!string.IsNullOrWhiteSpace(version) &&
102-
!version.Equals("latest", StringComparison.OrdinalIgnoreCase) &&
103-
!version.Equals(entry.Version, StringComparison.OrdinalIgnoreCase))
104-
{
105-
return entry with
106-
{
107-
Version = version,
108-
Dll = $"{entry.Name}-v{version}.dll",
109-
Deps = $"{entry.Name}-v{version}-deps.zip",
110-
};
111-
}
112-
return entry;
99+
return entry?.WithPinnedVersion(version);
113100
}
114101
}
115102
}

src/Schuly.API/Plugins/PluginRegistry.cs

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,23 @@ public sealed record RegistryPlugin
1313
[JsonPropertyName("version")] public string Version { get; init; } = "";
1414
[JsonPropertyName("description")] public string? Description { get; init; }
1515
[JsonPropertyName("authors")] public string? Authors { get; init; }
16+
17+
// A pinned version that differs from the index's current one: the registry
18+
// keeps every build under dll/<name>-v<ver>.dll, so synthesize the filenames.
19+
public RegistryPlugin WithPinnedVersion(string? version)
20+
{
21+
if (string.IsNullOrWhiteSpace(version) ||
22+
version.Equals("latest", StringComparison.OrdinalIgnoreCase) ||
23+
version.Equals(Version, StringComparison.OrdinalIgnoreCase))
24+
return this;
25+
26+
return this with
27+
{
28+
Version = version,
29+
Dll = $"{Name}-v{version}.dll",
30+
Deps = $"{Name}-v{version}-deps.zip",
31+
};
32+
}
1633
}
1734

1835
/// <summary>
@@ -39,24 +56,7 @@ public async Task<IReadOnlyList<RegistryPlugin>> FetchIndexAsync(CancellationTok
3956
{
4057
var index = await FetchIndexAsync(ct);
4158
var entry = index.FirstOrDefault(p => p.Name.Equals(name, StringComparison.OrdinalIgnoreCase));
42-
if (entry is null)
43-
return null;
44-
45-
// A pinned version that differs from the index's current one: the registry
46-
// keeps every build under dll/<name>-v<ver>.dll, so synthesize the filenames.
47-
if (!string.IsNullOrWhiteSpace(version) &&
48-
!version.Equals("latest", StringComparison.OrdinalIgnoreCase) &&
49-
!version.Equals(entry.Version, StringComparison.OrdinalIgnoreCase))
50-
{
51-
return entry with
52-
{
53-
Version = version,
54-
Dll = $"{entry.Name}-v{version}.dll",
55-
Deps = $"{entry.Name}-v{version}-deps.zip",
56-
};
57-
}
58-
59-
return entry;
59+
return entry?.WithPinnedVersion(version);
6060
}
6161

6262
public Task<byte[]> DownloadArtifactAsync(string file, CancellationToken ct = default) =>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using Microsoft.EntityFrameworkCore;
2+
3+
namespace Schuly.Application.Queries.Exam
4+
{
5+
internal static class ExamQueryExtensions
6+
{
7+
// Student visibility: only exams for a class the user is enrolled in, with
8+
// only the user's own grades projected - never a classmate's. Admins see all.
9+
public static IQueryable<Domain.Exam> ApplyVisibility(this IQueryable<Domain.Exam> exams, bool isAdmin, IReadOnlyList<Guid> myIds)
10+
{
11+
IQueryable<Domain.Exam> scoped = exams.AsNoTracking().Include(e => e.Class);
12+
13+
if (!isAdmin)
14+
scoped = scoped.Where(e => e.Class!.Students.Any(su => myIds.Contains(su.Id)));
15+
16+
return scoped.Include(e => e.Grades.Where(g => isAdmin || myIds.Contains(g.SchoolUserId)));
17+
}
18+
}
19+
}

src/Schuly.Application/Queries/Exam/GetExamQuery.cs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,8 @@ public async ValueTask<Result<ExamDto>> Handle(GetExamQuery query, CancellationT
2121
var isAdmin = userService.IsCurrentUserAdmin();
2222
IReadOnlyList<Guid> myIds = isAdmin ? [] : await userService.GetCurrentUserSchoolUserIdsAsync(cancellationToken);
2323

24-
IQueryable<Domain.Exam> dbQuery = dbContext.Exams.AsNoTracking().Include(e => e.Class);
25-
26-
if (!isAdmin)
27-
dbQuery = dbQuery.Where(e => e.Class!.Students.Any(su => myIds.Contains(su.Id)));
28-
29-
var exam = await dbQuery
30-
.Include(e => e.Grades.Where(g => isAdmin || myIds.Contains(g.SchoolUserId)))
24+
var exam = await dbContext.Exams
25+
.ApplyVisibility(isAdmin, myIds)
3126
.SingleOrDefaultAsync(e => e.Id == query.ExamId, cancellationToken);
3227

3328
if (exam == null)

src/Schuly.Application/Queries/Exam/GetExamsQuery.cs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,8 @@ public async ValueTask<Result<List<ExamDto>>> Handle(GetExamsQuery query, Cancel
2121
var isAdmin = userService.IsCurrentUserAdmin();
2222
IReadOnlyList<Guid> myIds = isAdmin ? [] : await userService.GetCurrentUserSchoolUserIdsAsync(cancellationToken);
2323

24-
IQueryable<Domain.Exam> dbQuery = dbContext.Exams.AsNoTracking().Include(e => e.Class);
25-
26-
if (!isAdmin)
27-
dbQuery = dbQuery.Where(e => e.Class!.Students.Any(su => myIds.Contains(su.Id)));
28-
29-
var exams = await dbQuery
30-
.Include(e => e.Grades.Where(g => isAdmin || myIds.Contains(g.SchoolUserId)))
24+
var exams = await dbContext.Exams
25+
.ApplyVisibility(isAdmin, myIds)
3126
.ToListAsync(cancellationToken);
3227

3328
return Result<List<ExamDto>>.Success(exams.ToDto());

0 commit comments

Comments
 (0)