feat: add audited one-shot prepare gate

This commit is contained in:
2026-07-18 12:29:09 +09:00
parent 1302b1b92f
commit 5379511b8a
25 changed files with 6188 additions and 41 deletions

View File

@@ -68,6 +68,31 @@ public sealed class OracleManualFinancialMutationExecutorTests
Assert.True(plan.TransactionDisposed);
}
[Fact]
public async Task DeniedAuthorizationCreatesNoConnectionOrTransaction()
{
var plan = new Plan();
var factory = new Factory(plan);
var authorization = new DenyAllDatabaseMutationAuthorization();
var service = Service(Executor(factory, mutationAuthorization: authorization));
var exception = await Assert.ThrowsAsync<ManualFinancialMutationException>(() =>
service.CreateAsync(Sales("Alpha")));
Assert.False(exception.OutcomeUnknown);
var denied = Assert.IsType<DatabaseMutationAuthorizationException>(
exception.InnerException);
Assert.Equal(DatabaseMutationTarget.ManualFinancial, denied.Request.Target);
Assert.Equal(DataSourceKind.Oracle, denied.Request.Source);
Assert.Equal(nameof(ManualFinancialMutationKind.Create), denied.Request.MutationKind);
Assert.NotEqual(Guid.Empty, denied.Request.OperationId);
Assert.Single(authorization.Requests);
Assert.Equal(0, factory.CreateCount);
Assert.Equal(0, plan.OpenCount);
Assert.Equal(0, plan.BeginCount);
Assert.Empty(plan.Commands);
}
[Fact]
public async Task Zero_affected_create_rolls_back_as_known_duplicate_before_commit()
{
@@ -141,7 +166,8 @@ public sealed class OracleManualFinancialMutationExecutorTests
private static OracleManualFinancialMutationExecutor Executor(
Factory factory,
int operationTimeoutSeconds = 30) =>
int operationTimeoutSeconds = 30,
IDatabaseMutationAuthorization? mutationAuthorization = null) =>
new(
factory,
new DatabaseResilienceOptions
@@ -151,7 +177,8 @@ public sealed class OracleManualFinancialMutationExecutorTests
InitialRetryDelayMilliseconds = 30_000
},
new StubErrorDetector(false),
command => Assert.IsType<FakeCommand>(command).BindByName = true);
command => Assert.IsType<FakeCommand>(command).BindByName = true,
mutationAuthorization ?? DatabaseMutationAuthorization.AllowAll);
private static ManualSalesRecord Sales(string stockName) =>
new(