using ZB.MOM.WW.ScadaBridge.Commons.Types.Audit; namespace ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Repositories; /// /// Hash-chain tamper evidence for the central AuditLog table (audit roadmap T1, /// alog.md §11.4, ScadaBridge#41). /// /// /// /// One chain per partition = UTC calendar month of OccurredAtUtc (the same /// month the ps_AuditLog_Month scheme partitions on). Each chained row carries a /// ChainSeq (1, 2, 3 … within its month) and /// RowHash = SHA-256(prev.RowHash || canonical(row)), where prev is the row /// at ChainSeq - 1 (32 zero bytes for the first). The canonical serialisation /// covers every writable column plus the month and sequence number. /// /// /// Rows are linked by a chaining job, not by the hot-path writers: two central /// nodes and the site-ingest path all INSERT concurrently, so a write-time chain would /// need a global serialisation point on every audit write. The job serialises itself /// with an exclusive SQL Server application lock, so even a dual-active central pair /// produces one gap-free chain per month. /// /// public interface IAuditLogHashChain { /// /// Links up to unchained rows (oldest /// OccurredAtUtc first) onto the end of their month's chain, in one transaction. /// Returns immediately with set when another /// chainer holds the chain lock. /// /// Maximum rows to chain in this pass. /// Cancellation token. /// How many rows were chained, and whether the lock was busy. Task ChainPendingAsync(int batchSize, CancellationToken ct = default); /// /// Verifies one month's chain end to end and reports the first break. /// /// The first instant of the month (UTC, day 1, midnight). /// Cancellation token. /// The verification result. Task VerifyMonthAsync(DateTime monthStartUtc, CancellationToken ct = default); }