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.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/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/CompletionController.cs b/SurveyBackend/SurveyBackend.API/Controllers/CompletionController.cs
new file mode 100644
index 0000000..162fda4
--- /dev/null
+++ b/SurveyBackend/SurveyBackend.API/Controllers/CompletionController.cs
@@ -0,0 +1,51 @@
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using SurveyBackend.Core.Contexts;
+using SurveyBackend.DTOs.Completion;
+using SurveyBackend.Mappers;
+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)
+ {
+ var models = await _completionService.GetCompletionsBySurveyIdAsync(surveyId);
+ var result = models.Select(CompletionMapper.ModelToOutputDto);
+ return Ok(result);
+ }
+
+ [HttpGet]
+ [Route("/api/completions/{id:int}")]
+ [Authorize]
+ public async Task GetCompletionAsync(int id)
+ {
+ var model = await _completionService.GetCompletionByIdAsync(id);
+ var result = CompletionMapper.ModelToOutputDto(model);
+ return Ok(result);
+ }
+
+ [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/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/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/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..c83305c
--- /dev/null
+++ b/SurveyBackend/SurveyBackend.API/DTOs/Completion/CompletionOutputDto.cs
@@ -0,0 +1,9 @@
+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; }
+}
\ 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/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/CompletionMapper.cs b/SurveyBackend/SurveyBackend.API/Mappers/CompletionMapper.cs
new file mode 100644
index 0000000..3eb1edf
--- /dev/null
+++ b/SurveyBackend/SurveyBackend.API/Mappers/CompletionMapper.cs
@@ -0,0 +1,22 @@
+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
+ {
+ Id = model.Id,
+ SurveyId = model.SurveyId,
+ CompletedBy = model.CompletedBy,
+ FinishedAt = model.FinishedAt
+ };
+}
\ No newline at end of file
diff --git a/SurveyBackend/SurveyBackend.API/Mappers/QuestionMapper.cs b/SurveyBackend/SurveyBackend.API/Mappers/QuestionMapper.cs
index 6d50d50..6cc41dc 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,21 +69,16 @@ public static class QuestionMapper
{
Id = questionId,
Title = dto.Title,
- SurveyId = surveyId,
},
"singleanswerquestion" => new SingleAnswerQuestion
{
Id = questionId,
Title = dto.Title,
- SurveyId = surveyId,
- AnswerVariants = [],
},
"multipleanswerquestion" => new MultipleAnswerQuestion
{
Id = questionId,
Title = dto.Title,
- SurveyId = surveyId,
- AnswerVariants = []
},
_ => throw new BadRequestException("Unknown question type")
};
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 829f13f..3c66899 100644
--- a/SurveyBackend/SurveyBackend.API/Program.cs
+++ b/SurveyBackend/SurveyBackend.API/Program.cs
@@ -5,18 +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.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;
@@ -39,21 +34,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.AddSurveyBackendInfrastructure();
+ builder.Services.AddSurveyLibInfrastructure();
+ builder.Services.AddSurveyBackendServices();
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
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
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
new file mode 100644
index 0000000..b39ef85
--- /dev/null
+++ b/SurveyBackend/SurveyBackend.Infrastructure/DependencyInjection.cs
@@ -0,0 +1,15 @@
+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/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
{
diff --git a/SurveyBackend/SurveyBackend.Services/Services/AnswerService.cs b/SurveyBackend/SurveyBackend.Services/Services/AnswerService.cs
new file mode 100644
index 0000000..e3fba4e
--- /dev/null
+++ b/SurveyBackend/SurveyBackend.Services/Services/AnswerService.cs
@@ -0,0 +1,58 @@
+using SurveyBackend.Services.Exceptions;
+using SurveyLib.Core.Models;
+using SurveyLib.Core.Repositories;
+using SurveyLib.Core.Services;
+
+namespace SurveyBackend.Services.Services;
+
+public class AnswerService : IAnswerService
+{
+ private readonly IAnswerRepository _answerRepository;
+ private readonly IQuestionRepository _questionRepository;
+ private readonly ICompletionRepository _completionRepository;
+
+ public AnswerService(IAnswerRepository answerRepository, IQuestionRepository questionRepository,
+ ICompletionRepository completionRepository)
+ {
+ _answerRepository = answerRepository;
+ _questionRepository = questionRepository;
+ _completionRepository = completionRepository;
+ }
+
+ 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)
+ {
+ 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 bd46cba..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,34 +8,76 @@ 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)
{
+ 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)
{
+ 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 NotFoundException("Answer Variant not found");
+ }
+
+ answerVariant.QuestionId = answerVariantBase.QuestionId;
+
await _answerVariantsRepository.UpdateAsync(answerVariant);
}
public async Task DeleteAnswerVariantAsync(int id)
{
+ 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)
{
- 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)
{
+ 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
new file mode 100644
index 0000000..6aee2dc
--- /dev/null
+++ b/SurveyBackend/SurveyBackend.Services/Services/CompletionService.cs
@@ -0,0 +1,64 @@
+using SurveyBackend.Services.Exceptions;
+using SurveyLib.Core.Models;
+using SurveyLib.Core.Repositories;
+using SurveyLib.Core.Services;
+
+namespace SurveyBackend.Services.Services;
+
+public class CompletionService : ICompletionService
+{
+ private readonly ICompletionRepository _completionRepository;
+ private readonly ISurveyRepository _surveyRepository;
+
+ public CompletionService(ICompletionRepository completionRepository, ISurveyRepository surveyRepository)
+ {
+ _completionRepository = completionRepository;
+ _surveyRepository = surveyRepository;
+ }
+
+ public async Task AddCompletionAsync(Completion completion)
+ {
+ var survey = await _surveyRepository.GetByIdAsync(completion.SurveyId);
+ if (survey is null)
+ {
+ throw new NotFoundException("Survey not found");
+ }
+
+ 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 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)
+ {
+ var survey = await _surveyRepository.GetByIdAsync(surveyId);
+ if (survey is null)
+ {
+ throw new NotFoundException("Survey not found");
+ }
+
+ // 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..2dcf297 100644
--- a/SurveyBackend/SurveyBackend.Services/Services/QuestionService.cs
+++ b/SurveyBackend/SurveyBackend.Services/Services/QuestionService.cs
@@ -22,11 +22,25 @@ public class QuestionService : IQuestionService
public async Task AddQuestionAsync(QuestionBase question)
{
+ var survey = await _surveyRepository.GetByIdAsync(question.SurveyId);
+ if (survey is null)
+ {
+ throw new NotFoundException("Survey not found");
+ }
+
await _questionRepository.AddAsync(question);
}
public async Task UpdateQuestionAsync(QuestionBase question)
{
+ 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/SurveyBackend/SurveyBackend.Services/Services/SurveyService.cs b/SurveyBackend/SurveyBackend.Services/Services/SurveyService.cs
index b39c371..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;
@@ -64,6 +63,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..d9f16ee 160000
--- a/SurveyLib
+++ b/SurveyLib
@@ -1 +1 @@
-Subproject commit 7d47ab9e60645032bc41daee5535aba2b7eeebdf
+Subproject commit d9f16ee761e31bb7af7a067c38f5fa02083f9d6c