1use serde::{Deserialize, Serialize};
7use std::fmt;
8use uuid::Uuid;
9
10#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
23pub struct CollectiveId(pub Uuid);
24
25impl CollectiveId {
26 #[inline]
28 pub fn new() -> Self {
29 Self(Uuid::now_v7())
30 }
31
32 #[inline]
35 pub fn nil() -> Self {
36 Self(Uuid::nil())
37 }
38
39 #[inline]
41 pub fn as_bytes(&self) -> &[u8; 16] {
42 self.0.as_bytes()
43 }
44
45 #[inline]
47 pub fn from_bytes(bytes: [u8; 16]) -> Self {
48 Self(Uuid::from_bytes(bytes))
49 }
50}
51
52impl Default for CollectiveId {
53 fn default() -> Self {
57 Self::nil()
58 }
59}
60
61impl fmt::Display for CollectiveId {
62 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63 write!(f, "{}", self.0)
64 }
65}
66
67#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
72pub struct ExperienceId(pub Uuid);
73
74impl ExperienceId {
75 #[inline]
77 pub fn new() -> Self {
78 Self(Uuid::now_v7())
79 }
80
81 #[inline]
83 pub fn nil() -> Self {
84 Self(Uuid::nil())
85 }
86
87 #[inline]
89 pub fn as_bytes(&self) -> &[u8; 16] {
90 self.0.as_bytes()
91 }
92
93 #[inline]
95 pub fn from_bytes(bytes: [u8; 16]) -> Self {
96 Self(Uuid::from_bytes(bytes))
97 }
98}
99
100impl Default for ExperienceId {
101 fn default() -> Self {
105 Self::nil()
106 }
107}
108
109impl fmt::Display for ExperienceId {
110 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
111 write!(f, "{}", self.0)
112 }
113}
114
115#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
120pub struct Timestamp(pub i64);
121
122impl Timestamp {
123 #[inline]
128 pub fn now() -> Self {
129 use std::time::{SystemTime, UNIX_EPOCH};
130 let duration = SystemTime::now()
131 .duration_since(UNIX_EPOCH)
132 .unwrap_or_default();
133 Self(duration.as_millis() as i64)
134 }
135
136 #[inline]
138 pub const fn from_millis(millis: i64) -> Self {
139 Self(millis)
140 }
141
142 #[inline]
144 pub const fn as_millis(&self) -> i64 {
145 self.0
146 }
147
148 #[inline]
150 pub fn to_be_bytes(&self) -> [u8; 8] {
151 self.0.to_be_bytes()
152 }
153}
154
155impl fmt::Display for Timestamp {
156 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
157 write!(f, "{}", self.0)
158 }
159}
160
161#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
166pub struct RelationId(pub Uuid);
167
168impl RelationId {
169 #[inline]
171 pub fn new() -> Self {
172 Self(Uuid::now_v7())
173 }
174
175 #[inline]
177 pub fn nil() -> Self {
178 Self(Uuid::nil())
179 }
180
181 #[inline]
183 pub fn as_bytes(&self) -> &[u8; 16] {
184 self.0.as_bytes()
185 }
186
187 #[inline]
189 pub fn from_bytes(bytes: [u8; 16]) -> Self {
190 Self(Uuid::from_bytes(bytes))
191 }
192}
193
194impl Default for RelationId {
195 fn default() -> Self {
199 Self::nil()
200 }
201}
202
203impl fmt::Display for RelationId {
204 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
205 write!(f, "{}", self.0)
206 }
207}
208
209#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
222pub struct InsightId(pub Uuid);
223
224impl InsightId {
225 #[inline]
227 pub fn new() -> Self {
228 Self(Uuid::now_v7())
229 }
230
231 #[inline]
233 pub fn nil() -> Self {
234 Self(Uuid::nil())
235 }
236
237 #[inline]
239 pub fn as_bytes(&self) -> &[u8; 16] {
240 self.0.as_bytes()
241 }
242
243 #[inline]
245 pub fn from_bytes(bytes: [u8; 16]) -> Self {
246 Self(Uuid::from_bytes(bytes))
247 }
248}
249
250impl Default for InsightId {
251 fn default() -> Self {
255 Self::nil()
256 }
257}
258
259impl fmt::Display for InsightId {
260 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
261 write!(f, "{}", self.0)
262 }
263}
264
265#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
270pub struct UserId(pub String);
271
272impl UserId {
273 pub fn new(id: impl Into<String>) -> Self {
275 Self(id.into())
276 }
277
278 pub fn as_str(&self) -> &str {
280 &self.0
281 }
282}
283
284impl fmt::Display for UserId {
285 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
286 write!(f, "{}", self.0)
287 }
288}
289
290#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
295pub struct AgentId(pub String);
296
297impl AgentId {
298 pub fn new(id: impl Into<String>) -> Self {
300 Self(id.into())
301 }
302
303 pub fn as_str(&self) -> &str {
305 &self.0
306 }
307}
308
309impl fmt::Display for AgentId {
310 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
311 write!(f, "{}", self.0)
312 }
313}
314
315#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
320pub struct TaskId(pub String);
321
322impl TaskId {
323 pub fn new(id: impl Into<String>) -> Self {
325 Self(id.into())
326 }
327
328 pub fn as_str(&self) -> &str {
330 &self.0
331 }
332}
333
334impl fmt::Display for TaskId {
335 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
336 write!(f, "{}", self.0)
337 }
338}
339
340pub type Embedding = Vec<f32>;
344
345#[cfg(test)]
346mod tests {
347 use super::*;
348
349 #[test]
350 fn test_collective_id_new_is_unique() {
351 let id1 = CollectiveId::new();
352 let id2 = CollectiveId::new();
353 assert_ne!(id1, id2);
354 }
355
356 #[test]
357 fn test_collective_id_nil() {
358 let id = CollectiveId::nil();
359 assert_eq!(id.0, Uuid::nil());
360 }
361
362 #[test]
363 fn test_collective_id_bytes_roundtrip() {
364 let id = CollectiveId::new();
365 let bytes = *id.as_bytes();
366 let restored = CollectiveId::from_bytes(bytes);
367 assert_eq!(id, restored);
368 }
369
370 #[test]
371 fn test_collective_id_serialization() {
372 let id = CollectiveId::new();
373 let bytes = bincode::serialize(&id).unwrap();
374 let restored: CollectiveId = bincode::deserialize(&bytes).unwrap();
375 assert_eq!(id, restored);
376 }
377
378 #[test]
379 fn test_experience_id_new_is_unique() {
380 let id1 = ExperienceId::new();
381 let id2 = ExperienceId::new();
382 assert_ne!(id1, id2);
383 }
384
385 #[test]
386 fn test_experience_id_serialization() {
387 let id = ExperienceId::new();
388 let bytes = bincode::serialize(&id).unwrap();
389 let restored: ExperienceId = bincode::deserialize(&bytes).unwrap();
390 assert_eq!(id, restored);
391 }
392
393 #[test]
394 fn test_relation_id_new_is_unique() {
395 let id1 = RelationId::new();
396 let id2 = RelationId::new();
397 assert_ne!(id1, id2);
398 }
399
400 #[test]
401 fn test_relation_id_nil() {
402 let id = RelationId::nil();
403 assert_eq!(id.0, Uuid::nil());
404 }
405
406 #[test]
407 fn test_relation_id_bytes_roundtrip() {
408 let id = RelationId::new();
409 let bytes = *id.as_bytes();
410 let restored = RelationId::from_bytes(bytes);
411 assert_eq!(id, restored);
412 }
413
414 #[test]
415 fn test_relation_id_serialization() {
416 let id = RelationId::new();
417 let bytes = bincode::serialize(&id).unwrap();
418 let restored: RelationId = bincode::deserialize(&bytes).unwrap();
419 assert_eq!(id, restored);
420 }
421
422 #[test]
423 fn test_insight_id_new_is_unique() {
424 let id1 = InsightId::new();
425 let id2 = InsightId::new();
426 assert_ne!(id1, id2);
427 }
428
429 #[test]
430 fn test_insight_id_nil() {
431 let id = InsightId::nil();
432 assert_eq!(id.0, Uuid::nil());
433 }
434
435 #[test]
436 fn test_insight_id_bytes_roundtrip() {
437 let id = InsightId::new();
438 let bytes = *id.as_bytes();
439 let restored = InsightId::from_bytes(bytes);
440 assert_eq!(id, restored);
441 }
442
443 #[test]
444 fn test_insight_id_serialization() {
445 let id = InsightId::new();
446 let bytes = bincode::serialize(&id).unwrap();
447 let restored: InsightId = bincode::deserialize(&bytes).unwrap();
448 assert_eq!(id, restored);
449 }
450
451 #[test]
452 fn test_timestamp_now() {
453 let t1 = Timestamp::now();
454 std::thread::sleep(std::time::Duration::from_millis(1));
455 let t2 = Timestamp::now();
456 assert!(t1 < t2, "Timestamps should be ordered");
457 }
458
459 #[test]
460 fn test_timestamp_ordering() {
461 let t1 = Timestamp::from_millis(1000);
462 let t2 = Timestamp::from_millis(2000);
463 assert!(t1 < t2);
464 }
465
466 #[test]
467 fn test_timestamp_be_bytes() {
468 let t1 = Timestamp::from_millis(100);
470 let t2 = Timestamp::from_millis(200);
471 assert!(t1.to_be_bytes() < t2.to_be_bytes());
472 }
473
474 #[test]
475 fn test_user_id() {
476 let id = UserId::new("user-123");
477 assert_eq!(id.as_str(), "user-123");
478 assert_eq!(format!("{}", id), "user-123");
479 }
480
481 #[test]
482 fn test_agent_id() {
483 let id = AgentId::new("claude-opus");
484 assert_eq!(id.as_str(), "claude-opus");
485 }
486
487 #[test]
488 fn test_task_id() {
489 let id = TaskId::new("task-456");
490 assert_eq!(id.as_str(), "task-456");
491 }
492}