nodedb_types/sync/wire/spatial.rs
1// SPDX-License-Identifier: Apache-2.0
2
3//! Spatial insert/delete sync messages (client → server / server → client).
4//!
5//! `SpatialInsertMsg` carries one geometry entry from a Lite client to
6//! Origin for R-tree indexing. `SpatialDeleteMsg` removes a document's
7//! geometry from Origin's R-tree.
8//!
9//! Wire opcodes:
10//! - `0xAA` — `SpatialInsert` (Lite → Origin)
11//! - `0xAB` — `SpatialInsertAck` (Origin → Lite)
12//! - `0xAC` — `SpatialDelete` (Lite → Origin)
13//! - `0xAD` — `SpatialDeleteAck` (Origin → Lite)
14
15use serde::{Deserialize, Serialize};
16
17use crate::sync::wire::ack_status::AckStatus;
18
19/// Spatial insert request (Lite → Origin, 0xAA).
20///
21/// Requests that Origin index the geometry for `(collection, field, doc_id)` in
22/// its per-field R-tree. Origin assigns a surrogate for `doc_id`, computes the
23/// bounding box from the geometry, and inserts the entry into
24/// `CoreLoop::spatial_indexes`.
25///
26/// `geometry_bytes` is a MessagePack-serialised `nodedb_types::geometry::Geometry`
27/// value produced via `zerompk::to_msgpack_vec(&geometry)`.
28#[derive(
29 Debug, Clone, Serialize, Deserialize, zerompk::ToMessagePack, zerompk::FromMessagePack,
30)]
31pub struct SpatialInsertMsg {
32 /// Lite instance ID (for routing and dedup).
33 pub lite_id: String,
34 /// Target collection name.
35 pub collection: String,
36 /// Geometry field name within the collection.
37 pub field: String,
38 /// External document identifier.
39 pub doc_id: String,
40 /// MessagePack-serialised `Geometry` value.
41 pub geometry_bytes: Vec<u8>,
42 /// Monotonic batch ID (Lite-assigned, per-operation). Used for ACK correlation.
43 pub batch_id: u64,
44 /// Stable identity of the originating producer. 0 for legacy clients.
45 #[serde(default)]
46 pub producer_id: u64,
47 /// Monotonic epoch counter incremented on every producer restart.
48 #[serde(default)]
49 pub epoch: u64,
50 /// Per-stream monotonic sequence number within the epoch.
51 #[serde(default)]
52 pub seq: u64,
53}
54
55/// Spatial insert acknowledgment (Origin → Lite, 0xAB).
56#[derive(
57 Debug, Clone, Serialize, Deserialize, zerompk::ToMessagePack, zerompk::FromMessagePack,
58)]
59pub struct SpatialInsertAckMsg {
60 /// Collection acknowledged.
61 pub collection: String,
62 /// Field acknowledged.
63 pub field: String,
64 /// Document ID from the originating `SpatialInsertMsg`.
65 pub doc_id: String,
66 /// Batch ID from the originating `SpatialInsertMsg`.
67 pub batch_id: u64,
68 /// `true` if the geometry was successfully indexed on Origin.
69 pub accepted: bool,
70 /// Rejection detail when `accepted == false`.
71 #[serde(default)]
72 pub reject_reason: Option<String>,
73 /// Highest sequence number from this producer that has been durably applied.
74 #[serde(default)]
75 pub applied_seq: u64,
76 /// Idempotency outcome of the acknowledged message.
77 #[serde(default)]
78 pub status: AckStatus,
79}
80
81/// Spatial delete request (Lite → Origin, 0xAC).
82///
83/// Removes the document identified by `doc_id` from Origin's R-tree index
84/// for the given `(collection, field)`.
85#[derive(
86 Debug, Clone, Serialize, Deserialize, zerompk::ToMessagePack, zerompk::FromMessagePack,
87)]
88pub struct SpatialDeleteMsg {
89 /// Lite instance ID.
90 pub lite_id: String,
91 /// Target collection name.
92 pub collection: String,
93 /// Geometry field name within the collection.
94 pub field: String,
95 /// External document identifier to remove.
96 pub doc_id: String,
97 /// Monotonic batch ID for ACK correlation.
98 pub batch_id: u64,
99 /// Stable identity of the originating producer. 0 for legacy clients.
100 #[serde(default)]
101 pub producer_id: u64,
102 /// Monotonic epoch counter incremented on every producer restart.
103 #[serde(default)]
104 pub epoch: u64,
105 /// Per-stream monotonic sequence number within the epoch.
106 #[serde(default)]
107 pub seq: u64,
108}
109
110/// Spatial delete acknowledgment (Origin → Lite, 0xAD).
111#[derive(
112 Debug, Clone, Serialize, Deserialize, zerompk::ToMessagePack, zerompk::FromMessagePack,
113)]
114pub struct SpatialDeleteAckMsg {
115 /// Collection acknowledged.
116 pub collection: String,
117 /// Field acknowledged.
118 pub field: String,
119 /// Document ID from the originating `SpatialDeleteMsg`.
120 pub doc_id: String,
121 /// Batch ID from the originating `SpatialDeleteMsg`.
122 pub batch_id: u64,
123 /// `true` if the document was successfully removed from Origin's R-tree.
124 pub accepted: bool,
125 /// Rejection detail when `accepted == false`.
126 #[serde(default)]
127 pub reject_reason: Option<String>,
128 /// Highest sequence number from this producer that has been durably applied.
129 #[serde(default)]
130 pub applied_seq: u64,
131 /// Idempotency outcome of the acknowledged message.
132 #[serde(default)]
133 pub status: AckStatus,
134}