fix(cli): correct audit query channel/kind/status enum names + drop dead --instance flag (#23 M8)
This commit is contained in:
@@ -26,11 +26,16 @@ public static class AuditCommands
|
|||||||
{
|
{
|
||||||
var sinceOption = new Option<string?>("--since") { Description = "Start time: relative (1h, 24h, 7d) or ISO-8601" };
|
var sinceOption = new Option<string?>("--since") { Description = "Start time: relative (1h, 24h, 7d) or ISO-8601" };
|
||||||
var untilOption = new Option<string?>("--until") { Description = "End time: relative (1h, 24h, 7d) or ISO-8601" };
|
var untilOption = new Option<string?>("--until") { Description = "End time: relative (1h, 24h, 7d) or ISO-8601" };
|
||||||
var channelOption = new Option<string?>("--channel") { Description = "Filter by channel (OutboundApi, OutboundDb, Notification, InboundApi)" };
|
var channelOption = new Option<string?>("--channel") { Description = "Filter by channel (ApiOutbound, DbOutbound, Notification, ApiInbound)" };
|
||||||
var kindOption = new Option<string?>("--kind") { Description = "Filter by event kind" };
|
channelOption.AcceptOnlyFromAmong("ApiOutbound", "DbOutbound", "Notification", "ApiInbound");
|
||||||
var statusOption = new Option<string?>("--status") { Description = "Filter by status (single value)" };
|
var kindOption = new Option<string?>("--kind") { Description = "Filter by event kind (ApiCall, ApiCallCached, DbWrite, DbWriteCached, NotifySend, NotifyDeliver, InboundRequest, InboundAuthFailure, CachedSubmit, CachedResolve)" };
|
||||||
|
kindOption.AcceptOnlyFromAmong(
|
||||||
|
"ApiCall", "ApiCallCached", "DbWrite", "DbWriteCached", "NotifySend",
|
||||||
|
"NotifyDeliver", "InboundRequest", "InboundAuthFailure", "CachedSubmit", "CachedResolve");
|
||||||
|
var statusOption = new Option<string?>("--status") { Description = "Filter by status (Submitted, Forwarded, Attempted, Delivered, Failed, Parked, Discarded, Skipped)" };
|
||||||
|
statusOption.AcceptOnlyFromAmong(
|
||||||
|
"Submitted", "Forwarded", "Attempted", "Delivered", "Failed", "Parked", "Discarded", "Skipped");
|
||||||
var siteOption = new Option<string?>("--site") { Description = "Filter by source site ID" };
|
var siteOption = new Option<string?>("--site") { Description = "Filter by source site ID" };
|
||||||
var instanceOption = new Option<string?>("--instance") { Description = "Filter by instance" };
|
|
||||||
var targetOption = new Option<string?>("--target") { Description = "Filter by target (external system, DB connection, notification list)" };
|
var targetOption = new Option<string?>("--target") { Description = "Filter by target (external system, DB connection, notification list)" };
|
||||||
var actorOption = new Option<string?>("--actor") { Description = "Filter by actor" };
|
var actorOption = new Option<string?>("--actor") { Description = "Filter by actor" };
|
||||||
var correlationIdOption = new Option<string?>("--correlation-id") { Description = "Filter by correlation ID" };
|
var correlationIdOption = new Option<string?>("--correlation-id") { Description = "Filter by correlation ID" };
|
||||||
@@ -46,7 +51,6 @@ public static class AuditCommands
|
|||||||
cmd.Add(kindOption);
|
cmd.Add(kindOption);
|
||||||
cmd.Add(statusOption);
|
cmd.Add(statusOption);
|
||||||
cmd.Add(siteOption);
|
cmd.Add(siteOption);
|
||||||
cmd.Add(instanceOption);
|
|
||||||
cmd.Add(targetOption);
|
cmd.Add(targetOption);
|
||||||
cmd.Add(actorOption);
|
cmd.Add(actorOption);
|
||||||
cmd.Add(correlationIdOption);
|
cmd.Add(correlationIdOption);
|
||||||
@@ -74,7 +78,6 @@ public static class AuditCommands
|
|||||||
Kind = result.GetValue(kindOption),
|
Kind = result.GetValue(kindOption),
|
||||||
Status = result.GetValue(statusOption),
|
Status = result.GetValue(statusOption),
|
||||||
Site = result.GetValue(siteOption),
|
Site = result.GetValue(siteOption),
|
||||||
Instance = result.GetValue(instanceOption),
|
|
||||||
Target = result.GetValue(targetOption),
|
Target = result.GetValue(targetOption),
|
||||||
Actor = result.GetValue(actorOption),
|
Actor = result.GetValue(actorOption),
|
||||||
CorrelationId = result.GetValue(correlationIdOption),
|
CorrelationId = result.GetValue(correlationIdOption),
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ public sealed class AuditQueryArgs
|
|||||||
public string? Kind { get; set; }
|
public string? Kind { get; set; }
|
||||||
public string? Status { get; set; }
|
public string? Status { get; set; }
|
||||||
public string? Site { get; set; }
|
public string? Site { get; set; }
|
||||||
public string? Instance { get; set; }
|
|
||||||
public string? Target { get; set; }
|
public string? Target { get; set; }
|
||||||
public string? Actor { get; set; }
|
public string? Actor { get; set; }
|
||||||
public string? CorrelationId { get; set; }
|
public string? CorrelationId { get; set; }
|
||||||
@@ -102,7 +101,6 @@ public static class AuditQueryHelpers
|
|||||||
Add("status", args.ErrorsOnly ? "Failed" : args.Status);
|
Add("status", args.ErrorsOnly ? "Failed" : args.Status);
|
||||||
|
|
||||||
Add("sourceSiteId", args.Site);
|
Add("sourceSiteId", args.Site);
|
||||||
Add("instance", args.Instance);
|
|
||||||
Add("target", args.Target);
|
Add("target", args.Target);
|
||||||
Add("actor", args.Actor);
|
Add("actor", args.Actor);
|
||||||
Add("correlationId", args.CorrelationId);
|
Add("correlationId", args.CorrelationId);
|
||||||
|
|||||||
@@ -1078,11 +1078,10 @@ scadalink --url <url> audit query [options]
|
|||||||
|--------|----------|---------|-------------|
|
|--------|----------|---------|-------------|
|
||||||
| `--since` | no | — | Start time: relative (`1h`, `24h`, `7d`) or ISO-8601 |
|
| `--since` | no | — | Start time: relative (`1h`, `24h`, `7d`) or ISO-8601 |
|
||||||
| `--until` | no | — | End time: relative (`1h`, `24h`, `7d`) or ISO-8601 |
|
| `--until` | no | — | End time: relative (`1h`, `24h`, `7d`) or ISO-8601 |
|
||||||
| `--channel` | no | — | Filter by channel (`OutboundApi`, `OutboundDb`, `Notification`, `InboundApi`) |
|
| `--channel` | no | — | Filter by channel (`ApiOutbound`, `DbOutbound`, `Notification`, `ApiInbound`) |
|
||||||
| `--kind` | no | — | Filter by event kind |
|
| `--kind` | no | — | Filter by event kind (`ApiCall`, `ApiCallCached`, `DbWrite`, `DbWriteCached`, `NotifySend`, `NotifyDeliver`, `InboundRequest`, `InboundAuthFailure`, `CachedSubmit`, `CachedResolve`) |
|
||||||
| `--status` | no | — | Filter by status (single value) |
|
| `--status` | no | — | Filter by status (`Submitted`, `Forwarded`, `Attempted`, `Delivered`, `Failed`, `Parked`, `Discarded`, `Skipped`) |
|
||||||
| `--site` | no | — | Filter by source site ID |
|
| `--site` | no | — | Filter by source site ID |
|
||||||
| `--instance` | no | — | Filter by instance |
|
|
||||||
| `--target` | no | — | Filter by target (external system, DB connection, notification list) |
|
| `--target` | no | — | Filter by target (external system, DB connection, notification list) |
|
||||||
| `--actor` | no | — | Filter by actor |
|
| `--actor` | no | — | Filter by actor |
|
||||||
| `--correlation-id` | no | — | Filter by correlation ID |
|
| `--correlation-id` | no | — | Filter by correlation ID |
|
||||||
|
|||||||
@@ -58,11 +58,10 @@ public class AuditQueryCommandTests
|
|||||||
{
|
{
|
||||||
Since = "1h",
|
Since = "1h",
|
||||||
Until = "2026-05-20T12:00:00Z",
|
Until = "2026-05-20T12:00:00Z",
|
||||||
Channel = "OutboundApi",
|
Channel = "ApiOutbound",
|
||||||
Kind = "CachedCall",
|
Kind = "ApiCallCached",
|
||||||
Status = "Delivered",
|
Status = "Delivered",
|
||||||
Site = "site-1",
|
Site = "site-1",
|
||||||
Instance = "pump-7",
|
|
||||||
Target = "weather-api",
|
Target = "weather-api",
|
||||||
Actor = "multi-role",
|
Actor = "multi-role",
|
||||||
CorrelationId = "abc-123",
|
CorrelationId = "abc-123",
|
||||||
@@ -73,11 +72,12 @@ public class AuditQueryCommandTests
|
|||||||
var qs = AuditQueryHelpers.BuildQueryString(args, now, afterOccurredAtUtc: null, afterEventId: null);
|
var qs = AuditQueryHelpers.BuildQueryString(args, now, afterOccurredAtUtc: null, afterEventId: null);
|
||||||
var parsed = HttpUtility.ParseQueryString(qs.TrimStart('?'));
|
var parsed = HttpUtility.ParseQueryString(qs.TrimStart('?'));
|
||||||
|
|
||||||
Assert.Equal("OutboundApi", parsed["channel"]);
|
Assert.Equal("ApiOutbound", parsed["channel"]);
|
||||||
Assert.Equal("CachedCall", parsed["kind"]);
|
Assert.Equal("ApiCallCached", parsed["kind"]);
|
||||||
Assert.Equal("Delivered", parsed["status"]);
|
Assert.Equal("Delivered", parsed["status"]);
|
||||||
Assert.Equal("site-1", parsed["sourceSiteId"]);
|
Assert.Equal("site-1", parsed["sourceSiteId"]);
|
||||||
Assert.Equal("pump-7", parsed["instance"]);
|
// --instance was dropped: AuditLogQueryFilter has no instance column.
|
||||||
|
Assert.Null(parsed["instance"]);
|
||||||
Assert.Equal("weather-api", parsed["target"]);
|
Assert.Equal("weather-api", parsed["target"]);
|
||||||
Assert.Equal("multi-role", parsed["actor"]);
|
Assert.Equal("multi-role", parsed["actor"]);
|
||||||
Assert.Equal("abc-123", parsed["correlationId"]);
|
Assert.Equal("abc-123", parsed["correlationId"]);
|
||||||
@@ -243,4 +243,43 @@ public class AuditQueryCommandTests
|
|||||||
var parse = root.Parse(new[] { "audit", "query", "--format", "table" });
|
var parse = root.Parse(new[] { "audit", "query", "--format", "table" });
|
||||||
Assert.Empty(parse.Errors);
|
Assert.Empty(parse.Errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---- Enum-name validation (fast-fail) ----------------------------------
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Query_ChannelWithRealEnumName_IsAccepted()
|
||||||
|
{
|
||||||
|
var root = AuditCommandTestHarness.BuildRoot();
|
||||||
|
var parse = root.Parse(new[] { "audit", "query", "--channel", "ApiOutbound" });
|
||||||
|
Assert.Empty(parse.Errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Query_ChannelWithInvalidName_FailsFast_NonZeroExit()
|
||||||
|
{
|
||||||
|
// "OutboundApi" is the old (non-existent) name; the real enum is "ApiOutbound".
|
||||||
|
var root = AuditCommandTestHarness.BuildRoot();
|
||||||
|
var (exit, _, err) = AuditCommandTestHarness.Invoke(root, "audit", "query", "--channel", "OutboundApi");
|
||||||
|
Assert.NotEqual(0, exit);
|
||||||
|
Assert.NotEqual("", err);
|
||||||
|
Assert.Contains("OutboundApi", err);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Query_KindWithInvalidName_FailsFast_NonZeroExit()
|
||||||
|
{
|
||||||
|
var root = AuditCommandTestHarness.BuildRoot();
|
||||||
|
var (exit, _, err) = AuditCommandTestHarness.Invoke(root, "audit", "query", "--kind", "CachedCall");
|
||||||
|
Assert.NotEqual(0, exit);
|
||||||
|
Assert.NotEqual("", err);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Query_StatusWithInvalidName_FailsFast_NonZeroExit()
|
||||||
|
{
|
||||||
|
var root = AuditCommandTestHarness.BuildRoot();
|
||||||
|
var (exit, _, err) = AuditCommandTestHarness.Invoke(root, "audit", "query", "--status", "Bogus");
|
||||||
|
Assert.NotEqual(0, exit);
|
||||||
|
Assert.NotEqual("", err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user