1use serde::{Deserialize, Serialize};
2use std::fmt;
3use std::str::FromStr;
4use tap_msg::utils::NameHashable;
5
6#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
7#[serde(rename_all = "snake_case")]
8pub enum TransactionType {
9 Transfer,
10 Payment,
11}
12
13impl fmt::Display for TransactionType {
14 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
15 match self {
16 TransactionType::Transfer => write!(f, "transfer"),
17 TransactionType::Payment => write!(f, "payment"),
18 }
19 }
20}
21
22impl TryFrom<&str> for TransactionType {
23 type Error = String;
24
25 fn try_from(value: &str) -> Result<Self, Self::Error> {
26 match value {
27 "transfer" => Ok(TransactionType::Transfer),
28 "payment" => Ok(TransactionType::Payment),
29 _ => Err(format!("Invalid transaction type: {}", value)),
30 }
31 }
32}
33
34#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
35#[serde(rename_all = "snake_case")]
36pub enum TransactionStatus {
37 Pending,
38 Confirmed,
39 Failed,
40 Cancelled,
41 Reverted,
42}
43
44impl fmt::Display for TransactionStatus {
45 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46 match self {
47 TransactionStatus::Pending => write!(f, "pending"),
48 TransactionStatus::Confirmed => write!(f, "confirmed"),
49 TransactionStatus::Failed => write!(f, "failed"),
50 TransactionStatus::Cancelled => write!(f, "cancelled"),
51 TransactionStatus::Reverted => write!(f, "reverted"),
52 }
53 }
54}
55
56impl TryFrom<&str> for TransactionStatus {
57 type Error = String;
58
59 fn try_from(value: &str) -> Result<Self, Self::Error> {
60 match value {
61 "pending" => Ok(TransactionStatus::Pending),
62 "confirmed" => Ok(TransactionStatus::Confirmed),
63 "failed" => Ok(TransactionStatus::Failed),
64 "cancelled" => Ok(TransactionStatus::Cancelled),
65 "reverted" => Ok(TransactionStatus::Reverted),
66 _ => Err(format!("Invalid transaction status: {}", value)),
67 }
68 }
69}
70
71#[derive(Debug, Clone, Serialize, Deserialize)]
72pub struct Transaction {
73 pub id: i64,
74 pub transaction_type: TransactionType,
75 pub reference_id: String,
76 pub from_did: Option<String>,
77 pub to_did: Option<String>,
78 pub thread_id: Option<String>,
79 pub message_type: String,
80 pub status: TransactionStatus,
81 pub message_json: serde_json::Value,
82 pub created_at: String,
83 pub updated_at: String,
84}
85
86#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
87#[serde(rename_all = "snake_case")]
88pub enum MessageDirection {
89 Incoming,
90 Outgoing,
91}
92
93impl fmt::Display for MessageDirection {
94 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
95 match self {
96 MessageDirection::Incoming => write!(f, "incoming"),
97 MessageDirection::Outgoing => write!(f, "outgoing"),
98 }
99 }
100}
101
102impl TryFrom<&str> for MessageDirection {
103 type Error = String;
104
105 fn try_from(value: &str) -> Result<Self, Self::Error> {
106 match value {
107 "incoming" => Ok(MessageDirection::Incoming),
108 "outgoing" => Ok(MessageDirection::Outgoing),
109 _ => Err(format!("Invalid message direction: {}", value)),
110 }
111 }
112}
113
114#[derive(Debug, Clone, Serialize, Deserialize)]
115pub struct Message {
116 pub id: i64,
117 pub message_id: String,
118 pub message_type: String,
119 pub from_did: Option<String>,
120 pub to_did: Option<String>,
121 pub thread_id: Option<String>,
122 pub parent_thread_id: Option<String>,
123 pub direction: MessageDirection,
124 pub message_json: serde_json::Value,
125 pub created_at: String,
126}
127
128#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
129#[serde(rename_all = "snake_case")]
130pub enum DeliveryStatus {
131 Pending,
132 Success,
133 Failed,
134}
135
136impl fmt::Display for DeliveryStatus {
137 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
138 match self {
139 DeliveryStatus::Pending => write!(f, "pending"),
140 DeliveryStatus::Success => write!(f, "success"),
141 DeliveryStatus::Failed => write!(f, "failed"),
142 }
143 }
144}
145
146impl TryFrom<&str> for DeliveryStatus {
147 type Error = String;
148
149 fn try_from(value: &str) -> Result<Self, Self::Error> {
150 match value {
151 "pending" => Ok(DeliveryStatus::Pending),
152 "success" => Ok(DeliveryStatus::Success),
153 "failed" => Ok(DeliveryStatus::Failed),
154 _ => Err(format!("Invalid delivery status: {}", value)),
155 }
156 }
157}
158
159impl FromStr for DeliveryStatus {
160 type Err = String;
161
162 fn from_str(s: &str) -> Result<Self, Self::Err> {
163 Self::try_from(s)
164 }
165}
166
167#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
168#[serde(rename_all = "snake_case")]
169pub enum DeliveryType {
170 Https,
172 Internal,
174 ReturnPath,
176 Pickup,
178}
179
180impl fmt::Display for DeliveryType {
181 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
182 match self {
183 DeliveryType::Https => write!(f, "https"),
184 DeliveryType::Internal => write!(f, "internal"),
185 DeliveryType::ReturnPath => write!(f, "return_path"),
186 DeliveryType::Pickup => write!(f, "pickup"),
187 }
188 }
189}
190
191impl TryFrom<&str> for DeliveryType {
192 type Error = String;
193
194 fn try_from(value: &str) -> Result<Self, Self::Error> {
195 match value {
196 "https" => Ok(DeliveryType::Https),
197 "internal" => Ok(DeliveryType::Internal),
198 "return_path" => Ok(DeliveryType::ReturnPath),
199 "pickup" => Ok(DeliveryType::Pickup),
200 _ => Err(format!("Invalid delivery type: {}", value)),
201 }
202 }
203}
204
205impl FromStr for DeliveryType {
206 type Err = String;
207
208 fn from_str(s: &str) -> Result<Self, Self::Err> {
209 Self::try_from(s)
210 }
211}
212
213#[derive(Debug, Clone, Serialize, Deserialize)]
214pub struct Delivery {
215 pub id: i64,
216 pub message_id: String,
217 pub message_text: String,
218 pub recipient_did: String,
219 pub delivery_url: Option<String>,
220 pub delivery_type: DeliveryType,
221 pub status: DeliveryStatus,
222 pub retry_count: i32,
223 pub last_http_status_code: Option<i32>,
224 pub error_message: Option<String>,
225 pub created_at: String,
226 pub updated_at: String,
227 pub delivered_at: Option<String>,
228}
229
230#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
231#[serde(rename_all = "snake_case")]
232pub enum SourceType {
233 Https,
235 Internal,
237 WebSocket,
239 ReturnPath,
241 Pickup,
243}
244
245impl fmt::Display for SourceType {
246 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
247 match self {
248 SourceType::Https => write!(f, "https"),
249 SourceType::Internal => write!(f, "internal"),
250 SourceType::WebSocket => write!(f, "websocket"),
251 SourceType::ReturnPath => write!(f, "return_path"),
252 SourceType::Pickup => write!(f, "pickup"),
253 }
254 }
255}
256
257impl TryFrom<&str> for SourceType {
258 type Error = String;
259
260 fn try_from(value: &str) -> Result<Self, Self::Error> {
261 match value {
262 "https" => Ok(SourceType::Https),
263 "internal" => Ok(SourceType::Internal),
264 "websocket" => Ok(SourceType::WebSocket),
265 "return_path" => Ok(SourceType::ReturnPath),
266 "pickup" => Ok(SourceType::Pickup),
267 _ => Err(format!("Invalid source type: {}", value)),
268 }
269 }
270}
271
272impl FromStr for SourceType {
273 type Err = String;
274
275 fn from_str(s: &str) -> Result<Self, Self::Err> {
276 Self::try_from(s)
277 }
278}
279
280#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
281#[serde(rename_all = "snake_case")]
282pub enum ReceivedStatus {
283 Pending,
284 Processed,
285 Failed,
286}
287
288impl fmt::Display for ReceivedStatus {
289 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
290 match self {
291 ReceivedStatus::Pending => write!(f, "pending"),
292 ReceivedStatus::Processed => write!(f, "processed"),
293 ReceivedStatus::Failed => write!(f, "failed"),
294 }
295 }
296}
297
298impl TryFrom<&str> for ReceivedStatus {
299 type Error = String;
300
301 fn try_from(value: &str) -> Result<Self, Self::Error> {
302 match value {
303 "pending" => Ok(ReceivedStatus::Pending),
304 "processed" => Ok(ReceivedStatus::Processed),
305 "failed" => Ok(ReceivedStatus::Failed),
306 _ => Err(format!("Invalid received status: {}", value)),
307 }
308 }
309}
310
311impl FromStr for ReceivedStatus {
312 type Err = String;
313
314 fn from_str(s: &str) -> Result<Self, Self::Err> {
315 Self::try_from(s)
316 }
317}
318
319#[derive(Debug, Clone, Serialize, Deserialize)]
320pub struct Received {
321 pub id: i64,
322 pub message_id: Option<String>,
323 pub raw_message: String,
324 pub source_type: SourceType,
325 pub source_identifier: Option<String>,
326 pub status: ReceivedStatus,
327 pub error_message: Option<String>,
328 pub received_at: String,
329 pub processed_at: Option<String>,
330 pub processed_message_id: Option<String>,
331}
332
333#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
334#[serde(rename_all = "snake_case")]
335pub enum SchemaType {
336 Person,
337 Organization,
338 Thing,
339}
340
341impl fmt::Display for SchemaType {
342 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
343 match self {
344 SchemaType::Person => write!(f, "Person"),
345 SchemaType::Organization => write!(f, "Organization"),
346 SchemaType::Thing => write!(f, "Thing"),
347 }
348 }
349}
350
351impl TryFrom<&str> for SchemaType {
352 type Error = String;
353
354 fn try_from(value: &str) -> Result<Self, Self::Error> {
355 match value {
356 "Person" => Ok(SchemaType::Person),
357 "Organization" => Ok(SchemaType::Organization),
358 "Thing" => Ok(SchemaType::Thing),
359 _ => Err(format!("Invalid schema type: {}", value)),
360 }
361 }
362}
363
364impl FromStr for SchemaType {
365 type Err = String;
366
367 fn from_str(s: &str) -> Result<Self, Self::Err> {
368 Self::try_from(s)
369 }
370}
371
372#[derive(Debug, Clone, Serialize, Deserialize)]
373pub struct Customer {
374 pub id: String,
375 pub agent_did: String,
376 pub schema_type: SchemaType,
377
378 pub given_name: Option<String>,
380 pub family_name: Option<String>,
381 pub display_name: Option<String>,
382
383 pub legal_name: Option<String>,
385 pub lei_code: Option<String>,
386 pub mcc_code: Option<String>,
387
388 pub address_country: Option<String>,
390 pub address_locality: Option<String>,
391 pub postal_code: Option<String>,
392 pub street_address: Option<String>,
393
394 pub profile: serde_json::Value,
396
397 pub ivms101_data: Option<serde_json::Value>,
399
400 pub verified_at: Option<String>,
402 pub created_at: String,
403 pub updated_at: String,
404}
405
406#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
407#[serde(rename_all = "snake_case")]
408pub enum IdentifierType {
409 Did,
410 Email,
411 Phone,
412 Url,
413 Account,
414 Other,
415}
416
417impl fmt::Display for IdentifierType {
418 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
419 match self {
420 IdentifierType::Did => write!(f, "did"),
421 IdentifierType::Email => write!(f, "email"),
422 IdentifierType::Phone => write!(f, "phone"),
423 IdentifierType::Url => write!(f, "url"),
424 IdentifierType::Account => write!(f, "account"),
425 IdentifierType::Other => write!(f, "other"),
426 }
427 }
428}
429
430impl TryFrom<&str> for IdentifierType {
431 type Error = String;
432
433 fn try_from(value: &str) -> Result<Self, Self::Error> {
434 match value {
435 "did" => Ok(IdentifierType::Did),
436 "email" => Ok(IdentifierType::Email),
437 "phone" => Ok(IdentifierType::Phone),
438 "url" => Ok(IdentifierType::Url),
439 "account" => Ok(IdentifierType::Account),
440 "other" => Ok(IdentifierType::Other),
441 _ => Err(format!("Invalid identifier type: {}", value)),
442 }
443 }
444}
445
446impl FromStr for IdentifierType {
447 type Err = String;
448
449 fn from_str(s: &str) -> Result<Self, Self::Err> {
450 Self::try_from(s)
451 }
452}
453
454#[derive(Debug, Clone, Serialize, Deserialize)]
455pub struct CustomerIdentifier {
456 pub id: String, pub customer_id: String,
458 pub identifier_type: IdentifierType,
459 pub verified: bool,
460 pub verification_method: Option<String>,
461 pub verified_at: Option<String>,
462 pub created_at: String,
463}
464
465#[derive(Debug, Clone, Serialize, Deserialize)]
466pub struct CustomerRelationship {
467 pub id: String,
468 pub customer_id: String,
469 pub relationship_type: String,
470 pub related_identifier: String,
471 pub proof: Option<serde_json::Value>,
472 pub confirmed_at: Option<String>,
473 pub created_at: String,
474}
475
476#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
477#[serde(rename_all = "snake_case")]
478pub enum DecisionStatus {
479 Pending,
480 Delivered,
481 Resolved,
482 Expired,
483}
484
485impl fmt::Display for DecisionStatus {
486 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
487 match self {
488 DecisionStatus::Pending => write!(f, "pending"),
489 DecisionStatus::Delivered => write!(f, "delivered"),
490 DecisionStatus::Resolved => write!(f, "resolved"),
491 DecisionStatus::Expired => write!(f, "expired"),
492 }
493 }
494}
495
496impl TryFrom<&str> for DecisionStatus {
497 type Error = String;
498
499 fn try_from(value: &str) -> Result<Self, Self::Error> {
500 match value {
501 "pending" => Ok(DecisionStatus::Pending),
502 "delivered" => Ok(DecisionStatus::Delivered),
503 "resolved" => Ok(DecisionStatus::Resolved),
504 "expired" => Ok(DecisionStatus::Expired),
505 _ => Err(format!("Invalid decision status: {}", value)),
506 }
507 }
508}
509
510impl FromStr for DecisionStatus {
511 type Err = String;
512
513 fn from_str(s: &str) -> Result<Self, Self::Err> {
514 Self::try_from(s)
515 }
516}
517
518#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
519#[serde(rename_all = "snake_case")]
520pub enum DecisionType {
521 AuthorizationRequired,
522 PolicySatisfactionRequired,
523 SettlementRequired,
524}
525
526impl fmt::Display for DecisionType {
527 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
528 match self {
529 DecisionType::AuthorizationRequired => write!(f, "authorization_required"),
530 DecisionType::PolicySatisfactionRequired => {
531 write!(f, "policy_satisfaction_required")
532 }
533 DecisionType::SettlementRequired => write!(f, "settlement_required"),
534 }
535 }
536}
537
538impl TryFrom<&str> for DecisionType {
539 type Error = String;
540
541 fn try_from(value: &str) -> Result<Self, Self::Error> {
542 match value {
543 "authorization_required" => Ok(DecisionType::AuthorizationRequired),
544 "policy_satisfaction_required" => Ok(DecisionType::PolicySatisfactionRequired),
545 "settlement_required" => Ok(DecisionType::SettlementRequired),
546 _ => Err(format!("Invalid decision type: {}", value)),
547 }
548 }
549}
550
551impl FromStr for DecisionType {
552 type Err = String;
553
554 fn from_str(s: &str) -> Result<Self, Self::Err> {
555 Self::try_from(s)
556 }
557}
558
559#[derive(Debug, Clone, Serialize, Deserialize)]
560pub struct DecisionLogEntry {
561 pub id: i64,
562 pub transaction_id: String,
563 pub agent_did: String,
564 pub decision_type: DecisionType,
565 pub context_json: serde_json::Value,
566 pub status: DecisionStatus,
567 pub resolution: Option<String>,
568 pub resolution_detail: Option<serde_json::Value>,
569 pub created_at: String,
570 pub delivered_at: Option<String>,
571 pub resolved_at: Option<String>,
572}
573
574impl NameHashable for Customer {}
576
577impl Customer {
578 pub fn generate_name_hash(&self) -> Option<String> {
580 match self.schema_type {
581 SchemaType::Person => {
582 if let (Some(given), Some(family)) = (&self.given_name, &self.family_name) {
584 Some(Self::hash_name(&format!("{} {}", given, family)))
585 } else {
586 self.display_name
587 .as_ref()
588 .map(|display| Self::hash_name(display))
589 }
590 }
591 SchemaType::Organization => {
592 self.legal_name.as_ref().map(|name| Self::hash_name(name))
594 }
595 _ => None,
596 }
597 }
598
599 pub fn add_name_hash_to_profile(&mut self) {
601 if let Some(hash) = self.generate_name_hash() {
602 if let serde_json::Value::Object(ref mut map) = self.profile {
603 map.insert("nameHash".to_string(), serde_json::Value::String(hash));
604 }
605 }
606 }
607
608 pub fn get_name_hash(&self) -> Option<String> {
610 if let serde_json::Value::Object(map) = &self.profile {
611 map.get("nameHash")
612 .and_then(|v| v.as_str())
613 .map(|s| s.to_string())
614 } else {
615 None
616 }
617 }
618}