namespace ZB.MOM.WW.ScadaBridge.InboundAPI;
public class InboundApiOptions
{
///
/// Default cap on the inbound API request body, in bytes.
///
public const long DefaultMaxRequestBodyBytes = 1L * 1024 * 1024; // 1 MiB
/// Default timeout for inbound API method execution before the request is cancelled.
public TimeSpan DefaultMethodTimeout { get; set; } = TimeSpan.FromSeconds(30);
///
/// Maximum accepted request body size for POST /api/{methodName}.
/// Requests whose body exceeds this are rejected with HTTP 413 before being
/// buffered into a . The inbound API
/// has no rate limiting (a deliberate design choice), so an explicit, modest cap
/// bounds per-request allocations.
///
public long MaxRequestBodyBytes { get; set; } = DefaultMaxRequestBodyBytes;
///
/// Server-side HMAC pepper for inbound-API bearer credentials, bound from
/// ScadaBridge:InboundApi:ApiKeyPepper.
///
/// Auth re-arch: the legacy SQL Server hashing path that consumed this
/// property was retired. The pepper itself is still required — the shared
/// ZB.MOM.WW.Auth.ApiKeys verifier reads the SAME configuration key
/// (PepperSecretName in the Host composition root points at it) to pepper
/// the SQLite-stored keys. It is a secret: supply a strong, random value
/// (≥ 16 characters), DIFFERENT per environment, via a secret store and never
/// hard-coded. This property is retained so the section still binds cleanly; the
/// value is consumed by the library verifier, not by AddInboundAPI.
///
///
public string ApiKeyPepper { get; set; } = string.Empty;
///
/// How long a resolved
/// ApiMethod row (found OR not-found) is served from
/// before the next request re-fetches it from the repository. The
/// ScriptArtifactChangeSubscriber/IScriptArtifactChangeBus pipeline
/// invalidates a specific method's entry immediately on a bundle-import change (the fast
/// path); this TTL is the self-healing fallback for changes the bus does not cover (e.g.
/// an operator edit via the Management API/UI, which does not publish a bus notification),
/// bounding staleness without requiring every mutation path to remember to invalidate.
/// Short by design — the whole point is to absorb repeated-request-storm SQL, not to
/// serve minutes-old method definitions.
///
public TimeSpan ApiMethodCacheTtl { get; set; } = TimeSpan.FromSeconds(5);
///
/// Standby-node forwarding (2026-08-28): the HTTP base URLs of the OTHER central
/// node(s) — e.g. ["http://scadabridge-central-b:5000"] on central-a — that a
/// standby relays POST /api/{methodName} to instead of answering 503
/// STANDBY_NODE. Tried in order; the first peer that is not itself a standby
/// serves the call. Empty (the default) keeps the pre-forwarding behaviour: a standby
/// refuses with 503. Method scripts still execute only on the active node — the
/// standby is a pure relay (see ). Each entry
/// must be an absolute http/https URL; never list this node's own address
/// (it would cost one wasted round-trip per call — the loop guard stops it bouncing).
///
public List StandbyForwardPeerEndpoints { get; set; } = new();
///
/// End-to-end relay budget spanning connection, permitted standby retries and response
/// consumption. Size it for the longest method execution plus network overhead. A send
/// whose response is lost or times out returns OUTCOME_UNKNOWN and is never replayed.
/// Default 60 s.
///
public TimeSpan StandbyForwardTimeout { get; set; } = TimeSpan.FromSeconds(60);
/// Default value of , also used when no options instance is available.
public const int DefaultMaxLogLinesPerRun = 200;
///
/// Flow Debugger step logs (design 2026-09-09 D7): how many Log.* lines ONE traced
/// method execution may turn into ScriptTrace/ScriptLog audit rows. Past the cap the
/// lines are dropped from the trace — they still reach the node's ILogger — and the
/// run ends with a single runtime-sourced warning row naming the dropped count, so a
/// truncated trace is never silently short. Untraced executions emit no rows at all and are
/// therefore unaffected by this value. Must be greater than zero.
///
public int MaxLogLinesPerRun { get; set; } = DefaultMaxLogLinesPerRun;
}