From db012aed92df1624e77da5b298a464d4c10855cc Mon Sep 17 00:00:00 2001 From: shept Date: Fri, 30 May 2025 23:19:50 +0500 Subject: [PATCH 01/10] move passwordhasher to helpers --- .../{Services => Helpers}/Sha256PasswordHasher.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename SurveyBackend/SurveyBackend.Services/{Services => Helpers}/Sha256PasswordHasher.cs (97%) diff --git a/SurveyBackend/SurveyBackend.Services/Services/Sha256PasswordHasher.cs b/SurveyBackend/SurveyBackend.Services/Helpers/Sha256PasswordHasher.cs similarity index 97% rename from SurveyBackend/SurveyBackend.Services/Services/Sha256PasswordHasher.cs rename to SurveyBackend/SurveyBackend.Services/Helpers/Sha256PasswordHasher.cs index ed54508..ec91b8b 100644 --- a/SurveyBackend/SurveyBackend.Services/Services/Sha256PasswordHasher.cs +++ b/SurveyBackend/SurveyBackend.Services/Helpers/Sha256PasswordHasher.cs @@ -1,7 +1,7 @@ using System.Security.Cryptography; using SurveyBackend.Core.Services; -namespace SurveyBackend.Services.Services; +namespace SurveyBackend.Services.Helpers; public class Sha256PasswordHasher : IPasswordHasher { From 77cfacb95e1e886d6accbdd0ba35bd1e30b28b28 Mon Sep 17 00:00:00 2001 From: shept Date: Fri, 30 May 2025 23:54:45 +0500 Subject: [PATCH 02/10] add nullableUserId to IUserContext.cs --- .../SurveyBackend.API/Contexts/UserContext.cs | 19 +++++++++++++++---- .../Contexts/IUserContext.cs | 1 + 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/SurveyBackend/SurveyBackend.API/Contexts/UserContext.cs b/SurveyBackend/SurveyBackend.API/Contexts/UserContext.cs index de5e7f1..337e9e1 100644 --- a/SurveyBackend/SurveyBackend.API/Contexts/UserContext.cs +++ b/SurveyBackend/SurveyBackend.API/Contexts/UserContext.cs @@ -24,8 +24,19 @@ public class UserContext : IUserContext /// Возвращает UserId из токена, при отсуствии кидает Unauthorized /// /// - public int UserId => - int.Parse( - _httpContextAccessor.HttpContext?.User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier) - ?.Value ?? throw new UnauthorizedException("Where's your token mister")); + //public int UserId => + // int.Parse( + // _httpContextAccessor.HttpContext?.User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier)?.Value ?? throw new UnauthorizedException("Where's your token mister")); + private string? ClaimValue + => _httpContextAccessor.HttpContext?.User?.FindFirstValue(ClaimTypes.NameIdentifier); + + public int UserId + => int.TryParse(ClaimValue, out var id) + ? id + : throw new UnauthorizedException("User ID claim missing or malformed"); + + public int? NullableUserId + => int.TryParse(ClaimValue, out var id) + ? id + : null; } \ No newline at end of file diff --git a/SurveyBackend/SurveyBackend.Core/Contexts/IUserContext.cs b/SurveyBackend/SurveyBackend.Core/Contexts/IUserContext.cs index 4cd9127..2cc0cfa 100644 --- a/SurveyBackend/SurveyBackend.Core/Contexts/IUserContext.cs +++ b/SurveyBackend/SurveyBackend.Core/Contexts/IUserContext.cs @@ -3,4 +3,5 @@ namespace SurveyBackend.Core.Contexts; public interface IUserContext { int UserId { get; } + int? NullableUserId { get; } } \ No newline at end of file From 4b4739ce891d8d0fcb4814e4649171398795b4c0 Mon Sep 17 00:00:00 2001 From: shept Date: Sat, 31 May 2025 00:05:45 +0500 Subject: [PATCH 03/10] i'm sorry guys it's stupid commit... --- .../Controllers/CompletionController.cs | 48 +++++++++++++++++++ .../DTOs/Answer/AnswerCreateDto.cs | 7 +++ .../DTOs/Answer/AnswerOutputDto.cs | 8 ++++ .../DTOs/Completion/CompletionCreateDto.cs | 8 ++++ .../DTOs/Completion/CompletionOutputDto.cs | 10 ++++ .../SurveyBackend.API/Mappers/AnswerMapper.cs | 20 ++++++++ .../Mappers/CompletionMapper.cs | 21 ++++++++ SurveyBackend/SurveyBackend.API/Program.cs | 3 ++ .../Services/AnswerVariantsService.cs | 5 ++ .../Services/CompletionService.cs | 40 ++++++++++++++++ .../Services/QuestionService.cs | 2 + .../Services/SurveyService.cs | 1 + SurveyLib | 2 +- 13 files changed, 174 insertions(+), 1 deletion(-) create mode 100644 SurveyBackend/SurveyBackend.API/Controllers/CompletionController.cs create mode 100644 SurveyBackend/SurveyBackend.API/DTOs/Answer/AnswerCreateDto.cs create mode 100644 SurveyBackend/SurveyBackend.API/DTOs/Answer/AnswerOutputDto.cs create mode 100644 SurveyBackend/SurveyBackend.API/DTOs/Completion/CompletionCreateDto.cs create mode 100644 SurveyBackend/SurveyBackend.API/DTOs/Completion/CompletionOutputDto.cs create mode 100644 SurveyBackend/SurveyBackend.API/Mappers/AnswerMapper.cs create mode 100644 SurveyBackend/SurveyBackend.API/Mappers/CompletionMapper.cs create mode 100644 SurveyBackend/SurveyBackend.Services/Services/CompletionService.cs diff --git a/SurveyBackend/SurveyBackend.API/Controllers/CompletionController.cs b/SurveyBackend/SurveyBackend.API/Controllers/CompletionController.cs new file mode 100644 index 0000000..72a8fda --- /dev/null +++ b/SurveyBackend/SurveyBackend.API/Controllers/CompletionController.cs @@ -0,0 +1,48 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using SurveyBackend.Contexts; +using SurveyBackend.Core.Contexts; +using SurveyBackend.DTOs.Completion; +using SurveyBackend.Mappers; +using SurveyLib.Core.Models; +using SurveyLib.Core.Services; + +namespace SurveyBackend.Controllers; + +[ApiController] +[Route("api/surveys/{surveyId:int}/completions")] +public class CompletionController : ControllerBase +{ + private readonly ICompletionService _completionService; + private readonly IUserContext _userContext; + + public CompletionController(ICompletionService completionService, IUserContext userContext) + { + _completionService = completionService; + _userContext = userContext; + } + + [HttpGet] + [Authorize] + public async Task GetCompletionsAsync(int surveyId) + { + return NotFound(); + } + + [HttpGet("{id:int}")] + [Authorize] + public async Task GetCompletionAsync(int id) + { + return NotFound(); + } + + [HttpPost] + [AllowAnonymous] + public async Task PostCompletionAsync([FromBody] CompletionCreateDto dto, [FromRoute] int surveyId) + { + var userId = _userContext.NullableUserId; + var model = CompletionMapper.CreateDtoToModel(dto, surveyId, userId); + await _completionService.AddCompletionAsync(model); + return Ok(); + } +} \ No newline at end of file diff --git a/SurveyBackend/SurveyBackend.API/DTOs/Answer/AnswerCreateDto.cs b/SurveyBackend/SurveyBackend.API/DTOs/Answer/AnswerCreateDto.cs new file mode 100644 index 0000000..f2040f1 --- /dev/null +++ b/SurveyBackend/SurveyBackend.API/DTOs/Answer/AnswerCreateDto.cs @@ -0,0 +1,7 @@ +namespace SurveyBackend.DTOs.Answer; + +public class AnswerCreateDto +{ + public int QuestionId { get; set; } + public required string AnswerText { get; set; } +} \ No newline at end of file diff --git a/SurveyBackend/SurveyBackend.API/DTOs/Answer/AnswerOutputDto.cs b/SurveyBackend/SurveyBackend.API/DTOs/Answer/AnswerOutputDto.cs new file mode 100644 index 0000000..a3dec70 --- /dev/null +++ b/SurveyBackend/SurveyBackend.API/DTOs/Answer/AnswerOutputDto.cs @@ -0,0 +1,8 @@ +namespace SurveyBackend.DTOs.Answer; + +public class AnswerOutputDto +{ + public int QuestionId { get; set; } + public int CompletionId { get; set; } + public required string AnswerText { get; set; } +} \ No newline at end of file diff --git a/SurveyBackend/SurveyBackend.API/DTOs/Completion/CompletionCreateDto.cs b/SurveyBackend/SurveyBackend.API/DTOs/Completion/CompletionCreateDto.cs new file mode 100644 index 0000000..daac77f --- /dev/null +++ b/SurveyBackend/SurveyBackend.API/DTOs/Completion/CompletionCreateDto.cs @@ -0,0 +1,8 @@ +using SurveyBackend.DTOs.Answer; + +namespace SurveyBackend.DTOs.Completion; + +public class CompletionCreateDto +{ + public List Answers { get; set; } +} \ No newline at end of file diff --git a/SurveyBackend/SurveyBackend.API/DTOs/Completion/CompletionOutputDto.cs b/SurveyBackend/SurveyBackend.API/DTOs/Completion/CompletionOutputDto.cs new file mode 100644 index 0000000..0514242 --- /dev/null +++ b/SurveyBackend/SurveyBackend.API/DTOs/Completion/CompletionOutputDto.cs @@ -0,0 +1,10 @@ +using SurveyBackend.DTOs.Answer; + +namespace SurveyBackend.DTOs.Completion; + +public class CompletionOutputDto +{ + public int? CompletedBy { get; set; } + public DateTime FinishedAt { get; set; } + public List Answers { get; set; } +} \ No newline at end of file diff --git a/SurveyBackend/SurveyBackend.API/Mappers/AnswerMapper.cs b/SurveyBackend/SurveyBackend.API/Mappers/AnswerMapper.cs new file mode 100644 index 0000000..c5fd2bd --- /dev/null +++ b/SurveyBackend/SurveyBackend.API/Mappers/AnswerMapper.cs @@ -0,0 +1,20 @@ +using SurveyBackend.DTOs.Answer; +using SurveyLib.Core.Models; + +namespace SurveyBackend.Mappers; + +public static class AnswerMapper +{ + public static Answer CreateDtoToModel(AnswerCreateDto dto) => new Answer + { + QuestionId = dto.QuestionId, + AnswerText = dto.AnswerText, + }; + + public static AnswerOutputDto ModelToOutputDto(Answer model) => new AnswerOutputDto + { + QuestionId = model.QuestionId, + AnswerText = model.AnswerText, + CompletionId = model.CompletionId, + }; +} \ No newline at end of file diff --git a/SurveyBackend/SurveyBackend.API/Mappers/CompletionMapper.cs b/SurveyBackend/SurveyBackend.API/Mappers/CompletionMapper.cs new file mode 100644 index 0000000..9596947 --- /dev/null +++ b/SurveyBackend/SurveyBackend.API/Mappers/CompletionMapper.cs @@ -0,0 +1,21 @@ +using SurveyBackend.DTOs.Completion; +using SurveyLib.Core.Models; + +namespace SurveyBackend.Mappers; + +public static class CompletionMapper +{ + public static Completion CreateDtoToModel(CompletionCreateDto dto, int surveyId, int? performerId) => new Completion + { + SurveyId = surveyId, + CompletedBy = performerId, + Answers = dto.Answers.Select(AnswerMapper.CreateDtoToModel).ToList(), + }; + + public static CompletionOutputDto ModelToOutputDto(Completion model) => new CompletionOutputDto + { + CompletedBy = model.CompletedBy, + FinishedAt = model.FinishedAt, + Answers = model.Answers.Select(AnswerMapper.ModelToOutputDto).ToList(), + }; +} \ No newline at end of file diff --git a/SurveyBackend/SurveyBackend.API/Program.cs b/SurveyBackend/SurveyBackend.API/Program.cs index 829f13f..54545b3 100644 --- a/SurveyBackend/SurveyBackend.API/Program.cs +++ b/SurveyBackend/SurveyBackend.API/Program.cs @@ -12,6 +12,7 @@ using SurveyBackend.Infrastructure.Data; using SurveyBackend.Infrastructure.Repositories; using SurveyBackend.Middlewares; using SurveyBackend.Services; +using SurveyBackend.Services.Helpers; using SurveyBackend.Services.Services; using SurveyLib.Core.Repositories; using SurveyLib.Core.Services; @@ -49,10 +50,12 @@ public class Program builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); + builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); + builder.Services.AddScoped(); builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) diff --git a/SurveyBackend/SurveyBackend.Services/Services/AnswerVariantsService.cs b/SurveyBackend/SurveyBackend.Services/Services/AnswerVariantsService.cs index bd46cba..9808150 100644 --- a/SurveyBackend/SurveyBackend.Services/Services/AnswerVariantsService.cs +++ b/SurveyBackend/SurveyBackend.Services/Services/AnswerVariantsService.cs @@ -15,26 +15,31 @@ public class AnswerVariantsService : IAnswerVariantsService public async Task AddAnswerVariantAsync(AnswerVariant answerVariant) { + // TODO: проверка существования такого вопроса await _answerVariantsRepository.AddAsync(answerVariant); } public async Task UpdateAnswerVariantAsync(AnswerVariant answerVariant) { + // TODO: опять проверка существования, но еще и варианта await _answerVariantsRepository.UpdateAsync(answerVariant); } public async Task DeleteAnswerVariantAsync(int id) { + // TODO: проверка существования варианта await _answerVariantsRepository.DeleteAsync(id); } public async Task GetAnswerVariantByIdAsync(int id) { + // TODO: проверка существования варианта return await _answerVariantsRepository.GetByIdAsync(id); } public async Task> GetAnswerVariantsByQuestionIdAsync(int questionId) { + // TODO: проверка существования вопроса return await _answerVariantsRepository.GetAnswerVariantsByQuestionIdAsync(questionId); } } \ No newline at end of file diff --git a/SurveyBackend/SurveyBackend.Services/Services/CompletionService.cs b/SurveyBackend/SurveyBackend.Services/Services/CompletionService.cs new file mode 100644 index 0000000..8d2e633 --- /dev/null +++ b/SurveyBackend/SurveyBackend.Services/Services/CompletionService.cs @@ -0,0 +1,40 @@ +using SurveyLib.Core.Models; +using SurveyLib.Core.Repositories; +using SurveyLib.Core.Services; + +namespace SurveyBackend.Services.Services; + +public class CompletionService : ICompletionService +{ + private readonly ICompletionRepository _completionRepository; + + public CompletionService(ICompletionRepository completionRepository) + { + _completionRepository = completionRepository; + } + + public async Task AddCompletionAsync(Completion completion) + { + // TODO: проверить существование опроса + await _completionRepository.AddAsync(completion); + } + + public async Task UpdateCompletionAsync(Completion completion) + { + // TODO: лол а что вообще значит ОбновитьВыполнение, надо выпилить из SurveyLib + await _completionRepository.UpdateAsync(completion); + } + + public async Task DeleteCompletionAsync(int id) + { + // TODO: да и удалять их как-то бессмысленно + await _completionRepository.DeleteAsync(id); + } + + public async Task> GetCompletionsBySurveyIdAsync(int surveyId) + { + // TODO: проверить существование опроса + // TODO: проверить что запрашивает создатель (хз как) + return await _completionRepository.GetCompletionsBySurveyIdAsync(surveyId); + } +} \ No newline at end of file diff --git a/SurveyBackend/SurveyBackend.Services/Services/QuestionService.cs b/SurveyBackend/SurveyBackend.Services/Services/QuestionService.cs index a726427..d364fdb 100644 --- a/SurveyBackend/SurveyBackend.Services/Services/QuestionService.cs +++ b/SurveyBackend/SurveyBackend.Services/Services/QuestionService.cs @@ -22,11 +22,13 @@ public class QuestionService : IQuestionService public async Task AddQuestionAsync(QuestionBase question) { + // TODO: проверить существование опроса await _questionRepository.AddAsync(question); } public async Task UpdateQuestionAsync(QuestionBase question) { + // TODO: проверить существование вопроса await _questionRepository.UpdateAsync(question); } diff --git a/SurveyBackend/SurveyBackend.Services/Services/SurveyService.cs b/SurveyBackend/SurveyBackend.Services/Services/SurveyService.cs index b39c371..5190a0c 100644 --- a/SurveyBackend/SurveyBackend.Services/Services/SurveyService.cs +++ b/SurveyBackend/SurveyBackend.Services/Services/SurveyService.cs @@ -64,6 +64,7 @@ public class SurveyService : ISurveyService public async Task> GetSurveysByUserIdAsync(int userId) { + // TODO: проверить существование юзера return await _surveyRepository.GetSurveysByUserIdAsync(userId); } } \ No newline at end of file diff --git a/SurveyLib b/SurveyLib index 7d47ab9..14d0f36 160000 --- a/SurveyLib +++ b/SurveyLib @@ -1 +1 @@ -Subproject commit 7d47ab9e60645032bc41daee5535aba2b7eeebdf +Subproject commit 14d0f36cb801c707104af14d6cebe6da866d848a From 58b5b2b17dd9305ef9189ebe8f26c00e4a69d0ea Mon Sep 17 00:00:00 2001 From: shept Date: Sat, 31 May 2025 00:10:17 +0500 Subject: [PATCH 04/10] Update SurveyLib --- SurveyLib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SurveyLib b/SurveyLib index 14d0f36..6349edf 160000 --- a/SurveyLib +++ b/SurveyLib @@ -1 +1 @@ -Subproject commit 14d0f36cb801c707104af14d6cebe6da866d848a +Subproject commit 6349edf237839ed67b596e25b7c11510e97df325 From c2f6ba6dde14b79a8ee0b043c51f4dfcfa3e9179 Mon Sep 17 00:00:00 2001 From: shept Date: Sat, 31 May 2025 00:14:37 +0500 Subject: [PATCH 05/10] add completions methods (not final) --- .../Controllers/CompletionController.cs | 8 ++++++-- .../DTOs/Completion/CompletionOutputDto.cs | 3 ++- .../SurveyBackend.API/Mappers/CompletionMapper.cs | 5 +++-- .../Services/CompletionService.cs | 12 ++++++++++++ 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/SurveyBackend/SurveyBackend.API/Controllers/CompletionController.cs b/SurveyBackend/SurveyBackend.API/Controllers/CompletionController.cs index 72a8fda..cae1bc9 100644 --- a/SurveyBackend/SurveyBackend.API/Controllers/CompletionController.cs +++ b/SurveyBackend/SurveyBackend.API/Controllers/CompletionController.cs @@ -26,14 +26,18 @@ public class CompletionController : ControllerBase [Authorize] public async Task GetCompletionsAsync(int surveyId) { - return NotFound(); + var models = await _completionService.GetCompletionsBySurveyIdAsync(surveyId); + var result = models.Select(CompletionMapper.ModelToOutputDto); + return Ok(result); } [HttpGet("{id:int}")] [Authorize] public async Task GetCompletionAsync(int id) { - return NotFound(); + var model = await _completionService.GetCompletionByIdAsync(id); + var result = CompletionMapper.ModelToOutputDto(model); + return Ok(result); } [HttpPost] diff --git a/SurveyBackend/SurveyBackend.API/DTOs/Completion/CompletionOutputDto.cs b/SurveyBackend/SurveyBackend.API/DTOs/Completion/CompletionOutputDto.cs index 0514242..d546267 100644 --- a/SurveyBackend/SurveyBackend.API/DTOs/Completion/CompletionOutputDto.cs +++ b/SurveyBackend/SurveyBackend.API/DTOs/Completion/CompletionOutputDto.cs @@ -4,7 +4,8 @@ namespace SurveyBackend.DTOs.Completion; public class CompletionOutputDto { + public int Id { get; set; } + public int SurveyId { get; set; } public int? CompletedBy { get; set; } public DateTime FinishedAt { get; set; } - public List Answers { get; set; } } \ No newline at end of file diff --git a/SurveyBackend/SurveyBackend.API/Mappers/CompletionMapper.cs b/SurveyBackend/SurveyBackend.API/Mappers/CompletionMapper.cs index 9596947..3eb1edf 100644 --- a/SurveyBackend/SurveyBackend.API/Mappers/CompletionMapper.cs +++ b/SurveyBackend/SurveyBackend.API/Mappers/CompletionMapper.cs @@ -14,8 +14,9 @@ public static class CompletionMapper public static CompletionOutputDto ModelToOutputDto(Completion model) => new CompletionOutputDto { + Id = model.Id, + SurveyId = model.SurveyId, CompletedBy = model.CompletedBy, - FinishedAt = model.FinishedAt, - Answers = model.Answers.Select(AnswerMapper.ModelToOutputDto).ToList(), + FinishedAt = model.FinishedAt }; } \ No newline at end of file diff --git a/SurveyBackend/SurveyBackend.Services/Services/CompletionService.cs b/SurveyBackend/SurveyBackend.Services/Services/CompletionService.cs index 8d2e633..655c9dd 100644 --- a/SurveyBackend/SurveyBackend.Services/Services/CompletionService.cs +++ b/SurveyBackend/SurveyBackend.Services/Services/CompletionService.cs @@ -1,3 +1,4 @@ +using SurveyBackend.Services.Exceptions; using SurveyLib.Core.Models; using SurveyLib.Core.Repositories; using SurveyLib.Core.Services; @@ -31,6 +32,17 @@ public class CompletionService : ICompletionService await _completionRepository.DeleteAsync(id); } + public async Task GetCompletionByIdAsync(int id) + { + var completion = await _completionRepository.GetByIdAsync(id); + if (completion is null) + { + throw new NotFoundException("Completion not found"); + } + + return completion; + } + public async Task> GetCompletionsBySurveyIdAsync(int surveyId) { // TODO: проверить существование опроса From 637e6c98242acb011eeb864597e295c01ec6248b Mon Sep 17 00:00:00 2001 From: shept Date: Sat, 31 May 2025 01:03:12 +0500 Subject: [PATCH 06/10] Update SurveyLib and start refactoring endpoint paths --- .../Controllers/CompletionController.cs | 5 ++--- .../Controllers/QuestionController.cs | 13 +++++++------ .../SurveyBackend.API/Mappers/QuestionMapper.cs | 8 ++++---- .../Services/QuestionService.cs | 9 ++++++++- SurveyLib | 2 +- 5 files changed, 22 insertions(+), 15 deletions(-) diff --git a/SurveyBackend/SurveyBackend.API/Controllers/CompletionController.cs b/SurveyBackend/SurveyBackend.API/Controllers/CompletionController.cs index cae1bc9..162fda4 100644 --- a/SurveyBackend/SurveyBackend.API/Controllers/CompletionController.cs +++ b/SurveyBackend/SurveyBackend.API/Controllers/CompletionController.cs @@ -1,10 +1,8 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; -using SurveyBackend.Contexts; using SurveyBackend.Core.Contexts; using SurveyBackend.DTOs.Completion; using SurveyBackend.Mappers; -using SurveyLib.Core.Models; using SurveyLib.Core.Services; namespace SurveyBackend.Controllers; @@ -31,7 +29,8 @@ public class CompletionController : ControllerBase return Ok(result); } - [HttpGet("{id:int}")] + [HttpGet] + [Route("/api/completions/{id:int}")] [Authorize] public async Task GetCompletionAsync(int id) { diff --git a/SurveyBackend/SurveyBackend.API/Controllers/QuestionController.cs b/SurveyBackend/SurveyBackend.API/Controllers/QuestionController.cs index ee94aab..9f1b5dc 100644 --- a/SurveyBackend/SurveyBackend.API/Controllers/QuestionController.cs +++ b/SurveyBackend/SurveyBackend.API/Controllers/QuestionController.cs @@ -64,11 +64,11 @@ public class QuestionController : ControllerBase /// /// [Authorize] - [HttpPut("{id}")] - public async Task UpdateQuestion([FromBody] QuestionUpdateDto dto, [FromRoute] int id, - [FromRoute] int surveyId) + [HttpPut] + [Route("/api/questions/{id:int}")] + public async Task UpdateQuestion([FromBody] QuestionUpdateDto dto, [FromRoute] int id) { - var question = QuestionMapper.QuestionUpdateToModel(dto, surveyId, id); + var question = QuestionMapper.QuestionUpdateToModel(dto, id); await _questionService.UpdateQuestionAsync(question); var result = QuestionMapper.ModelToQuestionDto(question); return Ok(result); @@ -81,8 +81,9 @@ public class QuestionController : ControllerBase /// /// [Authorize] - [HttpDelete("{id}")] - public async Task DeleteQuestion([FromRoute] int id, [FromRoute] int surveyId) + [HttpDelete] + [Route("/api/questions/{id:int}")] + public async Task DeleteQuestion([FromRoute] int id) { await _questionService.DeleteQuestionAsync(id); return Ok(); diff --git a/SurveyBackend/SurveyBackend.API/Mappers/QuestionMapper.cs b/SurveyBackend/SurveyBackend.API/Mappers/QuestionMapper.cs index 6d50d50..53da810 100644 --- a/SurveyBackend/SurveyBackend.API/Mappers/QuestionMapper.cs +++ b/SurveyBackend/SurveyBackend.API/Mappers/QuestionMapper.cs @@ -61,7 +61,7 @@ public static class QuestionMapper }; } - public static QuestionBase QuestionUpdateToModel(QuestionCreateDto dto, int surveyId, int questionId) + public static QuestionBase QuestionUpdateToModel(QuestionCreateDto dto, int questionId) { return dto.QuestionType.ToLower() switch { @@ -69,20 +69,20 @@ public static class QuestionMapper { Id = questionId, Title = dto.Title, - SurveyId = surveyId, + SurveyId = 0, // bad logic, need to do something }, "singleanswerquestion" => new SingleAnswerQuestion { Id = questionId, Title = dto.Title, - SurveyId = surveyId, + SurveyId = 0, AnswerVariants = [], }, "multipleanswerquestion" => new MultipleAnswerQuestion { Id = questionId, Title = dto.Title, - SurveyId = surveyId, + SurveyId = 0, AnswerVariants = [] }, _ => throw new BadRequestException("Unknown question type") diff --git a/SurveyBackend/SurveyBackend.Services/Services/QuestionService.cs b/SurveyBackend/SurveyBackend.Services/Services/QuestionService.cs index d364fdb..003028c 100644 --- a/SurveyBackend/SurveyBackend.Services/Services/QuestionService.cs +++ b/SurveyBackend/SurveyBackend.Services/Services/QuestionService.cs @@ -28,7 +28,14 @@ public class QuestionService : IQuestionService public async Task UpdateQuestionAsync(QuestionBase question) { - // TODO: проверить существование вопроса + var questionBase = await _questionRepository.GetByIdAsNoTrackingAsync(question.Id); + if (questionBase is null) + { + throw new NotFoundException("Question not found"); + } + + question.SurveyId = questionBase.SurveyId; + await _questionRepository.UpdateAsync(question); } diff --git a/SurveyLib b/SurveyLib index 6349edf..f02a36d 160000 --- a/SurveyLib +++ b/SurveyLib @@ -1 +1 @@ -Subproject commit 6349edf237839ed67b596e25b7c11510e97df325 +Subproject commit f02a36dd85184c31a58e1d84081220a08b1c5d99 From d73e0a104f81f789ffe14734c5aefe3c2f8437fc Mon Sep 17 00:00:00 2001 From: shept Date: Sat, 31 May 2025 01:24:48 +0500 Subject: [PATCH 07/10] add basic versions of retrieving answers by question or completion --- .../Controllers/AnswerController.cs | 37 +++++++++++++++++ .../Controllers/AnswerVariantsController.cs | 16 ++++---- .../Mappers/AnswerVariantMapper.cs | 3 +- .../Mappers/QuestionMapper.cs | 5 --- SurveyBackend/SurveyBackend.API/Program.cs | 2 + .../Services/AnswerService.cs | 40 +++++++++++++++++++ .../Services/AnswerVariantsService.cs | 8 ++++ 7 files changed, 95 insertions(+), 16 deletions(-) create mode 100644 SurveyBackend/SurveyBackend.API/Controllers/AnswerController.cs create mode 100644 SurveyBackend/SurveyBackend.Services/Services/AnswerService.cs diff --git a/SurveyBackend/SurveyBackend.API/Controllers/AnswerController.cs b/SurveyBackend/SurveyBackend.API/Controllers/AnswerController.cs new file mode 100644 index 0000000..27453e6 --- /dev/null +++ b/SurveyBackend/SurveyBackend.API/Controllers/AnswerController.cs @@ -0,0 +1,37 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using SurveyBackend.Mappers; +using SurveyLib.Core.Services; + +namespace SurveyBackend.Controllers; + +[ApiController] +public class AnswerController : ControllerBase +{ + private readonly IAnswerService _answerService; + + public AnswerController(IAnswerService answerService) + { + _answerService = answerService; + } + + [Authorize] + [HttpGet] + [Route("api/questions/{id:int}/answers")] + public async Task GetAnswersByQuestionId(int id) + { + var models = await _answerService.GetAnswersByQuestionIdAsync(id); + var result = models.Select(AnswerMapper.ModelToOutputDto); + return Ok(result); + } + + [Authorize] + [HttpGet] + [Route("api/completions/{id:int}/answers")] + public async Task GetAnswersByCompletionId(int id) + { + var models = await _answerService.GetAnswersByCompletionIdAsync(id); + var result = models.Select(AnswerMapper.ModelToOutputDto); + return Ok(result); + } +} \ No newline at end of file diff --git a/SurveyBackend/SurveyBackend.API/Controllers/AnswerVariantsController.cs b/SurveyBackend/SurveyBackend.API/Controllers/AnswerVariantsController.cs index fe44196..1aca7f9 100644 --- a/SurveyBackend/SurveyBackend.API/Controllers/AnswerVariantsController.cs +++ b/SurveyBackend/SurveyBackend.API/Controllers/AnswerVariantsController.cs @@ -52,16 +52,15 @@ public class AnswerVariantsController : ControllerBase /// /// Обновить вариант ответа на вопрос /// - /// Идентификатор опроса - /// Идентификатор вопроса /// Идентификатор варианта ответа /// Объект с данными для обновления варианта ответа /// Результат обновленного варианта ответа [Authorize] - [HttpPut("{id}")] - public async Task Update(int surveyId, int questionId, int id, [FromBody] AnswerVariantUpdateDto dto) + [HttpPut] + [Route("/api/answerVariants/{id:int}")] + public async Task Update(int id, [FromBody] AnswerVariantUpdateDto dto) { - var model = AnswerVariantMapper.UpdateDtoToModel(dto, questionId, id); + var model = AnswerVariantMapper.UpdateDtoToModel(dto, id); await _answerVariantsService.UpdateAnswerVariantAsync(model); var result = AnswerVariantMapper.ModelToOutputDto(model); return Ok(result); @@ -70,13 +69,12 @@ public class AnswerVariantsController : ControllerBase /// /// Удалить вариант ответа на вопрос /// - /// Идентификатор опроса - /// Идентификатор вопроса /// Идентификатор варианта ответа /// Результат операции удаления [Authorize] - [HttpDelete("{id}")] - public async Task Delete(int surveyId, int questionId, int id) + [HttpDelete] + [Route("/api/answerVariants/{id:int}")] + public async Task Delete(int id) { await _answerVariantsService.DeleteAnswerVariantAsync(id); return Ok(); diff --git a/SurveyBackend/SurveyBackend.API/Mappers/AnswerVariantMapper.cs b/SurveyBackend/SurveyBackend.API/Mappers/AnswerVariantMapper.cs index 337f043..97e6892 100644 --- a/SurveyBackend/SurveyBackend.API/Mappers/AnswerVariantMapper.cs +++ b/SurveyBackend/SurveyBackend.API/Mappers/AnswerVariantMapper.cs @@ -11,10 +11,9 @@ public static class AnswerVariantMapper Text = dto.Text }; - public static AnswerVariant UpdateDtoToModel(AnswerVariantUpdateDto dto, int questionId, int answerVariantId) => + public static AnswerVariant UpdateDtoToModel(AnswerVariantUpdateDto dto, int answerVariantId) => new AnswerVariant { - QuestionId = questionId, Id = answerVariantId, Text = dto.Text }; diff --git a/SurveyBackend/SurveyBackend.API/Mappers/QuestionMapper.cs b/SurveyBackend/SurveyBackend.API/Mappers/QuestionMapper.cs index 53da810..6cc41dc 100644 --- a/SurveyBackend/SurveyBackend.API/Mappers/QuestionMapper.cs +++ b/SurveyBackend/SurveyBackend.API/Mappers/QuestionMapper.cs @@ -69,21 +69,16 @@ public static class QuestionMapper { Id = questionId, Title = dto.Title, - SurveyId = 0, // bad logic, need to do something }, "singleanswerquestion" => new SingleAnswerQuestion { Id = questionId, Title = dto.Title, - SurveyId = 0, - AnswerVariants = [], }, "multipleanswerquestion" => new MultipleAnswerQuestion { Id = questionId, Title = dto.Title, - SurveyId = 0, - AnswerVariants = [] }, _ => throw new BadRequestException("Unknown question type") }; diff --git a/SurveyBackend/SurveyBackend.API/Program.cs b/SurveyBackend/SurveyBackend.API/Program.cs index 54545b3..4e09b03 100644 --- a/SurveyBackend/SurveyBackend.API/Program.cs +++ b/SurveyBackend/SurveyBackend.API/Program.cs @@ -51,11 +51,13 @@ public class Program builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); + builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); + builder.Services.AddScoped(); builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) diff --git a/SurveyBackend/SurveyBackend.Services/Services/AnswerService.cs b/SurveyBackend/SurveyBackend.Services/Services/AnswerService.cs new file mode 100644 index 0000000..758a513 --- /dev/null +++ b/SurveyBackend/SurveyBackend.Services/Services/AnswerService.cs @@ -0,0 +1,40 @@ +using SurveyLib.Core.Models; +using SurveyLib.Core.Repositories; +using SurveyLib.Core.Services; + +namespace SurveyBackend.Services.Services; + +public class AnswerService : IAnswerService +{ + private readonly IAnswerRepository _answerRepository; + + public AnswerService(IAnswerRepository answerRepository) + { + _answerRepository = answerRepository; + } + + public async Task AddAnswerAsync(Answer answer) + { + await _answerRepository.AddAsync(answer); + } + + public async Task UpdateAnswerAsync(Answer answer) + { + await _answerRepository.UpdateAsync(answer); + } + + public async Task DeleteAnswerAsync(int id) + { + await _answerRepository.DeleteAsync(id); + } + + public async Task> GetAnswersByCompletionIdAsync(int completionId) + { + return await _answerRepository.GetAnswersByCompletionIdAsync(completionId); + } + + public async Task> GetAnswersByQuestionIdAsync(int questionId) + { + return await _answerRepository.GetAnswersByQuestionIdAsync(questionId); + } +} \ No newline at end of file diff --git a/SurveyBackend/SurveyBackend.Services/Services/AnswerVariantsService.cs b/SurveyBackend/SurveyBackend.Services/Services/AnswerVariantsService.cs index 9808150..cd02fbc 100644 --- a/SurveyBackend/SurveyBackend.Services/Services/AnswerVariantsService.cs +++ b/SurveyBackend/SurveyBackend.Services/Services/AnswerVariantsService.cs @@ -22,6 +22,14 @@ public class AnswerVariantsService : IAnswerVariantsService public async Task UpdateAnswerVariantAsync(AnswerVariant answerVariant) { // TODO: опять проверка существования, но еще и варианта + var answerVariantBase = await _answerVariantsRepository.GetByIdAsNoTrackingAsync(answerVariant.Id); + if (answerVariantBase is null) + { + throw new Exception("Answer Variant not found"); + } + + answerVariant.QuestionId = answerVariantBase.QuestionId; + await _answerVariantsRepository.UpdateAsync(answerVariant); } From 7ccf8cb01834b0ffb7f50d60cca2e0bfcfd65355 Mon Sep 17 00:00:00 2001 From: shept Date: Sat, 31 May 2025 01:32:50 +0500 Subject: [PATCH 08/10] Update SurveyLib and moved all AddScoped to DI methods --- SurveyBackend/SurveyBackend.API/Program.cs | 24 ++++------------- .../DependencyInjection.cs | 16 +++++++++++ .../DependencyInjection.cs | 27 +++++++++++++++++++ SurveyLib | 2 +- 4 files changed, 49 insertions(+), 20 deletions(-) create mode 100644 SurveyBackend/SurveyBackend.Infrastructure/DependencyInjection.cs create mode 100644 SurveyBackend/SurveyBackend.Services/DependencyInjection.cs diff --git a/SurveyBackend/SurveyBackend.API/Program.cs b/SurveyBackend/SurveyBackend.API/Program.cs index 4e09b03..49a209a 100644 --- a/SurveyBackend/SurveyBackend.API/Program.cs +++ b/SurveyBackend/SurveyBackend.API/Program.cs @@ -8,6 +8,7 @@ using SurveyBackend.Core.Contexts; using SurveyBackend.Core.Repositories; using SurveyBackend.Core.Services; using SurveyBackend.Filters; +using SurveyBackend.Infrastructure; using SurveyBackend.Infrastructure.Data; using SurveyBackend.Infrastructure.Repositories; using SurveyBackend.Middlewares; @@ -16,6 +17,7 @@ using SurveyBackend.Services.Helpers; using SurveyBackend.Services.Services; using SurveyLib.Core.Repositories; using SurveyLib.Core.Services; +using SurveyLib.Infrastructure.EFCore; using SurveyLib.Infrastructure.EFCore.Data; using SurveyLib.Infrastructure.EFCore.Repositories; @@ -40,25 +42,9 @@ public class Program builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - - builder.Services.AddScoped(); - - builder.Services.AddScoped(); - - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - builder.Services.AddScoped(); - + builder.Services.AddSurveyBackendInfrastructure(); + builder.Services.AddSurveyLibInfrastructure(); + builder.Services.AddSurveyBackendServices(); builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => diff --git a/SurveyBackend/SurveyBackend.Infrastructure/DependencyInjection.cs b/SurveyBackend/SurveyBackend.Infrastructure/DependencyInjection.cs new file mode 100644 index 0000000..896c129 --- /dev/null +++ b/SurveyBackend/SurveyBackend.Infrastructure/DependencyInjection.cs @@ -0,0 +1,16 @@ +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using SurveyBackend.Core.Repositories; +using SurveyBackend.Infrastructure.Repositories; + +namespace SurveyBackend.Infrastructure; + +public static class DependencyInjection +{ + public static IServiceCollection AddSurveyBackendInfrastructure(this IServiceCollection services) + { + services.AddScoped(); + + return services; + } +} \ No newline at end of file diff --git a/SurveyBackend/SurveyBackend.Services/DependencyInjection.cs b/SurveyBackend/SurveyBackend.Services/DependencyInjection.cs new file mode 100644 index 0000000..6523f4f --- /dev/null +++ b/SurveyBackend/SurveyBackend.Services/DependencyInjection.cs @@ -0,0 +1,27 @@ +using Microsoft.Extensions.DependencyInjection; +using SurveyBackend.Core.Services; +using SurveyBackend.Services.Helpers; +using SurveyBackend.Services.Services; +using SurveyLib.Core.Services; + +namespace SurveyBackend.Services; + +public static class DependencyInjection +{ + public static IServiceCollection AddSurveyBackendServices(this IServiceCollection services) + { + services.AddScoped(); + + services.AddScoped(); + + services.AddScoped(); + + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + + return services; + } +} \ No newline at end of file diff --git a/SurveyLib b/SurveyLib index f02a36d..d9f16ee 160000 --- a/SurveyLib +++ b/SurveyLib @@ -1 +1 @@ -Subproject commit f02a36dd85184c31a58e1d84081220a08b1c5d99 +Subproject commit d9f16ee761e31bb7af7a067c38f5fa02083f9d6c From 9a7c74e3071825667e9345353fa581b8f1e05087 Mon Sep 17 00:00:00 2001 From: shept Date: Sat, 31 May 2025 01:34:42 +0500 Subject: [PATCH 09/10] remove all unused imports --- .../SurveyBackend.API/Controllers/AuthController.cs | 1 - .../SurveyBackend.API/Controllers/SurveyController.cs | 3 --- .../DTOs/Completion/CompletionOutputDto.cs | 2 -- SurveyBackend/SurveyBackend.API/Mappers/UserMapper.cs | 1 - SurveyBackend/SurveyBackend.API/Program.cs | 8 -------- SurveyBackend/SurveyBackend.Core/Models/User.cs | 2 -- .../SurveyBackend.Infrastructure/DependencyInjection.cs | 1 - .../SurveyBackend.Services/Services/SurveyService.cs | 1 - 8 files changed, 19 deletions(-) diff --git a/SurveyBackend/SurveyBackend.API/Controllers/AuthController.cs b/SurveyBackend/SurveyBackend.API/Controllers/AuthController.cs index 5eb80ad..3457741 100644 --- a/SurveyBackend/SurveyBackend.API/Controllers/AuthController.cs +++ b/SurveyBackend/SurveyBackend.API/Controllers/AuthController.cs @@ -2,7 +2,6 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using SurveyBackend.Core.Contexts; using SurveyBackend.Core.Services; -using SurveyBackend.DTOs; using SurveyBackend.DTOs.User; using SurveyBackend.Mappers; using IAuthorizationService = SurveyBackend.Core.Services.IAuthorizationService; diff --git a/SurveyBackend/SurveyBackend.API/Controllers/SurveyController.cs b/SurveyBackend/SurveyBackend.API/Controllers/SurveyController.cs index 6dbf611..1440bf8 100644 --- a/SurveyBackend/SurveyBackend.API/Controllers/SurveyController.cs +++ b/SurveyBackend/SurveyBackend.API/Controllers/SurveyController.cs @@ -1,11 +1,8 @@ -using System.Security.Claims; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using SurveyBackend.Core.Contexts; using SurveyBackend.DTOs.Survey; using SurveyBackend.Mappers; -using SurveyBackend.Services.Exceptions; -using SurveyLib.Core.Models; using SurveyLib.Core.Services; namespace SurveyBackend.Controllers; diff --git a/SurveyBackend/SurveyBackend.API/DTOs/Completion/CompletionOutputDto.cs b/SurveyBackend/SurveyBackend.API/DTOs/Completion/CompletionOutputDto.cs index d546267..c83305c 100644 --- a/SurveyBackend/SurveyBackend.API/DTOs/Completion/CompletionOutputDto.cs +++ b/SurveyBackend/SurveyBackend.API/DTOs/Completion/CompletionOutputDto.cs @@ -1,5 +1,3 @@ -using SurveyBackend.DTOs.Answer; - namespace SurveyBackend.DTOs.Completion; public class CompletionOutputDto diff --git a/SurveyBackend/SurveyBackend.API/Mappers/UserMapper.cs b/SurveyBackend/SurveyBackend.API/Mappers/UserMapper.cs index 0d9a216..87340ac 100644 --- a/SurveyBackend/SurveyBackend.API/Mappers/UserMapper.cs +++ b/SurveyBackend/SurveyBackend.API/Mappers/UserMapper.cs @@ -1,5 +1,4 @@ using SurveyBackend.Core.Models; -using SurveyBackend.DTOs; using SurveyBackend.DTOs.User; namespace SurveyBackend.Mappers; diff --git a/SurveyBackend/SurveyBackend.API/Program.cs b/SurveyBackend/SurveyBackend.API/Program.cs index 49a209a..3c66899 100644 --- a/SurveyBackend/SurveyBackend.API/Program.cs +++ b/SurveyBackend/SurveyBackend.API/Program.cs @@ -5,21 +5,13 @@ using Microsoft.IdentityModel.Tokens; using Microsoft.OpenApi.Models; using SurveyBackend.Contexts; using SurveyBackend.Core.Contexts; -using SurveyBackend.Core.Repositories; -using SurveyBackend.Core.Services; using SurveyBackend.Filters; using SurveyBackend.Infrastructure; using SurveyBackend.Infrastructure.Data; -using SurveyBackend.Infrastructure.Repositories; using SurveyBackend.Middlewares; using SurveyBackend.Services; -using SurveyBackend.Services.Helpers; -using SurveyBackend.Services.Services; -using SurveyLib.Core.Repositories; -using SurveyLib.Core.Services; using SurveyLib.Infrastructure.EFCore; using SurveyLib.Infrastructure.EFCore.Data; -using SurveyLib.Infrastructure.EFCore.Repositories; namespace SurveyBackend; diff --git a/SurveyBackend/SurveyBackend.Core/Models/User.cs b/SurveyBackend/SurveyBackend.Core/Models/User.cs index 257d4fa..bf0ad21 100644 --- a/SurveyBackend/SurveyBackend.Core/Models/User.cs +++ b/SurveyBackend/SurveyBackend.Core/Models/User.cs @@ -1,5 +1,3 @@ -using Microsoft.AspNetCore.Identity; - namespace SurveyBackend.Core.Models; public class User diff --git a/SurveyBackend/SurveyBackend.Infrastructure/DependencyInjection.cs b/SurveyBackend/SurveyBackend.Infrastructure/DependencyInjection.cs index 896c129..b39ef85 100644 --- a/SurveyBackend/SurveyBackend.Infrastructure/DependencyInjection.cs +++ b/SurveyBackend/SurveyBackend.Infrastructure/DependencyInjection.cs @@ -1,4 +1,3 @@ -using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using SurveyBackend.Core.Repositories; using SurveyBackend.Infrastructure.Repositories; diff --git a/SurveyBackend/SurveyBackend.Services/Services/SurveyService.cs b/SurveyBackend/SurveyBackend.Services/Services/SurveyService.cs index 5190a0c..78e0da8 100644 --- a/SurveyBackend/SurveyBackend.Services/Services/SurveyService.cs +++ b/SurveyBackend/SurveyBackend.Services/Services/SurveyService.cs @@ -1,5 +1,4 @@ using SurveyBackend.Core.Contexts; -using SurveyBackend.Core.Repositories; using SurveyBackend.Services.Exceptions; using SurveyLib.Core.Models; using SurveyLib.Core.Repositories; From a5aad0904635a6e2fc9c737ce0b0b7d5e11234e6 Mon Sep 17 00:00:00 2001 From: shept Date: Sat, 31 May 2025 01:41:54 +0500 Subject: [PATCH 10/10] added existance check (not sure if it's working) --- .../Services/AnswerService.cs | 20 +++++++- .../Services/AnswerVariantsService.cs | 46 +++++++++++++++---- .../Services/CompletionService.cs | 18 ++++++-- .../Services/QuestionService.cs | 7 ++- 4 files changed, 78 insertions(+), 13 deletions(-) diff --git a/SurveyBackend/SurveyBackend.Services/Services/AnswerService.cs b/SurveyBackend/SurveyBackend.Services/Services/AnswerService.cs index 758a513..e3fba4e 100644 --- a/SurveyBackend/SurveyBackend.Services/Services/AnswerService.cs +++ b/SurveyBackend/SurveyBackend.Services/Services/AnswerService.cs @@ -1,3 +1,4 @@ +using SurveyBackend.Services.Exceptions; using SurveyLib.Core.Models; using SurveyLib.Core.Repositories; using SurveyLib.Core.Services; @@ -7,10 +8,15 @@ namespace SurveyBackend.Services.Services; public class AnswerService : IAnswerService { private readonly IAnswerRepository _answerRepository; + private readonly IQuestionRepository _questionRepository; + private readonly ICompletionRepository _completionRepository; - public AnswerService(IAnswerRepository answerRepository) + public AnswerService(IAnswerRepository answerRepository, IQuestionRepository questionRepository, + ICompletionRepository completionRepository) { _answerRepository = answerRepository; + _questionRepository = questionRepository; + _completionRepository = completionRepository; } public async Task AddAnswerAsync(Answer answer) @@ -30,11 +36,23 @@ public class AnswerService : IAnswerService public async Task> GetAnswersByCompletionIdAsync(int completionId) { + var completion = await _completionRepository.GetByIdAsync(completionId); + if (completion is null) + { + throw new NotFoundException("Completion not found"); + } + return await _answerRepository.GetAnswersByCompletionIdAsync(completionId); } public async Task> GetAnswersByQuestionIdAsync(int questionId) { + var question = await _questionRepository.GetByIdAsync(questionId); + if (question is null) + { + throw new NotFoundException("Question not found"); + } + return await _answerRepository.GetAnswersByQuestionIdAsync(questionId); } } \ No newline at end of file diff --git a/SurveyBackend/SurveyBackend.Services/Services/AnswerVariantsService.cs b/SurveyBackend/SurveyBackend.Services/Services/AnswerVariantsService.cs index cd02fbc..091d1f7 100644 --- a/SurveyBackend/SurveyBackend.Services/Services/AnswerVariantsService.cs +++ b/SurveyBackend/SurveyBackend.Services/Services/AnswerVariantsService.cs @@ -1,3 +1,4 @@ +using SurveyBackend.Services.Exceptions; using SurveyLib.Core.Models; using SurveyLib.Core.Repositories; using SurveyLib.Core.Services; @@ -7,25 +8,39 @@ namespace SurveyBackend.Services.Services; public class AnswerVariantsService : IAnswerVariantsService { private readonly IAnswerVariantsRepository _answerVariantsRepository; + private readonly IQuestionRepository _questionRepository; - public AnswerVariantsService(IAnswerVariantsRepository answerVariantsRepository) + public AnswerVariantsService(IAnswerVariantsRepository answerVariantsRepository, + IQuestionRepository questionRepository) { _answerVariantsRepository = answerVariantsRepository; + _questionRepository = questionRepository; } + // TODO: любой кто будет читать этот код, я понимаю проблему дублирования, не злитесь пожалуйста, я потом пишу на адекватные валидаторы и не будет дублирования public async Task AddAnswerVariantAsync(AnswerVariant answerVariant) { - // TODO: проверка существования такого вопроса + var question = await _questionRepository.GetByIdAsync(answerVariant.QuestionId); + if (question is null) + { + throw new NotFoundException("Question not found"); + } + await _answerVariantsRepository.AddAsync(answerVariant); } public async Task UpdateAnswerVariantAsync(AnswerVariant answerVariant) { - // TODO: опять проверка существования, но еще и варианта + var question = await _questionRepository.GetByIdAsync(answerVariant.QuestionId); + if (question is null) + { + throw new NotFoundException("Question not found"); + } + var answerVariantBase = await _answerVariantsRepository.GetByIdAsNoTrackingAsync(answerVariant.Id); if (answerVariantBase is null) { - throw new Exception("Answer Variant not found"); + throw new NotFoundException("Answer Variant not found"); } answerVariant.QuestionId = answerVariantBase.QuestionId; @@ -35,19 +50,34 @@ public class AnswerVariantsService : IAnswerVariantsService public async Task DeleteAnswerVariantAsync(int id) { - // TODO: проверка существования варианта + var answerVariantBase = await _answerVariantsRepository.GetByIdAsNoTrackingAsync(id); + if (answerVariantBase is null) + { + throw new NotFoundException("Answer Variant not found"); + } + await _answerVariantsRepository.DeleteAsync(id); } public async Task GetAnswerVariantByIdAsync(int id) { - // TODO: проверка существования варианта - return await _answerVariantsRepository.GetByIdAsync(id); + var answerVariant = await _answerVariantsRepository.GetByIdAsync(id); + if (answerVariant is null) + { + throw new NotFoundException("Answer Variant not found"); + } + + return answerVariant; } public async Task> GetAnswerVariantsByQuestionIdAsync(int questionId) { - // TODO: проверка существования вопроса + var question = await _questionRepository.GetByIdAsync(questionId); + if (question is null) + { + throw new NotFoundException("Question not found"); + } + return await _answerVariantsRepository.GetAnswerVariantsByQuestionIdAsync(questionId); } } \ No newline at end of file diff --git a/SurveyBackend/SurveyBackend.Services/Services/CompletionService.cs b/SurveyBackend/SurveyBackend.Services/Services/CompletionService.cs index 655c9dd..6aee2dc 100644 --- a/SurveyBackend/SurveyBackend.Services/Services/CompletionService.cs +++ b/SurveyBackend/SurveyBackend.Services/Services/CompletionService.cs @@ -8,15 +8,22 @@ namespace SurveyBackend.Services.Services; public class CompletionService : ICompletionService { private readonly ICompletionRepository _completionRepository; + private readonly ISurveyRepository _surveyRepository; - public CompletionService(ICompletionRepository completionRepository) + public CompletionService(ICompletionRepository completionRepository, ISurveyRepository surveyRepository) { _completionRepository = completionRepository; + _surveyRepository = surveyRepository; } public async Task AddCompletionAsync(Completion completion) { - // TODO: проверить существование опроса + var survey = await _surveyRepository.GetByIdAsync(completion.SurveyId); + if (survey is null) + { + throw new NotFoundException("Survey not found"); + } + await _completionRepository.AddAsync(completion); } @@ -45,7 +52,12 @@ public class CompletionService : ICompletionService public async Task> GetCompletionsBySurveyIdAsync(int surveyId) { - // TODO: проверить существование опроса + var survey = await _surveyRepository.GetByIdAsync(surveyId); + if (survey is null) + { + throw new NotFoundException("Survey not found"); + } + // TODO: проверить что запрашивает создатель (хз как) return await _completionRepository.GetCompletionsBySurveyIdAsync(surveyId); } diff --git a/SurveyBackend/SurveyBackend.Services/Services/QuestionService.cs b/SurveyBackend/SurveyBackend.Services/Services/QuestionService.cs index 003028c..2dcf297 100644 --- a/SurveyBackend/SurveyBackend.Services/Services/QuestionService.cs +++ b/SurveyBackend/SurveyBackend.Services/Services/QuestionService.cs @@ -22,7 +22,12 @@ public class QuestionService : IQuestionService public async Task AddQuestionAsync(QuestionBase question) { - // TODO: проверить существование опроса + var survey = await _surveyRepository.GetByIdAsync(question.SurveyId); + if (survey is null) + { + throw new NotFoundException("Survey not found"); + } + await _questionRepository.AddAsync(question); }