feat: Phase II auto-write (WriteGuard, audit, auth) + WO-2~7 완료
Phase II:
- FfOperatorAction entity + ff_operator_action DDL/DbSet
- IFeedforwardWriteGuard + FeedforwardWriteGuard (SP bounds, grade C, transient, NaN)
- IFeedforwardAuditService + FeedforwardAuditService (raw ADO insert/query)
- FeedforwardSupervisor.AutoWriteAsync (per-stream OPC UA after Tick, rate-limited)
- FeedforwardConfigStore: advisory_only now read/writes DB, sp_node_id column
- FeedforwardController: auth (X-Kb-Token) on config/delete/write/audit;
POST write/{id}/{key} manual SP write; GET audit; write results in MapColumn
- ff.js: token header, auto-write badge, per-stream write result, spNodeId, advisoryOnly
- ff.css: .ff-write-badge, .ff-write, .ff-write-err, .ff-wg-blocked
- Program.cs: register audit (Scoped) + write guard (Singleton)
WO-2~7 (build 0W/0E, test 22/22):
- PCT monitor, θ auto-tune, slow bias, front position indicator,
total reflux recovery, config form expansion
This commit is contained in:
35
src/Infrastructure/Control/FeedforwardWriteGuard.cs
Normal file
35
src/Infrastructure/Control/FeedforwardWriteGuard.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
using ExperionCrawler.Core.Application.Feedforward;
|
||||
|
||||
namespace ExperionCrawler.Infrastructure.Control;
|
||||
|
||||
public sealed class FeedforwardWriteGuard : IFeedforwardWriteGuard
|
||||
{
|
||||
public WriteCheckResult Check(ColumnConfig cfg, StreamAdvisory adv, StreamConfig sc, AdvisoryResult column)
|
||||
{
|
||||
if (adv.Role != StreamRole.Commanded)
|
||||
return new WriteCheckResult(false, "Commanded 스트림만 SP 쓰기 대상");
|
||||
|
||||
if (cfg.AdvisoryOnly)
|
||||
return new WriteCheckResult(false, "컬럼이 AdvisoryOnly 모드");
|
||||
|
||||
if (adv.RecommendedSp is not double sp)
|
||||
return new WriteCheckResult(false, "권장 SP 없음");
|
||||
|
||||
if (!adv.Valid)
|
||||
return new WriteCheckResult(false, "Advisory 무효(전환류 오버라이드 등)");
|
||||
|
||||
if (adv.Grade == Confidence.C)
|
||||
return new WriteCheckResult(false, $"신뢰도 C — SP 쓰기 차단");
|
||||
|
||||
if (column.Transient)
|
||||
return new WriteCheckResult(false, "과도 상태 — SP 쓰기 차단");
|
||||
|
||||
if (sp < sc.SpMin || sp > sc.SpMax)
|
||||
return new WriteCheckResult(false, $"SP {sp:F2} 허용범위 [{sc.SpMin:F2}, {sc.SpMax:F2}] 벗어남");
|
||||
|
||||
if (double.IsNaN(sp) || double.IsInfinity(sp))
|
||||
return new WriteCheckResult(false, "SP 값이 NaN/Infinity");
|
||||
|
||||
return new WriteCheckResult(true, null);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user