Files
git.stella-ops.org/src/Policy/StellaOps.Policy.Engine/Overlay/FileOverlayStore.cs
2026-02-01 21:37:40 +02:00

51 lines
1.5 KiB
C#

using Microsoft.Extensions.Hosting;
using System.Text;
using System.Text.Json;
namespace StellaOps.Policy.Engine.Overlay;
/// <summary>
/// Persists overlay projections as NDJSON files under overlay/{tenant}/{ruleId}/{version}.ndjson.
/// </summary>
internal sealed class FileOverlayStore : IOverlayStore
{
private readonly string _root;
public FileOverlayStore(IHostEnvironment env)
{
_root = Path.Combine(env.ContentRootPath, "overlay");
}
public async Task SaveAsync(OverlayProjection projection, CancellationToken cancellationToken = default)
{
if (projection is null)
{
throw new ArgumentNullException(nameof(projection));
}
var tenant = Sanitize(projection.Tenant);
var rule = Sanitize(projection.RuleId);
var dir = Path.Combine(_root, tenant, rule);
Directory.CreateDirectory(dir);
var path = Path.Combine(dir, $"{projection.Version}.ndjson");
var lines = new[]
{
JsonSerializer.Serialize(new OverlayProjectionHeader("overlay-projection-v1")),
JsonSerializer.Serialize(projection)
};
await File.WriteAllLinesAsync(path, lines, Encoding.UTF8, cancellationToken).ConfigureAwait(false);
}
private static string Sanitize(string value)
{
foreach (var ch in Path.GetInvalidFileNameChars())
{
value = value.Replace(ch, '_');
}
return string.IsNullOrWhiteSpace(value) ? "unknown" : value;
}
}