PACS System 0.1.0
PACS DICOM system library
Loading...
Searching...
No Matches
sync_types.h
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2021-2025, 🍀☀🌕🌥 🌊
3// See the LICENSE file in the project root for full license information.
4
18#pragma once
19
20#include <chrono>
21#include <cstddef>
22#include <cstdint>
23#include <functional>
24#include <optional>
25#include <string>
26#include <string_view>
27#include <vector>
28
29namespace kcenon::pacs::client {
30
31// =============================================================================
32// Sync Direction
33// =============================================================================
34
38enum class sync_direction {
39 pull,
40 push,
42};
43
49[[nodiscard]] constexpr const char* to_string(sync_direction direction) noexcept {
50 switch (direction) {
51 case sync_direction::pull: return "pull";
52 case sync_direction::push: return "push";
53 case sync_direction::bidirectional: return "bidirectional";
54 default: return "unknown";
55 }
56}
57
64 std::string_view str) noexcept {
65 if (str == "pull") return sync_direction::pull;
66 if (str == "push") return sync_direction::push;
67 if (str == "bidirectional") return sync_direction::bidirectional;
69}
70
71// =============================================================================
72// Conflict Type
73// =============================================================================
74
84
90[[nodiscard]] constexpr const char* to_string(sync_conflict_type type) noexcept {
91 switch (type) {
92 case sync_conflict_type::missing_local: return "missing_local";
93 case sync_conflict_type::missing_remote: return "missing_remote";
94 case sync_conflict_type::modified: return "modified";
95 case sync_conflict_type::count_mismatch: return "count_mismatch";
96 default: return "unknown";
97 }
98}
99
106 std::string_view str) noexcept {
107 if (str == "missing_local") return sync_conflict_type::missing_local;
108 if (str == "missing_remote") return sync_conflict_type::missing_remote;
109 if (str == "modified") return sync_conflict_type::modified;
110 if (str == "count_mismatch") return sync_conflict_type::count_mismatch;
112}
113
114// =============================================================================
115// Conflict Resolution
116// =============================================================================
117
126
132[[nodiscard]] constexpr const char* to_string(
133 conflict_resolution resolution) noexcept {
134 switch (resolution) {
135 case conflict_resolution::prefer_local: return "prefer_local";
136 case conflict_resolution::prefer_remote: return "prefer_remote";
137 case conflict_resolution::prefer_newer: return "prefer_newer";
138 default: return "unknown";
139 }
140}
141
148 std::string_view str) noexcept {
149 if (str == "prefer_local") return conflict_resolution::prefer_local;
150 if (str == "prefer_remote") return conflict_resolution::prefer_remote;
151 if (str == "prefer_newer") return conflict_resolution::prefer_newer;
153}
154
155// =============================================================================
156// Sync Config
157// =============================================================================
158
165 // =========================================================================
166 // Identification
167 // =========================================================================
168
169 std::string config_id;
170 std::string source_node_id;
171 std::string name;
172 bool enabled{true};
173
174 // =========================================================================
175 // Sync Scope
176 // =========================================================================
177
178 std::chrono::hours lookback{24};
179 std::vector<std::string> modalities;
180 std::vector<std::string> patient_id_patterns;
181
182 // =========================================================================
183 // Sync Behavior
184 // =========================================================================
185
187 bool delete_missing{false};
188 bool overwrite_existing{false};
189 bool sync_metadata_only{false};
190
191 // =========================================================================
192 // Schedule
193 // =========================================================================
194
195 std::string schedule_cron;
196
197 // =========================================================================
198 // Statistics
199 // =========================================================================
200
201 std::chrono::system_clock::time_point last_sync;
202 std::chrono::system_clock::time_point last_successful_sync;
203 size_t total_syncs{0};
204 size_t studies_synced{0};
205
206 // =========================================================================
207 // Database Fields
208 // =========================================================================
209
210 int64_t pk{0};
211};
212
213// =============================================================================
214// Sync Conflict
215// =============================================================================
216
221 std::string config_id;
222 std::string study_uid;
223 std::string patient_id;
224
226
227 std::chrono::system_clock::time_point local_modified;
228 std::chrono::system_clock::time_point remote_modified;
229
232
233 bool resolved{false};
235
236 std::chrono::system_clock::time_point detected_at;
237 std::optional<std::chrono::system_clock::time_point> resolved_at;
238
239 // =========================================================================
240 // Database Fields
241 // =========================================================================
242
243 int64_t pk{0};
244};
245
246// =============================================================================
247// Sync Result
248// =============================================================================
249
254 std::string config_id;
255 std::string job_id;
256 bool success{false};
257
258 // =========================================================================
259 // Counts
260 // =========================================================================
261
262 size_t studies_checked{0};
263 size_t studies_synced{0};
264 size_t studies_skipped{0};
267
268 // =========================================================================
269 // Issues
270 // =========================================================================
271
272 std::vector<sync_conflict> conflicts;
273 std::vector<std::string> errors;
274
275 // =========================================================================
276 // Timing
277 // =========================================================================
278
279 std::chrono::system_clock::time_point started_at;
280 std::chrono::system_clock::time_point completed_at;
281 std::chrono::milliseconds elapsed{0};
282};
283
284// =============================================================================
285// Sync History
286// =============================================================================
287
292 std::string config_id;
293 std::string job_id;
294 bool success{false};
295
297 size_t studies_synced{0};
299
300 std::vector<std::string> errors;
301
302 std::chrono::system_clock::time_point started_at;
303 std::chrono::system_clock::time_point completed_at;
304
305 int64_t pk{0};
306};
307
308// =============================================================================
309// Sync Manager Configuration
310// =============================================================================
311
321
322// =============================================================================
323// Sync Statistics
324// =============================================================================
325
338
339// =============================================================================
340// Callbacks
341// =============================================================================
342
350using sync_progress_callback = std::function<void(
351 const std::string& config_id,
352 size_t studies_synced,
353 size_t studies_total)>;
354
361using sync_completion_callback = std::function<void(
362 const std::string& config_id,
363 const sync_result& result)>;
364
370using sync_conflict_callback = std::function<void(const sync_conflict& conflict)>;
371
372} // namespace kcenon::pacs::client
conflict_resolution
Strategy for resolving synchronization conflicts.
Definition sync_types.h:121
@ prefer_newer
Use the newer version based on timestamp.
std::function< void( const std::string &config_id, size_t studies_synced, size_t studies_total)> sync_progress_callback
Callback for sync progress updates.
Definition sync_types.h:350
conflict_resolution conflict_resolution_from_string(std::string_view str) noexcept
Parse conflict_resolution from string.
Definition sync_types.h:147
sync_conflict_type
Type of synchronization conflict.
Definition sync_types.h:78
@ missing_remote
Study exists locally but not on remote.
@ missing_local
Study exists on remote but not locally.
@ modified
Study modified on both sides.
@ count_mismatch
Instance counts differ.
std::function< void(const sync_conflict &conflict)> sync_conflict_callback
Callback for conflict detection.
Definition sync_types.h:370
sync_direction
Direction of synchronization.
Definition sync_types.h:38
@ push
Push from local to remote.
@ pull
Pull from remote to local.
constexpr const char * to_string(job_type type) noexcept
Convert job_type to string representation.
Definition job_types.h:54
sync_conflict_type sync_conflict_type_from_string(std::string_view str) noexcept
Parse sync_conflict_type from string.
Definition sync_types.h:105
std::function< void( const std::string &config_id, const sync_result &result)> sync_completion_callback
Callback for sync completion.
Definition sync_types.h:361
sync_direction sync_direction_from_string(std::string_view str) noexcept
Parse sync_direction from string.
Definition sync_types.h:63
Configuration for a synchronization task.
Definition sync_types.h:164
std::vector< std::string > modalities
Modality filter (empty = all)
Definition sync_types.h:179
std::chrono::hours lookback
How far back to sync.
Definition sync_types.h:178
std::string name
Human-readable name.
Definition sync_types.h:171
int64_t pk
Primary key (0 if not persisted)
Definition sync_types.h:210
bool delete_missing
Delete local if not on remote.
Definition sync_types.h:187
std::string schedule_cron
Cron expression for scheduling.
Definition sync_types.h:195
sync_direction direction
Direction of sync.
Definition sync_types.h:186
bool overwrite_existing
Overwrite if different.
Definition sync_types.h:188
std::chrono::system_clock::time_point last_successful_sync
Definition sync_types.h:202
std::string source_node_id
Remote node to sync with.
Definition sync_types.h:170
bool enabled
Whether this config is active.
Definition sync_types.h:172
std::chrono::system_clock::time_point last_sync
Definition sync_types.h:201
std::string config_id
Unique configuration identifier.
Definition sync_types.h:169
std::vector< std::string > patient_id_patterns
Patient ID patterns (empty = all)
Definition sync_types.h:180
bool sync_metadata_only
Only sync metadata, not images.
Definition sync_types.h:189
Represents a conflict detected during synchronization.
Definition sync_types.h:220
std::chrono::system_clock::time_point detected_at
Definition sync_types.h:236
std::chrono::system_clock::time_point local_modified
Definition sync_types.h:227
bool resolved
Whether this conflict was resolved.
Definition sync_types.h:233
std::string study_uid
Study Instance UID.
Definition sync_types.h:222
sync_conflict_type conflict_type
Type of conflict.
Definition sync_types.h:225
std::string config_id
Config that detected this conflict.
Definition sync_types.h:221
conflict_resolution resolution_used
Resolution strategy used.
Definition sync_types.h:234
std::chrono::system_clock::time_point remote_modified
Definition sync_types.h:228
std::optional< std::chrono::system_clock::time_point > resolved_at
Definition sync_types.h:237
int64_t pk
Primary key (0 if not persisted)
Definition sync_types.h:243
std::string patient_id
Patient ID for reference.
Definition sync_types.h:223
Historical record of a sync operation.
Definition sync_types.h:291
std::vector< std::string > errors
Definition sync_types.h:300
std::chrono::system_clock::time_point started_at
Definition sync_types.h:302
std::chrono::system_clock::time_point completed_at
Definition sync_types.h:303
Configuration for the sync manager.
Definition sync_types.h:315
std::chrono::seconds comparison_timeout
Timeout for compare.
Definition sync_types.h:317
bool auto_resolve_conflicts
Auto-resolve conflicts.
Definition sync_types.h:318
size_t max_concurrent_syncs
Max parallel syncs.
Definition sync_types.h:316
Result of a synchronization operation.
Definition sync_types.h:253
std::chrono::milliseconds elapsed
Definition sync_types.h:281
bool success
Overall success.
Definition sync_types.h:256
size_t bytes_transferred
Total bytes transferred.
Definition sync_types.h:266
size_t instances_transferred
Individual instances transferred.
Definition sync_types.h:265
std::vector< std::string > errors
Error messages.
Definition sync_types.h:273
size_t studies_synced
Studies actually synced.
Definition sync_types.h:263
std::string job_id
Job ID if async.
Definition sync_types.h:255
size_t studies_skipped
Studies skipped.
Definition sync_types.h:264
std::string config_id
Configuration used.
Definition sync_types.h:254
std::vector< sync_conflict > conflicts
Conflicts detected.
Definition sync_types.h:272
size_t studies_checked
Total studies compared.
Definition sync_types.h:262
std::chrono::system_clock::time_point started_at
Definition sync_types.h:279
std::chrono::system_clock::time_point completed_at
Definition sync_types.h:280
Aggregate statistics for synchronization operations.
Definition sync_types.h:329