feat(stage3): scaffold task-001 baseline
- WHY: establish Stage 3 task-001 execution baseline per repo intent - WHAT: add minimal solution/project skeleton and boundary docs - RULE: apply stage3 execution runtime and repository workflow directives
This commit is contained in:
parent
eb664ef06e
commit
1df7551e41
10
Furniture.Bff.slnx
Normal file
10
Furniture.Bff.slnx
Normal file
@ -0,0 +1,10 @@
|
||||
<Solution>
|
||||
<Folder Name="/src/">
|
||||
<Project Path="src/Furniture.Bff.Contracts/Furniture.Bff.Contracts.csproj" />
|
||||
<Project Path="src/Furniture.Bff.Application/Furniture.Bff.Application.csproj" />
|
||||
<Project Path="src/Furniture.Bff.Rest/Furniture.Bff.Rest.csproj" />
|
||||
</Folder>
|
||||
<Folder Name="/tests/">
|
||||
<Project Path="tests/Furniture.Bff.Application.UnitTests/Furniture.Bff.Application.UnitTests.csproj" />
|
||||
</Folder>
|
||||
</Solution>
|
||||
15
docs/api/external-api-surface.md
Normal file
15
docs/api/external-api-surface.md
Normal file
@ -0,0 +1,15 @@
|
||||
# External API Surface
|
||||
|
||||
## Active External Protocol
|
||||
|
||||
- REST is the active external protocol for this BFF deployment.
|
||||
|
||||
## Endpoint Baseline
|
||||
|
||||
- `GET /api/furniture/{furnitureId}/availability`
|
||||
|
||||
## Edge Responsibilities
|
||||
|
||||
- Validate and normalize consumer request inputs.
|
||||
- Map downstream service responses to consumer-facing shapes.
|
||||
- Map downstream errors to consistent API error models.
|
||||
20
docs/architecture/protocol-adaptation.puml
Normal file
20
docs/architecture/protocol-adaptation.puml
Normal file
@ -0,0 +1,20 @@
|
||||
@startuml
|
||||
skinparam packageStyle rectangle
|
||||
|
||||
package "furniture-bff" {
|
||||
class Program
|
||||
interface IGetFurnitureAvailabilityHandler
|
||||
class GetFurnitureAvailabilityHandler
|
||||
interface IFurnitureServiceClient
|
||||
|
||||
GetFurnitureAvailabilityHandler ..|> IGetFurnitureAvailabilityHandler
|
||||
GetFurnitureAvailabilityHandler --> IFurnitureServiceClient
|
||||
}
|
||||
|
||||
package "Consumers" as Consumers
|
||||
package "furniture-service" as FurnitureService
|
||||
|
||||
Consumers --> Program : REST
|
||||
Program --> IGetFurnitureAvailabilityHandler
|
||||
IFurnitureServiceClient ..> FurnitureService : gRPC/internal
|
||||
@enduml
|
||||
16
docs/operations/tracing-and-headers.md
Normal file
16
docs/operations/tracing-and-headers.md
Normal file
@ -0,0 +1,16 @@
|
||||
# Tracing and Headers
|
||||
|
||||
## Required Incoming Headers
|
||||
|
||||
- `X-Correlation-Id`
|
||||
- `X-Request-Id`
|
||||
|
||||
## Forwarding Rules
|
||||
|
||||
- Preserve correlation headers to downstream service calls.
|
||||
- Add correlation headers if missing at the edge.
|
||||
|
||||
## Observability Baseline
|
||||
|
||||
- Log protocol, route, and correlation identifiers per request.
|
||||
- Capture downstream call duration per request.
|
||||
@ -0,0 +1,16 @@
|
||||
using Furniture.Bff.Contracts.Api;
|
||||
|
||||
namespace Furniture.Bff.Application.Adapters;
|
||||
|
||||
/// <summary>
|
||||
/// Service adapter boundary used by BFF handlers.
|
||||
/// </summary>
|
||||
public interface IFurnitureServiceClient
|
||||
{
|
||||
/// <summary>
|
||||
/// Retrieves furniture availability from downstream service.
|
||||
/// </summary>
|
||||
/// <param name="furnitureId">Furniture identifier.</param>
|
||||
/// <returns>Consumer-ready availability contract.</returns>
|
||||
Task<GetFurnitureAvailabilityApiResponse> GetAvailabilityAsync(string furnitureId);
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Furniture.Bff.Contracts\Furniture.Bff.Contracts.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@ -0,0 +1,17 @@
|
||||
using Furniture.Bff.Application.Adapters;
|
||||
using Furniture.Bff.Contracts.Api;
|
||||
|
||||
namespace Furniture.Bff.Application.Handlers;
|
||||
|
||||
/// <summary>
|
||||
/// Default edge handler implementation for furniture availability.
|
||||
/// </summary>
|
||||
public sealed class GetFurnitureAvailabilityHandler(IFurnitureServiceClient serviceClient)
|
||||
: IGetFurnitureAvailabilityHandler
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public Task<GetFurnitureAvailabilityApiResponse> HandleAsync(GetFurnitureAvailabilityApiRequest request)
|
||||
{
|
||||
return serviceClient.GetAvailabilityAsync(request.FurnitureId);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
using Furniture.Bff.Contracts.Api;
|
||||
|
||||
namespace Furniture.Bff.Application.Handlers;
|
||||
|
||||
/// <summary>
|
||||
/// Edge handler boundary for furniture availability endpoint.
|
||||
/// </summary>
|
||||
public interface IGetFurnitureAvailabilityHandler
|
||||
{
|
||||
/// <summary>
|
||||
/// Handles external request and returns API response.
|
||||
/// </summary>
|
||||
/// <param name="request">API request contract.</param>
|
||||
/// <returns>API response contract.</returns>
|
||||
Task<GetFurnitureAvailabilityApiResponse> HandleAsync(GetFurnitureAvailabilityApiRequest request);
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
namespace Furniture.Bff.Contracts.Api;
|
||||
|
||||
/// <summary>
|
||||
/// External REST request contract for furniture availability.
|
||||
/// </summary>
|
||||
/// <param name="FurnitureId">Furniture identifier provided by consumers.</param>
|
||||
public sealed record GetFurnitureAvailabilityApiRequest(string FurnitureId);
|
||||
@ -0,0 +1,8 @@
|
||||
namespace Furniture.Bff.Contracts.Api;
|
||||
|
||||
/// <summary>
|
||||
/// External REST response contract for furniture availability.
|
||||
/// </summary>
|
||||
/// <param name="FurnitureId">Requested furniture identifier.</param>
|
||||
/// <param name="QuantityAvailable">Availability value for client display.</param>
|
||||
public sealed record GetFurnitureAvailabilityApiResponse(string FurnitureId, int QuantityAvailable);
|
||||
@ -0,0 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
12
src/Furniture.Bff.Rest/Endpoints/EndpointConventions.cs
Normal file
12
src/Furniture.Bff.Rest/Endpoints/EndpointConventions.cs
Normal file
@ -0,0 +1,12 @@
|
||||
namespace Furniture.Bff.Rest.Endpoints;
|
||||
|
||||
/// <summary>
|
||||
/// Defines endpoint conventions for the furniture BFF REST surface.
|
||||
/// </summary>
|
||||
public static class EndpointConventions
|
||||
{
|
||||
/// <summary>
|
||||
/// Prefix used by public furniture API routes.
|
||||
/// </summary>
|
||||
public const string ApiPrefix = "/api/furniture";
|
||||
}
|
||||
11
src/Furniture.Bff.Rest/Furniture.Bff.Rest.csproj
Normal file
11
src/Furniture.Bff.Rest/Furniture.Bff.Rest.csproj
Normal file
@ -0,0 +1,11 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Furniture.Bff.Application\Furniture.Bff.Application.csproj" />
|
||||
<ProjectReference Include="..\Furniture.Bff.Contracts\Furniture.Bff.Contracts.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
13
src/Furniture.Bff.Rest/Program.cs
Normal file
13
src/Furniture.Bff.Rest/Program.cs
Normal file
@ -0,0 +1,13 @@
|
||||
using Furniture.Bff.Contracts.Api;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
// Stage 3 skeleton: single active external protocol for this deployment is REST.
|
||||
var app = builder.Build();
|
||||
|
||||
app.MapGet("/api/furniture/{furnitureId}/availability", (string furnitureId) =>
|
||||
{
|
||||
return Results.Ok(new GetFurnitureAvailabilityApiResponse(furnitureId, 0));
|
||||
});
|
||||
|
||||
app.Run();
|
||||
@ -0,0 +1,21 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="coverlet.collector" Version="6.0.4" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
|
||||
<PackageReference Include="xunit" Version="2.9.3" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.4" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Using Include="Xunit" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\Furniture.Bff.Application\Furniture.Bff.Application.csproj" />
|
||||
<ProjectReference Include="..\..\src\Furniture.Bff.Contracts\Furniture.Bff.Contracts.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@ -0,0 +1,27 @@
|
||||
using Furniture.Bff.Application.Adapters;
|
||||
using Furniture.Bff.Application.Handlers;
|
||||
using Furniture.Bff.Contracts.Api;
|
||||
|
||||
namespace Furniture.Bff.Application.UnitTests;
|
||||
|
||||
public class GetFurnitureAvailabilityHandlerTests
|
||||
{
|
||||
[Fact]
|
||||
public async Task HandleAsync_WhenCalled_DelegatesToServiceClient()
|
||||
{
|
||||
var handler = new GetFurnitureAvailabilityHandler(new FakeFurnitureServiceClient());
|
||||
|
||||
var response = await handler.HandleAsync(new GetFurnitureAvailabilityApiRequest("FUR-001"));
|
||||
|
||||
Assert.Equal("FUR-001", response.FurnitureId);
|
||||
Assert.Equal(3, response.QuantityAvailable);
|
||||
}
|
||||
|
||||
private sealed class FakeFurnitureServiceClient : IFurnitureServiceClient
|
||||
{
|
||||
public Task<GetFurnitureAvailabilityApiResponse> GetAvailabilityAsync(string furnitureId)
|
||||
{
|
||||
return Task.FromResult(new GetFurnitureAvailabilityApiResponse(furnitureId, 3));
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user