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/// deleting every card changes no answer except the cards themselves.
10///
11/// `card_revision` is the card's own compare-and-set token, separate from the
12/// node's revision. Rewriting a card never advances the node.
13#[derive(Debug, Clone, PartialEq, Eq)]
14pub struct NodeCard {
15 pub node_id: String,
16 /// Language tag the card is written in. Part of the identity: a Spanish
17 /// and an English card for one node coexist and neither shadows the other.
18 pub language: String,
19 pub text: String,
20 /// Revision of the node body this card was authored from.
21 pub source_revision: u64,
22 /// The public token of that body version, kept for provenance. It is not
23 /// what validity is decided on: it is derived from the event and the node
24 /// identity, so a write can change the text without changing it.
25 pub source_content_hash: String,
26 /// Digest over the exact stored record of that body version. This is the
27 /// identity a card is bound to, and the one a reuse check compares.
28 pub source_record_digest: String,
29 /// Canonical UTF-8 bytes of the body this card stood in for, recorded at
30 /// authorship so a reader can see what the card saves without loading it.
31 pub source_body_bytes: u64,
32 /// Writer name recorded at authorship.
33 pub authored_by: String,
34 /// RFC3339 instant stamped by the kernel, not by the caller. A historical
35 /// read compares against this so a card cannot appear before it existed.
36 pub authored_at: String,
37 pub card_revision: u64,
38}
39
40impl NodeCard {
41 /// Everything a read may disclose about this card when it may not show
42 /// the prose.
43 pub fn stamp(&self) -> NodeCardStamp {
44 NodeCardStamp {
45 source_revision: self.source_revision,
46 source_content_hash: self.source_content_hash.clone(),
47 source_record_digest: self.source_record_digest.clone(),
48 source_body_bytes: self.source_body_bytes,
49 card_revision: self.card_revision,
50 authored_by: self.authored_by.clone(),
51 authored_at: self.authored_at.clone(),
52 text_bytes: self.text.len() as u64,
53 }
54 }
55}