using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using T120B165_ImgBoard.Dtos; using T120B165_ImgBoard.Dtos.Tag; using T120B165_ImgBoard.Models; using T120B165_ImgBoard.Services; using T120B165_ImgBoard.Utils; namespace T120B165_ImgBoard.Controllers; [ApiController] [Route("api/tags")] public class TagController(ITagService tagService) : ControllerBase { /// /// Creates a new tag. /// /// New tag data. /// Returns the newly created tag /// If request is malformed /// If authentication is missing /// If authorization is missing /// If tag already exists with such name [HttpPost] [Authorize(Roles = UserRoles.Admin)] [ProducesResponseType(StatusCodes.Status201Created)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status409Conflict)] public async Task> Create(CreateTagDto dto) { // Check if tag exists, if it does, throw a conflict var existingTag = await tagService.GetByName(dto.Name); if (existingTag != null) { return Problem( detail: "Tag with such name already exists.", statusCode: StatusCodes.Status409Conflict ); } var createdTag = await tagService.Create(dto.Type, dto.Name); return CreatedAtAction(nameof(Get), new { name = createdTag.Name }, createdTag); } /// /// Get a paginated list of tags. /// /// The page number /// Returns paginated list /// If request is malformed [HttpGet] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] public async Task>> GetAll(int pageNumber = 1) { return Ok(await tagService.GetAll(pageNumber)); } /// /// Get specific tag by name. /// /// The tag name /// The tag data /// If request is malformed /// If tag does not exist [HttpGet("{name}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task> Get(string name) { var tag = await tagService.GetByName(name); if (tag == null) { return NotFound(); } return Ok(tag); } /// /// Delete specified tag. /// /// The tag name /// Indicates tag deletion success /// If request is malformed /// If authentication is missing /// If authorization is missing /// If tag does not exist [HttpDelete("{name}")] [Authorize(Roles = UserRoles.Admin)] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task Delete(string name) { var deleted = await tagService.DeleteByName(name); if (!deleted) return NotFound(); return NoContent(); } /// /// Update specified tag. /// /// The tag name /// The new tag data /// Indicates tag update success /// If request is malformed /// If authentication is missing /// If authorization is missing /// If tag does not exist [HttpPatch("{name}")] [Authorize(Roles = UserRoles.Admin)] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status401Unauthorized)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task> Update(string name, EditTagDto dto) { var tag = await tagService.GetByName(name); if (tag == null) return NotFound(); var updatedTag = await tagService.Update(tag, dto.Type); return Ok(updatedTag); } }