Round #227
07 May 2026, 15:29· csharp· meta/llama-3.3-70b-instruct· r12-real-contracts
- Complexity
- band 0
- ZP / UO / OBS
- 6 / 0 / 0
- Journey weight
- 474
- Lightshift ΔL
- —
Prompt
Implement a business rule validator that checks account balance before transfer
Zero-point index (what the engine surfaced)
ZPI-ZPI-0020 | 2026-05-07T15:29:16Z
Implement a business rule validator that checks account balance before transfer
ZERO POINT — 6 entries (structural invariants)
● hsl(159.80, 100%, 21%) IValidator<T> [contract]
● hsl(240.67, 100%, 21%) AbstractValidator<T> [contract]
● hsl(175.80, 100%, 21%) IValidatableObject [contract]
● hsl(328.68, 100%, 21%) IValidatorFactory [contract]
● hsl(145.31, 100%, 21%) ValidationResult [contract]
● hsl(39.29, 100%, 21%) ValidationContext<T> [contract]
UNOBSERVED — 0 entries (implied truths)
OBSERVED — 0 entries (explicit in request)
COMPLEXITY │ 6 entries │ spread: 0° │ band: LOW
Baseline response (no ZPI)
**Business Rule Validator for Account Balance Before Transfer**
===========================================================
Below is an example implementation of a business rule validator in C# that checks the account balance before a transfer.
### Account Class
```csharp
public class Account
{
public decimal Balance { get; set; }
public string AccountNumber { get; set; }
public Account(string accountNumber, decimal balance)
{
AccountNumber = accountNumber;
Balance = balance;
}
}
```
### Transfer Request Class
```csharp
public class TransferRequest
{
public Account SourceAccount { get; set; }
public Account DestinationAccount { get; set; }
public decimal Amount { get; set; }
public TransferRequest(Account sourceAccount, Account destinationAccount, decimal amount)
{
SourceAccount = sourceAccount;
DestinationAccount = destinationAccount;
Amount = amount;
}
}
```
### Business Rule Validator Interface
```csharp
public interface IBusinessRuleValidator
{
bool IsValid(TransferRequest request);
string ErrorMessage { get; }
}
```
### InsufficientBalanceValidator Class
```csharp
public class InsufficientBalanceValidator : IBusinessRuleValidator
{
public bool IsValid(TransferRequest request)
{
return request.SourceAccount.Balance >= request.Amount;
}
public string ErrorMessage => "Insufficient balance in source account.";
}
```
### NegativeAmountValidator Class
```csharp
public class NegativeAmountValidator : IBusinessRuleValidator
{
public bool IsValid(TransferRequest request)
{
return request.Amount > 0;
}
public string ErrorMessage => "Transfer amount cannot be negative or zero.";
}
```
### Business Rule Validator Factory Class
```csharp
public class BusinessRuleValidatorFactory
{
public static IBusinessRuleValidator[] GetValidators()
{
return new IBusinessRuleValidator[]
{
new InsufficientBalanceValidator(),
new NegativeAmountValidator()
};
}
}
```
### Transfer Service Class
```csharp
public class TransferService
{
public void Transfer(TransferRequest request)
{
var validators = BusinessRuleValidatorFactory.GetValidators();
foreach (var validator in validators)
{
if (!validator.IsValid(request))
{
throw new InvalidOperationException(validator.ErrorMessage);
}
}
// Perform transfer
request.SourceAccount.Balance -= request.Amount;
request.DestinationAccount.Balance += request.Amount;
}
}
```
### Example Usage
```csharp
public class Program
{
public static void Main()
{
var sourceAccount = new Account("12345", 1000);
var destinationAccount = new Account("67890", 500);
var transferRequest = new TransferRequest(sourceAccount, destinationAccount, 200);
var transferService = new TransferService();
try
{
transferService.Transfer(transferRequest);
Console.WriteLine("Transfer successful.");
}
catch (InvalidOperationException ex)
{
Console.WriteLine(ex.Message);
}
}
}
```
In this example, we have implemented two business rule validators: `InsufficientBalanceValidator` and `NegativeAmountValidator`. The `TransferService` class uses these validators to check the transfer request before performing the transfer. If any of the validators return `false`, an `InvalidOperationException` is thrown with the corresponding error message.
Enhanced response (with ZPI)
```csharp
using System;
using System.Threading.Tasks;
using FluentValidation;
using Microsoft.Extensions.DependencyInjection;
// Define the Account class
public class Account
{
public decimal Balance { get; set; }
public decimal TransferAmount { get; set; }
}
// Define the AccountValidator class
public class AccountValidator : AbstractValidator<Account>
{
public AccountValidator()
{
RuleFor(account => account.TransferAmount)
.Must((account, transferAmount) => transferAmount <= account.Balance)
.WithMessage("Insufficient balance for transfer");
}
}
// Define the AccountService class
public class AccountService
{
private readonly IValidator<Account> _validator;
public AccountService(IValidator<Account> validator)
{
_validator = validator;
}
public async Task ValidateTransferAsync(Account account)
{
var validationResult = await _validator.ValidateAsync(account);
if (!validationResult.IsValid)
{
throw new ValidationException(validationResult.Errors);
}
}
}
// Define the ValidationException class
public class ValidationException : Exception
{
public ValidationException(System.Collections.Generic.IEnumerable<ValidationFailure> errors)
: base("Validation failed")
{
Errors = errors;
}
public System.Collections.Generic.IEnumerable<ValidationFailure> Errors { get; }
}
class Program
{
static async Task Main(string[] args)
{
// Register the services
var serviceProvider = new ServiceCollection()
.AddFluentValidation(options =>
{
options.RegisterValidatorsFromAssembly(typeof(AccountValidator).Assembly);
})
.BuildServiceProvider();
var accountService = serviceProvider.GetService<AccountService>();
// Create an account
var account = new Account
{
Balance = 100,
TransferAmount = 150
};
try
{
await accountService.ValidateTransferAsync(account);
}
catch (ValidationException ex)
{
foreach (var error in ex.Errors)
{
Console.WriteLine(error.ErrorMessage);
}
}
}
}
```
This implementation uses the `AbstractValidator<T>` class from the FluentValidation library to define a validator for the `Account` class. The `AccountValidator` class checks if the transfer amount is less than or equal to the account balance. If the validation fails, a `ValidationException` is thrown.
The `AccountService` class uses the `IValidator<T>` interface to validate the account before transfer. The `ValidateTransferAsync` method calls the `ValidateAsync` method of the validator and throws a `ValidationException` if the validation fails.
In the `Main` method, the services are registered using the `ServiceCollection` class. The `AccountService` instance is created and used to validate an account. If the validation fails, the error messages are printed to the console.
This implementation provides a clear and focused way to validate business rules for account transfers. It uses a well-established library (FluentValidation) and follows best practices for dependency injection and error handling.
Grader chain
Each grader reads the same baseline + enhanced pair and casts an independent verdict. Disagreement is the framework's own signal — not noise to be averaged away.
V1claude-haiku-4-5-20251001
WorseV4qwen2.5-coder-7b-instruct
BetterComments
Our grader said what it said. What do you say? Comment as a guest below.
No comments yet. Be the first to say what you make of this round.