Compare commits

..

No commits in common. "c82b8254204d8b83158f47200459d7fd4a7549a2" and "330f9ef74240001b715f5475f89decfb91f7c60c" have entirely different histories.

19 changed files with 147 additions and 227 deletions

60
.gitignore vendored
View File

@ -1,23 +1,53 @@
# Repository orchestration folders (local only)
.repo-tasks/
.repo-context/
# AgileWebs local orchestration
.tasks/
.agile/
# .NET build outputs
**/bin/
**/obj/
# Build artifacts
**/[Bb]in/
**/[Oo]bj/
/**/out/
/**/artifacts/
# IDE and editor files
.vs/
TestResults/
**/TestResults/
*.user
*.suo
*.rsuser
# IDE
.idea/
.vscode/
*.suo
*.user
*.userosscache
*.sln.docstates
*.rsuser
*.swp
*.swo
# Package artifacts
# NuGet
*.nupkg
*.snupkg
artifacts/
**/packages/*
!**/packages/build/
# Test output
**/TestResults/
*.trx
*.coverage
*.coveragexml
# Logs
*.log
logs/
# Local environment files
.env
.env.*
!.env.example
# Docker
.docker/
**/.docker/
*.pid
docker-compose.override.yml
docker-compose.*.override.yml
# OS files
.DS_Store
Thumbs.db

View File

@ -0,0 +1,86 @@
# Stage 1 Task
## 0. Header
- Task ID: TASK-20260222-001
- Title: Extract catalog contract ownership from legacy adapters
- Status: Planned
- Priority: P1
- Target Repo: building-block-catalog
- Target Branch: feature/building-block-catalog-001
- Related Master Plan: plan/master-stage1-structural-normalization-2026-02-22.md
- Related Mini Plan: plan/building-block-catalog-mini-plan.md
## 1. Goal (What and Why)
### What
- Identify product, tag, tag type, and tag override contract candidates
- Define clean contract ownership for catalog building block
### Why
- Catalog contracts must be reusable without implementation leakage
## 2. Scope
### In Scope
- Ownership split and contract inventory for catalog capability
### Out of Scope
- Furniture implementation migration
## 3. Constraints (Non-Negotiable)
- Stage 1 planning only. No implementation changes.
- Do not modify any file under legacy.
- Do not run repo provisioning or CI generation.
- Follow the approved architecture boundaries and protocol policy.
- Keep identity abstractions inside Thalos repositories.
## 4. Documentation Requirement
- [ ] Capture planning decisions clearly for handoff.
- [ ] Identify documentation and diagram updates expected in later stages.
## 5. Context
- This task derives from plan/building-block-catalog-mini-plan.md.
- This task must remain decision-focused and implementation-ready.
## 6. Proposed Approach
- Define a catalog contract ownership matrix from legacy adapter inputs
## 7. Execution Steps
1. Review legacy evidence relevant to this task scope.
2. Define target boundary decisions and contract implications.
3. Record risks, dependencies, and compatibility notes.
4. Produce clear handoff guidance for implementation stage.
## 8. Acceptance Criteria
- [ ] Decisions are explicit, scoped, and actionable.
- [ ] Ownership boundaries are unambiguous.
- [ ] Protocol policy alignment is explicit where applicable.
- [ ] No forbidden Stage 1 actions were performed.
## 9. Testing Plan
### Unit Tests
- Not applicable for Stage 1 planning artifacts.
### Validation
- Ensure consistency with master plan and mini plan.
## 10. Definition of Done
- [ ] Task content is complete and consistent with other task files.
- [ ] References to master and mini plans are correct.
- [ ] Handoff notes are clear enough for immediate implementation.
## 11. Risks and Questions
- Risk: boundary drift during implementation.
- Mitigation: enforce repo intent metadata and mini plan ownership.
## 12. Handoff Notes
- Preserve approved constraints exactly.
- Implementers should execute this task only after reading master and mini plans.
END OF TASK
## 13. Completion Metadata
- Completion Stage: Stage 3 Execution
- Completed On: 2026-02-22
- Completed By: Codex
- Completion Branch: feature/building-block-catalog-001
- Completion Commit: d45d882
- Lifecycle State: done

View File

@ -1,10 +0,0 @@
<Project>
<PropertyGroup>
<Authors>AgileWebs</Authors>
<Company>AgileWebs</Company>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>https://gitea.dream-views.com/AgileWebs/building-block-catalog</RepositoryUrl>
<PackageProjectUrl>https://gitea.dream-views.com/AgileWebs/building-block-catalog</PackageProjectUrl>
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
</PropertyGroup>
</Project>

View File

@ -3,24 +3,16 @@ skinparam packageStyle rectangle
package "building-block-catalog" {
package "BuildingBlock.Catalog.Contracts" {
class Conventions
class Products
class Tags
interface Adapters
class Grpc
interface Abstractions
}
}
package "blueprint-platform" {
interface IBlueprintPackageContract
}
package "furniture-dal" as FurnitureDal
package "furniture-service" as FurnitureService
package "furniture-bff" as FurnitureBff
Conventions ..> IBlueprintPackageContract
FurnitureDal --> Products
FurnitureDal --> Tags
FurnitureService --> Products

View File

@ -6,16 +6,12 @@
## Contract Groups
- `Conventions`: transport-neutral request/response and envelope conventions.
- `Products`: transport-neutral product contract shapes.
- `Tags`: transport-neutral tag, tag type, and tag override contract shapes.
- `Products`: product contract shapes.
- `Tags`: tag, tag type, and tag override contract shapes.
- `Abstractions`: marker abstraction for contract ownership.
- `Adapters`: protocol adapter boundaries.
- `Grpc`: gRPC contract shapes for adapter translation.
## Ownership Boundary
- This repository owns reusable catalog capability contracts.
- Contract metadata consumes `Core.Blueprint.Common.Contracts` and does not redefine Blueprint contracts.
- Persistence and transport implementations remain outside this package.
- Persistence and transport concerns remain outside this package.
- Identity abstractions remain Thalos-owned.

View File

@ -6,12 +6,7 @@
- Breaking changes require major version increments.
- Deprecated members remain through one deprecation cycle.
## Blueprint Compatibility
- Package descriptor metadata is implemented via `IBlueprintPackageContract` from `Core.Blueprint.Common.Contracts`.
- Catalog contracts consume Blueprint common contract primitives rather than redefining them.
## Compatibility Notes
- Consumers (`furniture-dal`, `furniture-service`, `furniture-bff`) update explicitly.
- Protocol adapters remain edge concerns; catalog contracts remain transport-neutral.
- Transport-specific adapters are out of scope for this contracts package.

View File

@ -1,29 +0,0 @@
# Catalog Contracts NuGet Publication Baseline
## Feed
- Source: `https://gitea.dream-views.com/api/packages/AgileWebs/nuget/index.json`
- Authentication: Gitea login + token
- HTTP requirement: `allowInsecureConnections="true"` in `nuget.config`
## Stable Version Matrix
| Package | Version | Published On |
| --- | --- | --- |
| BuildingBlock.Catalog.Contracts | 0.2.0 | 2026-02-25 |
## Dependency Note
`BuildingBlock.Catalog.Contracts` depends on:
- `Core.Blueprint.Common` version `0.2.0`
Stable package waves must keep dependency versions aligned.
## Consumer Validation
Restore validation passed using:
- `TargetFramework`: `net10.0`
- `PackageReference`: `BuildingBlock.Catalog.Contracts` `0.2.0`
- Restore flags: `--no-cache --force`

View File

@ -1,25 +0,0 @@
using BuildingBlock.Catalog.Contracts.Grpc;
using BuildingBlock.Catalog.Contracts.Products;
using BuildingBlock.Catalog.Contracts.Responses;
namespace BuildingBlock.Catalog.Contracts.Adapters;
/// <summary>
/// Defines adapter boundary for catalog gRPC contract translation.
/// </summary>
public interface ICatalogGrpcContractAdapter
{
/// <summary>
/// Maps transport-neutral product contract into gRPC shape.
/// </summary>
/// <param name="contract">Transport-neutral product contract.</param>
/// <returns>gRPC product contract shape.</returns>
CatalogProductGrpcContract ToGrpcProduct(ProductContract contract);
/// <summary>
/// Maps gRPC product contract into transport-neutral response.
/// </summary>
/// <param name="contract">gRPC product contract shape.</param>
/// <returns>Transport-neutral product response contract.</returns>
ProductContractResponse FromGrpcProduct(CatalogProductGrpcContract contract);
}

View File

@ -4,7 +4,4 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Core.Blueprint.Common" Version="0.2.0" />
</ItemGroup>
</Project>

View File

@ -1,8 +0,0 @@
namespace BuildingBlock.Catalog.Contracts.Conventions;
/// <summary>
/// Defines transport-neutral envelope metadata for catalog contract messages.
/// </summary>
/// <param name="ContractVersion">Contract schema version.</param>
/// <param name="CorrelationId">Correlation identifier for cross-service tracing.</param>
public sealed record CatalogContractEnvelope(string ContractVersion, string CorrelationId);

View File

@ -1,15 +0,0 @@
using Core.Blueprint.Common.Contracts;
namespace BuildingBlock.Catalog.Contracts.Conventions;
/// <summary>
/// Defines package descriptor metadata for catalog contracts package.
/// </summary>
public sealed class CatalogPackageContract : IBlueprintPackageContract
{
/// <inheritdoc />
public BlueprintPackageDescriptor Descriptor { get; } = new(
"BuildingBlock.Catalog.Contracts",
PackageVersionPolicy.Minor,
["Core.Blueprint.Common"]);
}

View File

@ -1,9 +0,0 @@
namespace BuildingBlock.Catalog.Contracts.Conventions;
/// <summary>
/// Defines transport-neutral request contract shape for catalog capability operations.
/// </summary>
/// <typeparam name="TResponse">Response contract type.</typeparam>
public interface ICatalogContractRequest<out TResponse>
{
}

View File

@ -1,8 +0,0 @@
namespace BuildingBlock.Catalog.Contracts.Grpc;
/// <summary>
/// Defines minimal gRPC contract shape for catalog product adapter translation.
/// </summary>
/// <param name="ProductId">Product identifier.</param>
/// <param name="DisplayName">Product display name.</param>
public sealed record CatalogProductGrpcContract(string ProductId, string DisplayName);

View File

@ -1,15 +1,8 @@
using BuildingBlock.Catalog.Contracts.Conventions;
namespace BuildingBlock.Catalog.Contracts.Products;
/// <summary>
/// Transport-neutral catalog product contract.
/// Catalog product contract.
/// </summary>
/// <param name="Envelope">Contract envelope metadata.</param>
/// <param name="ProductId">Product identifier in catalog capability scope.</param>
/// <param name="DisplayName">Product display name.</param>
public sealed record ProductContract(
CatalogContractEnvelope Envelope,
string ProductId,
string DisplayName)
: ICatalogContractRequest<Responses.ProductContractResponse>;
public sealed record ProductContract(string ProductId, string DisplayName);

View File

@ -1,14 +0,0 @@
using BuildingBlock.Catalog.Contracts.Conventions;
namespace BuildingBlock.Catalog.Contracts.Responses;
/// <summary>
/// Transport-neutral catalog product response contract.
/// </summary>
/// <param name="Envelope">Contract envelope metadata.</param>
/// <param name="ProductId">Product identifier in catalog capability scope.</param>
/// <param name="DisplayName">Product display name.</param>
public sealed record ProductContractResponse(
CatalogContractEnvelope Envelope,
string ProductId,
string DisplayName);

View File

@ -1,16 +1,9 @@
using BuildingBlock.Catalog.Contracts.Conventions;
namespace BuildingBlock.Catalog.Contracts.Tags;
/// <summary>
/// Transport-neutral catalog tag contract.
/// Catalog tag contract.
/// </summary>
/// <param name="Envelope">Contract envelope metadata.</param>
/// <param name="TagId">Tag identifier.</param>
/// <param name="TagTypeId">Tag type identifier.</param>
/// <param name="Value">Tag value.</param>
public sealed record TagContract(
CatalogContractEnvelope Envelope,
string TagId,
string TagTypeId,
string Value);
public sealed record TagContract(string TagId, string TagTypeId, string Value);

View File

@ -1,16 +1,9 @@
using BuildingBlock.Catalog.Contracts.Conventions;
namespace BuildingBlock.Catalog.Contracts.Tags;
/// <summary>
/// Transport-neutral catalog tag override contract.
/// Catalog tag override contract for consumer-specific overrides.
/// </summary>
/// <param name="Envelope">Contract envelope metadata.</param>
/// <param name="TagId">Tag identifier.</param>
/// <param name="TargetScope">Override target scope.</param>
/// <param name="OverrideValue">Override value.</param>
public sealed record TagOverrideContract(
CatalogContractEnvelope Envelope,
string TagId,
string TargetScope,
string OverrideValue);
public sealed record TagOverrideContract(string TagId, string TargetScope, string OverrideValue);

View File

@ -1,14 +1,8 @@
using BuildingBlock.Catalog.Contracts.Conventions;
namespace BuildingBlock.Catalog.Contracts.Tags;
/// <summary>
/// Transport-neutral catalog tag type contract.
/// Catalog tag type contract.
/// </summary>
/// <param name="Envelope">Contract envelope metadata.</param>
/// <param name="TagTypeId">Tag type identifier.</param>
/// <param name="Name">Tag type name.</param>
public sealed record TagTypeContract(
CatalogContractEnvelope Envelope,
string TagTypeId,
string Name);
public sealed record TagTypeContract(string TagTypeId, string Name);

View File

@ -1,57 +1,26 @@
using BuildingBlock.Catalog.Contracts.Conventions;
using BuildingBlock.Catalog.Contracts.Products;
using BuildingBlock.Catalog.Contracts.Responses;
using BuildingBlock.Catalog.Contracts.Tags;
using Core.Blueprint.Common.Contracts;
namespace BuildingBlock.Catalog.Contracts.UnitTests;
public class ContractShapeTests
{
[Fact]
public void ProductContract_WhenCreated_StoresTransportNeutralValues()
public void ProductContract_WhenCreated_StoresRequiredValues()
{
var envelope = new CatalogContractEnvelope("1.0.0", "corr-123");
var contract = new ProductContract(envelope, "PRD-001", "Chair");
var contract = new ProductContract("PRD-001", "Chair");
Assert.Equal("1.0.0", contract.Envelope.ContractVersion);
Assert.Equal("corr-123", contract.Envelope.CorrelationId);
Assert.Equal("PRD-001", contract.ProductId);
Assert.Equal("Chair", contract.DisplayName);
}
[Fact]
public void TagOverrideContract_WhenCreated_StoresTransportNeutralValues()
public void TagOverrideContract_WhenCreated_StoresRequiredValues()
{
var envelope = new CatalogContractEnvelope("1.0.0", "corr-123");
var contract = new TagOverrideContract(envelope, "TAG-001", "furniture", "featured");
var contract = new TagOverrideContract("TAG-001", "furniture", "featured");
Assert.Equal("1.0.0", contract.Envelope.ContractVersion);
Assert.Equal("corr-123", contract.Envelope.CorrelationId);
Assert.Equal("TAG-001", contract.TagId);
Assert.Equal("furniture", contract.TargetScope);
Assert.Equal("featured", contract.OverrideValue);
}
[Fact]
public void CatalogPackageContract_WhenCreated_UsesBlueprintDescriptorContract()
{
IBlueprintPackageContract contract = new CatalogPackageContract();
Assert.Equal("BuildingBlock.Catalog.Contracts", contract.Descriptor.PackageId);
Assert.Equal(PackageVersionPolicy.Minor, contract.Descriptor.VersionPolicy);
Assert.Contains("Core.Blueprint.Common", contract.Descriptor.DependencyPackageIds);
}
[Fact]
public void ProductContractResponse_WhenCreated_StoresTransportNeutralValues()
{
var envelope = new CatalogContractEnvelope("1.0.0", "corr-456");
var response = new ProductContractResponse(envelope, "PRD-001", "Chair");
Assert.Equal("1.0.0", response.Envelope.ContractVersion);
Assert.Equal("corr-456", response.Envelope.CorrelationId);
Assert.Equal("PRD-001", response.ProductId);
Assert.Equal("Chair", response.DisplayName);
}
}