56 lines
1.8 KiB
C#
56 lines
1.8 KiB
C#
using Nexus.Api.Repositories;
|
|
|
|
namespace Nexus.Api.Services;
|
|
|
|
/// <summary>
|
|
/// Process-local projection of the persisted, owner-approved OpenClaw
|
|
/// management boundary. The database profile remains the durable authority;
|
|
/// this projection lets synchronous capability checks use the same decision.
|
|
/// </summary>
|
|
public interface IOpenClawManagementState
|
|
{
|
|
bool Enabled { get; }
|
|
void SetEnabled(bool enabled);
|
|
}
|
|
|
|
public sealed class OpenClawManagementState : IOpenClawManagementState
|
|
{
|
|
private int enabled;
|
|
|
|
public bool Enabled => Volatile.Read(ref enabled) == 1;
|
|
|
|
public void SetEnabled(bool value)
|
|
=> Interlocked.Exchange(ref enabled, value ? 1 : 0);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Hydrates the local projection from the primary persisted connection profile
|
|
/// once application services are available.
|
|
/// </summary>
|
|
public sealed class OpenClawManagementStateInitializer(
|
|
IServiceScopeFactory scopeFactory,
|
|
IOpenClawManagementState state,
|
|
ILogger<OpenClawManagementStateInitializer> logger) : IHostedService
|
|
{
|
|
public async Task StartAsync(CancellationToken cancellationToken)
|
|
{
|
|
state.SetEnabled(false);
|
|
try
|
|
{
|
|
await using var scope = scopeFactory.CreateAsyncScope();
|
|
var profiles = scope.ServiceProvider
|
|
.GetRequiredService<IOpenClawConnectionProfileRepository>();
|
|
var profile = await profiles.GetPrimaryAsync(cancellationToken);
|
|
state.SetEnabled(profile?.ManagementEnabled ?? false);
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
logger.LogWarning(
|
|
exception,
|
|
"OpenClaw management state could not be hydrated from the primary profile");
|
|
}
|
|
}
|
|
|
|
public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
|
|
}
|