Portal Community

IBusinessServiceRegistry Interface

// ProcessEngine/BusinessServices/IBusinessServiceRegistry.cs
public interface IBusinessServiceRegistry
{
    // Get service definition by ID
    IBusinessServiceDefinition? GetService(string serviceId);

    // Get all registered service IDs
    IReadOnlyList<string> GetAllServiceIds();

    // Get the endpoint URL for a specific operation
    Task<string> ResolveEndpointAsync(string serviceId, string operationId);

    // Check if a service is healthy
    Task<bool> IsHealthyAsync(string serviceId);
}

IBusinessServiceDefinition

// ProcessEngine/BusinessServices/IBusinessServiceDefinition.cs
public interface IBusinessServiceDefinition
{
    string ServiceId { get; }
    string DisplayName { get; }
    string BaseUrl { get; }
    string ApiVersion { get; }
    AuthType AuthType { get; }
    IReadOnlyList<ServiceOperation> Operations { get; }
}

public record ServiceOperation
{
    public string OperationId { get; init; }
    public string HttpMethod { get; init; }
    public string Path { get; init; }    // relative to BaseUrl; may include {param} tokens
    public string InputSchema { get; init; }   // JSON Schema
    public string OutputSchema { get; init; }  // JSON Schema
}

Registration Example

// PayrollServiceDefinition.cs
public class PayrollServiceDefinition : IBusinessServiceDefinition
{
    public string ServiceId => "payroll-service";
    public string DisplayName => "Payroll Service";
    public string BaseUrl => "https://payroll.internal.bizfirstai.com";
    public string ApiVersion => "v2";
    public AuthType AuthType => AuthType.MutualTLS;

    public IReadOnlyList<ServiceOperation> Operations => new[]
    {
        new ServiceOperation
        {
            OperationId = "calculatePayslip",
            HttpMethod = "POST",
            Path = "/api/v2/payslips/calculate",
            InputSchema = "{ required: ['employeeId','periodStart','periodEnd'] }"
        },
        new ServiceOperation
        {
            OperationId = "getPayHistory",
            HttpMethod = "GET",
            Path = "/api/v2/employees/{employeeId}/pay-history"
        }
    };
}

// DI registration
services.AddSingleton<IBusinessServiceDefinition, PayrollServiceDefinition>();

Service Discovery Flow

  1. Node config specifies serviceId: "payroll-service" and operationId: "calculatePayslip"
  2. Executor calls _registry.ResolveEndpointAsync("payroll-service", "calculatePayslip")
  3. Registry looks up the service definition, constructs the full URL
  4. Executor calls the URL with auth headers injected by IBusinessServiceAuthProvider