nodedb_types/sync/wire/fts.rs
1// SPDX-License-Identifier: Apache-2.0
2
3//! FTS index/delete sync messages (client → server / server → client).
4//!
5//! `FtsIndexMsg` carries one document's string fields from a Lite client to
6//! Origin for full-text indexing. `FtsDeleteMsg` removes a document from
7//! Origin's inverted index.
8//!
9//! Wire opcodes:
10//! - `0xA6` — `FtsIndex` (Lite → Origin)
11//! - `0xA7` — `FtsIndexAck` (Origin → Lite)
12//! - `0xA8` — `FtsDelete` (Lite → Origin)
13//! - `0xA9` — `FtsDeleteAck` (Origin → Lite)
14
15use serde::{Deserialize, Serialize};
16
17use crate::sync::wire::ack_status::AckStatus;
18
19/// FTS index request (Lite → Origin, 0xA6).
20///
21/// Requests that Origin index a document's top-level string fields into its
22/// inverted BM25 indexes: the whole-document index and one index per field.
23/// Origin allocates a surrogate for `(collection, doc_id)` and calls
24/// `InvertedIndex::index_document` on the Data Plane. Empty `fields` remove
25/// the document from every index.
26#[derive(
27 Debug, Clone, Serialize, Deserialize, zerompk::ToMessagePack, zerompk::FromMessagePack,
28)]
29pub struct FtsIndexMsg {
30 /// Lite instance ID (for routing and dedup).
31 pub lite_id: String,
32 /// Target collection name.
33 pub collection: String,
34 /// External document identifier.
35 pub doc_id: String,
36 /// `(field, text)` per top-level string field of the document.
37 pub fields: Vec<(String, String)>,
38 /// Monotonic batch ID (Lite-assigned, per-document). Used for ACK correlation.
39 pub batch_id: u64,
40 /// Stable identity of the originating producer. 0 for legacy clients.
41 #[serde(default)]
42 pub producer_id: u64,
43 /// Monotonic epoch counter incremented on every producer restart.
44 #[serde(default)]
45 pub epoch: u64,
46 /// Per-stream monotonic sequence number within the epoch.
47 #[serde(default)]
48 pub seq: u64,
49}
50
51/// FTS index acknowledgment (Origin → Lite, 0xA7).
52#[derive(
53 Debug, Clone, Serialize, Deserialize, zerompk::ToMessagePack, zerompk::FromMessagePack,
54)]
55pub struct FtsIndexAckMsg {
56 /// Collection acknowledged.
57 pub collection: String,
58 /// Document ID from the originating `FtsIndexMsg`.
59 pub doc_id: String,
60 /// Batch ID from the originating `FtsIndexMsg`.
61 pub batch_id: u64,
62 /// `true` if the document was successfully indexed on Origin.
63 pub accepted: bool,
64 /// Rejection detail when `accepted == false`.
65 #[serde(default)]
66 pub reject_reason: Option<String>,
67 /// Highest sequence number from this producer that has been durably applied.
68 #[serde(default)]
69 pub applied_seq: u64,
70 /// Idempotency outcome of the acknowledged message.
71 #[serde(default)]
72 pub status: AckStatus,
73}
74
75/// FTS delete request (Lite → Origin, 0xA8).
76///
77/// Removes the document identified by `doc_id` from Origin's inverted index.
78#[derive(
79 Debug, Clone, Serialize, Deserialize, zerompk::ToMessagePack, zerompk::FromMessagePack,
80)]
81pub struct FtsDeleteMsg {
82 /// Lite instance ID.
83 pub lite_id: String,
84 /// Target collection name.
85 pub collection: String,
86 /// External document identifier to remove.
87 pub doc_id: String,
88 /// Monotonic batch ID for ACK correlation.
89 pub batch_id: u64,
90 /// Stable identity of the originating producer. 0 for legacy clients.
91 #[serde(default)]
92 pub producer_id: u64,
93 /// Monotonic epoch counter incremented on every producer restart.
94 #[serde(default)]
95 pub epoch: u64,
96 /// Per-stream monotonic sequence number within the epoch.
97 #[serde(default)]
98 pub seq: u64,
99}
100
101/// FTS delete acknowledgment (Origin → Lite, 0xA9).
102#[derive(
103 Debug, Clone, Serialize, Deserialize, zerompk::ToMessagePack, zerompk::FromMessagePack,
104)]
105pub struct FtsDeleteAckMsg {
106 /// Collection acknowledged.
107 pub collection: String,
108 /// Document ID from the originating `FtsDeleteMsg`.
109 pub doc_id: String,
110 /// Batch ID from the originating `FtsDeleteMsg`.
111 pub batch_id: u64,
112 /// `true` if the document was successfully removed from Origin's index.
113 pub accepted: bool,
114 /// Rejection detail when `accepted == false`.
115 #[serde(default)]
116 pub reject_reason: Option<String>,
117 /// Highest sequence number from this producer that has been durably applied.
118 #[serde(default)]
119 pub applied_seq: u64,
120 /// Idempotency outcome of the acknowledged message.
121 #[serde(default)]
122 pub status: AckStatus,
123}