Skip to content

Commit

Permalink
chore: Add delete child button
Browse files Browse the repository at this point in the history
Allow admins to delete children.
  • Loading branch information
LuukvH committed Jun 26, 2024
1 parent 9892255 commit 3c49b2d
Show file tree
Hide file tree
Showing 10 changed files with 265 additions and 171 deletions.
10 changes: 7 additions & 3 deletions src/Services/CRM/Api/Controllers/ChildrenController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using KDVManager.Services.CRM.Application.Features.Children.Commands.DeleteChild;
using KDVManager.Services.CRM.Application.Features.Children.Queries.GetChildList;
using MediatR;
using System.Net;
using Microsoft.AspNetCore.Mvc;
using KDVManager.Services.CRM.Application.Contracts.Pagination;
using KDVManager.Services.CRM.Application.Features.Children.Queries.GetChildDetail;
Expand Down Expand Up @@ -46,17 +47,20 @@ public async Task<ActionResult<Guid>> CreateChild([FromBody] CreateChildCommand
return Ok(id);
}

[HttpPut("{ChildId:guid}", Name = "UpdateChild")]
public async Task<ActionResult<Guid>> UpdateChild([FromRoute] Guid ChildId, [FromBody] UpdateChildCommand updateChildCommand)
[HttpPut("{Id:guid}", Name = "UpdateChild")]
[ProducesResponseType((int)HttpStatusCode.NoContent)]
[ProducesResponseType(typeof(UnprocessableEntityResponse), (int)HttpStatusCode.UnprocessableEntity)]
public async Task<ActionResult<Guid>> UpdateChild([FromRoute] Guid Id, [FromBody] UpdateChildCommand updateChildCommand)
{
// Set the route id to the command
updateChildCommand.Id = ChildId;
updateChildCommand.Id = Id;

await _mediator.Send(updateChildCommand);
return NoContent();
}

[HttpDelete("{Id:guid}", Name = "DeleteChild")]
[ProducesResponseType((int)HttpStatusCode.NoContent)]
public async Task<ActionResult<Guid>> DeleteChild([FromRoute] DeleteChildCommand deleteChildCommand)
{
await _mediator.Send(deleteChildCommand);
Expand Down
98 changes: 46 additions & 52 deletions src/Services/CRM/Api/Middleware/ExceptionHandlerMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,72 +6,66 @@
using System.Text.Json.Serialization;
using Microsoft.AspNetCore.Http;

namespace KDVManager.Services.CRM.Api.Middleware
namespace KDVManager.Services.CRM.Api.Middleware;

public class ExceptionHandlerMiddleware
{
public class ExceptionHandlerMiddleware
private readonly RequestDelegate _next;

public ExceptionHandlerMiddleware(RequestDelegate next)
{
private readonly RequestDelegate _next;
_next = next;
}

public ExceptionHandlerMiddleware(RequestDelegate next)
public async Task Invoke(HttpContext context)
{
try
{
_next = next;
await _next(context);
}

public async Task Invoke(HttpContext context)
catch (Exception exception)
{
try
{
await _next(context);
}
catch (Exception exception)
{
await ConvertException(context, exception);
}
await ConvertException(context, exception);
}
}

private Task ConvertException(HttpContext context, Exception exception)
{
HttpStatusCode httpStatusCode = HttpStatusCode.InternalServerError;

context.Response.ContentType = "application/json";

var result = string.Empty;
var jsonSerializerOptions = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};
private Task ConvertException(HttpContext context, Exception exception)
{
HttpStatusCode httpStatusCode = HttpStatusCode.InternalServerError;

switch (exception)
{
case ValidationException validationException:
httpStatusCode = HttpStatusCode.UnprocessableEntity;
result = JsonSerializer.Serialize(new
{
status = (int)httpStatusCode,
errors = validationException.ValidationErrors
}, jsonSerializerOptions);
break;
case BadRequestException badRequestException:
httpStatusCode = HttpStatusCode.BadRequest;
break;
case NotFoundException notFoundException:
httpStatusCode = HttpStatusCode.NotFound;
break;
case Exception ex:
httpStatusCode = HttpStatusCode.BadRequest;
break;
}
context.Response.ContentType = "application/json";

context.Response.StatusCode = (int)httpStatusCode;
var result = string.Empty;
var jsonSerializerOptions = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};

switch (exception)
{
case ValidationException validationException:
httpStatusCode = HttpStatusCode.UnprocessableEntity;
result = JsonSerializer.Serialize(new UnprocessableEntityResponse((int)httpStatusCode, validationException), jsonSerializerOptions);
break;
case BadRequestException badRequestException:
httpStatusCode = HttpStatusCode.BadRequest;
break;
case NotFoundException notFoundException:
httpStatusCode = HttpStatusCode.NotFound;
break;
case Exception ex:
httpStatusCode = HttpStatusCode.BadRequest;
break;
}

if (result == string.Empty)
{
result = JsonSerializer.Serialize(new { error = exception.Message, status = (int)httpStatusCode }, jsonSerializerOptions);
context.Response.StatusCode = (int)httpStatusCode;

}
if (result == string.Empty)
{
result = JsonSerializer.Serialize(new { error = exception.Message, status = (int)httpStatusCode }, jsonSerializerOptions);

return context.Response.WriteAsync(result);
}

return context.Response.WriteAsync(result);
}
}
35 changes: 35 additions & 0 deletions src/Services/CRM/Api/Responses/UnprocessableEntityResponse.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System.ComponentModel.DataAnnotations;
using KDVManager.Services.CRM.Application.Exceptions;
using ValidationException = KDVManager.Services.CRM.Application.Exceptions.ValidationException;

public class ValidationError
{
[Required]
public required string Property { get; set; }

[Required]
public required string Code { get; set; }

[Required]
public required string Title { get; set; }
}

public class UnprocessableEntityResponse
{
[Required]
public int Status { get; set; }

[Required]
public IEnumerable<ValidationError> Errors { get; set; } = new List<ValidationError>();

public UnprocessableEntityResponse(int status, ValidationException validationException)
{
Status = status;
Errors = validationException.ValidationErrors.Select(ve => new ValidationError
{
Property = System.Text.Json.JsonNamingPolicy.CamelCase.ConvertName(ve.Property),
Code = ve.Code,
Title = ve.Title
});
}
}
117 changes: 45 additions & 72 deletions src/web/output.openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -151,20 +151,13 @@
"tags": ["Children"],
"operationId": "UpdateChild",
"parameters": [
{
"name": "childId",
"in": "query",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "Id",
"in": "path",
"required": true,
"schema": {
"type": "string"
"type": "string",
"format": "uuid"
}
}
],
Expand All @@ -188,25 +181,25 @@
}
},
"responses": {
"200": {
"description": "Success",
"204": {
"description": "Success"
},
"422": {
"description": "Client Error",
"content": {
"text/plain": {
"schema": {
"type": "string",
"format": "uuid"
"$ref": "#/components/schemas/UnprocessableEntityResponse"
}
},
"application/json": {
"schema": {
"type": "string",
"format": "uuid"
"$ref": "#/components/schemas/UnprocessableEntityResponse"
}
},
"text/json": {
"schema": {
"type": "string",
"format": "uuid"
"$ref": "#/components/schemas/UnprocessableEntityResponse"
}
}
}
Expand All @@ -228,28 +221,8 @@
}
],
"responses": {
"200": {
"description": "Success",
"content": {
"text/plain": {
"schema": {
"type": "string",
"format": "uuid"
}
},
"application/json": {
"schema": {
"type": "string",
"format": "uuid"
}
},
"text/json": {
"schema": {
"type": "string",
"format": "uuid"
}
}
}
"204": {
"description": "Success"
}
}
}
Expand Down Expand Up @@ -636,6 +609,23 @@
},
"additionalProperties": false
},
"UnprocessableEntityResponse": {
"required": ["errors", "status"],
"type": "object",
"properties": {
"status": {
"type": "integer",
"format": "int32"
},
"errors": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ValidationError"
}
}
},
"additionalProperties": false
},
"UpdateChildCommand": {
"type": "object",
"properties": {
Expand All @@ -655,6 +645,22 @@
},
"additionalProperties": false
},
"ValidationError": {
"required": ["code", "property", "title"],
"type": "object",
"properties": {
"property": {
"type": "string"
},
"code": {
"type": "string"
},
"title": {
"type": "string"
}
},
"additionalProperties": false
},
"AddGroupCommand": {
"type": "object",
"properties": {
Expand Down Expand Up @@ -705,39 +711,6 @@
}
},
"additionalProperties": {}
},
"UnprocessableEntityResponse": {
"required": ["errors", "status"],
"type": "object",
"properties": {
"status": {
"type": "integer",
"format": "int32"
},
"errors": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ValidationError"
}
}
},
"additionalProperties": false
},
"ValidationError": {
"required": ["code", "property", "title"],
"type": "object",
"properties": {
"property": {
"type": "string"
},
"code": {
"type": "string"
},
"title": {
"type": "string"
}
},
"additionalProperties": false
}
}
}
Expand Down
Loading

0 comments on commit 3c49b2d

Please sign in to comment.