Act on the wj architectural review: races, limits, pool and contract gaps
Findings F2, F4, F5, F6, F7, F8, F9, F10, F11 and F13 from wj-architectural-review.md. F1/F1a (the non-sargable LOWER pattern) and F3 (the warranty sync holding a pooled connection) are being handled separately and are untouched here. - A collector check-in that raced another for the same PC lost everything: the unique index on the application fingerprint raised, nothing caught it, and the whole check-in rolled back, discarding state, events and hardware, answering the agent with form copy meant for a person. The insert now runs in a savepoint, reconciles what the other transaction already wrote, one row per savepoint so a second collision skips a row rather than the batch, and the check-in commits with a warning. This is the shape the delete side of the same function already had. - Enrollment is deliberately unauthenticated, so it now carries a per-address rate limit and a cap on pending requests, and the cap is a setting an admin can see and change. A flood can no longer bury the approval queue or grow the table without bound. - The fleet alert poll no longer formats debug strings on every request. - BusinessUnit is on the contract surface (0.34.0), so the endpoints plugin stops reaching into a core table with raw SQL. - A test walks every asset type descriptor and proves the endpoint it names really refuses a caller without the declared permission. - The plugin settings routes now need a permission; they were telling anyone which modules a site runs and where its components live. - The connection pool is sized explicitly with a short timeout, and the arithmetic against the server's connection ceiling is written next to the worker count instead of being left to defaults nobody chose. - Fleet alerts carry both the correct lowercase keys and the old camelCase pair. Trays older than 1.7.0 match keys case-sensitively and would have gone quiet on every PC not yet upgraded; the old pair goes when they are. - The dev server proxy points at localhost again, with environment variables for the remote-box workflow, and one developer's address is out of the server certificate page.
This commit is contained in:
@@ -99,9 +99,9 @@ public sealed class FleetAlert
|
||||
private string title = "";
|
||||
private string message = "";
|
||||
|
||||
[JsonPropertyName("notificationId")] public int NotificationId { get; set; }
|
||||
[JsonPropertyName("notificationid")] public int NotificationId { get; set; }
|
||||
[JsonPropertyName("type")] public string TypeName { get => typeName; set => typeName = value ?? ""; }
|
||||
[JsonPropertyName("typeColor")] public string TypeColor { get => typeColor; set => typeColor = value ?? ""; }
|
||||
[JsonPropertyName("typecolor")] public string TypeColor { get => typeColor; set => typeColor = value ?? ""; }
|
||||
[JsonPropertyName("title")] public string Title { get => title; set => title = value ?? ""; }
|
||||
[JsonPropertyName("message")] public string Message { get => message; set => message = value ?? ""; }
|
||||
[JsonPropertyName("timeout")] public int? Timeout { get; set; }
|
||||
@@ -126,7 +126,7 @@ public sealed class FleetAlertList : List<FleetAlert>
|
||||
}
|
||||
|
||||
// Deserializes the data array one element at a time. An element that fails
|
||||
// to bind, or has no usable notificationId, is recorded and skipped.
|
||||
// to bind, or has no usable notificationid, is recorded and skipped.
|
||||
public sealed class TolerantFleetAlertListConverter : JsonConverter<List<FleetAlert>>
|
||||
{
|
||||
public override List<FleetAlert>? Read(
|
||||
@@ -146,7 +146,7 @@ public sealed class TolerantFleetAlertListConverter : JsonConverter<List<FleetAl
|
||||
{
|
||||
var alert = element.RootElement.Deserialize<FleetAlert>(options);
|
||||
if (alert is null || alert.NotificationId <= 0)
|
||||
list.Skipped.Add($"element {index}: missing notificationId");
|
||||
list.Skipped.Add($"element {index}: missing notificationid");
|
||||
else
|
||||
list.Add(alert);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user