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}