Skip to content

Commit a657ab8

Browse files
authored
Merge pull request #9 from csvitor-dev/develop
chore: update main
2 parents 0b72736 + d0fc21a commit a657ab8

58 files changed

Lines changed: 1643 additions & 5 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,4 +397,5 @@ FodyWeavers.xsd
397397
*.msp
398398

399399
# JetBrains Rider
400+
.idea/
400401
*.sln.iml

RecipesApp.sln

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,16 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RecipesApp.Infra", "src\Bac
2121
EndProject
2222
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RecipesApp.Communication", "src\Shared\RecipesApp.Communication\RecipesApp.Communication.csproj", "{68639CA6-1A2C-4A87-8AC5-16F24EAC28A9}"
2323
EndProject
24+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{C1D0FD22-94B4-4FC6-AD0A-8FB3F188E0EE}"
25+
EndProject
26+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommonTestUtilities", "test\CommonTestUtilities\CommonTestUtilities.csproj", "{57ADA9DB-D6F6-4D89-8D1F-64894A1D0451}"
27+
EndProject
28+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Validators.Test", "test\Validators.Test\Validators.Test.csproj", "{993F9D03-5E41-4B0F-8C63-4ADB422814EE}"
29+
EndProject
30+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UseCases.Test", "test\UseCases.Test\UseCases.Test.csproj", "{FAE3D4EC-E66B-4C4E-913A-1E49F4D46C5D}"
31+
EndProject
32+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "API.Test", "test\API.Test\API.Test.csproj", "{D82F1550-371B-4C6D-8CAE-3DCD1B0984E2}"
33+
EndProject
2434
Global
2535
GlobalSection(SolutionConfigurationPlatforms) = preSolution
2636
Debug|Any CPU = Debug|Any CPU
@@ -51,6 +61,22 @@ Global
5161
{68639CA6-1A2C-4A87-8AC5-16F24EAC28A9}.Debug|Any CPU.Build.0 = Debug|Any CPU
5262
{68639CA6-1A2C-4A87-8AC5-16F24EAC28A9}.Release|Any CPU.ActiveCfg = Release|Any CPU
5363
{68639CA6-1A2C-4A87-8AC5-16F24EAC28A9}.Release|Any CPU.Build.0 = Release|Any CPU
64+
{57ADA9DB-D6F6-4D89-8D1F-64894A1D0451}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
65+
{57ADA9DB-D6F6-4D89-8D1F-64894A1D0451}.Debug|Any CPU.Build.0 = Debug|Any CPU
66+
{57ADA9DB-D6F6-4D89-8D1F-64894A1D0451}.Release|Any CPU.ActiveCfg = Release|Any CPU
67+
{57ADA9DB-D6F6-4D89-8D1F-64894A1D0451}.Release|Any CPU.Build.0 = Release|Any CPU
68+
{993F9D03-5E41-4B0F-8C63-4ADB422814EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
69+
{993F9D03-5E41-4B0F-8C63-4ADB422814EE}.Debug|Any CPU.Build.0 = Debug|Any CPU
70+
{993F9D03-5E41-4B0F-8C63-4ADB422814EE}.Release|Any CPU.ActiveCfg = Release|Any CPU
71+
{993F9D03-5E41-4B0F-8C63-4ADB422814EE}.Release|Any CPU.Build.0 = Release|Any CPU
72+
{FAE3D4EC-E66B-4C4E-913A-1E49F4D46C5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
73+
{FAE3D4EC-E66B-4C4E-913A-1E49F4D46C5D}.Debug|Any CPU.Build.0 = Debug|Any CPU
74+
{FAE3D4EC-E66B-4C4E-913A-1E49F4D46C5D}.Release|Any CPU.ActiveCfg = Release|Any CPU
75+
{FAE3D4EC-E66B-4C4E-913A-1E49F4D46C5D}.Release|Any CPU.Build.0 = Release|Any CPU
76+
{D82F1550-371B-4C6D-8CAE-3DCD1B0984E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
77+
{D82F1550-371B-4C6D-8CAE-3DCD1B0984E2}.Debug|Any CPU.Build.0 = Debug|Any CPU
78+
{D82F1550-371B-4C6D-8CAE-3DCD1B0984E2}.Release|Any CPU.ActiveCfg = Release|Any CPU
79+
{D82F1550-371B-4C6D-8CAE-3DCD1B0984E2}.Release|Any CPU.Build.0 = Release|Any CPU
5480
EndGlobalSection
5581
GlobalSection(SolutionProperties) = preSolution
5682
HideSolutionNode = FALSE
@@ -64,6 +90,10 @@ Global
6490
{B88DCFE5-032D-412B-89A9-A3AE8EAFA835} = {C4E08D9E-2204-45CB-922E-FE6E8DBC058B}
6591
{A52FFCB3-A84B-4E77-ADC2-DD4DB79CC474} = {C4E08D9E-2204-45CB-922E-FE6E8DBC058B}
6692
{68639CA6-1A2C-4A87-8AC5-16F24EAC28A9} = {56BEA599-5A43-4E39-91F4-458CDA73107D}
93+
{57ADA9DB-D6F6-4D89-8D1F-64894A1D0451} = {C1D0FD22-94B4-4FC6-AD0A-8FB3F188E0EE}
94+
{993F9D03-5E41-4B0F-8C63-4ADB422814EE} = {C1D0FD22-94B4-4FC6-AD0A-8FB3F188E0EE}
95+
{FAE3D4EC-E66B-4C4E-913A-1E49F4D46C5D} = {C1D0FD22-94B4-4FC6-AD0A-8FB3F188E0EE}
96+
{D82F1550-371B-4C6D-8CAE-3DCD1B0984E2} = {C1D0FD22-94B4-4FC6-AD0A-8FB3F188E0EE}
6797
EndGlobalSection
6898
GlobalSection(ExtensibilityGlobals) = postSolution
6999
SolutionGuid = {655B2453-B859-4205-B05E-64082CF48732}

docker-compose.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
services:
2+
mssql:
3+
image: mcr.microsoft.com/mssql/server:2022-latest
4+
container_name: asp-net-mssql
5+
environment:
6+
- SA_PASSWORD=@PassWord123
7+
- ACCEPT_EULA=Y
8+
- MSSQL_PID=Developer
9+
- MSSQL_DATABASE=recipes_app_db
10+
ports:
11+
- 1433:1433
12+
volumes:
13+
- mssql_data:/var/opt/mssql
14+
restart: unless-stopped
15+
16+
volumes:
17+
mssql_data:
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using Microsoft.AspNetCore.Mvc;
2+
using RecipesApp.Application.UseCases.User.Register;
3+
using RecipesApp.Communication.Requests;
4+
using RecipesApp.Communication.Responses;
5+
6+
namespace RecipesApp.API.Controllers;
7+
8+
[Route("[controller]")]
9+
[ApiController]
10+
public class UsersController : ControllerBase
11+
{
12+
[HttpPost]
13+
[ProducesResponseType(typeof(RegisterUserResponseJSON), StatusCodes.Status201Created)]
14+
public async Task<IActionResult> Register(
15+
[FromServices] IRegisterUserUC uc,
16+
[FromBody] RegisterUserRequestJSON request)
17+
{
18+
var result = await uc.Execute(request);
19+
20+
return Created(string.Empty, result);
21+
}
22+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
using Microsoft.AspNetCore.Mvc;
2+
using Microsoft.AspNetCore.Mvc.Filters;
3+
using RecipesApp.Communication.Responses.Errors;
4+
using RecipesApp.Exception.Base;
5+
using RecipesApp.Exception.Project;
6+
using RecipesApp.Exception.Resources;
7+
8+
namespace RecipesApp.API.Filters;
9+
10+
public class ExceptionFilter : IExceptionFilter
11+
{
12+
public void OnException(ExceptionContext context)
13+
{
14+
if (context.Exception is ProjectException)
15+
HandleProjectException(context);
16+
else
17+
ThrowUnknowException(context);
18+
19+
}
20+
private void HandleProjectException(ExceptionContext context)
21+
{
22+
if (context.Exception is ErrorOnValidationException)
23+
{
24+
ErrorOnValidationException ex = (context.Exception as ErrorOnValidationException)!;
25+
26+
context.HttpContext
27+
.Response.StatusCode = StatusCodes.Status400BadRequest;
28+
context.Result = new BadRequestObjectResult(new ErrorListResponseJSON(ex.ErrorMessages));
29+
}
30+
}
31+
private void ThrowUnknowException(ExceptionContext context)
32+
{
33+
context.HttpContext
34+
.Response.StatusCode = StatusCodes.Status500InternalServerError;
35+
context.Result = new ObjectResult(
36+
new ErrorListResponseJSON(ResourcesAccessor.UNKNOWN_ERROR)
37+
);
38+
}
39+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
using System.Globalization;
2+
3+
namespace RecipesApp.API.Middlewares;
4+
5+
public class CultureMiddleware(RequestDelegate next)
6+
{
7+
private readonly RequestDelegate _next = next;
8+
9+
public async Task Invoke(HttpContext context)
10+
{
11+
string? requestedCulture = context.Request
12+
.Headers.AcceptLanguage.FirstOrDefault();
13+
requestedCulture = ValidStringCulture(requestedCulture);
14+
15+
CultureInfo culture = new(requestedCulture);
16+
17+
CultureInfo.CurrentCulture = culture;
18+
CultureInfo.CurrentUICulture = culture;
19+
20+
await _next(context);
21+
}
22+
private string ValidStringCulture(string? culture)
23+
{
24+
var cultures = CultureInfo.GetCultures(CultureTypes.AllCultures);
25+
bool isValid = !string.IsNullOrWhiteSpace(culture) && cultures.Any((c) => c.Name.Equals(culture));
26+
27+
return isValid ? culture! : "en";
28+
}
29+
}

src/BackEnd/RecipesApp.API/Program.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
using RecipesApp.API.Filters;
2+
using RecipesApp.API.Middlewares;
3+
using RecipesApp.Application;
4+
using RecipesApp.Infra.Data.Migrations;
5+
using RecipesApp.Infra.Extensions;
6+
17
var builder = WebApplication.CreateBuilder(args);
28

39
// Add services to the container.
@@ -6,6 +12,12 @@
612
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
713
builder.Services.AddEndpointsApiExplorer();
814
builder.Services.AddSwaggerGen();
15+
builder.Services.AddMvc(
16+
(opt) => opt.Filters.Add(typeof(ExceptionFilter))
17+
);
18+
19+
builder.Services.AddApplication(builder.Configuration);
20+
builder.Services.AddInfra(builder.Configuration);
921

1022
var app = builder.Build();
1123

@@ -16,10 +28,30 @@
1628
app.UseSwaggerUI();
1729
}
1830

31+
app.UseMiddleware<CultureMiddleware>();
32+
1933
app.UseHttpsRedirection();
2034

2135
app.UseAuthorization();
2236

2337
app.MapControllers();
2438

39+
MigrateDb(builder.Configuration);
40+
2541
app.Run();
42+
43+
void MigrateDb(IConfiguration configuration)
44+
{
45+
if (configuration.IsTesting())
46+
return;
47+
48+
var scope = app.Services
49+
.GetRequiredService<IServiceScopeFactory>().CreateScope();
50+
51+
MigrationDb.Migrate(
52+
configuration.ConnectionString(),
53+
scope.ServiceProvider
54+
);
55+
}
56+
57+
public partial class Program;

src/BackEnd/RecipesApp.API/RecipesApp.API.csproj

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,11 @@
1010
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2" />
1111
</ItemGroup>
1212

13-
<ItemGroup>
14-
<Folder Include="Controllers\" />
15-
</ItemGroup>
16-
1713
<ItemGroup>
1814
<ProjectReference Include="..\..\Shared\RecipesApp.Communication\RecipesApp.Communication.csproj" />
1915
<ProjectReference Include="..\..\Shared\RecipesApp.Exception\RecipesApp.Exception.csproj" />
2016
<ProjectReference Include="..\RecipesApp.Application\RecipesApp.Application.csproj" />
17+
<ProjectReference Include="..\RecipesApp.Infra\RecipesApp.Infra.csproj" />
2118
</ItemGroup>
2219

2320
</Project>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"EnvironmentTesting": true,
3+
"Logging": {
4+
"LogLevel": {
5+
"Default": "Information",
6+
"Microsoft.AspNetCore": "Warning"
7+
}
8+
},
9+
"Settings": {
10+
"key": "dot"
11+
}
12+
}

src/BackEnd/RecipesApp.API/appsettings.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,11 @@
55
"Microsoft.AspNetCore": "Warning"
66
}
77
},
8-
"AllowedHosts": "*"
8+
"AllowedHosts": "*",
9+
"ConnectionStrings": {
10+
"db": "Server=localhost,1433;Database=RecipesAppDB;User ID=sa;Password=@PassWord123;Trusted_Connection=False;TrustServerCertificate=True;"
11+
},
12+
"Settings": {
13+
"key": "1q2w3e4r@#$"
14+
}
915
}

0 commit comments

Comments
 (0)