Core Data Types
Purpose¶
Core .NET library providing the Virtufin data model: Entity-Attribute-Value framework, Variant discriminated union, FlatBuffers serialization, and reactive observables for NATS, WebSocket, and Valkey data sources.
Requirements¶
Requirement: Entity-Attribute-Value Model¶
The library SHALL provide a registry-based EAV framework where entities own named attributes whose values are provided by pluggable value providers.
Scenario: Entity lifecycle¶
- WHEN an entity is created with a unique identifier
- THEN it SHALL be registerable in a global registry and support adding attributes of any type
Scenario: Value observation¶
- WHEN an attribute value changes
- THEN value providers SHALL notify subscribers reactively
Requirement: Variant Discriminated Union¶
The library SHALL provide a sealed Variant type representing a value that is exactly one of: None, Bool, Byte, Int16, Int32, Int64, Float, Double, String, a typed array of any of the preceding primitive kinds, a nested array of Variant (ArrayVariant), or Dictionary. It SHALL support FlatBuffers serialization and implicit conversions from C# primitives.
Scenario: Type-safe construction¶
- WHEN a Variant is constructed from a C# primitive (int, string, bool, etc.)
- THEN the type SHALL be determined at construction and retrievable via pattern matching
Scenario: FlatBuffers serialization¶
- WHEN a Variant is serialized to FlatBuffers binary
- THEN it SHALL deserialize to an equivalent Variant with the same value and type
Scenario: Implicit conversions¶
- WHEN a Variant is used where a
stringorintis expected - THEN the implicit conversion SHALL succeed if the underlying type matches, or throw if it does not
Requirement: Reactive Observables¶
The library SHALL provide IObservable<T> implementations for NATS, WebSocket, and Valkey data sources. Observables SHALL auto-reconnect on connection loss.
Scenario: NATS subscription¶
- WHEN a NATS observable is subscribed to with a subject pattern
- THEN each message published on matching subjects SHALL be delivered to all subscribers
Scenario: Connection lifecycle¶
- WHEN the underlying connection to a data source is lost
- THEN the observable SHALL reconnect automatically and resume message delivery
Requirement: Financial Domain Types¶
The library SHALL provide financial domain primitives including Currency (the full ISO 4217 currency code set, not limited to any subset) and Cash. Operations on mismatched currencies SHALL be rejected.
Note (2026-07-26):
Cashcurrently has no arithmetic operators at all (+,-, equality) — the mismatch-rejection behavior described by "Operations on mismatched currencies SHALL be rejected" has no implementation yet to test against. This requirement describes the intended contract, not current behavior.
Scenario: Cash arithmetic¶
- WHEN two Cash values with the same currency are added
- THEN the result SHALL be a Cash with the summed amount and same currency
Scenario: Currency mismatch¶
- WHEN two Cash values with different currencies are combined
- THEN the operation SHALL reject with a clear error
Requirement: FlatBuffers Wire Format¶
The library SHALL define a FlatBuffers schema for the Variant type and generate serialization code at build time. All language SDKs SHOULD use this schema for cross-language data interchange.
Scenario: Cross-language compatibility¶
- WHEN a Variant is serialized by a C# producer
- THEN a Python or TypeScript consumer using the same FlatBuffers schema SHALL be able to deserialize it correctly
Scenario: Build-time code generation¶
- WHEN the project is built
- THEN the FlatBuffers compiler (
flatc) SHALL generate C# serialization code before compilation begins