Skip to content

Commit 525c1e6

Browse files
refactor: changed the EventBus credits, combined the sending and evaluation of the LTI solution, and fixed a bug in the validation of the HW
1 parent b6a268b commit 525c1e6

8 files changed

Lines changed: 110 additions & 112 deletions

File tree

HwProj.APIGateway/HwProj.APIGateway.API/HwProj.APIGateway.API.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
</ItemGroup>
2222

2323
<ItemGroup>
24-
<PackageReference Include="LtiAdvantage" Version="2.0.1" />
24+
<PackageReference Include="LtiAdvantage" Version="3.0.0" />
2525
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.20" />
2626
<PackageReference Include="Swashbuckle.AspNetCore" Version="9.0.4" />
2727
<PackageReference Include="AutoMapper" Version="15.0.1" />

HwProj.APIGateway/HwProj.APIGateway.API/Lti/Controllers/LtiAssignmentsGradesControllers.cs

Lines changed: 7 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,13 @@ public async Task<IActionResult> UpdateTaskScore(long taskId, [FromBody] Score s
6363

6464
try
6565
{
66-
await this.SetTaskGrade(taskId, score);
66+
await solutionsClient.PostAndRateSolutionForLti(
67+
taskId: taskId,
68+
userId: score.UserId,
69+
scoreGiven: score.ScoreGiven,
70+
scoreMaximum: score.ScoreMaximum,
71+
comment: $"Результат: {score.ScoreGiven}/{score.ScoreMaximum}\n\n" + score.Comment);
72+
6773
return Ok(new { message = "Score updated successfully" });
6874
}
6975
catch (KeyNotFoundException ex)
@@ -75,25 +81,4 @@ public async Task<IActionResult> UpdateTaskScore(long taskId, [FromBody] Score s
7581
return StatusCode(500, "Internal Server Error");
7682
}
7783
}
78-
79-
private async Task SetTaskGrade(long taskId, Score score)
80-
{
81-
var postSolutionModel = new PostSolutionModel
82-
{
83-
StudentId = score.UserId,
84-
LecturerComment = score.Comment,
85-
Rating = (int)Math.Round(score.ScoreGiven)
86-
};
87-
88-
89-
var solutionId = await solutionsClient.PostSolutionForLti(taskId, postSolutionModel);
90-
91-
var rate = new RateSolutionModel
92-
{
93-
Rating = (int)Math.Round(score.ScoreGiven),
94-
LecturerComment = score.Comment
95-
};
96-
97-
await solutionsClient.RateSolutionForLti(solutionId, rate);
98-
}
9984
}

HwProj.CoursesService/HwProj.CoursesService.API/Controllers/HomeworksController.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ public async Task<IActionResult> UpdateHomework(long homeworkId,
5454
[FromBody] CreateHomeworkViewModel homeworkViewModel)
5555
{
5656
var homework = await _homeworksService.GetForEditingHomeworkAsync(homeworkId);
57-
var validationResult = Validator.ValidateHomework(homeworkViewModel, homework);
57+
var validationResult = Validator.ValidateHomework(homeworkViewModel,
58+
homework);
5859
if (validationResult.Any()) return BadRequest(validationResult);
5960

6061
var updatedHomework = await _homeworksService.UpdateHomeworkAsync(homeworkId, homeworkViewModel);

HwProj.CoursesService/HwProj.CoursesService.API/Domains/Validations.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,15 @@ public static List<string> ValidateHomework(CreateHomeworkViewModel homework, Ho
7676
{
7777
var errors = new List<string>();
7878

79-
homework.Tasks.ForEach(task => errors.AddRange(ValidateTask(task, homework.ToHomework().ToHomeworkViewModel())));
79+
var homeworkContext = new HomeworkViewModel()
80+
{
81+
PublicationDate = homework.PublicationDate,
82+
DeadlineDate = homework.DeadlineDate,
83+
HasDeadline = homework.HasDeadline,
84+
IsDeadlineStrict = homework.IsDeadlineStrict
85+
};
86+
87+
homework.Tasks.ForEach(task => errors.AddRange(ValidateTask(task, homeworkContext)));
8088

8189
if (homework.HasDeadline == false && homework.DeadlineDate != null)
8290
{

HwProj.SolutionsService/HwProj.SolutionsService.API/Controllers/SolutionsController.cs

Lines changed: 50 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -72,28 +72,67 @@ public async Task<Solution[]> GetTaskSolutionsFromStudent(long taskId, string st
7272
[ProducesResponseType(typeof(long), (int)HttpStatusCode.OK)]
7373
public async Task<IActionResult> PostSolution(long taskId, [FromBody] PostSolutionModel solutionModel)
7474
{
75-
return await PostSolutionInternal(taskId, solutionModel);
75+
var task = await _coursesClient.GetTask(taskId);
76+
if (!task.CanSendSolution)
77+
return BadRequest();
78+
79+
var solution = _mapper.Map<Solution>(solutionModel);
80+
var solutionId = await _solutionsService.PostOrUpdateAsync(taskId, solution);
81+
82+
return Ok(solutionId);
7683
}
7784

78-
[HttpPost("postSolutionForLti/{taskId}")]
85+
[HttpPost("postAndRateSolutionForLti/{taskId}")]
7986
[ProducesResponseType(typeof(long), (int)HttpStatusCode.OK)]
80-
public async Task<IActionResult> PostSolutionForLti(long taskId, [FromBody] PostSolutionModel solutionModel)
87+
public async Task<IActionResult> PostAndRateSolutionForLti(long taskId,
88+
[FromBody] PostSolutionModel solutionModel)
8189
{
82-
return await PostSolutionInternal(taskId, solutionModel, true);
90+
var task = await _coursesClient.GetTask(taskId);
91+
if (!task.CanSendSolution || solutionModel.Rating == null)
92+
{
93+
return BadRequest();
94+
}
95+
96+
var mapSolution = _mapper.Map<Solution>(solutionModel);
97+
var solutionId = await _solutionsService.PostOrUpdateAsyncForLti(taskId, mapSolution);
98+
var solution = await _solutionsService.GetSolutionAsync(solutionId);
99+
var homework = await _coursesClient.GetHomework(task.HomeworkId);
100+
var course = await _coursesClient.GetCourseByTaskForLti(homework.CourseId, solution.StudentId);
101+
102+
var lecturerId = Request.GetUserIdFromHeader();
103+
104+
if (course == null) return Forbid();
105+
106+
var ratting = solutionModel.Rating ?? 0;
107+
var rateSolutionModel = new RateSolutionModel
108+
{
109+
LecturerComment = solutionModel.LecturerComment,
110+
Rating = ratting
111+
};
112+
113+
await _solutionsService.RateSolutionAsync(solutionId, lecturerId!, rateSolutionModel.Rating, rateSolutionModel.LecturerComment);
114+
return Ok();
115+
83116
}
84117

85118
[HttpPost("rateSolution/{solutionId}")]
86119
public async Task<IActionResult> RateSolution(long solutionId,
87120
[FromBody] RateSolutionModel rateSolutionModel)
88121
{
89-
return await this.RateSolutionInternal(solutionId, rateSolutionModel);
90-
}
122+
var solution = await _solutionsService.GetSolutionAsync(solutionId);
123+
var task = await _coursesClient.GetTask(solution.TaskId);
124+
var homework = await _coursesClient.GetHomework(task.HomeworkId);
125+
var course = await _coursesClient.GetCourseByTask(homework.CourseId);
91126

92-
[HttpPost("rateSolutionForLti/{solutionId}")]
93-
public async Task<IActionResult> RateSolutionForLti(long solutionId,
94-
[FromBody] RateSolutionModel rateSolutionModel)
95-
{
96-
return await this.RateSolutionInternal(solutionId, rateSolutionModel, true);
127+
var lecturerId = Request.GetUserIdFromHeader();
128+
129+
if (course != null && lecturerId != null && course.MentorIds.Contains(lecturerId))
130+
{
131+
await _solutionsService.RateSolutionAsync(solutionId, lecturerId, rateSolutionModel.Rating, rateSolutionModel.LecturerComment);
132+
return Ok();
133+
}
134+
135+
return Forbid();
97136
}
98137

99138
[HttpPost("rateEmptySolution/{taskId}")]
@@ -302,46 +341,5 @@ public async Task<SolutionActualityDto> GetSolutionActuality(long solutionId)
302341
{
303342
return await _solutionsService.GetSolutionActuality(solutionId);
304343
}
305-
306-
private async Task<IActionResult> PostSolutionInternal(
307-
long taskId, PostSolutionModel solutionModel, bool isLtiRequest = false)
308-
{
309-
var task = await _coursesClient.GetTask(taskId);
310-
if (!task.CanSendSolution)
311-
return BadRequest();
312-
313-
var solution = _mapper.Map<Solution>(solutionModel);
314-
var solutionId = isLtiRequest ?
315-
await _solutionsService.PostOrUpdateAsyncForLti(taskId, solution) :
316-
await _solutionsService.PostOrUpdateAsync(taskId, solution);
317-
318-
return Ok(solutionId);
319-
}
320-
321-
private async Task<IActionResult> RateSolutionInternal(long solutionId,
322-
RateSolutionModel rateSolutionModel, bool isLtiRequest = false)
323-
{
324-
var solution = await _solutionsService.GetSolutionAsync(solutionId);
325-
var task = await _coursesClient.GetTask(solution.TaskId);
326-
var homework = await _coursesClient.GetHomework(task.HomeworkId);
327-
var course = isLtiRequest
328-
? await _coursesClient.GetCourseByTaskForLti(homework.CourseId, solution.StudentId)
329-
: await _coursesClient.GetCourseByTask(homework.CourseId);
330-
331-
var lecturerId = Request.GetUserIdFromHeader();
332-
if (isLtiRequest && course != null)
333-
{
334-
await _solutionsService.RateSolutionAsync(solutionId, lecturerId!, rateSolutionModel.Rating, rateSolutionModel.LecturerComment);
335-
return Ok();
336-
}
337-
338-
if (course != null && lecturerId != null && course.MentorIds.Contains(lecturerId))
339-
{
340-
await _solutionsService.RateSolutionAsync(solutionId, lecturerId, rateSolutionModel.Rating, rateSolutionModel.LecturerComment);
341-
return Ok();
342-
}
343-
344-
return Forbid();
345-
}
346344
}
347345
}

HwProj.SolutionsService/HwProj.SolutionsService.API/Services/SolutionsService.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,11 @@ await _coursesServiceClient.GetCourseByTaskForLti(solution.TaskId, solution.Stud
358358
await _coursesServiceClient.GetCourseByTask(solution.TaskId);
359359
var student = await _authServiceClient.GetAccountData(solutionModel.StudentId);
360360
var studentModel = _mapper.Map<AccountDataDto>(student);
361-
// _eventBus.Publish(new StudentPassTaskEvent(course, solutionModel, studentModel, task));
361+
362+
if (!isLtiRequest)
363+
{
364+
_eventBus.Publish(new StudentPassTaskEvent(course, solutionModel, studentModel, task));
365+
}
362366
}
363367

364368
if (task.Tags.Contains(HomeworkTags.Test))

HwProj.SolutionsService/HwProj.SolutionsService.Client/ISolutionsServiceClient.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,8 @@ public interface ISolutionsServiceClient
1010
Task<Solution> GetSolutionById(long solutionId);
1111
Task<Solution[]> GetUserSolutions(long taskId, string studentId);
1212
Task<long> PostSolution(long taskId, PostSolutionModel model);
13-
Task<long> PostSolutionForLti(long taskId, PostSolutionModel model);
1413
Task PostEmptySolutionWithRate(long taskId, SolutionViewModel solution);
1514
Task RateSolution(long solutionId, RateSolutionModel rateSolutionModel);
16-
Task RateSolutionForLti(long solutionId, RateSolutionModel rateSolutionModel);
1715
Task MarkSolution(long solutionId);
1816
Task DeleteSolution(long solutionId);
1917
Task<long> PostGroupSolution(SolutionViewModel model, long taskId, long groupId);
@@ -27,5 +25,7 @@ public interface ISolutionsServiceClient
2725
Task<TaskSolutionsStats[]> GetTaskSolutionsStats(GetTasksSolutionsModel tasksSolutionsDTO);
2826
Task<SolutionActualityDto> GetSolutionActuality(long solutionId);
2927
Task<bool> Ping();
28+
Task PostAndRateSolutionForLti(
29+
long taskId, string userId, double scoreGiven, double scoreMaximum, string comment);
3030
}
3131
}

HwProj.SolutionsService/HwProj.SolutionsService.Client/SolutionsServiceClient.cs

Lines changed: 34 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,24 @@ public async Task<Solution[]> GetUserSolutions(long taskId, string studentId)
7272

7373
public async Task<long> PostSolution(long taskId, PostSolutionModel model)
7474
{
75-
return await PostSolutionInternal(taskId, model);
76-
}
75+
using var httpRequest = new HttpRequestMessage(
76+
HttpMethod.Post,
77+
_solutionServiceUri + $"api/Solutions/{taskId}")
78+
{
79+
Content = new StringContent(
80+
JsonConvert.SerializeObject(model),
81+
Encoding.UTF8,
82+
"application/json")
83+
};
7784

78-
public async Task<long> PostSolutionForLti(long taskId, PostSolutionModel model)
79-
{
80-
return await PostSolutionInternal(taskId, model, true);
85+
httpRequest.TryAddUserId(_httpContextAccessor);
86+
var response = await _httpClient.SendAsync(httpRequest);
87+
if (response.IsSuccessStatusCode)
88+
{
89+
return await response.DeserializeAsync<long>();
90+
}
91+
92+
throw new ForbiddenException();
8193
}
8294

8395
public async Task PostEmptySolutionWithRate(long taskId, SolutionViewModel model)
@@ -99,23 +111,11 @@ public async Task PostEmptySolutionWithRate(long taskId, SolutionViewModel model
99111
}
100112

101113
public async Task RateSolution(long solutionId, RateSolutionModel rateSolutionModel)
102-
{
103-
await RateSolutionInternal(solutionId, rateSolutionModel);
104-
}
105-
106-
public async Task RateSolutionForLti(long solutionId, RateSolutionModel rateSolutionModel)
107-
{
108-
await RateSolutionInternal(solutionId, rateSolutionModel, true);
109-
}
110-
111-
private async Task RateSolutionInternal(
112-
long solutionId, RateSolutionModel rateSolutionModel, bool isLtiRequest = false)
113114
{
114115
using var httpRequest = new HttpRequestMessage(
115116
HttpMethod.Post,
116117
_solutionServiceUri +
117-
$"api/Solutions/" +
118-
$"{(isLtiRequest ? "rateSolutionForLti" : "rateSolution")}/{solutionId}")
118+
$"api/Solutions/rateSolution/{solutionId}")
119119
{
120120
Content = new StringContent(
121121
JsonConvert.SerializeObject(rateSolutionModel),
@@ -298,28 +298,30 @@ public async Task<bool> Ping()
298298
}
299299
}
300300

301-
private async Task<long> PostSolutionInternal(
302-
long taskId, PostSolutionModel model, bool isLtiRequest = false)
301+
public async Task PostAndRateSolutionForLti(
302+
long taskId, string userId, double scoreGiven, double scoreMaximum, string comment)
303303
{
304-
using var httpRequest = new HttpRequestMessage(
305-
HttpMethod.Post,
306-
_solutionServiceUri + $"api/Solutions/" +
307-
$"{(isLtiRequest ? "postSolutionForLti/" : "")}{taskId}")
304+
var model = new PostSolutionModel
308305
{
309-
Content = new StringContent(
310-
JsonConvert.SerializeObject(model),
311-
Encoding.UTF8,
312-
"application/json")
306+
StudentId = userId,
307+
LecturerComment = comment,
308+
Rating = (int)Math.Round(scoreGiven)
313309
};
314310

311+
using var httpRequest = new HttpRequestMessage(
312+
HttpMethod.Post,
313+
_solutionServiceUri + $"api/Solutions/postAndRateSolutionForLti/{taskId}");
314+
httpRequest.Content = new StringContent(
315+
JsonConvert.SerializeObject(model),
316+
Encoding.UTF8,
317+
"application/json");
318+
315319
httpRequest.TryAddUserId(_httpContextAccessor);
316320
var response = await _httpClient.SendAsync(httpRequest);
317-
if (response.IsSuccessStatusCode)
321+
if (!response.IsSuccessStatusCode)
318322
{
319-
return await response.DeserializeAsync<long>();
323+
throw new ForbiddenException();
320324
}
321-
322-
throw new ForbiddenException();
323325
}
324326
}
325327
}

0 commit comments

Comments
 (0)