Merge branch 'unstable' into 'main'
A lot of API fixes + added Completions and Answers See merge request internship-2025/survey-webapp/survey-webapp!25
This commit is contained in:
commit
47467f0fa3
28 changed files with 425 additions and 61 deletions
|
|
@ -24,8 +24,19 @@ public class UserContext : IUserContext
|
|||
/// Возвращает UserId из токена, при отсуствии кидает Unauthorized
|
||||
/// </summary>
|
||||
/// <exception cref="UnauthorizedAccessException"></exception>
|
||||
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;
|
||||
}
|
||||
|
|
@ -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<IActionResult> 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<IActionResult> GetAnswersByCompletionId(int id)
|
||||
{
|
||||
var models = await _answerService.GetAnswersByCompletionIdAsync(id);
|
||||
var result = models.Select(AnswerMapper.ModelToOutputDto);
|
||||
return Ok(result);
|
||||
}
|
||||
}
|
||||
|
|
@ -52,16 +52,15 @@ public class AnswerVariantsController : ControllerBase
|
|||
/// <summary>
|
||||
/// Обновить вариант ответа на вопрос
|
||||
/// </summary>
|
||||
/// <param name="surveyId">Идентификатор опроса</param>
|
||||
/// <param name="questionId">Идентификатор вопроса</param>
|
||||
/// <param name="id">Идентификатор варианта ответа</param>
|
||||
/// <param name="dto">Объект с данными для обновления варианта ответа</param>
|
||||
/// <returns>Результат обновленного варианта ответа</returns>
|
||||
[Authorize]
|
||||
[HttpPut("{id}")]
|
||||
public async Task<IActionResult> Update(int surveyId, int questionId, int id, [FromBody] AnswerVariantUpdateDto dto)
|
||||
[HttpPut]
|
||||
[Route("/api/answerVariants/{id:int}")]
|
||||
public async Task<IActionResult> 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
|
|||
/// <summary>
|
||||
/// Удалить вариант ответа на вопрос
|
||||
/// </summary>
|
||||
/// <param name="surveyId">Идентификатор опроса</param>
|
||||
/// <param name="questionId">Идентификатор вопроса</param>
|
||||
/// <param name="id">Идентификатор варианта ответа</param>
|
||||
/// <returns>Результат операции удаления</returns>
|
||||
[Authorize]
|
||||
[HttpDelete("{id}")]
|
||||
public async Task<IActionResult> Delete(int surveyId, int questionId, int id)
|
||||
[HttpDelete]
|
||||
[Route("/api/answerVariants/{id:int}")]
|
||||
public async Task<IActionResult> Delete(int id)
|
||||
{
|
||||
await _answerVariantsService.DeleteAnswerVariantAsync(id);
|
||||
return Ok();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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<IActionResult> 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<IActionResult> GetCompletionAsync(int id)
|
||||
{
|
||||
var model = await _completionService.GetCompletionByIdAsync(id);
|
||||
var result = CompletionMapper.ModelToOutputDto(model);
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[AllowAnonymous]
|
||||
public async Task<IActionResult> PostCompletionAsync([FromBody] CompletionCreateDto dto, [FromRoute] int surveyId)
|
||||
{
|
||||
var userId = _userContext.NullableUserId;
|
||||
var model = CompletionMapper.CreateDtoToModel(dto, surveyId, userId);
|
||||
await _completionService.AddCompletionAsync(model);
|
||||
return Ok();
|
||||
}
|
||||
}
|
||||
|
|
@ -64,11 +64,11 @@ public class QuestionController : ControllerBase
|
|||
/// <param name="surveyId"></param>
|
||||
/// <returns></returns>
|
||||
[Authorize]
|
||||
[HttpPut("{id}")]
|
||||
public async Task<IActionResult> UpdateQuestion([FromBody] QuestionUpdateDto dto, [FromRoute] int id,
|
||||
[FromRoute] int surveyId)
|
||||
[HttpPut]
|
||||
[Route("/api/questions/{id:int}")]
|
||||
public async Task<IActionResult> 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
|
|||
/// <param name="surveyId"></param>
|
||||
/// <returns></returns>
|
||||
[Authorize]
|
||||
[HttpDelete("{id}")]
|
||||
public async Task<IActionResult> DeleteQuestion([FromRoute] int id, [FromRoute] int surveyId)
|
||||
[HttpDelete]
|
||||
[Route("/api/questions/{id:int}")]
|
||||
public async Task<IActionResult> DeleteQuestion([FromRoute] int id)
|
||||
{
|
||||
await _questionService.DeleteQuestionAsync(id);
|
||||
return Ok();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
namespace SurveyBackend.DTOs.Answer;
|
||||
|
||||
public class AnswerCreateDto
|
||||
{
|
||||
public int QuestionId { get; set; }
|
||||
public required string AnswerText { get; set; }
|
||||
}
|
||||
|
|
@ -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; }
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
using SurveyBackend.DTOs.Answer;
|
||||
|
||||
namespace SurveyBackend.DTOs.Completion;
|
||||
|
||||
public class CompletionCreateDto
|
||||
{
|
||||
public List<AnswerCreateDto> Answers { get; set; }
|
||||
}
|
||||
|
|
@ -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; }
|
||||
}
|
||||
20
SurveyBackend/SurveyBackend.API/Mappers/AnswerMapper.cs
Normal file
20
SurveyBackend/SurveyBackend.API/Mappers/AnswerMapper.cs
Normal file
|
|
@ -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,
|
||||
};
|
||||
}
|
||||
|
|
@ -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
|
||||
};
|
||||
|
|
|
|||
22
SurveyBackend/SurveyBackend.API/Mappers/CompletionMapper.cs
Normal file
22
SurveyBackend/SurveyBackend.API/Mappers/CompletionMapper.cs
Normal file
|
|
@ -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
|
||||
};
|
||||
}
|
||||
|
|
@ -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")
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
using SurveyBackend.Core.Models;
|
||||
using SurveyBackend.DTOs;
|
||||
using SurveyBackend.DTOs.User;
|
||||
|
||||
namespace SurveyBackend.Mappers;
|
||||
|
|
|
|||
|
|
@ -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<IUserContext, UserContext>();
|
||||
|
||||
builder.Services.AddScoped<IUserRepository, UserRepository>();
|
||||
builder.Services.AddScoped<IUserService, UserService>();
|
||||
|
||||
builder.Services.AddScoped<IPasswordHasher, Sha256PasswordHasher>();
|
||||
|
||||
builder.Services.AddScoped<IAuthorizationService, AuthorizationService>();
|
||||
|
||||
builder.Services.AddScoped<ISurveyRepository, SurveyRepository>();
|
||||
builder.Services.AddScoped<IQuestionRepository, QuestionRepository>();
|
||||
builder.Services.AddScoped<IAnswerVariantsRepository, AnswerVariantsRepository>();
|
||||
|
||||
builder.Services.AddScoped<ISurveyService, SurveyService>();
|
||||
builder.Services.AddScoped<IQuestionService, QuestionService>();
|
||||
builder.Services.AddScoped<IAnswerVariantsService, AnswerVariantsService>();
|
||||
|
||||
builder.Services.AddSurveyBackendInfrastructure();
|
||||
builder.Services.AddSurveyLibInfrastructure();
|
||||
builder.Services.AddSurveyBackendServices();
|
||||
|
||||
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
|
||||
.AddJwtBearer(options =>
|
||||
|
|
|
|||
|
|
@ -3,4 +3,5 @@ namespace SurveyBackend.Core.Contexts;
|
|||
public interface IUserContext
|
||||
{
|
||||
int UserId { get; }
|
||||
int? NullableUserId { get; }
|
||||
}
|
||||
|
|
@ -1,5 +1,3 @@
|
|||
using Microsoft.AspNetCore.Identity;
|
||||
|
||||
namespace SurveyBackend.Core.Models;
|
||||
|
||||
public class User
|
||||
|
|
|
|||
|
|
@ -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<IUserRepository, UserRepository>();
|
||||
|
||||
return services;
|
||||
}
|
||||
}
|
||||
27
SurveyBackend/SurveyBackend.Services/DependencyInjection.cs
Normal file
27
SurveyBackend/SurveyBackend.Services/DependencyInjection.cs
Normal file
|
|
@ -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<IUserService, UserService>();
|
||||
|
||||
services.AddScoped<IPasswordHasher, Sha256PasswordHasher>();
|
||||
|
||||
services.AddScoped<IAuthorizationService, AuthorizationService>();
|
||||
|
||||
services.AddScoped<ISurveyService, SurveyService>();
|
||||
services.AddScoped<IQuestionService, QuestionService>();
|
||||
services.AddScoped<IAnswerVariantsService, AnswerVariantsService>();
|
||||
services.AddScoped<ICompletionService, CompletionService>();
|
||||
services.AddScoped<IAnswerService, AnswerService>();
|
||||
|
||||
return services;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
using System.Security.Cryptography;
|
||||
using SurveyBackend.Core.Services;
|
||||
|
||||
namespace SurveyBackend.Services.Services;
|
||||
namespace SurveyBackend.Services.Helpers;
|
||||
|
||||
public class Sha256PasswordHasher : IPasswordHasher
|
||||
{
|
||||
|
|
@ -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<IEnumerable<Answer>> 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<IEnumerable<Answer>> GetAnswersByQuestionIdAsync(int questionId)
|
||||
{
|
||||
var question = await _questionRepository.GetByIdAsync(questionId);
|
||||
if (question is null)
|
||||
{
|
||||
throw new NotFoundException("Question not found");
|
||||
}
|
||||
|
||||
return await _answerRepository.GetAnswersByQuestionIdAsync(questionId);
|
||||
}
|
||||
}
|
||||
|
|
@ -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<AnswerVariant> 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<IEnumerable<AnswerVariant>> GetAnswerVariantsByQuestionIdAsync(int questionId)
|
||||
{
|
||||
var question = await _questionRepository.GetByIdAsync(questionId);
|
||||
if (question is null)
|
||||
{
|
||||
throw new NotFoundException("Question not found");
|
||||
}
|
||||
|
||||
return await _answerVariantsRepository.GetAnswerVariantsByQuestionIdAsync(questionId);
|
||||
}
|
||||
}
|
||||
|
|
@ -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<Completion> GetCompletionByIdAsync(int id)
|
||||
{
|
||||
var completion = await _completionRepository.GetByIdAsync(id);
|
||||
if (completion is null)
|
||||
{
|
||||
throw new NotFoundException("Completion not found");
|
||||
}
|
||||
|
||||
return completion;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Completion>> 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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<IEnumerable<Survey>> GetSurveysByUserIdAsync(int userId)
|
||||
{
|
||||
// TODO: проверить существование юзера
|
||||
return await _surveyRepository.GetSurveysByUserIdAsync(userId);
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit 7d47ab9e60645032bc41daee5535aba2b7eeebdf
|
||||
Subproject commit d9f16ee761e31bb7af7a067c38f5fa02083f9d6c
|
||||
Loading…
Add table
Add a link
Reference in a new issue