Skip to main content

kmp_domain/value_objects/
node_card.rs

1use crate::NodeCardStamp;
2
3/// A reader-authored compact view of one node body, in one language.
4///
5/// A card is derived, never canonical. It names the exact body version it was
6/// written from — revision and content hash — so a later reader can tell
7/// whether it still describes what the store holds, without trusting the
8/// prose. Nothing here participates in ranking, path selection or proof;
9/// rebuilding its presentation projection restores every recorded card version.
10/// Authored card events preserve the prose; the canonical body cannot regenerate it.
11///
12/// `card_revision` is the card's own compare-and-set token, separate from the
13/// node's revision. Rewriting a card never advances the node.
14#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
15pub struct NodeCard {
16    pub node_id: String,
17    /// Language tag the card is written in. Part of the identity: a Spanish
18    /// and an English card for one node coexist and neither shadows the other.
19    pub language: String,
20    pub text: String,
21    /// Revision of the node body this card was authored from.
22    pub source_revision: u64,
23    /// The public token of that body version, kept for provenance. It is not
24    /// what validity is decided on: it is derived from the event and the node
25    /// identity, so a write can change the text without changing it.
26    pub source_content_hash: String,
27    /// Digest over the exact stored record of that body version. This is the
28    /// identity a card is bound to, and the one a reuse check compares.
29    pub source_record_digest: String,
30    /// Canonical UTF-8 bytes of the body this card stood in for, recorded at
31    /// authorship so a reader can see what the card saves without loading it.
32    pub source_body_bytes: u64,
33    /// Writer name recorded at authorship.
34    pub authored_by: String,
35    /// RFC3339 instant stamped by the kernel, not by the caller. A historical
36    /// read compares against this so a card cannot appear before it existed.
37    pub authored_at: String,
38    pub card_revision: u64,
39}
40
41impl NodeCard {
42    /// Everything a read may disclose about this card when it may not show
43    /// the prose.
44    pub fn stamp(&self) -> NodeCardStamp {
45        NodeCardStamp {
46            source_revision: self.source_revision,
47            source_content_hash: self.source_content_hash.clone(),
48            source_record_digest: self.source_record_digest.clone(),
49            source_body_bytes: self.source_body_bytes,
50            card_revision: self.card_revision,
51            authored_by: self.authored_by.clone(),
52            authored_at: self.authored_at.clone(),
53            text_bytes: self.text.len() as u64,
54        }
55    }
56}