Skip to content

Commit

Permalink
Merge branch 'main' into jssbg-69_display-nodes
Browse files Browse the repository at this point in the history
  • Loading branch information
stamenione committed Jan 14, 2025
2 parents 008b1d8 + 18efe8e commit 8ee5c8a
Show file tree
Hide file tree
Showing 130 changed files with 2,126 additions and 364 deletions.
1 change: 1 addition & 0 deletions Backend/src/Applications/Core/Core.Api/Core.Api.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
<ProjectReference Include="..\..\..\Modules\Notes\Notes.Api\Notes.Api.csproj" />
<ProjectReference Include="..\..\..\Modules\Reminders\Reminders.Api\Reminders.Api.csproj" />
<ProjectReference Include="..\..\..\Modules\Timelines\Timelines.Api\Timelines.Api.csproj" />
<ProjectReference Include="..\..\..\Sdk\Core.Api.Sdk\Core.Api.Sdk.csproj" />
</ItemGroup>

<ItemGroup>
Expand Down
6 changes: 6 additions & 0 deletions Backend/src/Applications/Core/Core.Api/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
using BuildingBlocks.Domain;
using Carter;
using Core.Api.Extensions;
using Core.Api.Sdk;
using Core.Api.Sdk.Interfaces;
using HealthChecks.UI.Client;
using Microsoft.AspNetCore.Diagnostics.HealthChecks;

Expand All @@ -19,6 +21,8 @@
builder.Services.AddHealthChecks()
.AddNpgSql(builder.Configuration.GetConnectionString("DefaultConnection") ?? throw new InvalidOperationException());

builder.Services.AddHttpClient<ICoreApiClient, CoreApiClient>();

var app = builder.Build();

// Configure the HTTP request pipeline.
Expand All @@ -41,3 +45,5 @@
});

app.Run();

public abstract partial class Program; // This partial class is needed for the integration tests
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using BuildingBlocks.Domain.ValueObjects.Ids;

namespace BuildingBlocks.Api.Converters;

public class FileIdConverter : IRegister
{
public void Register(TypeAdapterConfig config) =>
config.NewConfig<FileAssetId, FileAssetId>().ConstructUsing(src => FileAssetId.Of(src.Value));
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
namespace BuildingBlocks.Api.Converters;

public class NodeIdConverter : IRegister
{
public void Register(TypeAdapterConfig config) =>
config.NewConfig<NodeId, NodeId>().ConstructUsing(src => NodeId.Of(src.Value));
}
using BuildingBlocks.Domain.ValueObjects.Ids;

namespace BuildingBlocks.Api.Converters;

public class NodeIdConverter : IRegister
{
public void Register(TypeAdapterConfig config) =>
config.NewConfig<NodeId, NodeId>().ConstructUsing(src => NodeId.Of(src.Value));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using BuildingBlocks.Domain.ValueObjects.Ids;

namespace BuildingBlocks.Api.Converters;

public class NoteIdConverter : IRegister
{
public void Register(TypeAdapterConfig config) =>
config.NewConfig<NoteId, NoteId>().ConstructUsing(src => NoteId.Of(src.Value));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using BuildingBlocks.Domain.ValueObjects.Ids;

namespace BuildingBlocks.Api.Converters;

public class ReminderIdConverter : IRegister
{
public void Register(TypeAdapterConfig config) =>
config.NewConfig<ReminderId, ReminderId>().ConstructUsing(src => ReminderId.Of(src.Value));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using BuildingBlocks.Domain.ValueObjects.Ids;

namespace BuildingBlocks.Api.Converters;

public class TimelineIdConverter : IRegister
{
public void Register(TypeAdapterConfig config) =>
config.NewConfig<TimelineId, TimelineId>().ConstructUsing(src => TimelineId.Of(src.Value));
}
3 changes: 1 addition & 2 deletions Backend/src/BuildingBlocks/BuildingBlocks.Api/GlobalUsing.cs
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
global using Mapster;
global using BuildingBlocks.Domain.ValueObjects.Ids;
global using Mapster;
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
using System.Text.Json.Serialization;
namespace BuildingBlocks.Domain.ValueObjects.Ids;

namespace BuildingBlocks.Domain.ValueObjects.Ids;

[JsonConverter(typeof(FileAssetIdJsonConverter))]
public record FileAssetId : StronglyTypedId
public class FileAssetId : StronglyTypedId
{
private FileAssetId(Guid value) : base(value) { }

public static FileAssetId Of(Guid value) => new(value);

private class FileAssetIdJsonConverter : StronglyTypedIdJsonConverter<FileAssetId>;
public override string ToString() => Value.ToString();
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,55 @@
using System.Text.Json.Serialization;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace BuildingBlocks.Domain.ValueObjects.Ids;

[JsonConverter(typeof(NodeIdJsonConverter))]
public record NodeId : StronglyTypedId
public class NodeId : StronglyTypedId
{
private NodeId(Guid value) : base(value) { }

public static NodeId Of(Guid value) => new(value);

private class NodeIdJsonConverter : StronglyTypedIdJsonConverter<NodeId>;
public override string ToString() => Value.ToString();
}

public class NodeIdJsonConverter : JsonConverter<NodeId>
{
public override NodeId Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
// ReSharper disable once SwitchStatementHandlesSomeKnownEnumValuesWithDefault
switch (reader.TokenType)
{
case JsonTokenType.String:
{
var guidString = reader.GetString();
if (!Guid.TryParse(guidString, out var guid))
throw new JsonException($"Invalid GUID format for NodeId: {guidString}");

return NodeId.Of(guid);
}
case JsonTokenType.StartObject:
{
using var jsonDoc = JsonDocument.ParseValue(ref reader);

if (!jsonDoc.RootElement.TryGetProperty("id", out JsonElement idElement))
throw new JsonException("Expected property 'id' not found.");

var guidString = idElement.GetString();

if (!Guid.TryParse(guidString, out var guid))
throw new JsonException($"Invalid GUID format for NodeId: {guidString}");

return NodeId.Of(guid);
}
default:
throw new JsonException(
$"Unexpected token parsing NodeId. Expected String or StartObject, got {reader.TokenType}.");
}
}

public override void Write(Utf8JsonWriter writer, NodeId value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.ToString());
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
using System.Text.Json.Serialization;
namespace BuildingBlocks.Domain.ValueObjects.Ids;

namespace BuildingBlocks.Domain.ValueObjects.Ids;

[JsonConverter(typeof(NoteIdJsonConverter))]
public record NoteId : StronglyTypedId
public class NoteId : StronglyTypedId
{
private NoteId(Guid value) : base(value) { }

public static NoteId Of(Guid value) => new(value);

private class NoteIdJsonConverter : StronglyTypedIdJsonConverter<NoteId>;
public override string ToString() => Value.ToString();
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
using System.Text.Json.Serialization;
namespace BuildingBlocks.Domain.ValueObjects.Ids;

namespace BuildingBlocks.Domain.ValueObjects.Ids;

[JsonConverter(typeof(ReminderIdJsonConverter))]
public record ReminderId : StronglyTypedId
public class ReminderId : StronglyTypedId
{
private ReminderId(Guid value) : base(value) { }

public static ReminderId Of(Guid value) => new(value);

private class ReminderIdJsonConverter : StronglyTypedIdJsonConverter<ReminderId>;
public override string ToString() => Value.ToString();
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
using System.Text.Json.Serialization;
namespace BuildingBlocks.Domain.ValueObjects.Ids;

namespace BuildingBlocks.Domain.ValueObjects.Ids;

[JsonConverter(typeof(TimelineIdJsonConverter))]
public record TimelineId : StronglyTypedId
public class TimelineId : StronglyTypedId
{
private TimelineId(Guid value) : base(value) { }

public static TimelineId Of(Guid value) => new(value);

private class TimelineIdJsonConverter : StronglyTypedIdJsonConverter<TimelineId>;
public override string ToString() => Value.ToString();
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
using System.Text.Json.Serialization;
using System.Text.Json;
namespace BuildingBlocks.Domain.ValueObjects;

namespace BuildingBlocks.Domain.ValueObjects;

public abstract record StronglyTypedId
public abstract class StronglyTypedId
{
protected StronglyTypedId(Guid value)
{
Expand All @@ -14,27 +11,6 @@ protected StronglyTypedId(Guid value)
}

public Guid Value { get; }

public override string ToString() => Value.ToString();
}

public class StronglyTypedIdJsonConverter<T> : JsonConverter<T> where T : StronglyTypedId
{
public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var value = reader.GetString();

if (Guid.TryParse(value, out var guid))
{
var constructor = typeof(T).GetConstructor(new[] { typeof(Guid) });

if (constructor != null)
return (T)constructor.Invoke(new object[] { guid });
}

throw new JsonException($"Invalid GUID format for {typeof(T).Name}: {value}");
}

public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options) =>
writer.WriteStringValue(value.Value.ToString());

public abstract override string ToString();
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
using BuildingBlocks.Domain.ValueObjects.Ids;
using Files.Application.Files.Commands.CreateFileAsset;
using Files.Application.Entities.Files.Commands.CreateFileAsset;

// ReSharper disable ClassNeverInstantiated.Global

namespace Files.Api.Endpoints;
namespace Files.Api.Endpoints.Files;

public class CreateFileAsset : ICarterModule
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System.Text.Json.Serialization;
using Files.Application.Entities.Files.Queries.GetFileAssetById;

namespace Files.Api.Endpoints.Files;

// ReSharper disable once UnusedType.Global
public class GetFileAssetById : ICarterModule
{
public void AddRoutes(IEndpointRouteBuilder app)
{
app.MapGet("/Files/{fileId}", async (string fileId, ISender sender) =>
{
var result = await sender.Send(new GetFileAssetByIdQuery(fileId));
var response = result.Adapt<GetFileAssetByIdResponse>();

return Results.Ok(response);
})
.WithName("GetFileAssetById")
.Produces<GetFileAssetByIdResponse>()
.ProducesProblem(StatusCodes.Status400BadRequest)
.ProducesProblem(StatusCodes.Status404NotFound)
.WithSummary("Get File Asset by Id")
.WithDescription("Get File Asset by Id");
}
}

// ReSharper disable once ClassNeverInstantiated.Global
// ReSharper disable once NotAccessedPositionalProperty.Global
public record GetFileAssetByIdResponse([property: JsonPropertyName("file")] FileAssetDto FileAssetDto);
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using BuildingBlocks.Application.Pagination;
using Files.Application.Entities.Files.Queries.ListFileAssets;

namespace Files.Api.Endpoints.Files;

public class ListFileAssets : ICarterModule
{
public void AddRoutes(IEndpointRouteBuilder app)
{
app.MapGet("/Files", async ([AsParameters] PaginationRequest query, ISender sender) =>
{
var result = await sender.Send(new ListFileAssetsQuery(query));
var response = result.Adapt<ListFileAssetsResponse>();

return Results.Ok(response);
})
.WithName("ListFileAssets")
.Produces<ListFileAssetsResponse>()
.ProducesProblem(StatusCodes.Status400BadRequest)
.WithSummary("List File Assets")
.WithDescription("List File Assets");
}
}

// ReSharper disable once ClassNeverInstantiated.Global
// ReSharper disable once NotAccessedPositionalProperty.Global
public record ListFileAssetsResponse(PaginatedResult<FileAssetDto> FileAssets);
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using BuildingBlocks.Api.Converters;
using Files.Application.Extensions;
using Files.Infrastructure;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

Expand All @@ -21,8 +20,7 @@ public static IServiceCollection AddFilesModule

private static IServiceCollection AddApiServices(this IServiceCollection services)
{
// services.AddExceptionHandler<CustomExceptionHandler>();
// services.AddHealthChecks()...
TypeAdapterConfig.GlobalSettings.Scan(typeof(FileIdConverter).Assembly);

return services;
}
Expand All @@ -31,9 +29,6 @@ public static IEndpointRouteBuilder UseFilesModule(this IEndpointRouteBuilder en
{
endpoints.MapGet("/Files/Test", () => "Files.Api Test -> Ok!");

// app.UseExceptionHandler(_ => { });
// app.UseHealthChecks...

return endpoints;
}
}
2 changes: 1 addition & 1 deletion Backend/src/Modules/Files/Files.Api/GlobalUsing.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
global using Microsoft.AspNetCore.Builder;
global using Microsoft.AspNetCore.Http;
global using Microsoft.AspNetCore.Routing;
global using Files.Application.Dtos;
global using Files.Application.Entities.Files.Dtos;
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
using BuildingBlocks.Domain.ValueObjects.Ids;
using Files.Application.Dtos;
using FluentValidation;
using Files.Application.Entities.Files.Dtos;

namespace Files.Application.Files.Commands.CreateFileAsset;
namespace Files.Application.Entities.Files.Commands.CreateFileAsset;

// ReSharper disable once ClassNeverInstantiated.Global
public record CreateFileAssetCommand(FileAssetDto FileAsset) : ICommand<CreateFileAssetResult>;

// ReSharper disable once NotAccessedPositionalProperty.Global
public record CreateFileAssetResult(FileAssetId Id);

public class CreateFileCommandValidator : AbstractValidator<CreateFileAssetCommand>
Expand Down
Loading

0 comments on commit 8ee5c8a

Please sign in to comment.