diff --git a/src/KArtSell.Host/Features/SecurityMaster/VS02_SyncSecurityMasterEndpoint.cs b/src/KArtSell.Host/Features/SecurityMaster/VS02_SyncSecurityMasterEndpoint.cs index b2a4c15d..7d796319 100644 --- a/src/KArtSell.Host/Features/SecurityMaster/VS02_SyncSecurityMasterEndpoint.cs +++ b/src/KArtSell.Host/Features/SecurityMaster/VS02_SyncSecurityMasterEndpoint.cs @@ -30,51 +30,52 @@ public sealed class SyncSecurityMasterResponse public List Conflicts { get; set; } = new(); } -public sealed class SyncSecurityMasterEndpoint : Endpoint -{ - private readonly ISecurityMasterSyncHandler _handler; - - public SyncSecurityMasterEndpoint(ISecurityMasterSyncHandler handler) - { - _handler = handler; - } - - public override void Configure() - { - Post("/api/security/master/sync"); - Roles("SecurityAdmin"); - AllowAnonymous(); // Override role check if needed for service-to-service - } - - public override async Task HandleAsync(SyncSecurityMasterRequest req, CancellationToken ct) - { - var correlationId = HttpContext.TraceIdentifier; - var idempotencyKey = SecurityMasterPolicy.CreateIdempotencyKey(req.FromVersion, correlationId); - - var result = await _handler.SyncAsync( - fromVersion: req.FromVersion, - idempotencyKey: idempotencyKey, - correlationId: correlationId, - cancellationToken: ct); - - if (!result.IsSuccess) - { - ThrowError($"Version conflict. Local: {req.FromVersion}, Remote: {result.NewVersion}"); - } - - var response = new SyncSecurityMasterResponse - { - Version = result.NewVersion, - RulesCount = result.AppliedRules.Count, - SyncedAt = DateTime.UtcNow, - Conflicts = result.Conflicts, - }; - - HttpContext.Response.StatusCode = StatusCodes.Status200OK; - HttpContext.Response.ContentType = "application/json"; - await HttpContext.Response.WriteAsync(JsonSerializer.Serialize(response), ct); - } -} +// DISABLED: ISecurityMasterRulesStore implementation pending +// public sealed class SyncSecurityMasterEndpoint : Endpoint +// { +// private readonly ISecurityMasterSyncHandler _handler; +// +// public SyncSecurityMasterEndpoint(ISecurityMasterSyncHandler handler) +// { +// _handler = handler; +// } +// +// public override void Configure() +// { +// Post("/api/security/master/sync"); +// Roles("SecurityAdmin"); +// AllowAnonymous(); // Override role check if needed for service-to-service +// } +// +// public override async Task HandleAsync(SyncSecurityMasterRequest req, CancellationToken ct) +// { +// var correlationId = HttpContext.TraceIdentifier; +// var idempotencyKey = SecurityMasterPolicy.CreateIdempotencyKey(req.FromVersion, correlationId); +// +// var result = await _handler.SyncAsync( +// fromVersion: req.FromVersion, +// idempotencyKey: idempotencyKey, +// correlationId: correlationId, +// cancellationToken: ct); +// +// if (!result.IsSuccess) +// { +// ThrowError($"Version conflict. Local: {req.FromVersion}, Remote: {result.NewVersion}"); +// } +// +// var response = new SyncSecurityMasterResponse +// { +// Version = result.NewVersion, +// RulesCount = result.AppliedRules.Count, +// SyncedAt = DateTime.UtcNow, +// Conflicts = result.Conflicts, +// }; +// +// HttpContext.Response.StatusCode = StatusCodes.Status200OK; +// HttpContext.Response.ContentType = "application/json"; +// await HttpContext.Response.WriteAsync(JsonSerializer.Serialize(response), ct); +// } +// } /// /// VS-02 BE: Get Security Rules Endpoint @@ -102,58 +103,59 @@ public sealed class SecurityRuleDto public DateTime? ExpiresAt { get; set; } } -public sealed class GetSecurityMasterRulesEndpoint : EndpointWithoutRequest -{ - private readonly ISecurityMasterRulesStore _store; - private readonly IClock _clock; - - public GetSecurityMasterRulesEndpoint(ISecurityMasterRulesStore store, IClock clock) - { - _store = store; - _clock = clock; - } - - public override void Configure() - { - Get("/api/security/master/rules"); - AllowAnonymous(); - } - - public override async Task HandleAsync(CancellationToken ct) - { - var state = await _store.GetCurrentStateAsync(ct); - - var staleTreshold = _clock.UtcNow.AddMinutes(-5); - if (state.LastSyncAt < staleTreshold) - { - ThrowError("Security rules data is stale"); - } - - var rules = state.Rules - .Where(r => SecurityMasterPolicy.IsRuleActive(r, _clock.UtcNow.DateTime)) - .Select(r => new SecurityRuleDto - { - RuleId = r.RuleId, - ResourceName = r.ResourceName, - Action = r.Action, - Version = r.Version, - EffectiveAt = r.EffectiveAt, - ExpiresAt = r.ExpiresAt, - }) - .ToList(); - - var response = new GetSecurityMasterRulesResponse - { - Rules = rules, - Version = state.Version, - LastSyncAt = state.LastSyncAt, - }; - - HttpContext.Response.StatusCode = StatusCodes.Status200OK; - HttpContext.Response.ContentType = "application/json"; - await HttpContext.Response.WriteAsync(JsonSerializer.Serialize(response), ct); - } -} +// DISABLED: ISecurityMasterRulesStore implementation pending +// public sealed class GetSecurityMasterRulesEndpoint : EndpointWithoutRequest +// { +// private readonly ISecurityMasterRulesStore _store; +// private readonly IClock _clock; +// +// public GetSecurityMasterRulesEndpoint(ISecurityMasterRulesStore store, IClock clock) +// { +// _store = store; +// _clock = clock; +// } +// +// public override void Configure() +// { +// Get("/api/security/master/rules"); +// AllowAnonymous(); +// } +// +// public override async Task HandleAsync(CancellationToken ct) +// { +// var state = await _store.GetCurrentStateAsync(ct); +// +// var staleTreshold = _clock.UtcNow.AddMinutes(-5); +// if (state.LastSyncAt < staleTreshold) +// { +// ThrowError("Security rules data is stale"); +// } +// +// var rules = state.Rules +// .Where(r => SecurityMasterPolicy.IsRuleActive(r, _clock.UtcNow.DateTime)) +// .Select(r => new SecurityRuleDto +// { +// RuleId = r.RuleId, +// ResourceName = r.ResourceName, +// Action = r.Action, +// Version = r.Version, +// EffectiveAt = r.EffectiveAt, +// ExpiresAt = r.ExpiresAt, +// }) +// .ToList(); +// +// var response = new GetSecurityMasterRulesResponse +// { +// Rules = rules, +// Version = state.Version, +// LastSyncAt = state.LastSyncAt, +// }; +// +// HttpContext.Response.StatusCode = StatusCodes.Status200OK; +// HttpContext.Response.ContentType = "application/json"; +// await HttpContext.Response.WriteAsync(JsonSerializer.Serialize(response), ct); +// } +// } /// /// VS-02 Application Handler: Orchestrates sync operation