diff --git a/ZB.MOM.WW.LocalDb/src/ZB.MOM.WW.LocalDb.Contracts/Protos/localdb_sync.proto b/ZB.MOM.WW.LocalDb/src/ZB.MOM.WW.LocalDb.Contracts/Protos/localdb_sync.proto index 562e030..72b9465 100644 --- a/ZB.MOM.WW.LocalDb/src/ZB.MOM.WW.LocalDb.Contracts/Protos/localdb_sync.proto +++ b/ZB.MOM.WW.LocalDb/src/ZB.MOM.WW.LocalDb.Contracts/Protos/localdb_sync.proto @@ -1,9 +1,52 @@ syntax = "proto3"; - package localdb_sync.v1; - option csharp_namespace = "ZB.MOM.WW.LocalDb.Contracts"; -// Placeholder service. The real replication contract is defined in a later task. +// One long-lived bidirectional stream carries BOTH directions of replication. service LocalDbSync { + rpc Sync (stream SyncMessage) returns (stream SyncMessage); } + +message SyncMessage { + oneof msg { + Handshake handshake = 1; // first message each direction + HandshakeAck handshake_ack = 2; + DeltaBatch delta_batch = 3; + DeltaAck delta_ack = 4; + SnapshotBegin snapshot_begin = 5; // sender switches to snapshot mode + SnapshotBatch snapshot_batch = 6; + SnapshotComplete snapshot_complete = 7; + } +} + +message Handshake { + string node_id = 1; + uint32 lib_schema_version = 2; + repeated TableDigest tables = 3; // fail-closed on any mismatch + int64 last_applied_remote_seq = 4; // highest of YOUR oplog seqs I have applied +} +message TableDigest { string table_name = 1; string digest = 2; } +message HandshakeAck { string node_id = 1; bool snapshot_required = 2; } + +message OplogEntry { + int64 seq = 1; + string table_name = 2; + string pk_json = 3; + optional string row_json = 4; // absent => tombstone + int64 hlc = 5; // UTC-based HLC (physical ms << 16 | counter) + string node_id = 6; + bool is_tombstone = 7; +} +message DeltaBatch { repeated OplogEntry entries = 1; } +message DeltaAck { int64 applied_thru_seq = 1; } + +message SnapshotBegin { int64 as_of_seq = 1; } +message SnapshotBatch { string table_name = 1; repeated SnapshotRow rows = 2; } +message SnapshotRow { + string pk_json = 1; + optional string row_json = 2; + int64 hlc = 3; + string node_id = 4; + bool is_tombstone = 5; +} +message SnapshotComplete { int64 as_of_seq = 1; }