-
Notifications
You must be signed in to change notification settings - Fork 2
Admin/text and video block and task#94 #165
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Changes from all commits
f99b956
4d76963
1c13a93
b8d4fba
c99304d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| namespace Streetcode.BLL.DTO.Media.Video | ||
| { | ||
| public class CreateVideoDTO : VideoDTO | ||
| { | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,11 +1,10 @@ | ||
| using Streetcode.BLL.DTO.AdditionalContent; | ||
|
|
||
| namespace Streetcode.BLL.DTO.Media.Video; | ||
|
|
||
| public class VideoDTO | ||
| { | ||
| public int Id { get; set; } | ||
| public string? Description { get; set; } | ||
| public string? Url { get; set; } | ||
| public int StreetcodeId { get; set; } | ||
| } | ||
| public int Id { get; set; } | ||
| public string? Title { get; set; } | ||
| public string? Description { get; set; } | ||
| public string? Url { get; set; } | ||
| public int StreetcodeId { get; set; } | ||
| } |
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| namespace Streetcode.BLL.DTO.Streetcode.TextContent; | ||
|
|
||
| public class TermCreateDTO | ||
| { | ||
| public string Title { get; set; } | ||
|
|
||
| public string Description { get; set; } | ||
|
|
||
| public int StreetcodeId { get; set; } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| using FluentResults; | ||
| using MediatR; | ||
| using Streetcode.BLL.DTO.Media.Video; | ||
|
|
||
| namespace Streetcode.BLL.MediatR.Media.Video.Create; | ||
|
|
||
| public record CreateVideoCommand(CreateVideoDTO CreateVideoRequest) : IRequest<Result<VideoDTO>>; |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,80 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| using AutoMapper; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| using FluentResults; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| using MediatR; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| using Microsoft.IdentityModel.Tokens; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| using Streetcode.BLL.DTO.Media.Video; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| using Streetcode.BLL.Interfaces.Logging; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| using Streetcode.DAL.Repositories.Interfaces.Base; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| using Entity = Streetcode.DAL.Entities.Media.Video; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| namespace Streetcode.BLL.MediatR.Media.Video.Create; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public class CreateVideoHandler : IRequestHandler<CreateVideoCommand, Result<VideoDTO>> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private readonly IMapper _mapper; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private readonly IRepositoryWrapper _repositoryWrapper; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private readonly ILoggerService _logger; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public CreateVideoHandler( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| IRepositoryWrapper repositoryWrapper, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| IMapper mapper, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ILoggerService logger) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| _repositoryWrapper = repositoryWrapper; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| _mapper = mapper; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| _logger = logger; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public async Task<Result<VideoDTO>> Handle(CreateVideoCommand request, CancellationToken cancellationToken) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var newVideo = _mapper.Map<Entity>(request.CreateVideoRequest); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var validation = VideoValidation(request, newVideo); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (validation != null) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return validation; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var entity = await _repositoryWrapper.VideoRepository.CreateAsync(newVideo); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| var resultIsSuccess = await _repositoryWrapper.SaveChangesAsync() > 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (resultIsSuccess) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return Result.Ok(_mapper.Map<VideoDTO>(entity)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const string errorMsg = "Failed to create a Video."; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return LogAndFail(request, errorMsg); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private Result<VideoDTO>? VideoValidation(CreateVideoCommand request, Entity? newVideo) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (newVideo == null) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const string errorMsg = "Cannot convert null to Video."; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return LogAndFail(request, errorMsg); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (newVideo.Title.Length > 100) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const string errorMsg = "Çàãîëîâîê â³äåî íå ìîæå áóòè á³ëüøå 100 ñèìâîë³â."; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return LogAndFail(request, errorMsg); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (newVideo.Url.IsNullOrEmpty()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const string errorMsg = "Ïîñèëàííÿ íà â³äåî º îáîâ'ÿçêîâèì."; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return LogAndFail(request, errorMsg); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return null; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+52
to
+73
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix potential NRE, replace mojibake messages, and use BCL null/whitespace checks
- private Result<VideoDTO>? VideoValidation(CreateVideoCommand request, Entity? newVideo)
+ private Result<VideoDTO>? VideoValidation(CreateVideoCommand request, Entity? newVideo)
{
if (newVideo == null)
{
- const string errorMsg = "Cannot convert null to Video.";
+ const string errorMsg = "Cannot convert null to Video.";
return LogAndFail(request, errorMsg);
}
- if (newVideo.Title.Length > 100)
+ if (string.IsNullOrWhiteSpace(newVideo.Title) || newVideo.Title!.Length > 100)
{
- const string errorMsg = "��������� ���� �� ���� ���� ����� 100 �������.";
+ const string errorMsg = "Title is required and must not exceed 100 characters.";
return LogAndFail(request, errorMsg);
}
- if (newVideo.Url.IsNullOrEmpty())
+ if (string.IsNullOrWhiteSpace(newVideo.Url) || !Uri.IsWellFormedUriString(newVideo.Url, UriKind.Absolute))
{
- const string errorMsg = "��������� �� ���� � ����'�������.";
+ const string errorMsg = "URL is required and must be absolute and well-formed.";
return LogAndFail(request, errorMsg);
}
return null;
}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private Result<VideoDTO> LogAndFail(CreateVideoCommand request, string errorMsg) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| _logger.LogError(request, errorMsg); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return Result.Fail(errorMsg); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| using FluentResults; | ||
| using MediatR; | ||
| using Streetcode.BLL.DTO.Streetcode.TextContent; | ||
|
|
||
| namespace Streetcode.BLL.MediatR.Streetcode.Term.Create; | ||
|
|
||
| public record CreateTermCommand(TermCreateDTO Term) : IRequest<Result<TermDTO>>; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| using AutoMapper; | ||
| using FluentResults; | ||
| using MediatR; | ||
| using Streetcode.BLL.DTO.Streetcode.TextContent; | ||
| using Streetcode.BLL.Interfaces.Logging; | ||
| using Streetcode.DAL.Repositories.Interfaces.Base; | ||
|
|
||
| using TermEntity = Streetcode.DAL.Entities.Streetcode.TextContent.Term; | ||
|
|
||
| namespace Streetcode.BLL.MediatR.Streetcode.Term.Create; | ||
|
|
||
| public class CreateTermHandler : IRequestHandler<CreateTermCommand, Result<TermDTO>> | ||
| { | ||
| private readonly IRepositoryWrapper _repository; | ||
| private readonly IMapper _mapper; | ||
| private readonly ILoggerService _logger; | ||
|
|
||
| public CreateTermHandler(IRepositoryWrapper repository, IMapper mapper, ILoggerService logger) | ||
| { | ||
| _repository = repository; | ||
| _mapper = mapper; | ||
| _logger = logger; | ||
| } | ||
|
|
||
| public async Task<Result<TermDTO>> Handle(CreateTermCommand request, CancellationToken cancellationToken) | ||
| { | ||
| var entity = _mapper.Map<TermEntity>(request.Term); | ||
|
|
||
| if (entity is null) | ||
| { | ||
| const string errorMsg = "Cannot map CreateTermRequest to entity."; | ||
| _logger.LogError(request, errorMsg); | ||
| return Result.Fail(errorMsg); | ||
| } | ||
|
|
||
| await _repository.TermRepository.CreateAsync(entity); | ||
| var result = await _repository.SaveChangesAsync(); | ||
|
|
||
| if (result > 0) | ||
| { | ||
| var dto = _mapper.Map<TermDTO>(entity); | ||
| return Result.Ok(dto); | ||
| } | ||
|
|
||
| const string failMsg = "Failed to save new Term."; | ||
| _logger.LogError(request, failMsg); | ||
| return Result.Fail(failMsg); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| using FluentValidation; | ||
| using Streetcode.BLL.MediatR.Media.Video.Create; | ||
|
|
||
| namespace Streetcode.BLL.Validator.Media.Video; | ||
|
|
||
| public sealed class CreateVideoCommandValidator : AbstractValidator<CreateVideoCommand> | ||
| { | ||
| public CreateVideoCommandValidator() | ||
| { | ||
| RuleFor(c => c.CreateVideoRequest.Title) | ||
| .NotEmpty() | ||
| .MaximumLength(100); | ||
|
|
||
| RuleFor(c => c.CreateVideoRequest.Url) | ||
| .NotEmpty() | ||
| .Must(url => Uri.IsWellFormedUriString(url, UriKind.Absolute)); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| using FluentValidation; | ||
| using Streetcode.BLL.MediatR.Streetcode.Term.Create; | ||
|
|
||
| namespace Streetcode.BLL.Validator.Streetcode.Term.Create; | ||
|
|
||
| public sealed class CreateTermValidator : AbstractValidator<CreateTermCommand> | ||
| { | ||
| public CreateTermValidator() | ||
| { | ||
| RuleFor(cmd => cmd.Term.Title) | ||
| .NotEmpty() | ||
| .MaximumLength(200); | ||
|
Comment on lines
+10
to
+12
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chainConfirm DB constraint parity for Title length (200). Ensure 🏁 Script executed: #!/bin/bash
# Verify DAL constraint for Term.Title
rg -nP '(class\\s+Term\\b|\\[MaxLength\\(\\s*200\\s*\\)\\])' -C3 --type=csLength of output: 25219 🏁 Script executed: #!/bin/bash
# Locate the Term entity class in DAL and verify Title length annotation
echo "Searching for Term entity definition…"
rg -nP 'public\s+class\s+Term\b' -C3 --type=cs
echo
echo "Checking for [MaxLength(200)] on Title property in Term entity…"
TERM_FILE=$(rg -lP 'public\s+class\s+Term\b' --type=cs)
rg -nP '\[MaxLength\(\s*200\s*\)\]' -C3 "$TERM_FILE"Length of output: 788 Add DB constraint for 🤖 Prompt for AI Agents |
||
|
|
||
| RuleFor(cmd => cmd.Term.Description) | ||
| .NotEmpty(); | ||
|
|
||
| RuleFor(cmd => cmd.Term.StreetcodeId) | ||
| .GreaterThan(0); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,22 +1,28 @@ | ||
| using System.ComponentModel.DataAnnotations; | ||
| using System; | ||
| using System.Collections.Generic; | ||
| using System.ComponentModel.DataAnnotations; | ||
| using System.ComponentModel.DataAnnotations.Schema; | ||
|
|
||
| namespace Streetcode.DAL.Entities.Streetcode.TextContent; | ||
|
|
||
| [Table("terms", Schema = "streetcode")] | ||
| public class Term | ||
| namespace Streetcode.DAL.Entities.Streetcode.TextContent | ||
| { | ||
| [Key] | ||
| [DatabaseGenerated(DatabaseGeneratedOption.Identity)] | ||
| public int Id { get; set; } | ||
| [Table("terms", Schema = "streetcode")] | ||
| public class Term | ||
| { | ||
| [Key] | ||
| [DatabaseGenerated(DatabaseGeneratedOption.Identity)] | ||
| public int Id { get; set; } | ||
|
|
||
| [Required] | ||
| [MaxLength(50)] | ||
| public string Title { get; set; } = string.Empty; | ||
|
|
||
| [Required] | ||
| [MaxLength(50)] | ||
| public string? Title { get; set; } | ||
| [Required] | ||
| [MaxLength(500)] | ||
| public string Description { get; set; } = string.Empty; | ||
|
|
||
| [Required] | ||
| [MaxLength(500)] | ||
| public string? Description { get; set; } | ||
| [ForeignKey(nameof(Streetcode))] | ||
| public int StreetcodeId { get; set; } | ||
|
|
||
| public List<RelatedTerm> RelatedTerms { get; set; } = new(); | ||
| } | ||
| public ICollection<RelatedTerm> RelatedTerms { get; set; } = new List<RelatedTerm>(); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,6 @@ | ||
| using Microsoft.AspNetCore.Mvc; | ||
| using Streetcode.BLL.DTO.Media; | ||
| using Streetcode.BLL.DTO.Media.Video; | ||
| using Streetcode.BLL.MediatR.Media.Video.Create; | ||
| using Streetcode.BLL.MediatR.Media.Video.GetAll; | ||
| using Streetcode.BLL.MediatR.Media.Video.GetById; | ||
| using Streetcode.BLL.MediatR.Media.Video.GetByStreetcodeId; | ||
|
|
@@ -25,4 +26,10 @@ public async Task<IActionResult> GetById([FromRoute] int id) | |
| { | ||
| return HandleResult(await Mediator.Send(new GetVideoByIdQuery(id))); | ||
| } | ||
| } | ||
|
|
||
| [HttpPost] | ||
| public async Task<IActionResult> Create([FromBody] CreateVideoDTO video) | ||
| { | ||
| return HandleResult(await Mediator.Send(new CreateVideoCommand(video))); | ||
| } | ||
|
Comment on lines
+30
to
+34
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chainPOST Create endpoint: OK; verify existing GET route ambiguity Create action wiring is fine. However, current GET routes use identical templates Example fix outside this hunk (for lines 18-26): [HttpGet("by-streetcode/{streetcodeId:int}")]
public async Task<IActionResult> GetByStreetcodeId([FromRoute] int streetcodeId) =>
HandleResult(await Mediator.Send(new GetVideoByStreetcodeIdQuery(streetcodeId)));
[HttpGet("{id:int}")]
public async Task<IActionResult> GetById([FromRoute] int id) =>
HandleResult(await Mediator.Send(new GetVideoByIdQuery(id)));🏁 Script executed: #!/bin/bash
# Locate the VideoController file
file=$(fd --hidden --full-path VideoController.cs)
# Show all HttpGet attributes with context
rg -nC2 "\[HttpGet" "$file"
# Show GetByStreetcodeId action with context
rg -nC2 "GetByStreetcodeId" "$file"
# Show GetById action with context
rg -nC2 "GetById" "$file"Length of output: 1277 Differentiate GET route templates to avoid ambiguity 🤖 Prompt for AI Agents |
||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Create DTO must not expose Id — avoid overposting/identity insert issues.
Inheriting from
VideoDTObringsIdinto the create contract. A client can set it, leading to inserts with explicit identity or unexpected behavior in EF.Refactor
CreateVideoDTOto its own shape withoutId:If keeping inheritance temporarily, at minimum ensure AutoMapper ignores
Idin the create mapping:ForMember(d => d.Id, opt => opt.Ignore());📝 Committable suggestion
🤖 Prompt for AI Agents