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:
+2
-2
@@ -6,7 +6,7 @@ using ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Entities;
|
||||
namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Configurations;
|
||||
|
||||
/// <summary>
|
||||
/// Maps the C5 (Task 2.5) <see cref="AuditLogRow"/> persistence shape to the central
|
||||
/// Maps the <see cref="AuditLogRow"/> persistence shape to the central
|
||||
/// <c>dbo.AuditLog</c> table: the 10 canonical <c>ZB.MOM.WW.Audit.AuditEvent</c> columns
|
||||
/// (writable) plus six read-only, server-side <b>computed columns</b> derived from
|
||||
/// <c>DetailsJson</c> via <c>JSON_VALUE</c> — five PERSISTED (<c>Kind</c>/<c>Status</c>/
|
||||
@@ -96,7 +96,7 @@ public class AuditLogEntityTypeConfiguration : IEntityTypeConfiguration<AuditLog
|
||||
builder.Property(e => e.Target)
|
||||
.HasMaxLength(256);
|
||||
|
||||
// SourceNode (Audit Log #23, SourceNode-stamping): node-local identifier of the
|
||||
// SourceNode (SourceNode-stamping): node-local identifier of the
|
||||
// cluster member that produced the row (e.g. "node-a", "central-a"). NULL is
|
||||
// valid for reconciled rows from a retired node and for direct-write rows
|
||||
// produced before this feature shipped. ASCII — varchar(64), no unicode.
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ using ZB.MOM.WW.ScadaBridge.Commons.Entities.InboundApi;
|
||||
|
||||
namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Configurations;
|
||||
|
||||
// Auth re-arch (C5): the SQL Server ApiKey entity was retired — inbound API keys now
|
||||
// The SQL Server ApiKey entity was retired — inbound API keys now
|
||||
// live in the shared ZB.MOM.WW.Auth.ApiKeys SQLite store. The former
|
||||
// ApiKeyConfiguration (and the ApiMethod.ApprovedApiKeyIds mapping) were removed; the
|
||||
// ApiKeys table + ApprovedApiKeyIds column are dropped by the RetireInboundApiKeyStore
|
||||
|
||||
+2
-2
@@ -5,8 +5,8 @@ using ZB.MOM.WW.ScadaBridge.Commons.Entities.Kpi;
|
||||
namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Configurations;
|
||||
|
||||
/// <summary>
|
||||
/// Maps the <see cref="KpiSample"/> POCO to the central <c>KpiSample</c> table
|
||||
/// (M6 "KPI History & Trends") — the tall / EAV row written by the recorder
|
||||
/// Maps the <see cref="KpiSample"/> POCO to the central <c>KpiSample</c> table —
|
||||
/// the tall / EAV row written by the recorder
|
||||
/// singleton. Operational history, NOT audit, so the table is non-partitioned,
|
||||
/// standard <c>[PRIMARY]</c> filegroup, no DB-role restriction.
|
||||
/// </summary>
|
||||
|
||||
+1
-1
@@ -87,7 +87,7 @@ public class SmsConfigurationConfiguration : IEntityTypeConfiguration<SmsConfigu
|
||||
|
||||
// The non-parameter constructor seeds ConnectionTimeoutSeconds/MaxRetries/RetryDelay
|
||||
// with sensible defaults; mapping them as REQUIRED columns preserves round-trip
|
||||
// fidelity for those values (S1 review note).
|
||||
// fidelity for those values.
|
||||
builder.Property(s => s.ConnectionTimeoutSeconds)
|
||||
.IsRequired();
|
||||
|
||||
|
||||
+4
-4
@@ -49,21 +49,21 @@ public class NotificationOutboxConfiguration : IEntityTypeConfiguration<Notifica
|
||||
|
||||
builder.Property(n => n.SourceScript).HasMaxLength(200);
|
||||
|
||||
// SourceNode (Audit Log #23, SourceNode-stamping): node-local identifier of the
|
||||
// SourceNode: node-local identifier of the
|
||||
// cluster member that produced the notification (e.g. "node-a", "central-a").
|
||||
// NULL is valid for rows that pre-date this feature. ASCII — varchar(64).
|
||||
// No index — KPIs are per-site on this table, not per-node; SourceNode is only
|
||||
// echoed onto NotifyDeliver audit rows (#23) for cross-row correlation.
|
||||
// echoed onto NotifyDeliver audit rows for cross-row correlation.
|
||||
builder.Property(n => n.SourceNode)
|
||||
.HasColumnType("varchar(64)")
|
||||
.HasMaxLength(64)
|
||||
.IsUnicode(false);
|
||||
|
||||
// OriginExecutionId (Audit Log #23): nullable uniqueidentifier carried from the
|
||||
// OriginExecutionId: nullable uniqueidentifier carried from the
|
||||
// site so the dispatcher can echo it onto NotifyDeliver audit rows. No index —
|
||||
// it is never a query predicate on this table, only copied onto audit events.
|
||||
|
||||
// OriginParentExecutionId (Audit Log #23): nullable uniqueidentifier carried from
|
||||
// OriginParentExecutionId: nullable uniqueidentifier carried from
|
||||
// the site — the routed run's parent ExecutionId — so the dispatcher can echo it
|
||||
// onto NotifyDeliver audit rows. No index — same rationale as OriginExecutionId.
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Configurations;
|
||||
|
||||
/// <summary>
|
||||
/// Maps the <see cref="PendingSecuredWrite"/> entity to the central
|
||||
/// <c>PendingSecuredWrites</c> table (M7 OPC UA / MxGateway UX, Task T14b).
|
||||
/// <c>PendingSecuredWrites</c> table.
|
||||
/// Operational (mutable) state — NOT audit — so the table is non-partitioned,
|
||||
/// standard <c>[PRIMARY]</c> filegroup, no DB-role restriction. Two named indexes
|
||||
/// back the Central UI's "pending in this status, newest first" and "writes for
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ public class LdapGroupMappingConfiguration : IEntityTypeConfiguration<LdapGroupM
|
||||
builder.HasIndex(m => m.LdapGroupName).IsUnique();
|
||||
|
||||
// Seed default group mappings matching GLAuth test users.
|
||||
// Role VALUES are the canonical six (Task 1.7): Administrator/Designer/
|
||||
// Role VALUES are the canonical six: Administrator/Designer/
|
||||
// Deployer. The LDAP group NAMES (SCADA-Admins etc.) are unchanged —
|
||||
// only the role each group maps to was canonicalized.
|
||||
builder.HasData(
|
||||
|
||||
+2
-2
@@ -5,8 +5,8 @@ using ZB.MOM.WW.ScadaBridge.Commons.Entities.Schemas;
|
||||
namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Configurations;
|
||||
|
||||
/// <summary>
|
||||
/// Maps the <see cref="SharedSchema"/> entity (M9 template-level JSON-Schema library,
|
||||
/// Task T32a). Mirrors <c>SharedScriptConfiguration</c>: surrogate key, a UNIQUE index on
|
||||
/// Maps the <see cref="SharedSchema"/> entity (template-level JSON-Schema library).
|
||||
/// Mirrors <c>SharedScriptConfiguration</c>: surrogate key, a UNIQUE index on
|
||||
/// <see cref="SharedSchema.Name"/>, a bounded <see cref="SharedSchema.Scope"/>, and an
|
||||
/// unbounded (<c>nvarchar(max)</c>) <see cref="SharedSchema.SchemaJson"/> body.
|
||||
/// Auto-discovered by <c>ApplyConfigurationsFromAssembly</c> in <c>ScadaBridgeDbContext</c>.
|
||||
|
||||
+3
-3
@@ -6,8 +6,8 @@ using ZB.MOM.WW.ScadaBridge.Commons.Types;
|
||||
namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Configurations;
|
||||
|
||||
/// <summary>
|
||||
/// Maps the <see cref="SiteCall"/> record to the central <c>SiteCalls</c> table
|
||||
/// (Site Call Audit #22, Audit Log #23 M3 Bundle B). Operational state — NOT audit —
|
||||
/// Maps the <see cref="SiteCall"/> record to the central <c>SiteCalls</c> table.
|
||||
/// Operational state — NOT audit —
|
||||
/// so the table is non-partitioned, standard <c>[PRIMARY]</c> filegroup, no DB-role
|
||||
/// restriction. Two named indexes back the Central UI's "from this site" and
|
||||
/// "in this status" queries.
|
||||
@@ -63,7 +63,7 @@ public class SiteCallEntityTypeConfiguration : IEntityTypeConfiguration<SiteCall
|
||||
builder.Property(s => s.LastError)
|
||||
.HasMaxLength(1024);
|
||||
|
||||
// SourceNode (Audit Log #23, SourceNode-stamping): node-local identifier of the
|
||||
// SourceNode (SourceNode-stamping): node-local identifier of the
|
||||
// cluster member that produced the call (e.g. "node-a", "central-a"). NULL is
|
||||
// valid for rows that pre-date this feature and for reconciled rows from a
|
||||
// retired node. ASCII — varchar(64). No index — Site Call Audit KPIs are
|
||||
|
||||
+1
-1
@@ -182,7 +182,7 @@ public class TemplateScriptConfiguration : IEntityTypeConfiguration<TemplateScri
|
||||
builder.Property(s => s.ReturnDefinition)
|
||||
.HasMaxLength(4000);
|
||||
|
||||
// M2.5 (#9): nullable per-script execution timeout (seconds). Null = use
|
||||
// Nullable per-script execution timeout (seconds). Null = use
|
||||
// the site's global ScriptExecutionTimeoutSeconds default.
|
||||
builder.Property(s => s.ExecutionTimeoutSeconds)
|
||||
.IsRequired(false);
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Entities;
|
||||
|
||||
/// <summary>
|
||||
/// EF Core persistence shape for the central <c>dbo.AuditLog</c> table after the
|
||||
/// C5 collapse (Audit Log #23, Task 2.5). The table is now the 10 canonical
|
||||
/// schema collapse. The table is now the 10 canonical
|
||||
/// <c>ZB.MOM.WW.Audit.AuditEvent</c> fields stored DIRECTLY plus a set of
|
||||
/// read-only, server-side <b>persisted computed columns</b> derived from
|
||||
/// <see cref="DetailsJson"/> (<c>JSON_VALUE</c> … <c>PERSISTED</c>) so the
|
||||
@@ -13,7 +13,7 @@ namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Entities;
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// <b>C5 (Task 2.5).</b> The transitional 24-typed-column shim is retired. The
|
||||
/// The transitional 24-typed-column shim is retired. The
|
||||
/// repository writes the 10 canonical columns directly (no <c>Decompose</c>) and
|
||||
/// the computed columns auto-derive at INSERT; reads build the canonical
|
||||
/// <c>AuditEvent</c> straight off the canonical columns (no <c>Recompose</c>).
|
||||
|
||||
+1
-1
@@ -177,7 +177,7 @@ WHERE pf.name = 'pf_AuditLog_Month';";
|
||||
ALTER PARTITION SCHEME {PartitionSchemeName} NEXT USED [{TargetFileGroup}];
|
||||
ALTER PARTITION FUNCTION {PartitionFunctionName}() SPLIT RANGE ('{literal}');";
|
||||
|
||||
// ConfigDB-019: the loop pre-reads max-boundary and only issues
|
||||
// The loop pre-reads max-boundary and only issues
|
||||
// SPLITs for strictly-greater months, so msg 7708/7711 ("boundary
|
||||
// already exists") cannot happen by construction. Any OTHER
|
||||
// SqlException (permission revoked on the role, deadlock victim,
|
||||
|
||||
+4
-4
@@ -5,7 +5,7 @@ using Microsoft.EntityFrameworkCore.Migrations;
|
||||
namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Migrations
|
||||
{
|
||||
/// <summary>
|
||||
/// Bundle C (#23 M1): creates the centralized AuditLog table with monthly
|
||||
/// Creates the centralized AuditLog table with monthly
|
||||
/// partitioning and the two access-control roles documented in alog.md §4.
|
||||
///
|
||||
/// Structure:
|
||||
@@ -19,7 +19,7 @@ namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Migrations
|
||||
/// must include the partition column.
|
||||
/// 4. Five reconciliation/query indexes from alog.md §4, plus the
|
||||
/// UX_AuditLog_EventId unique index that preserves single-column
|
||||
/// EventId uniqueness for InsertIfNotExistsAsync (M1-T8). All
|
||||
/// EventId uniqueness for InsertIfNotExistsAsync. All
|
||||
/// non-clustered indexes are partition-aligned on
|
||||
/// <c>ps_AuditLog_Month(OccurredAtUtc)</c>.
|
||||
/// 5. Two database roles:
|
||||
@@ -117,8 +117,8 @@ ON dbo.AuditLog (Target ASC, OccurredAtUtc DESC)
|
||||
WHERE Target IS NOT NULL
|
||||
ON ps_AuditLog_Month(OccurredAtUtc);");
|
||||
|
||||
// The EventId uniqueness index supports InsertIfNotExistsAsync
|
||||
// (M1-T8). It is INTENTIONALLY non-aligned (placed on [PRIMARY]
|
||||
// The EventId uniqueness index supports InsertIfNotExistsAsync. It
|
||||
// is INTENTIONALLY non-aligned (placed on [PRIMARY]
|
||||
// rather than ps_AuditLog_Month).
|
||||
//
|
||||
// SQL Server's rule for unique partition-aligned indexes is that the
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ using Microsoft.EntityFrameworkCore.Migrations;
|
||||
namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Migrations
|
||||
{
|
||||
/// <summary>
|
||||
/// C5 of the ScadaBridge audit re-architecture (Task 2.5): collapses the central
|
||||
/// Collapses the central
|
||||
/// <c>dbo.AuditLog</c> table from the transitional 24 typed columns to the 10
|
||||
/// canonical <c>ZB.MOM.WW.Audit.AuditEvent</c> columns plus six read-only,
|
||||
/// server-side <b>persisted computed columns</b> derived from <c>DetailsJson</c>
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Migrations
|
||||
{
|
||||
/// <summary>
|
||||
/// SMS Notifications (S2): makes a notification recipient's contact path optional and adds
|
||||
/// SMS Notifications: makes a notification recipient's contact path optional and adds
|
||||
/// the central SMS-provider (Twilio) configuration table.
|
||||
///
|
||||
/// 1. <c>NotificationRecipients.EmailAddress</c> becomes nullable — an SMS-only recipient
|
||||
|
||||
+11
-11
@@ -46,7 +46,7 @@ public class AuditLogRepository : IAuditLogRepository
|
||||
throw new ArgumentNullException(nameof(evt));
|
||||
}
|
||||
|
||||
// C5 (Task 2.5): write the 10 canonical columns DIRECTLY — no Decompose.
|
||||
// Write the 10 canonical columns DIRECTLY — no Decompose.
|
||||
// The five queryability columns (Kind/Status/SourceSiteId/ExecutionId/
|
||||
// ParentExecutionId) plus IngestedAtUtc are PERSISTED computed columns on
|
||||
// dbo.AuditLog; SQL Server derives them from DetailsJson at INSERT, so they
|
||||
@@ -109,7 +109,7 @@ VALUES
|
||||
throw new ArgumentNullException(nameof(paging));
|
||||
}
|
||||
|
||||
// C5 (Task 2.5): the filter predicates bind to the canonical columns and the
|
||||
// The filter predicates bind to the canonical columns and the
|
||||
// persisted computed columns directly — Channel→Category, Kind/Status/
|
||||
// SourceSiteId/ExecutionId/ParentExecutionId are computed columns. The
|
||||
// materialized rows are projected to the canonical record by reading the 10
|
||||
@@ -202,7 +202,7 @@ VALUES
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// C5 (Task 2.5): build the canonical <see cref="AuditEvent"/> DIRECTLY from the
|
||||
/// Build the canonical <see cref="AuditEvent"/> DIRECTLY from the
|
||||
/// 10 canonical columns of a materialized <see cref="AuditLogRow"/> read back from
|
||||
/// <c>dbo.AuditLog</c> — no 24-column <c>Recompose</c>, because the table now holds
|
||||
/// the canonical shape (every ScadaBridge domain field already lives in
|
||||
@@ -236,7 +236,7 @@ VALUES
|
||||
|
||||
// ISO 8601 in UTC — SQL Server's datetime2 literal parser accepts this
|
||||
// unambiguously and the value is round-trip-safe across SET DATEFORMAT
|
||||
// settings. CD-021: use datetime2(7) precision (.fffffff) so a future
|
||||
// settings. Use datetime2(7) precision (.fffffff) so a future
|
||||
// non-midnight or sub-second boundary doesn't silently round to the
|
||||
// wrong partition (today the migration only seeds at T00:00:00 exactly,
|
||||
// but the format string is on the boundary value's own contract — match
|
||||
@@ -264,7 +264,7 @@ VALUES
|
||||
DROP INDEX UX_AuditLog_EventId ON dbo.AuditLog;
|
||||
|
||||
-- 2. Staging table on [PRIMARY] (non-partitioned) with column shapes
|
||||
-- byte-identical to the C5 dbo.AuditLog — INCLUDING the persisted
|
||||
-- byte-identical to the dbo.AuditLog — INCLUDING the persisted
|
||||
-- computed columns, whose definitions must match EXACTLY (same
|
||||
-- expression text + PERSISTED) or ALTER TABLE ... SWITCH PARTITION
|
||||
-- rejects the operation with msg 4904/4948. The ordinal order also
|
||||
@@ -389,7 +389,7 @@ VALUES
|
||||
|
||||
var thresholdUtc = DateTime.SpecifyKind(threshold.ToUniversalTime(), DateTimeKind.Utc);
|
||||
|
||||
// M5.5 (T3) per-channel retention override purge. This is the ONLY DELETE
|
||||
// Per-channel retention override purge. This is the ONLY DELETE
|
||||
// against dbo.AuditLog in the codebase and it runs on the purge/maintenance
|
||||
// path, NOT the append-only writer role (which has INSERT + SELECT only — see
|
||||
// the DENY UPDATE/DENY DELETE grants in CollapseAuditLogToCanonical). The
|
||||
@@ -407,7 +407,7 @@ VALUES
|
||||
// single narrow exemption the append-only CI guard (AuditLogAppendOnlyGuardTests)
|
||||
// recognizes; any other UPDATE/DELETE targeting AuditLog still trips the guard.
|
||||
const string deleteBatchSql =
|
||||
"DELETE TOP (@batch) FROM dbo.AuditLog WHERE Category = @channel AND OccurredAtUtc < @threshold;"; // AUDIT-PURGE-ALLOWED: per-channel retention override (M5.5 T3), maintenance path
|
||||
"DELETE TOP (@batch) FROM dbo.AuditLog WHERE Category = @channel AND OccurredAtUtc < @threshold;"; // AUDIT-PURGE-ALLOWED: per-channel retention override, maintenance path
|
||||
|
||||
long totalDeleted = 0;
|
||||
|
||||
@@ -726,7 +726,7 @@ VALUES
|
||||
SELECT ParentExecutionId FROM Chain
|
||||
WHERE ParentExecutionId IS NOT NULL
|
||||
)
|
||||
-- C5 (Task 2.5): ExecutionId / ParentExecutionId / SourceSiteId
|
||||
-- ExecutionId / ParentExecutionId / SourceSiteId
|
||||
-- are persisted computed columns (same names); Channel is now the
|
||||
-- canonical Category column (Category = channel name, so the
|
||||
-- Channels aggregate still yields channel names); SourceInstanceId
|
||||
@@ -828,10 +828,10 @@ VALUES
|
||||
|
||||
var beforeUtc = DateTime.SpecifyKind(before.ToUniversalTime(), DateTimeKind.Utc);
|
||||
|
||||
// M5.6 (T5) SourceNode sentinel backfill. This is the ONE sanctioned UPDATE
|
||||
// SourceNode sentinel backfill. This is the ONE sanctioned UPDATE
|
||||
// against dbo.AuditLog in the codebase. It touches ONLY rows where
|
||||
// SourceNode IS NULL AND OccurredAtUtc < @before — rows that pre-date the
|
||||
// M5.6 feature and whose node-of-origin is UNKNOWABLE. The sentinel (default
|
||||
// SourceNode feature and whose node-of-origin is UNKNOWABLE. The sentinel (default
|
||||
// "unknown") makes that explicit. ExecutionId/ParentExecutionId are PERSISTED
|
||||
// COMPUTED columns derived from DetailsJson — mutating DetailsJson is forbidden
|
||||
// under the append-only invariant, so those stay NULL on pre-feature rows.
|
||||
@@ -849,7 +849,7 @@ VALUES
|
||||
// single narrow exemption the append-only CI guard (AuditLogAppendOnlyGuardTests)
|
||||
// recognises for an UPDATE; any other UPDATE targeting AuditLog still trips the guard.
|
||||
const string updateBatchSql =
|
||||
"UPDATE TOP (@batch) dbo.AuditLog SET SourceNode = @sentinel WHERE SourceNode IS NULL AND OccurredAtUtc < @before;"; // AUDIT-PURGE-ALLOWED: SourceNode sentinel backfill (M5.6 T5), maintenance path
|
||||
"UPDATE TOP (@batch) dbo.AuditLog SET SourceNode = @sentinel WHERE SourceNode IS NULL AND OccurredAtUtc < @before;"; // AUDIT-PURGE-ALLOWED: SourceNode sentinel backfill, maintenance path
|
||||
|
||||
long totalUpdated = 0;
|
||||
|
||||
|
||||
+3
-3
@@ -56,7 +56,7 @@ public class DeploymentManagerRepository : IDeploymentManagerRepository
|
||||
/// <inheritdoc />
|
||||
public async Task<DeploymentRecord?> GetCurrentDeploymentStatusAsync(int instanceId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
// DeploymentManager-026: deployments are insert-only (one row per deploy
|
||||
// Deployments are insert-only (one row per deploy
|
||||
// attempt), so two records for the same instance can tie on DeployedAt when
|
||||
// they are created within the same clock tick (a rapid redeploy, or a
|
||||
// redeploy immediately after a timed-out attempt). SQL Server's choice
|
||||
@@ -95,7 +95,7 @@ public class DeploymentManagerRepository : IDeploymentManagerRepository
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(expectedRowVersion);
|
||||
|
||||
// CD-017: DeploymentRecord carries a SQL Server rowversion concurrency token.
|
||||
// DeploymentRecord carries a SQL Server rowversion concurrency token.
|
||||
// The stub-attach delete path must seed EF's OriginalValues["RowVersion"] with
|
||||
// the caller's last-observed value so the generated SQL becomes
|
||||
// `DELETE ... WHERE Id = @id AND RowVersion = @prior`. Without this seeding a
|
||||
@@ -166,7 +166,7 @@ public class DeploymentManagerRepository : IDeploymentManagerRepository
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
// --- WP-8: DeployedConfigSnapshot ---
|
||||
// --- DeployedConfigSnapshot ---
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<DeployedConfigSnapshot?> GetDeployedSnapshotByInstanceIdAsync(int instanceId, CancellationToken cancellationToken = default)
|
||||
|
||||
+3
-3
@@ -22,7 +22,7 @@ public class ExternalSystemRepository : IExternalSystemRepository
|
||||
=> await _context.Set<ExternalSystemDefinition>().FindAsync(new object[] { id }, cancellationToken);
|
||||
|
||||
/// <inheritdoc />
|
||||
// ExternalSystemGateway-011: genuine name-keyed query (server-side WHERE) so the
|
||||
// Genuine name-keyed query (server-side WHERE) so the
|
||||
// gateway's hot-path resolution does not fetch every system and filter in memory.
|
||||
public async Task<ExternalSystemDefinition?> GetExternalSystemByNameAsync(string name, CancellationToken cancellationToken = default)
|
||||
=> await _context.Set<ExternalSystemDefinition>()
|
||||
@@ -52,7 +52,7 @@ public class ExternalSystemRepository : IExternalSystemRepository
|
||||
=> await _context.Set<ExternalSystemMethod>().FindAsync(new object[] { id }, cancellationToken);
|
||||
|
||||
/// <inheritdoc />
|
||||
// ExternalSystemGateway-011: genuine name-keyed query scoped to the parent system.
|
||||
// Genuine name-keyed query scoped to the parent system.
|
||||
public async Task<ExternalSystemMethod?> GetMethodByNameAsync(int externalSystemId, string methodName, CancellationToken cancellationToken = default)
|
||||
=> await _context.Set<ExternalSystemMethod>()
|
||||
.FirstOrDefaultAsync(
|
||||
@@ -83,7 +83,7 @@ public class ExternalSystemRepository : IExternalSystemRepository
|
||||
=> await _context.Set<DatabaseConnectionDefinition>().FindAsync(new object[] { id }, cancellationToken);
|
||||
|
||||
/// <inheritdoc />
|
||||
// ExternalSystemGateway-011: genuine name-keyed query (server-side WHERE).
|
||||
// Genuine name-keyed query (server-side WHERE).
|
||||
public async Task<DatabaseConnectionDefinition?> GetDatabaseConnectionByNameAsync(string name, CancellationToken cancellationToken = default)
|
||||
=> await _context.Set<DatabaseConnectionDefinition>()
|
||||
.FirstOrDefaultAsync(c => c.Name == name, cancellationToken);
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Repositories;
|
||||
|
||||
/// <summary>
|
||||
/// EF Core implementation of <see cref="IKpiHistoryRepository"/> over the central
|
||||
/// <c>KpiSample</c> table (M6 "KPI History & Trends"). See the interface for the
|
||||
/// <c>KpiSample</c> table ("KPI History & Trends"). See the interface for the
|
||||
/// contract; this class adds notes on the data-access strategy per method.
|
||||
/// </summary>
|
||||
public sealed class KpiHistoryRepository : IKpiHistoryRepository
|
||||
|
||||
+1
-1
@@ -182,7 +182,7 @@ VALUES
|
||||
query = query.Where(n => n.SourceSiteId == filter.SourceSiteId);
|
||||
}
|
||||
|
||||
// Task 16: SourceNode is exact-match like SourceSiteId. Rows with NULL
|
||||
// SourceNode is exact-match like SourceSiteId. Rows with NULL
|
||||
// SourceNode (legacy / unconfigured) are excluded when the filter is set.
|
||||
if (!string.IsNullOrEmpty(filter.SourceNode))
|
||||
{
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Repositories;
|
||||
|
||||
/// <summary>
|
||||
/// EF Core implementation of <see cref="ISecuredWriteRepository"/> over the central
|
||||
/// <c>PendingSecuredWrites</c> table (M7 OPC UA / MxGateway UX, Task T14b). Mirrors the
|
||||
/// <c>PendingSecuredWrites</c> table. Mirrors the
|
||||
/// <c>SiteCallAuditRepository</c> data-access shape: plain tracked EF reads/writes
|
||||
/// against the shared <see cref="ScadaBridgeDbContext"/>, no raw SQL needed.
|
||||
/// </summary>
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Repositories;
|
||||
|
||||
/// <summary>
|
||||
/// EF Core implementation of <see cref="ISharedSchemaRepository"/> over the central
|
||||
/// <c>SharedSchemas</c> JSON-Schema library table (M9, Task T32a). Plain tracked EF
|
||||
/// <c>SharedSchemas</c> JSON-Schema library table. Plain tracked EF
|
||||
/// reads/writes against the shared <see cref="ScadaBridgeDbContext"/>, saving on each
|
||||
/// mutating call — mirrors the <c>SecuredWriteRepository</c> data-access shape.
|
||||
/// </summary>
|
||||
|
||||
+3
-3
@@ -25,7 +25,7 @@ public class SiteCallAuditRepository : ISiteCallAuditRepository
|
||||
private const int SqlErrorPrimaryKeyViolation = 2627;
|
||||
|
||||
// Monotonic status ordering. Lower rank wins on tie (same-rank upserts are
|
||||
// no-ops, including terminal-over-terminal). Spec from Bundle B3 plan:
|
||||
// no-ops, including terminal-over-terminal):
|
||||
// Submitted < Forwarded < Attempted == Skipped < Delivered == Failed == Parked == Discarded.
|
||||
private static readonly Dictionary<string, int> StatusRank = new(StringComparer.Ordinal)
|
||||
{
|
||||
@@ -68,7 +68,7 @@ public class SiteCallAuditRepository : ISiteCallAuditRepository
|
||||
// this is check-then-act so a duplicate-key violation may surface under
|
||||
// concurrent inserts on the same id — caught + logged at Debug.
|
||||
//
|
||||
// SourceNode-stamping (Task 14): the column is included in the INSERT
|
||||
// SourceNode-stamping: the column is included in the INSERT
|
||||
// column list / VALUES so a fresh row carries the originating node
|
||||
// name (node-a/node-b for site rows). A null SourceNode (legacy hosts
|
||||
// / unstamped reconciled rows) writes NULL straight through.
|
||||
@@ -100,7 +100,7 @@ VALUES
|
||||
// incoming rank is strictly greater. Same-rank (including
|
||||
// terminal-over-terminal) is a no-op — first-write-wins at each rank.
|
||||
//
|
||||
// SourceNode-stamping (Task 14): SourceNode is updated via
|
||||
// SourceNode-stamping: SourceNode is updated via
|
||||
// COALESCE(@SourceNode, SourceNode). The operator returns @SourceNode
|
||||
// when it is non-null, otherwise the stored value — so the column
|
||||
// behaves protectively: a later packet that carries a null
|
||||
|
||||
+1
-1
@@ -44,7 +44,7 @@ public class TemplateEngineRepository : ITemplateEngineRepository
|
||||
public async Task<IReadOnlyList<Template>> GetTemplatesWithChildrenAsync(
|
||||
IEnumerable<string> names, CancellationToken cancellationToken = default)
|
||||
{
|
||||
// Transport-008: bulk lookup replaces the per-name N+1 in
|
||||
// Bulk lookup replaces the per-name N+1 in
|
||||
// BundleImporter.PreviewAsync. Filter out null / empty / duplicate
|
||||
// names before the query so EF emits a clean, deduplicated IN clause.
|
||||
if (names is null) return Array.Empty<Template>();
|
||||
|
||||
@@ -116,7 +116,7 @@ public class ScadaBridgeDbContext : DbContext, IDataProtectionKeyContext
|
||||
/// <summary>Gets the set of shared scripts.</summary>
|
||||
public DbSet<SharedScript> SharedScripts => Set<SharedScript>();
|
||||
|
||||
// Schemas (M9 template-level JSON-Schema library, T32a)
|
||||
// Schemas (template-level JSON-Schema library)
|
||||
/// <summary>Gets the set of shared JSON-Schema library entries.</summary>
|
||||
public DbSet<SharedSchema> SharedSchemas => Set<SharedSchema>();
|
||||
|
||||
@@ -127,7 +127,7 @@ public class ScadaBridgeDbContext : DbContext, IDataProtectionKeyContext
|
||||
public DbSet<SiteScopeRule> SiteScopeRules => Set<SiteScopeRule>();
|
||||
|
||||
// Inbound API
|
||||
// Auth re-arch (C5): the SQL Server ApiKeys DbSet was retired — inbound API keys
|
||||
// Auth re-arch: the SQL Server ApiKeys DbSet was retired — inbound API keys
|
||||
// now live in the shared ZB.MOM.WW.Auth.ApiKeys SQLite store. Only the method
|
||||
// catalogue remains in the configuration database.
|
||||
/// <summary>Gets the set of API methods.</summary>
|
||||
@@ -141,11 +141,11 @@ public class ScadaBridgeDbContext : DbContext, IDataProtectionKeyContext
|
||||
/// <summary>Gets the set of site calls.</summary>
|
||||
public DbSet<SiteCall> SiteCalls => Set<SiteCall>();
|
||||
|
||||
// Secured Writes (M7 OPC UA / MxGateway UX, T14b)
|
||||
// Secured Writes (OPC UA / MxGateway UX)
|
||||
/// <summary>Gets the set of pending two-person secured writes.</summary>
|
||||
public DbSet<PendingSecuredWrite> PendingSecuredWrites => Set<PendingSecuredWrite>();
|
||||
|
||||
// KPI History (M6 "KPI History & Trends")
|
||||
// KPI History ("KPI History & Trends")
|
||||
/// <summary>Gets the set of KPI samples (central tall/EAV KPI-history backbone).</summary>
|
||||
public DbSet<KpiSample> KpiSamples => Set<KpiSample>();
|
||||
|
||||
@@ -178,7 +178,7 @@ public class ScadaBridgeDbContext : DbContext, IDataProtectionKeyContext
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// C5 (Task 2.5): the central <c>dbo.AuditLog</c> persisted computed columns use
|
||||
/// The central <c>dbo.AuditLog</c> persisted computed columns use
|
||||
/// SQL Server's <c>JSON_VALUE</c> expression, which only SQL Server can evaluate.
|
||||
/// On a non-SQL-Server provider (the SQLite test contexts) emitting that SQL in a
|
||||
/// <c>CREATE TABLE</c> fails ("no such function: JSON_VALUE"). Strip the
|
||||
|
||||
@@ -57,7 +57,7 @@ public static class ServiceCollectionExtensions
|
||||
services.AddScoped<ISecuredWriteRepository, SecuredWriteRepository>();
|
||||
services.AddScoped<ISharedSchemaRepository, SharedSchemaRepository>();
|
||||
services.AddScoped<IKpiHistoryRepository, KpiHistoryRepository>();
|
||||
// Auth re-arch (C5): inbound API keys are no longer persisted in SQL Server —
|
||||
// Auth re-arch: inbound API keys are no longer persisted in SQL Server —
|
||||
// the repository now exposes only API-method access, so a plain scoped
|
||||
// registration suffices (no peppered-hasher accessor to wire).
|
||||
services.AddScoped<IInboundApiRepository, InboundApiRepository>();
|
||||
@@ -65,7 +65,7 @@ public static class ServiceCollectionExtensions
|
||||
services.AddScoped<IAuditService, AuditService>();
|
||||
services.AddScoped<IInstanceLocator, InstanceLocator>();
|
||||
|
||||
// #23 M6 Bundle D: IPartitionMaintenance drives the daily roll-forward
|
||||
// IPartitionMaintenance drives the daily roll-forward
|
||||
// of pf_AuditLog_Month from the central AuditLogPartitionMaintenanceService
|
||||
// hosted service. Scoped because the implementation reuses the per-scope
|
||||
// ScadaBridgeDbContext for raw-SQL execution; the hosted service opens a
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace ZB.MOM.WW.ScadaBridge.ConfigurationDatabase.Services;
|
||||
/// so each logical asynchronous call chain observes its own value. AuditService
|
||||
/// reads it while writing AuditLogEntry rows.
|
||||
/// <para>
|
||||
/// Thread-safety / concurrency contract (Transport-009): the previous Scoped
|
||||
/// Thread-safety / concurrency contract: the previous Scoped
|
||||
/// instance with a plain auto-property mutated by <c>BundleImporter.ApplyAsync</c>
|
||||
/// was vulnerable to cross-contamination if two imports ran concurrently inside
|
||||
/// a shared DI scope — either via <c>Task.WhenAll</c> on a single Blazor circuit
|
||||
|
||||
Reference in New Issue
Block a user