docs(comments): strip internal task/milestone/bundle bookkeeping from code comments
Remove project bookkeeping citations from shipped code comments across the solution: hyphenated task IDs (WP-14, StoreAndForward-025), milestone/task/ issue refs (M3, Task 4, Audit Log #23, #21), Bundle X task-bundle labels, and C/D/K/S/T phase labels. Comment text only — no code logic, string/log literals, or XML-doc structure changed. Genuine descriptions are preserved (only the citation is stripped), and technical lookalikes are retained (UTF-8, SHA-256, T00:00:00, M365, UTC-5, pre-C4/pre-C5 schema versions). Flagged by the new CommentChecker TaskReferenceInComment / TrackingReferenceInComment checks plus targeted grep passes; full solution builds clean, append-only guard tests pass.
This commit is contained in:
@@ -26,15 +26,15 @@ public sealed class InboundApiEndpoint
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// WP-1: POST /api/{methodName} endpoint registration.
|
||||
/// WP-2: Method routing and parameter validation.
|
||||
/// WP-3: Script execution on central.
|
||||
/// WP-5: Error handling — 401, 403, 400, 500.
|
||||
/// POST /api/{methodName} endpoint registration.
|
||||
/// Method routing and parameter validation.
|
||||
/// Script execution on central.
|
||||
/// Error handling — 401, 403, 400, 500.
|
||||
/// </summary>
|
||||
public static class EndpointExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Auth re-arch (A+B), InboundAPI-011 successor: the single message used for
|
||||
/// Auth re-arch (A+B), successor: the single message used for
|
||||
/// BOTH "method not found" and "key not in scope for this method" so the two
|
||||
/// outcomes are indistinguishable to the caller. A caller holding any valid key
|
||||
/// must not be able to enumerate which method names exist by observing a
|
||||
@@ -57,7 +57,7 @@ public static class EndpointExtensions
|
||||
public static IEndpointRouteBuilder MapInboundAPI(this IEndpointRouteBuilder endpoints)
|
||||
{
|
||||
endpoints.MapPost("/api/{methodName}", HandleInboundApiRequest)
|
||||
// InboundAPI-006 / InboundAPI-008: active-node gating + request body
|
||||
// Active-node gating + request body
|
||||
// size cap are enforced by the endpoint filter before the handler runs.
|
||||
.AddEndpointFilter<InboundApiEndpointFilter>();
|
||||
return endpoints;
|
||||
@@ -96,14 +96,14 @@ public static class EndpointExtensions
|
||||
|
||||
if (!verification.Succeeded)
|
||||
{
|
||||
// WP-5: 401 for any verifier failure. The failure reason is
|
||||
// 401 for any verifier failure. The failure reason is
|
||||
// discriminated for our own logs/telemetry but NEVER surfaced to the
|
||||
// caller — every reason maps to the one generic message so the auth
|
||||
// stage (missing vs unknown-key vs revoked vs secret-mismatch) is not
|
||||
// leaked.
|
||||
ScadaBridgeTelemetry.RecordInboundApiRequest("<unauthorized>");
|
||||
|
||||
// WP-5: Failures-only logging.
|
||||
// Failures-only logging.
|
||||
logger.LogWarning(
|
||||
"Inbound API auth failure for method {Method}: {Failure} (status 401)",
|
||||
methodName, verification.Failure);
|
||||
@@ -122,7 +122,7 @@ public static class EndpointExtensions
|
||||
// byte-identical (status + message), so a caller holding a valid key
|
||||
// cannot probe which method names exist.
|
||||
//
|
||||
// Review #3 (scope-check-before-DB-lookup): the in-memory scope check runs
|
||||
// The in-memory scope check runs
|
||||
// FIRST and the DB GetMethodByNameAsync only runs when the caller is in
|
||||
// scope. This removes a timing oracle — a not-in-scope caller no longer
|
||||
// pays a DB round-trip whose latency could distinguish "valid scope but no
|
||||
@@ -130,7 +130,7 @@ public static class EndpointExtensions
|
||||
// the reject path. The combined `method == null || !inScope` guard still
|
||||
// emits the single identical 403 body, preserving enumeration-safety.
|
||||
//
|
||||
// Review #2 (scope case-policy): scope strings ARE the method names, and
|
||||
// Scope strings ARE the method names, and
|
||||
// identity.Scopes.Contains(methodName) is an ordinal, case-SENSITIVE
|
||||
// comparison (HashSet<string> with the default StringComparer.Ordinal). A
|
||||
// scope must therefore match the registered method name's casing EXACTLY —
|
||||
@@ -161,18 +161,18 @@ public static class EndpointExtensions
|
||||
// set of configured API methods — never the raw caller-supplied route value.
|
||||
ScadaBridgeTelemetry.RecordInboundApiRequest(method.Name);
|
||||
|
||||
// Audit Log (#23 M4 Bundle D): publish the verified key's display name so
|
||||
// Publish the verified key's display name so
|
||||
// AuditWriteMiddleware can populate AuditEvent.Actor in its finally
|
||||
// block. Done AFTER auth+authz succeeded — auth failures leave the
|
||||
// slot empty and the middleware records the row with Actor=null.
|
||||
httpContext.Items[AuditWriteMiddleware.AuditActorItemKey] =
|
||||
identity.DisplayName;
|
||||
|
||||
// WP-2: Deserialize and validate parameters
|
||||
// Deserialize and validate parameters
|
||||
JsonElement? body = null;
|
||||
try
|
||||
{
|
||||
// InboundAPI-020: the content-type sniff must be case-insensitive — a
|
||||
// The content-type sniff must be case-insensitive — a
|
||||
// request with `application/JSON` or `Application/Json` is still JSON
|
||||
// and must enter the body-parsing path. The previous case-sensitive
|
||||
// `Contains("json")` silently skipped JSON deserialization for any
|
||||
@@ -193,7 +193,7 @@ public static class EndpointExtensions
|
||||
statusCode: 400);
|
||||
}
|
||||
|
||||
// M9-T32b: thread the JSON-Schema $ref resolution seam into parameter
|
||||
// Thread the JSON-Schema $ref resolution seam into parameter
|
||||
// validation so a method whose ParameterDefinitions use a {"$ref":"lib:Name"}
|
||||
// resolves the reference at RUNTIME (not just at deploy time). The shared-schema
|
||||
// library is pre-loaded ONCE per request into an in-memory map (the seam the
|
||||
@@ -214,12 +214,12 @@ public static class EndpointExtensions
|
||||
statusCode: 400);
|
||||
}
|
||||
|
||||
// WP-3: Execute the method's script
|
||||
// Execute the method's script
|
||||
var timeout = method.TimeoutSeconds > 0
|
||||
? TimeSpan.FromSeconds(method.TimeoutSeconds)
|
||||
: options.DefaultMethodTimeout;
|
||||
|
||||
// Audit Log #23 (ParentExecutionId): the inbound request's per-request
|
||||
// The inbound request's per-request
|
||||
// ExecutionId was minted early by AuditWriteMiddleware and stashed on
|
||||
// HttpContext.Items. Thread it into the executor so a routed
|
||||
// Route.To(...).Call(...) carries it as RouteToCallRequest.ParentExecutionId
|
||||
@@ -237,7 +237,7 @@ public static class EndpointExtensions
|
||||
|
||||
if (!scriptResult.Success)
|
||||
{
|
||||
// InboundAPI-004: a client-aborted request is not a script failure.
|
||||
// A client-aborted request is not a script failure.
|
||||
// Do not pollute the failure log (reserved for genuine script errors)
|
||||
// and do not attempt to write a 500 body to an already-gone connection.
|
||||
if (httpContext.RequestAborted.IsCancellationRequested)
|
||||
@@ -245,7 +245,7 @@ public static class EndpointExtensions
|
||||
return Results.Empty;
|
||||
}
|
||||
|
||||
// WP-5: 500 for script failures, safe error message
|
||||
// 500 for script failures, safe error message
|
||||
logger.LogWarning(
|
||||
"Inbound API script failure for method {Method}: {Error}",
|
||||
methodName, scriptResult.ErrorMessage);
|
||||
|
||||
Reference in New Issue
Block a user