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
063c1a2f2d
commit
058ba3196c
10
Furniture.Service.slnx
Normal file
10
Furniture.Service.slnx
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<Solution>
|
||||||
|
<Folder Name="/src/">
|
||||||
|
<Project Path="src/Furniture.Service.Contracts/Furniture.Service.Contracts.csproj" />
|
||||||
|
<Project Path="src/Furniture.Service.Application/Furniture.Service.Application.csproj" />
|
||||||
|
<Project Path="src/Furniture.Service.Grpc/Furniture.Service.Grpc.csproj" />
|
||||||
|
</Folder>
|
||||||
|
<Folder Name="/tests/">
|
||||||
|
<Project Path="tests/Furniture.Service.Application.UnitTests/Furniture.Service.Application.UnitTests.csproj" />
|
||||||
|
</Folder>
|
||||||
|
</Solution>
|
||||||
13
docs/application/use-case-boundaries.md
Normal file
13
docs/application/use-case-boundaries.md
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# Furniture Service Use-Case Boundaries
|
||||||
|
|
||||||
|
## Orchestration Responsibilities
|
||||||
|
|
||||||
|
- Application use cases orchestrate domain workflows.
|
||||||
|
- Use cases depend on DAL-facing ports, not persistence implementations.
|
||||||
|
- Transport handlers map to use-case contracts and do not own orchestration logic.
|
||||||
|
|
||||||
|
## Current Skeleton
|
||||||
|
|
||||||
|
- `IGetFurnitureAvailabilityUseCase`: orchestration boundary contract.
|
||||||
|
- `GetFurnitureAvailabilityUseCase`: orchestration implementation.
|
||||||
|
- `IFurnitureAvailabilityReadPort`: DAL-facing port.
|
||||||
12
docs/architecture/protocol-selection-policy.md
Normal file
12
docs/architecture/protocol-selection-policy.md
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
# Protocol Selection Policy
|
||||||
|
|
||||||
|
## Active Protocol Rule
|
||||||
|
|
||||||
|
- This service deployment uses one active protocol at a time.
|
||||||
|
- Internal default protocol is gRPC.
|
||||||
|
- Multi-protocol exposure is not allowed in a single deployment.
|
||||||
|
|
||||||
|
## Boundary Placement
|
||||||
|
|
||||||
|
- Protocol adaptation stays at BFF boundaries.
|
||||||
|
- Service orchestration remains transport-neutral at application contracts.
|
||||||
23
docs/architecture/service-contracts.puml
Normal file
23
docs/architecture/service-contracts.puml
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
@startuml
|
||||||
|
skinparam packageStyle rectangle
|
||||||
|
|
||||||
|
package "furniture-service" {
|
||||||
|
interface IGetFurnitureAvailabilityUseCase
|
||||||
|
class GetFurnitureAvailabilityUseCase
|
||||||
|
interface IFurnitureAvailabilityReadPort
|
||||||
|
class GetFurnitureAvailabilityRequest
|
||||||
|
class GetFurnitureAvailabilityResponse
|
||||||
|
|
||||||
|
GetFurnitureAvailabilityUseCase ..|> IGetFurnitureAvailabilityUseCase
|
||||||
|
GetFurnitureAvailabilityUseCase --> IFurnitureAvailabilityReadPort
|
||||||
|
IGetFurnitureAvailabilityUseCase --> GetFurnitureAvailabilityRequest
|
||||||
|
IGetFurnitureAvailabilityUseCase --> GetFurnitureAvailabilityResponse
|
||||||
|
}
|
||||||
|
|
||||||
|
package "furniture-bff" as FurnitureBff
|
||||||
|
package "furniture-dal" as FurnitureDal
|
||||||
|
|
||||||
|
FurnitureBff --> IGetFurnitureAvailabilityUseCase
|
||||||
|
GetFurnitureAvailabilityUseCase --> IFurnitureAvailabilityReadPort
|
||||||
|
IFurnitureAvailabilityReadPort ..> FurnitureDal
|
||||||
|
@enduml
|
||||||
@ -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.Service.Contracts\Furniture.Service.Contracts.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
using Furniture.Service.Contracts.UseCases;
|
||||||
|
|
||||||
|
namespace Furniture.Service.Application.Ports;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Defines DAL-facing read port for furniture availability.
|
||||||
|
/// </summary>
|
||||||
|
public interface IFurnitureAvailabilityReadPort
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves current availability for a furniture aggregate.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="furnitureId">Furniture aggregate identifier.</param>
|
||||||
|
/// <returns>Availability response contract.</returns>
|
||||||
|
Task<GetFurnitureAvailabilityResponse> GetAvailabilityAsync(string furnitureId);
|
||||||
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
using Furniture.Service.Application.Ports;
|
||||||
|
using Furniture.Service.Contracts.UseCases;
|
||||||
|
|
||||||
|
namespace Furniture.Service.Application.UseCases;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Default orchestration implementation for furniture availability lookup.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class GetFurnitureAvailabilityUseCase(IFurnitureAvailabilityReadPort readPort)
|
||||||
|
: IGetFurnitureAvailabilityUseCase
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public Task<GetFurnitureAvailabilityResponse> HandleAsync(GetFurnitureAvailabilityRequest request)
|
||||||
|
{
|
||||||
|
return readPort.GetAvailabilityAsync(request.FurnitureId);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
using Furniture.Service.Contracts.UseCases;
|
||||||
|
|
||||||
|
namespace Furniture.Service.Application.UseCases;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Defines orchestration boundary for furniture availability lookup.
|
||||||
|
/// </summary>
|
||||||
|
public interface IGetFurnitureAvailabilityUseCase
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Handles the availability lookup use case.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="request">Use-case request contract.</param>
|
||||||
|
/// <returns>Use-case response contract.</returns>
|
||||||
|
Task<GetFurnitureAvailabilityResponse> HandleAsync(GetFurnitureAvailabilityRequest request);
|
||||||
|
}
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
namespace Furniture.Service.Contracts.UseCases;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Request contract for furniture availability lookup.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="FurnitureId">Furniture aggregate identifier.</param>
|
||||||
|
public sealed record GetFurnitureAvailabilityRequest(string FurnitureId);
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
namespace Furniture.Service.Contracts.UseCases;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Response contract for furniture availability lookup.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="FurnitureId">Furniture aggregate identifier.</param>
|
||||||
|
/// <param name="QuantityAvailable">Available quantity for the requested furniture.</param>
|
||||||
|
public sealed record GetFurnitureAvailabilityResponse(string FurnitureId, int QuantityAvailable);
|
||||||
11
src/Furniture.Service.Grpc/Furniture.Service.Grpc.csproj
Normal file
11
src/Furniture.Service.Grpc/Furniture.Service.Grpc.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.Service.Application\Furniture.Service.Application.csproj" />
|
||||||
|
<ProjectReference Include="..\Furniture.Service.Contracts\Furniture.Service.Contracts.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
6
src/Furniture.Service.Grpc/Program.cs
Normal file
6
src/Furniture.Service.Grpc/Program.cs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
|
// Stage 3 skeleton: keep a single active internal protocol policy (gRPC-first).
|
||||||
|
var app = builder.Build();
|
||||||
|
|
||||||
|
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.Service.Application\Furniture.Service.Application.csproj" />
|
||||||
|
<ProjectReference Include="..\..\src\Furniture.Service.Contracts\Furniture.Service.Contracts.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
@ -0,0 +1,28 @@
|
|||||||
|
using Furniture.Service.Application.Ports;
|
||||||
|
using Furniture.Service.Application.UseCases;
|
||||||
|
using Furniture.Service.Contracts.UseCases;
|
||||||
|
|
||||||
|
namespace Furniture.Service.Application.UnitTests;
|
||||||
|
|
||||||
|
public class GetFurnitureAvailabilityUseCaseTests
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public async Task HandleAsync_WhenCalled_DelegatesToReadPort()
|
||||||
|
{
|
||||||
|
var port = new FakeFurnitureAvailabilityReadPort();
|
||||||
|
var useCase = new GetFurnitureAvailabilityUseCase(port);
|
||||||
|
|
||||||
|
var response = await useCase.HandleAsync(new GetFurnitureAvailabilityRequest("FUR-001"));
|
||||||
|
|
||||||
|
Assert.Equal("FUR-001", response.FurnitureId);
|
||||||
|
Assert.Equal(10, response.QuantityAvailable);
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed class FakeFurnitureAvailabilityReadPort : IFurnitureAvailabilityReadPort
|
||||||
|
{
|
||||||
|
public Task<GetFurnitureAvailabilityResponse> GetAvailabilityAsync(string furnitureId)
|
||||||
|
{
|
||||||
|
return Task.FromResult(new GetFurnitureAvailabilityResponse(furnitureId, 10));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user