Temporal workflow and activity contracts for distributed workflow processing system with support for multiple workflow types including Real Estate Ingestor (REI), Real Estate Processor (REP), and Payload Transformer (PT) services. Includes Temporalio.Extensions.Hosting for seamless .NET dependency injection integration.
$ dotnet add package BR.Workflow.ContractsA comprehensive .NET 8 library containing Temporal workflow and activity contracts for distributed workflow processing systems. Built with Clean Architecture principles and clear separation of concerns across service domains.
BR.Workflow.Contracts is the foundation for building distributed, scalable workflow systems using Temporal.io and .NET 8. It provides:
This package implements Clean Architecture with clear separation by service domains:
| Domain | Purpose | Key Responsibilities |
|---|---|---|
| REI (Real Estate Ingestor) | Event validation and blob operations | Event validation, blob downloads, status updates |
| REP (Real Estate Processor) | Order processing and business logic | Order management, schema validation, client communication |
| PT (Payload Transformer) | Data transformation for external services | Data mapping, format conversion, schema validation |
dotnet add package BR.Workflow.Contracts
Install-Package BR.Workflow.Contracts
<PackageReference Include="BR.Workflow.Contracts" Version="1.0.17" />
BR.Workflow.Contracts/
├── 📁 Workflows/ # Workflow orchestration contracts
│ ├── IStartRealEstateWorkflow.cs # Main workflow interface
│ └── Models/
│ └── RealEstateWorkflowOutput.cs
│
├── 📁 Activities/ # Activity contracts by service domain
│ ├── 🏠 REI/ # Real Estate Ingestor (3 activities)
│ │ ├── IValidateEventActivity.cs
│ │ ├── IDownloadBlobActivity.cs
│ │ └── IUpdateOrderStatusInBlobActivity.cs
│ │
│ ├── ⚙️ REP/ # Real Estate Processor (9 activities)
│ │ ├── IValidateSchemaTemplateActivity.cs
│ │ ├── IDetermineActionTypeActivity.cs
│ │ ├── ICreateOrderActivity.cs
│ │ ├── IUpdateOrderActivity.cs
│ │ ├── IApproveOrderActivity.cs
│ │ ├── IRejectOrderActivity.cs
│ │ ├── INotifyClientActivity.cs
│ │ ├── IUpdateDbActivity.cs
│ │ └── ICallApiGatewayActivity.cs
│ │
│ └── 🔄 PT/ # Payload Transformer (1 activity)
│ └── ITransformPayloadActivity.cs
│
├── 📁 Models/ # Data models organized by domain
│ ├── 🌐 Common/ # Shared models across all services
│ │ ├── AuditInfo.cs # Workflow execution audit
│ │ ├── ErrorInfo.cs # Error details and tracking
│ │ ├── ValidationError.cs # Validation failure details
│ │ ├── ValidationResult.cs # Validation operation results
│ │ ├── StatusUpdate.cs # Status change notifications
│ │ ├── ApiGatewayResponse.cs # External API responses
│ │ ├── BlobMetadata.cs # Blob storage metadata
│ │ ├── DownloadInfo.cs # Download operation details
│ │ └── DuplicateCheck.cs # Duplicate detection results
│ │
│ ├── 📨 Kafka/ # Kafka payload and workflow input
│ │ ├── RealEstateWorkflowInput.cs # Main workflow input
│ │ ├── EventInfo.cs # Event metadata and correlation
│ │ ├── ClientInfo.cs # Client identification
│ │ ├── BlobInfo.cs # Blob storage information
│ │ ├── DeadLetterEvent.cs # DLQ event handling
│ │ └── DlqDetails.cs # DLQ failure details
│ │
│ ├── 🏠 REI/ # Real Estate Ingestor models
│ │ ├── ValidateEventInput.cs # Event validation input
│ │ ├── ValidateEventOutput.cs # Event validation results
│ │ ├── DownloadBlobInput.cs # Blob download parameters
│ │ ├── DownloadBlobOutput.cs # Blob download results
│ │ ├── UpdateOrderStatusInput.cs # Status update input
│ │ └── UpdateOrderStatusOutput.cs # Status update results
│ │
│ ├── ⚙️ REP/ # Real Estate Processor models
│ │ ├── ValidateSchemaInput.cs # Schema validation input
│ │ ├── ValidateSchemaOutput.cs # Schema validation results
│ │ ├── DetermineActionInput.cs # Action determination input
│ │ ├── DetermineActionOutput.cs # Action determination results
│ │ ├── CreateOrderInput.cs # Order creation input
│ │ ├── CreateOrderOutput.cs # Order creation results
│ │ ├── UpdateOrderInput.cs # Order update input
│ │ ├── UpdateOrderOutput.cs # Order update results
│ │ ├── ApproveOrderInput.cs # Order approval input
│ │ ├── ApproveOrderOutput.cs # Order approval results
│ │ ├── RejectOrderInput.cs # Order rejection input
│ │ ├── RejectOrderOutput.cs # Order rejection results
│ │ ├── NotifyClientInput.cs # Client notification input
│ │ ├── NotifyClientOutput.cs # Client notification results
│ │ ├── UpdateDbInput.cs # Database update input
│ │ ├── UpdateDbOutput.cs # Database update results
│ │ ├── CallApiGatewayInput.cs # API Gateway call input
│ │ └── CallApiGatewayOutput.cs # API Gateway call results
│ │
│ └── 🔄 PT/ # Payload Transformer models
│ ├── TransformPayloadInput.cs # Transformation input
│ ├── TransformPayloadOutput.cs # Transformation results
│ └── TransformationRules.cs # Transformation configuration
│
├── 📁 Enums/ # Type-safe enumerations
│ ├── ActionType.cs # Order processing actions
│ ├── BrightRiverStatus.cs # Bright River specific statuses
│ ├── DeliveryStatus.cs # Delivery operation statuses
│ ├── HttpMethod.cs # HTTP method constants
│ ├── NotificationType.cs # Notification type definitions
│ ├── OrderStatus.cs # Order lifecycle statuses
│ └── ValidationSeverity.cs # Validation error severity levels
│
├── 📁 Extensions/ # Utility extension methods
│ ├── TemporalExtensions.cs # Workflow result helpers
│ ├── ContractExtensions.cs # Contract utility methods
│ └── ValidationExtensions.cs # Validation helper methods
│
├── 📁 Constants/ # Configuration constants
│ ├── ActivityNames.cs # Activity naming constants
│ ├── ConfigurationKeys.cs # Configuration key constants
│ ├── TaskQueues.cs # Task queue names
│ ├── WorkflowNames.cs # Workflow naming constants
│ └── WorkflowTypes.cs # Workflow type definitions
│
└── 📁 Scripts/ # Build and deployment automation
├── build-and-publish.ps1 # PowerShell build & publish script
├── build-and-publish.cmd # Windows batch build & publish script
├── build.ps1 # Comprehensive build script
├── build.cmd # Windows build script
└── publish.ps1 # NuGet publishing script
using BR.Workflow.Contracts.Workflows;
using BR.Workflow.Contracts.Models.Kafka;
using BR.Workflow.Contracts.Workflows.Models;
public class StartRealEstateWorkflow : IStartRealEstateWorkflow
{
public async Task<RealEstateWorkflowOutput> ExecuteAsync(RealEstateWorkflowInput input)
{
try
{
// Your workflow logic here
return new RealEstateWorkflowOutput
{
WorkflowId = Guid.NewGuid(),
Status = "Completed",
ClientId = input.ClientInfo.Id,
OrderId = Guid.NewGuid(),
ActionType = ActionType.Create,
ApiGatewayResponse = new ApiGatewayResponse
{
Success = true,
StatusCode = 200,
Message = "Order created successfully"
},
AuditInfo = new AuditInfo
{
CompletedAt = DateTime.UtcNow,
ErrorInfo = Array.Empty<ErrorInfo>()
}
};
}
catch (Exception ex)
{
return new RealEstateWorkflowOutput
{
WorkflowId = Guid.NewGuid(),
Status = "Failed",
ClientId = input.ClientInfo.Id,
OrderId = Guid.Empty,
ActionType = ActionType.Create,
ApiGatewayResponse = new ApiGatewayResponse
{
Success = false,
StatusCode = 500,
Message = ex.Message
},
AuditInfo = new AuditInfo
{
CompletedAt = DateTime.UtcNow,
ErrorInfo = new[] { new ErrorInfo { Message = ex.Message, Severity = ValidationSeverity.Error } }
}
};
}
}
}
using BR.Workflow.Contracts.Activities.REI;
using BR.Workflow.Contracts.Models.REI;
using BR.Workflow.Contracts.Models.Common;
public class ValidateEventActivity : IValidateEventActivity
{
public async Task<ValidateEventOutput> ValidateAsync(ValidateEventInput input)
{
var validationErrors = new List<ValidationError>();
// Validate correlation ID
if (string.IsNullOrEmpty(input.CorrelationId))
{
validationErrors.Add(new ValidationError
{
Field = nameof(input.CorrelationId),
Message = "Correlation ID is required",
Severity = ValidationSeverity.Error
});
}
// Validate client ID
if (input.ClientId == Guid.Empty)
{
validationErrors.Add(new ValidationError
{
Field = nameof(input.ClientId),
Message = "Valid Client ID is required",
Severity = ValidationSeverity.Error
});
}
// Check for duplicates
var duplicateCheck = await CheckForDuplicatesAsync(input.CorrelationId, input.ClientId);
return new ValidateEventOutput
{
CanProceed = validationErrors.Count == 0,
DuplicateCheck = duplicateCheck,
ValidationErrors = validationErrors.ToArray()
};
}
private async Task<DuplicateCheck> CheckForDuplicatesAsync(string correlationId, Guid clientId)
{
// Your duplicate checking logic here
return new DuplicateCheck
{
RecentlyDownloaded = false,
DownloadCount = 0
};
}
}
using BR.Workflow.Contracts.Extensions;
// Create workflow results easily
var successResult = TemporalExtensions.CreateSuccessResult(
workflowId: Guid.NewGuid(),
status: "Completed",
clientId: clientId,
orderId: orderId,
actionType: ActionType.Create
);
// Validate contract inputs
if (!input.IsValid())
{
var errors = input.GetValidationErrors();
foreach (var error in errors)
{
Console.WriteLine($"Validation Error: {error.Field} - {error.Message}");
}
}
// Create error results
var errorResult = TemporalExtensions.CreateErrorResult(
workflowId: Guid.NewGuid(),
status: "Failed",
clientId: clientId,
orderId: orderId,
actionType: ActionType.Create,
errorMessage: "Processing failed"
);
Purpose: Handle incoming events and manage blob storage operations
Key Activities:
IValidateEventActivity - Validate incoming events and check for duplicatesIDownloadBlobActivity - Download blob content from Azure StorageIUpdateOrderStatusInBlobActivity - Update order status in blob storageUse Cases:
Purpose: Core business logic for order processing and client communication
Key Activities:
IValidateSchemaTemplateActivity - Validate data against business schemasIDetermineActionTypeActivity - Determine processing action typeICreateOrderActivity - Create new ordersIUpdateOrderActivity - Update existing ordersIApproveOrderActivity - Approve ordersIRejectOrderActivity - Reject ordersINotifyClientActivity - Notify clients of status changesIUpdateDbActivity - Update processing status in databaseICallApiGatewayActivity - Communicate with external servicesUse Cases:
Purpose: Transform data between different service formats
Key Activities:
ITransformPayloadActivity - Transform data between formatsUse Cases:
The library provides dual-purpose models that serve both Kafka messaging and workflow processing:
| Model | Purpose | Key Properties |
|---|---|---|
RealEstateWorkflowInput | Main workflow input from Kafka | EventInfo, ClientInfo, BlobInfo |
EventInfo | Event metadata and correlation | Name, CorrelationId, Timestamp |
ClientInfo | Client identification | Id, Name, Reference |
BlobInfo | Azure Blob Storage information | Url, Container, BlobName |
JsonPropertyName attributes for camelCase JSON// Kafka message processing
var kafkaPayload = JsonSerializer.Deserialize<RealEstateWorkflowInput>(kafkaMessage);
// Validate the payload
if (!kafkaPayload.IsValid())
{
var errors = kafkaPayload.GetValidationErrors();
// Handle validation errors...
}
// Workflow execution
var result = await workflow.ExecuteAsync(kafkaPayload);
| Interface | Purpose | Output |
|---|---|---|
IStartRealEstateWorkflow | Main workflow orchestration | RealEstateWorkflowOutput |
| Activity | Purpose | Input | Output |
|---|---|---|---|
IValidateEventActivity | Validate incoming events | ValidateEventInput | ValidateEventOutput |
IDownloadBlobActivity | Download blob content | DownloadBlobInput | DownloadBlobOutput |
IUpdateOrderStatusInBlobActivity | Update blob status | UpdateOrderStatusInput | UpdateOrderStatusOutput |
| Activity | Purpose | Input | Output |
|---|---|---|---|
IValidateSchemaTemplateActivity | Validate business schemas | ValidateSchemaInput | ValidateSchemaOutput |
IDetermineActionTypeActivity | Determine processing action | DetermineActionInput | DetermineActionOutput |
ICreateOrderActivity | Create new orders | CreateOrderInput | CreateOrderOutput |
IUpdateOrderActivity | Update existing orders | UpdateOrderInput | UpdateOrderOutput |
IApproveOrderActivity | Approve orders | ApproveOrderInput | ApproveOrderOutput |
IRejectOrderActivity | Reject orders | RejectOrderInput | RejectOrderOutput |
INotifyClientActivity | Notify clients | NotifyClientInput | NotifyClientOutput |
IUpdateDbActivity | Update database | UpdateDbInput | UpdateDbOutput |
ICallApiGatewayActivity | Call external APIs | CallApiGatewayInput | CallApiGatewayOutput |
| Activity | Purpose | Input | Output |
|---|---|---|---|
ITransformPayloadActivity | Transform data formats | TransformPayloadInput | TransformPayloadOutput |
| Enum | Values | Purpose |
|---|---|---|
ActionType | Create, Update, Approve, Reject | Order processing actions |
BrightRiverStatus | Pending, Processing, Completed, Failed | Bright River specific statuses |
OrderStatus | Draft, Submitted, Approved, Rejected | Order lifecycle statuses |
ValidationSeverity | Info, Warning, Error, Critical | Validation error severity |
DeliveryStatus | Pending, Delivered, Failed | Delivery operation statuses |
HttpMethod | GET, POST, PUT, DELETE | HTTP method constants |
NotificationType | Email, SMS, Push | Notification type definitions |
The project follows all specified C# .NET development guidelines:
# PowerShell (Recommended)
.\scripts\build-and-publish.ps1 -ApiKey "your-nuget-api-key"
# Windows Batch
.\scripts\build-and-publish.cmd "your-nuget-api-key"
# Dry run (test without publishing)
.\scripts\build-and-publish.ps1 -ApiKey "your-nuget-api-key" -DryRun
# Restore packages
dotnet restore
# Build project
dotnet build --configuration Release
# Create NuGet package
dotnet pack --configuration Release --output nupkg
# Publish to NuGet
dotnet nuget push "nupkg\BR.Workflow.Contracts.1.0.17.nupkg" --source "https://api.nuget.org/v3/index.json" --api-key "your-api-key"
The package includes scripts for:
When extending these contracts:
This project is licensed under the MIT License - see the LICENSE file for details.
Built with ❤️ by the Bright River RealEstate Platform Team