Files
aquacom-gateway-suite/ARCHITECTURE.md
T
2026-10-05 20:32:13 +02:00

3603 lines
40 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# \# AquaCom Integration Gateway – Architecture
#
# \## 1. Purpose
#
# This document defines the high-level software architecture of the \*\*AquaCom Integration Gateway\*\*.
#
# It describes:
#
# \- major system components;
# \- dependency direction;
# \- data flows;
# \- architectural boundaries;
# \- live-data handling;
# \- historical-data handling;
# \- OPC UA integration;
# \- storage integration;
# \- diagnostics;
# \- security boundaries;
# \- extension points.
#
# Detailed functional requirements are defined in:
#
# ```text
# docs/product/software-specification.md
# ```
#
# Implementation requirements and Codex-specific development rules are defined in:
#
# ```text
# docs/product/codex-implementation-specification.md
# AGENTS.md
# ```
#
# Detailed subsystem architecture is documented under:
#
# ```text
# docs/architecture/
# ```
#
# AquaCom-specific protocol knowledge is documented under:
#
# ```text
# docs/protocol/
# ```
#
# \---
#
# \# 2. System purpose
#
# The AquaCom Integration Gateway provides a modern integration boundary between AquaCom-compatible field equipment and higher-level systems.
#
# The gateway shall:
#
# \- communicate with AquaCom field devices;
# \- acquire current process values;
# \- retrieve historical process values;
# \- normalize AquaCom-specific information into a protocol-independent model;
# \- expose current values using OPC UA;
# \- expose historical values using OPC UA Historical Access;
# \- store historical data in one or more configurable destinations;
# \- recover historical information following communication interruptions;
# \- provide operational and protocol diagnostics.
#
# The gateway shall not make higher-level systems dependent on AquaCom-specific behavior.
#
# \---
#
# \# 3. Architectural principle
#
# The central architecture is:
#
# ```text
# AquaCom field device
#   │
#   ▼
# AquaCom Transport
#   │
#   ▼
# AquaCom Protocol Engine
#   │
#   ▼
# Station / Session Manager
#   │
#   ▼
# Canonical Data Model
#   │
#   ├─────────────────────► Current-State Service
#   │ │
#   │ ▼
#   │ OPC UA Data Access
#   │
#   └─────────────────────► Historical Pipeline
#   │
#   ┌───────────┼────────────┐
#   │ │ │
#   ▼ ▼ ▼
#   Repository Storage A Storage B
#   │
#   ▼
#   OPC UA Historical Access
# ```
#
# The canonical data model forms the boundary between AquaCom-specific functionality and all northbound integrations.
#
# \---
#
# \# 4. Architectural goals
#
# The architecture shall support:
#
# \- protocol isolation;
# \- storage independence;
# \- stable internal identifiers;
# \- stable OPC UA NodeIds;
# \- correct handling of source timestamps;
# \- reliable history recovery;
# \- multiple historical storage destinations;
# \- store-and-forward;
# \- independent subsystem testing;
# \- restart recovery;
# \- future replacement of individual technologies;
# \- future addition of other northbound interfaces.
#
# The architecture shall avoid tight coupling between:
#
# ```text
# AquaCom
# OPC UA
# Database technology
# Historian technology
# SCADA platform
# ```
#
# \---
#
# \# 5. Architectural boundaries
#
# The following boundaries are mandatory.
#
# \## 5.1 AquaCom boundary
#
# Only the AquaCom subsystem may:
#
# \- encode AquaCom telegrams;
# \- decode AquaCom telegrams;
# \- calculate or verify AquaCom checksums;
# \- interpret AquaCom operation codes;
# \- interpret AquaCom addressing;
# \- interpret AquaCom-specific value formats.
#
# No OPC UA or storage module shall perform AquaCom protocol processing.
#
# \---
#
# \## 5.2 Canonical model boundary
#
# AquaCom data shall be converted into canonical gateway objects before being forwarded to:
#
# \- current-state handling;
# \- history handling;
# \- OPC UA;
# \- storage systems;
# \- diagnostics where appropriate.
#
# The canonical model shall remain independent of AquaCom and OPC UA.
#
# \---
#
# \## 5.3 OPC UA boundary
#
# The OPC UA subsystem shall consume canonical gateway information.
#
# It shall not:
#
# \- communicate directly with AquaCom stations;
# \- decode telegrams;
# \- synchronously request historical data from an RTU;
# \- depend upon a particular storage technology.
#
# \---
#
# \## 5.4 Storage boundary
#
# Storage destinations shall receive canonical historical records.
#
# Storage implementations shall not depend upon:
#
# \- AquaCom telegrams;
# \- AquaCom transport;
# \- OPC UA server internals.
#
# \---
#
# \# 6. Source tree
#
# The logical source structure is:
#
# ```text
# src/
# ├── core/
# ├── aquacom/
# ├── history/
# ├── storage/
# ├── opcua/
# ├── diagnostics/
# └── host/
# ```
#
# The exact language-specific package or project structure may differ, but the architectural responsibilities shall remain equivalent.
#
# \---
#
# \# 7. Dependency direction
#
# Allowed dependencies shall broadly follow:
#
# ```text
#   host
#   │
#   ┌───────────┼─────────────┐
#   │ │ │
#   ▼ ▼ ▼
#   opcua history diagnostics
#   │ │
#   │ storage
#   │ │
#   └──────┬────┘
#   ▼
#   core
#   ▲
#   │
#   aquacom
# ```
#
# The most important rule is:
#
# ```text
# core
# ```
#
# shall not depend upon:
#
# ```text
# aquacom
# opcua
# storage technology
# ```
#
# \---
#
# \# 8. Core subsystem
#
# The `core` subsystem contains protocol-independent domain concepts.
#
# Examples include:
#
# ```text
# StationId
# PointId
# CurrentValue
# HistoricalSample
# DataQuality
# AcquisitionSource
# CommunicationState
# StationState
# HistorySynchronizationState
# ```
#
# The core subsystem defines shared contracts used between other modules.
#
# It shall contain no AquaCom protocol logic.
#
# It shall contain no OPC UA-specific types.
#
# It shall contain no database-specific types.
#
# \---
#
# \# 9. AquaCom subsystem
#
# The AquaCom subsystem contains:
#
# ```text
# Transport
# Protocol codec
# Telegram validation
# Station/session handling
# Live acquisition
# Historical acquisition
# Protocol diagnostics
# ```
#
# Logical structure:
#
# ```text
# AquaCom Transport
#   │
#   ▼
# Protocol Codec
#   │
#   ▼
# Protocol Operations
#   │
#   ▼
# Station Session
#   │
#   ├── Live Acquisition
#   └── Historical Acquisition
# ```
#
# Protocol implementation shall be evidence-based.
#
# Undocumented AquaCom behavior shall not be guessed.
#
# \---
#
# \# 10. AquaCom transport
#
# The transport layer is responsible for communication only.
#
# It may support implementations such as:
#
# ```text
# TCP
# Serial
# Serial-over-IP
# Other supported AquaCom transport
# ```
#
# The transport layer shall not interpret process values.
#
# Conceptual interface:
#
# ```text
# open
# close
# send
# receive
# health
# ```
#
# \---
#
# \# 11. AquaCom protocol engine
#
# The protocol engine is responsible for:
#
# \- framing;
# \- telegram validation;
# \- checksum handling;
# \- request encoding;
# \- response decoding;
# \- protocol error interpretation.
#
# Conceptual transformation:
#
# ```text
# raw bytes
#   │
#   ▼
# AquaCom message
#   │
#   ▼
# logical protocol result
# ```
#
# The codec shall be independently testable without a physical AquaCom device.
#
# \---
#
# \# 12. Station/session manager
#
# Each AquaCom station has an independent logical session.
#
# Conceptual station states:
#
# ```text
# DISABLED
# INITIALIZING
# CONNECTING
# ONLINE
# DEGRADED
# OFFLINE
# RECOVERING
# ```
#
# One failing station shall not stop communication with unrelated stations.
#
# The Station Manager owns:
#
# \- station lifecycle;
# \- communication status;
# \- retries;
# \- scheduling;
# \- station diagnostics;
# \- history recovery coordination.
#
# \---
#
# \# 13. Canonical data model
#
# The gateway uses a protocol-independent canonical model.
#
# \## 13.1 CurrentValue
#
# Conceptually:
#
# ```text
# CurrentValue
#   StationId
#   PointId
#   Value
#   DataType
#   Quality
#   SourceTimestamp
#   ReceivedTimestamp
#   UpdatedTimestamp
#   AcquisitionSource
# ```
#
# \---
#
# \## 13.2 HistoricalSample
#
# Conceptually:
#
# ```text
# HistoricalSample
#   StationId
#   PointId
#   Value
#   DataType
#   Quality
#   SourceTimestamp
#   ReceivedTimestamp
#   AcquisitionSource
#   AcquisitionId
# ```
#
# Historical samples shall retain the timestamp associated with the process state.
#
# \---
#
# \# 14. Timestamp model
#
# The gateway shall distinguish at least:
#
# ```text
# SourceTimestamp
# ReceivedTimestamp
# ```
#
# Where applicable also:
#
# ```text
# UpdatedTimestamp
# ServerTimestamp
# ```
#
# Their meanings are:
#
# | Timestamp | Meaning |
# |---|---|
# | SourceTimestamp | Time associated with the value at the source |
# | ReceivedTimestamp | Time the gateway received the information |
# | UpdatedTimestamp | Time current gateway state was changed |
# | ServerTimestamp | Timestamp used by the OPC UA server |
#
# The following must never be assumed:
#
# ```text
# ReceivedTimestamp = SourceTimestamp
# ```
#
# \---
#
# \# 15. Fundamental historical rule
#
# The fundamental historical-data rule is:
#
# > A historical sample represents the process at its SourceTimestamp, not at the time the gateway receives the sample.
#
# Example:
#
# ```text
# Historical value:
#   SourceTimestamp = 14:05
#   ReceivedTimestamp = 18:30
# ```
#
# The value belongs to history at:
#
# ```text
# 14:05
# ```
#
# It shall not become a new current process value at:
#
# ```text
# 18:30
# ```
#
# \---
#
# \# 16. Live-data architecture
#
# Live AquaCom values follow:
#
# ```text
# AquaCom response
#   │
#   ▼
# Protocol decode
#   │
#   ▼
# Point mapping
#   │
#   ▼
# Canonical CurrentValue
#   │
#   ▼
# Current-State Service
#   │
#   ├────────► OPC UA
#   │
#   └────────► Historical pipeline
#   if live historization is enabled
# ```
#
# The Current-State Service maintains the latest accepted value for each configured point.
#
# \---
#
# \# 17. Current-State Service
#
# Responsibilities:
#
# \- maintain the latest current value;
# \- reject obsolete current-state updates where applicable;
# \- expose current values to OPC UA;
# \- notify subscribers of valid changes;
# \- preserve quality and timestamps.
#
# Conceptual interface:
#
# ```text
# update(CurrentValue)
#
# get(PointId)
#
# getAll(StationId)
#
# subscribe(PointId)
# ```
#
# Historical backfill shall not directly call `update(CurrentValue)`.
#
# \---
#
# \# 18. Historical-data architecture
#
# Historical AquaCom data follows:
#
# ```text
# AquaCom history
#   │
#   ▼
# Historical Acquisition Manager
#   │
#   ▼
# Canonical HistoricalSample
#   │
#   ▼
# Historical Pipeline
#   │
#   ├────────► History Repository
#   ├────────► Storage Sink A
#   ├────────► Storage Sink B
#   └────────► Other configured destinations
# ```
#
# The historical pipeline is independent from OPC UA.
#
# \---
#
# \# 19. Historical Acquisition Manager
#
# The Historical Acquisition Manager is responsible for:
#
# \- determining missing intervals;
# \- requesting AquaCom history;
# \- processing historical responses;
# \- maintaining synchronization state;
# \- managing watermarks;
# \- performing reconnect/backfill;
# \- throttling history retrieval;
# \- avoiding interference with live polling.
#
# Live acquisition shall normally have higher communication priority than bulk history recovery.
#
# \---
#
# \# 20. Historical synchronization
#
# Each station may maintain persistent synchronization state.
#
# Conceptually:
#
# ```text
# StationId
# HistoryStreamId
# LastCompleteTimestamp
# LastAttemptTimestamp
# LastSuccessfulTimestamp
# SynchronizationState
# ```
#
# Example:
#
# ```text
# 12:00 history synchronized
#
# 12:03 communication lost
#
# 17:24 communication restored
#
# 12:00 → 17:24
#   identified as recovery interval
# ```
#
# The gateway then retrieves available AquaCom history for that interval.
#
# \---
#
# \# 21. Watermark rule
#
# A history synchronization watermark shall only advance after the corresponding interval has been successfully handled according to the configured persistence policy.
#
# The following is prohibited:
#
# ```text
# receive historical packet
#   │
#   ▼
# advance watermark
#   │
#   ▼
# storage fails
# ```
#
# Preferred behavior is:
#
# ```text
# receive
#   ↓
# validate
#   ↓
# persist/durably queue
#   ↓
# advance synchronization state
# ```
#
# \---
#
# \# 22. Historical pipeline
#
# The historical pipeline shall conceptually perform:
#
# ```text
# HistoricalSample
#   │
#   ▼
# Validation
#   │
#   ▼
# Normalization
#   │
#   ▼
# Deduplication
#   │
#   ▼
# Durable Spool
#   │
#   ▼
# Distribution
# ```
#
# This pipeline provides a stable boundary between acquisition and storage.
#
# \---
#
# \# 23. Deduplication
#
# The default historical logical identity is:
#
# ```text
# StationId
# \+
# PointId
# \+
# SourceTimestamp
# ```
#
# A stronger AquaCom-provided identifier may be used where verified.
#
# Identical samples shall not create unintended duplicate history.
#
# Conflicting samples sharing the same logical identity shall generate diagnostics.
#
# The default conflict strategy should favor explicit conflict detection rather than silent overwrite.
#
# \---
#
# \# 24. Durable spool
#
# The historical spool provides restart-safe delivery.
#
# Conceptually:
#
# ```text
# HistoricalSample
#   │
#   ▼
# Persistent spool
#   │
#   ├────► Repository
#   ├────► Sink A
#   └────► Sink B
# ```
#
# Each destination maintains independent acknowledgement.
#
# Example:
#
# ```text
# Record 4711
#
# Repository ACK
# CentralHistorian ACK
# Archive PENDING
# ```
#
# The record remains until configured delivery requirements have been fulfilled.
#
# \---
#
# \# 25. History Repository
#
# A History Repository is a queryable historical source.
#
# It provides operations conceptually equivalent to:
#
# ```text
# store
# storeBatch
# readRaw
# readAtTime
# getBounds
# health
# ```
#
# The repository used by OPC UA Historical Access is selected by configuration.
#
# The OPC UA implementation shall not know whether the repository is:
#
# ```text
# relational database
# time-series database
# embedded historian
# industrial historian
# other queryable implementation
# ```
#
# \---
#
# \# 26. Storage Sink
#
# A Storage Sink is a destination receiving historical records.
#
# Conceptual interface:
#
# ```text
# initialize
# write
# writeBatch
# flush
# health
# shutdown
# ```
#
# A sink does not need to support historical queries.
#
# Examples:
#
# ```text
# SQL database
# time-series database
# enterprise historian
# file archive
# message broker
# data lake connector
# ```
#
# \---
#
# \# 27. Repository versus sink
#
# These shall remain separate concepts:
#
# ```text
# Repository
#   = query historical data
#
# Sink
#   = receive historical data
# ```
#
# One implementation may support both.
#
# Example:
#
# ```text
# Local historian
#   Repository: yes
#   Sink: yes
#
# Archive export
#   Repository: no
#   Sink: yes
# ```
#
# \---
#
# \# 28. Multiple storage destinations
#
# A historical record may be delivered to multiple independent destinations.
#
# Example:
#
# ```text
#   Historical Pipeline
#   │
#   ┌───────────────┼────────────────┐
#   │ │ │
#   ▼ ▼ ▼
#   Local Repository Central DB Archive
# ```
#
# Failure of one destination shall not unnecessarily block successful destinations.
#
# \---
#
# \# 29. OPC UA architecture
#
# The OPC UA subsystem provides northbound access to normalized gateway information.
#
# Logical components:
#
# ```text
# OPC UA Server
#   │
#   ├── Namespace Manager
#   ├── Current Value Provider
#   ├── Historical Provider
#   ├── Quality Mapper
#   ├── Diagnostics Provider
#   └── Security
# ```
#
# \---
#
# \# 30. OPC UA current data
#
# Current values are exposed through normal OPC UA Data Access.
#
# Mapping:
#
# ```text
# CurrentValue.Value
#   ↓
# OPC UA Value
#
# CurrentValue.SourceTimestamp
#   ↓
# OPC UA SourceTimestamp
#
# Gateway server time
#   ↓
# OPC UA ServerTimestamp
#
# CurrentValue.Quality
#   ↓
# OPC UA StatusCode
# ```
#
# \---
#
# \# 31. OPC UA Historical Access
#
# Historical Access shall query the configured History Repository.
#
# Correct flow:
#
# ```text
# OPC UA Client
#   │
#   │ HistoryRead
#   ▼
# OPC UA Server
#   │
#   ▼
# Historical Provider
#   │
#   ▼
# History Repository
#   │
#   ▼
# HistoricalSample\[]
#   │
#   ▼
# OPC UA DataValue\[]
# ```
#
# \---
#
# \# 32. Prohibited HistoryRead architecture
#
# The following architecture is prohibited:
#
# ```text
# OPC UA HistoryRead
#   │
#   ▼
# AquaCom request
#   │
#   ▼
# wait for RTU
#   │
#   ▼
# OPC UA response
# ```
#
# Historical synchronization and historical client access must be decoupled.
#
# \---
#
# \# 33. OPC UA namespace
#
# The default logical namespace shall resemble:
#
# ```text
# AquaCom
# │
# ├── Gateway
# │ ├── Status
# │ ├── Version
# │ ├── StartTime
# │ ├── ConfigurationVersion
# │ ├── HistoricalQueueDepth
# │ └── Storage
# │
# └── Stations
#   │
#   ├── PS001
#   │ ├── Process
#   │ │ ├── Level
#   │ │ ├── Pump01Running
#   │ │ └── Pump02Running
#   │ │
#   │ └── Diagnostics
#   │ ├── CommunicationState
#   │ ├── LastCommunication
#   │ ├── HistoryState
#   │ └── HistoryWatermark
#   │
#   └── PS002
# ```
#
# Exact organization may be configurable.
#
# \---
#
# \# 34. Stable OPC UA NodeIds
#
# OPC UA NodeIds shall derive from stable engineering identifiers.
#
# Example:
#
# ```text
# station/PS001/point/LEVEL
# ```
#
# Changing:
#
# ```text
# Wet well level
# ```
#
# to:
#
# ```text
# Inlet sump level
# ```
#
# shall not normally change the NodeId.
#
# Stable NodeIds are required to preserve client configuration.
#
# \---
#
# \# 35. Diagnostics architecture
#
# Diagnostics are separate from process data.
#
# Conceptually:
#
# ```text
# Diagnostics
# │
# ├── Gateway
# │
# ├── Station
# │
# ├── AquaCom Protocol
# │
# ├── History
# │
# ├── Storage
# └── OPC UA
# ```
#
# Diagnostics may be exposed through:
#
# \- logs;
# \- metrics;
# \- OPC UA diagnostic nodes;
# \- future management interfaces.
#
# \---
#
# \# 36. Gateway diagnostics
#
# Examples:
#
# ```text
# GatewayState
# Version
# ConfigurationVersion
# StartTime
# Uptime
# StationCount
# OnlineStationCount
# HistoricalQueueDepth
# SpoolDiskUsage
# OPCUAState
# ```
#
# \---
#
# \# 37. Station diagnostics
#
# Examples:
#
# ```text
# CommunicationState
# LastRequest
# LastResponse
# LastSuccessfulCommunication
# ConsecutiveFailures
# ProtocolErrors
# HistorySynchronizationState
# HistoryWatermark
# HistoricalBacklog
# ```
#
# \---
#
# \# 38. Storage diagnostics
#
# Per destination:
#
# ```text
# State
# LastSuccessfulWrite
# LastFailure
# PendingRecords
# RetryCount
# Latency
# ```
#
# A storage failure shall be identifiable independently from an AquaCom communication failure.
#
# \---
#
# \# 39. Logging
#
# Structured logging is preferred.
#
# Useful context includes:
#
# ```text
# timestamp
# severity
# component
# stationId
# pointId
# operation
# correlationId
# message
# error
# ```
#
# Raw AquaCom telegram logging shall be separately configurable.
#
# \---
#
# \# 40. Configuration architecture
#
# Configuration shall be external and machine-readable.
#
# Conceptual structure:
#
# ```text
# Gateway Configuration
# │
# ├── Gateway
# ├── AquaCom
# ├── Stations
# ├── Points
# ├── History
# ├── Storage
# ├── OPC UA
# ├── Security
# ├── Diagnostics
# └── Logging
# ```
#
# Configuration validation occurs before activation.
#
# \---
#
# \# 41. Station configuration
#
# A station definition contains concepts equivalent to:
#
# ```text
# StationId
# Enabled
# Transport
# AquaComAddress
# ProtocolProfile
# LiveAcquisition
# HistoricalAcquisition
# PointDefinitionSource
# Timezone
# ```
#
# Station configuration shall not be embedded directly in protocol source code.
#
# \---
#
# \# 42. Point configuration
#
# A point contains concepts equivalent to:
#
# ```text
# PointId
# DisplayName
# Description
# SourceReference
# DataType
# EngineeringUnit
# Scaling
# LiveEnabled
# HistoryEnabled
# OPCUAEnabled
# Historizing
# StoragePolicy
# ```
#
# `PointId` shall remain stable even if presentation metadata changes.
#
# \---
#
# \# 43. Security boundaries
#
# The architecture assumes AquaCom is a legacy field protocol.
#
# Security shall therefore be applied around the AquaCom communication environment.
#
# Conceptually:
#
# ```text
# SCADA / client network
#   │
#   ▼
# Firewall / segmentation
#   │
#   ▼
# AquaCom Gateway
#   │
#   ▼
# OT communication network
#   │
#   ▼
# Site firewall/router/VPN
#   │
#   ▼
# AquaCom RTU
# ```
#
# The gateway shall not assume that AquaCom itself provides modern confidentiality, authentication or authorization.
#
# \---
#
# \# 44. OPC UA security
#
# OPC UA security is handled within the OPC UA subsystem.
#
# Production architecture shall support:
#
# ```text
# application certificates
# trusted client management
# secure channels
# authentication
# authorization
# encrypted communication
# ```
#
# Insecure endpoints shall not be the normal production default.
#
# \---
#
# \# 45. Secrets boundary
#
# Secrets shall not form part of normal version-controlled configuration.
#
# Examples:
#
# ```text
# database passwords
# API tokens
# private keys
# certificate private keys
# ```
#
# These shall be injected through an external secret mechanism.
#
# \---
#
# \# 46. Host subsystem
#
# The `host` subsystem composes the application.
#
# Responsibilities include:
#
# \- configuration loading;
# \- dependency construction;
# \- subsystem startup;
# \- lifecycle management;
# \- shutdown;
# \- top-level health state.
#
# The host shall not become a location for protocol or business logic.
#
# \---
#
# \# 47. Startup architecture
#
# Conceptual startup sequence:
#
# ```text
# Load configuration
#   │
#   ▼
# Validate configuration
#   │
#   ▼
# Load persistent state
#   │
#   ▼
# Initialize storage
#   │
#   ▼
# Initialize historical services
#   │
#   ▼
# Initialize OPC UA
#   │
#   ▼
# Initialize AquaCom stations
#   │
#   ▼
# Start live acquisition
#   │
#   ▼
# Start historical synchronization
# ```
#
# A temporary failure of a non-critical secondary storage destination should not necessarily prevent the gateway from starting.
#
# \---
#
# \# 48. Shutdown architecture
#
# Conceptual controlled shutdown:
#
# ```text
# Stop accepting administrative changes
#   │
#   ▼
# Stop scheduling new acquisition
#   │
#   ▼
# Complete/cancel active transactions safely
#   │
#   ▼
# Persist synchronization state
#   │
#   ▼
# Flush durable state
#   │
#   ▼
# Stop OPC UA
#   │
#   ▼
# Close storage
#   │
#   ▼
# Terminate
# ```
#
# \---
#
# \# 49. Restart recovery
#
# After an unclean restart:
#
# ```text
# Load configuration
#   │
#   ▼
# Recover persistent spool
#   │
#   ▼
# Restore synchronization watermarks
#   │
#   ▼
# Reconnect AquaCom stations
#   │
#   ▼
# Resume live acquisition
#   │
#   ▼
# Resume historical recovery
# ```
#
# Live acquisition should resume before large backlog processing.
#
# \---
#
# \# 50. Scheduling priorities
#
# Where AquaCom communication capacity is limited, scheduling shall conceptually prioritize:
#
# ```text
# 1\. communication/session health
# 2\. current/live acquisition
# 3\. alarms/events when implemented
# 4\. explicit configuration operations
# 5\. historical backfill
# 6\. low-priority maintenance
# ```
#
# Historical synchronization shall be throttleable.
#
# \---
#
# \# 51. Resource boundaries
#
# All queues and caches shall be bounded.
#
# This applies to:
#
# ```text
# AquaCom request queues
# history queues
# storage retry queues
# OPC UA historical result sets
# continuation state
# logging buffers
# spool storage
# ```
#
# Overflow behavior shall be explicit and observable.
#
# \---
#
# \# 52. Testing architecture
#
# The system shall support independent testing of each architectural boundary.
#
# Conceptually:
#
# ```text
# Protocol Fixtures
#   │
#   ▼
# AquaCom Codec Tests
#
# Simulator
#   │
#   ▼
# Session / Acquisition Tests
#
# Historical Fixtures
#   │
#   ▼
# History Pipeline Tests
#
# Repository
#   │
#   ▼
# OPC UA HA Tests
#
# Current-State Service
#   │
#   ▼
# OPC UA DA Tests
# ```
#
# \---
#
# \# 53. AquaCom simulator
#
# The simulator shall permit development without operational AquaCom equipment.
#
# Supported scenarios shall eventually include:
#
# ```text
# normal live values
# normal history
# timeouts
# disconnects
# delayed response
# malformed telegram
# bad checksum
# duplicate history
# conflicting history
# clock error
# reconnect
# backfill
# ```
#
# The simulator is part of the architecture, not merely a temporary development tool.
#
# \---
#
# \# 54. Protocol evidence architecture
#
# AquaCom implementation is linked to documented evidence.
#
# Relevant repository area:
#
# ```text
# docs/protocol/
# ```
#
# Recommended structure:
#
# ```text
# aquacom.md
# known-operations.md
# protocol-gaps.md
# test-vectors.md
# ```
#
# Every implemented AquaCom behavior should be traceable to:
#
# ```text
# Specification
# Capture
# Known-good implementation
# Approved test vector
# ```
#
# Unknown behavior remains explicitly unresolved.
#
# \---
#
# \# 55. Error isolation
#
# Failures shall remain contained where possible.
#
# Examples:
#
# | Failure | Expected isolation |
# |---|---|
# | Station A offline | Station B continues |
# | Storage A offline | Storage B continues |
# | OPC UA client disconnect | Acquisition continues |
# | OPC UA server problem | AquaCom acquisition should continue where possible |
# | Historical backfill fails | Live acquisition continues |
# | Malformed AquaCom telegram | Telegram rejected, station diagnostics updated |
# | Secondary storage failure | Durable spool retains pending delivery |
#
# \---
#
# \# 56. Future extension points
#
# The architecture shall permit future addition of:
#
# ```text
# OPC UA Alarms \& Conditions
# AquaCom alarms/events
# AquaCom commands
# setpoint changes
# MQTT
# REST API
# external analytics
# central configuration
# redundant gateways
# high availability
# additional history repositories
# additional storage sinks
# ```
#
# These shall be added behind explicit subsystem interfaces.
#
# \---
#
# \# 57. Future process-control architecture
#
# If control functionality is introduced later, it shall use a separate command pipeline:
#
# ```text
# Northbound request
#   │
#   ▼
# Authentication
#   │
#   ▼
# Authorization
#   │
#   ▼
# Command validation
#   │
#   ▼
# Command service
#   │
#   ▼
# AquaCom command
#   │
#   ▼
# Confirmation / readback
#   │
#   ▼
# Audit
# ```
#
# A direct mapping from arbitrary OPC UA writes to raw AquaCom telegrams is not an acceptable control architecture.
#
# \---
#
# \# 58. Architectural invariants
#
# The following invariants shall hold throughout implementation.
#
# \## INV-001
#
# AquaCom-specific logic exists only behind the AquaCom abstraction.
#
# \## INV-002
#
# The canonical model contains no AquaCom telegram representation.
#
# \## INV-003
#
# The canonical model contains no OPC UA-specific representation.
#
# \## INV-004
#
# Historical samples do not update current state solely because they were recently retrieved.
#
# \## INV-005
#
# Historical SourceTimestamp is preserved.
#
# \## INV-006
#
# OPC UA HistoryRead queries a repository, not an AquaCom device.
#
# \## INV-007
#
# A storage failure does not directly stop unrelated live AquaCom acquisition.
#
# \## INV-008
#
# Point identity remains stable across display-name changes.
#
# \## INV-009
#
# OPC UA NodeIds remain stable across restart and normal upgrades.
#
# \## INV-010
#
# Unverified AquaCom protocol details are not implemented as guesses.
#
# \## INV-011
#
# Synchronization state required for recovery is persistent.
#
# \## INV-012
#
# Historical delivery supports bounded persistent buffering.
#
# \---
#
# \# 59. Primary end-to-end data flows
#
# \## 59.1 Live data
#
# ```text
# AquaCom RTU
#   │
#   ▼
# Transport
#   │
#   ▼
# Protocol Engine
#   │
#   ▼
# Station Manager
#   │
#   ▼
# CurrentValue
#   │
#   ▼
# Current-State Service
#   │
#   ├────► OPC UA
#   │
#   └────► Historical Pipeline
#   when live historization is enabled
# ```
#
# \---
#
# \## 59.2 AquaCom historical recovery
#
# ```text
# AquaCom RTU
#   │
#   ▼
# Historical Acquisition
#   │
#   ▼
# HistoricalSample
#   │
#   ▼
# Validation
#   │
#   ▼
# Deduplication
#   │
#   ▼
# Durable Spool
#   │
#   ├────► Repository
#   ├────► Storage A
#   └────► Storage B
# ```
#
# \---
#
# \## 59.3 OPC UA historical request
#
# ```text
# OPC UA Client
#   │
#   ▼
# HistoryRead
#   │
#   ▼
# OPC UA Historical Provider
#   │
#   ▼
# History Repository
#   │
#   ▼
# HistoricalSample\[]
#   │
#   ▼
# OPC UA DataValue\[]
# ```
#
# \---
#
# \# 60. Reference architecture
#
# The complete reference architecture is:
#
# ```text
#   FIELD / AQUACOM
#   │
#   ▼
#   ┌─────────────────────┐
#   │ AquaCom Transport │
#   └──────────┬──────────┘
#   │
#   ▼
#   ┌─────────────────────┐
#   │ Protocol Engine │
#   └──────────┬──────────┘
#   │
#   ▼
#   ┌─────────────────────┐
#   │ Station Manager │
#   └──────────┬──────────┘
#   │
#   ▼
#   ┌─────────────────────┐
#   │ Canonical Model │
#   └───────┬───────┬─────┘
#   │ │
#   LIVE HISTORY
#   │ │
#   ▼ ▼
#   ┌──────────────┐ ┌──────────────────┐
#   │Current-State │ │Historical │
#   │Service │ │Acquisition │
#   └──────┬───────┘ └────────┬─────────┘
#   │ │
#   │ ▼
#   │ ┌──────────────────┐
#   │ │Historical │
#   │ │Pipeline │
#   │ └────────┬─────────┘
#   │ │
#   │ ┌──────────┼───────────┐
#   │ │ │ │
#   │ ▼ ▼ ▼
#   │ Repository Sink A Sink B
#   │ │
#   │ │
#   ▼ ▼
#   ┌────────────────────────────┐
#   │ OPC UA Server │
#   │ │
#   │ Data Access │
#   │ Historical Access │
#   │ Diagnostics │
#   └──────────────┬─────────────┘
#   │
#   ▼
#   SCADA / Clients
# ```
#
# \---
#
# \# 61. Architecture decision summary
#
# The gateway is intentionally designed as an:
#
# ```text
# AquaCom Integration Gateway
# ```
#
# rather than merely an:
#
# ```text
# AquaCom OPC UA Server
# ```
#
# This allows:
#
# \- OPC UA to be replaced or supplemented;
# \- storage technology to change;
# \- multiple historians to coexist;
# \- AquaCom equipment to be gradually retired;
# \- other northbound interfaces to be added;
# \- historical acquisition to continue independently of OPC UA clients.
#
# The long-term architectural asset is therefore the normalized integration layer and historical recovery mechanism, not any single external interface.
#
# \---
#
# \# 62. Final architectural rule
#
# The most important data rule is:
#
# > Historical data is stored and exposed according to when the process value was valid, not when the gateway happened to retrieve it.
#
# The most important protocol rule is:
#
# > AquaCom behavior must be based on verified protocol knowledge and must never be invented merely to complete an implementation.
#
# The most important software rule is:
#
# > AquaCom, canonical data handling, historical persistence and OPC UA shall remain separate architectural concerns.