Skip to main content

gingr/mapping/
customer.rs

1use crate::{endpoint, response};
2use domain::{customer, entities};
3
4use super::{Error, ProviderField, Result};
5
6#[derive(Debug, Clone, PartialEq, Eq)]
7/// Customer mapping candidate produced from Gingr owner contact fields.
8pub struct ContactCandidate {
9    /// Gingr owner identifier kept as source evidence for the mapped customer.
10    pub provider_owner_id: endpoint::OwnerId,
11    /// Customer name assembled from Gingr owner fields; useful for staff-facing drafts but not proof of legal identity.
12    pub full_name: customer::Name,
13    /// Email address observed from Gingr and carried as customer-contact evidence.
14    pub email: Option<customer::Email>,
15    /// Mobile phone observed from Gingr and carried as customer-contact evidence.
16    pub mobile_phone: Option<customer::Phone>,
17    /// Preferred contact channel inferred from provider contact fields for NVA workflow routing.
18    pub preferred_contact: entities::ContactChannel,
19}
20
21/// Extracts customer contact fields Gingr exposed for owner-to-domain mapping.
22pub fn contact_candidate(record: &response::OwnerRecord) -> Result<ContactCandidate> {
23    let full_name = record
24        .display_name()
25        .ok_or(Error::MissingRequiredProviderField {
26            field: ProviderField::OwnerName,
27        })?;
28    let full_name =
29        customer::Name::try_new(full_name).map_err(|err| Error::InvalidDomainValue {
30            field: ProviderField::OwnerName,
31            reason: err.to_string(),
32        })?;
33    let email = record
34        .email
35        .as_ref()
36        .map(|email| customer::Email::try_new(email.as_str()))
37        .transpose()
38        .map_err(|err| Error::InvalidDomainValue {
39            field: ProviderField::OwnerName,
40            reason: err.to_string(),
41        })?;
42    let mobile_phone = record
43        .cell_phone
44        .as_deref()
45        .map(customer::Phone::try_new)
46        .transpose()
47        .map_err(|err| Error::InvalidDomainValue {
48            field: ProviderField::OwnerName,
49            reason: err.to_string(),
50        })?;
51    let preferred_contact = if email.is_some() {
52        entities::ContactChannel::Email
53    } else if mobile_phone.is_some() {
54        entities::ContactChannel::Sms
55    } else {
56        entities::ContactChannel::Portal
57    };
58
59    Ok(ContactCandidate {
60        provider_owner_id: record.id,
61        full_name,
62        email,
63        mobile_phone,
64        preferred_contact,
65    })
66}