Skip to main content

Customers Management Deep Dive

Overview​

This comprehensive guide covers Customer Management in the Ink platform, including customer lifecycle, profile management, address handling, and integration with external systems like QuickBooks and Salesforce.

Target Audience: Backend developers working with customer data Prerequisites: Service Layer Architecture, Integration Patterns Estimated Time: 45-60 minutes

Prerequisites​

Customers Lifecycle Architecture​

Installation Steps​

The Installation Steps section establishes the customers service management capabilities, including the core service, database schema, and external integrations.

What You'll Set Up:

  1. Customers Dependencies - Core libraries for customer management
  2. Customers Configuration - Settings for validation and external sync

Why This Matters:

  • Centralizes customer data management
  • Ensures data consistency across the platform
  • Manages integration with billing and CRM systems
  • Enforces business rules for customer accounts

When to Use:

  • Initial platform setup
  • Adding new customer-facing features
  • Integrating with new external systems
  • Implementing customer data policies

Key Capabilities Enabled:

  • Profile Management: Create and update customer details
  • Address Management: Handle billing and shipping addresses
  • External Sync: Synchronize with QuickBooks and Salesforce
  • Lifecycle Tracking: Monitor customer status and history
  • Settings Management: Configure per-customer preferences

Configuration Hierarchy:

customer
├── validation
│ ├── requireEmail: true
│ └── requirePhone: false
├── sync
│ ├── quickbooks: true
│ └── salesforce: true
└── lifecycle
├── inactiveDays: 90
└── churnThreshold: 180

1. Customer Dependencies​

What Are Customer Dependencies?​

The customer module relies on core Spring Boot starters, database drivers, and common internal libraries.

Why Are They Needed?​

  • Persistence: JPA/Hibernate for data storage
  • Web: REST API exposure
  • Validation: Bean validation for data integrity
  • Internal: Common DTOs and utilities

How/When Are They Used?​

  • Build Time: Compiled into the sureink-customer service
  • Runtime: Loaded by the Spring container

Dependency Relationships​

Code Example (XML)​

<!-- filepath: /sureink-customer/pom.xml -->
<dependencies>
<dependency>
<groupId>com.sureink</groupId>
<artifactId>sureink-model</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.sureink</groupId>
<artifactId>sureink-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
</dependencies>

2. Customer Configuration​

What Is Customer Configuration?​

Configuration settings control the behavior of the customer service, including validation rules and integration toggles.

Why Is It Needed?​

  • Feature Flags: Enable/disable integrations
  • Tuning: Adjust performance and limits
  • Policy: Enforce business rules via config

How/When Is It Used?​

  • Startup: Loaded during application bootstrap
  • Runtime: Injected into services via @Value

Configuration Flow​

Code Example (YAML)​

# filepath: /sureink-customer/src/main/resources/application.yml
customer:
code:
prefix: CUST
length: 8
sync:
quickbooks:
enabled: true
auto-create: true
salesforce:
enabled: true
validation:
email-domain-blocklist:
- mailinator.com
- tempmail.com

Configuration Section​

Main Entity: Customers​

What Is the Customers Entity?​

The Customer entity is the root aggregate for all customer-related data. It stores core profile information, status, and links to related entities.

Why Is It Needed?​

  • Identity: Unique identification of customers
  • State: Tracks lifecycle status (Lead, Active, etc.)
  • Audit: Supports history via Envers

How/When Is It Used?​

  • CRUD Operations: Created on signup, updated via profile
  • References: Linked to Orders, Subscriptions, and Projects

Entity Relationships​

Code Example (Java)​

// filepath: /sureink-model/src/main/java/com/sureink/customer/model/Customer.java
@Entity
@Table(schema = "customer")
@NoArgsConstructor(access = AccessLevel.PUBLIC)
@Getter
@Setter
public class Customer {

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "CUSTOMER_SEQUENCE")
@SequenceGenerator(name = "CUSTOMER_SEQUENCE", sequenceName = "customer_sequence", schema = "customer", allocationSize = 25)
Long id;

@Column(name = "name")
String name;

@Column(name = "code")
String code;

@Column(name = "full_name")
String fullName;

@Column(name = "created")
LocalDate created;

@Enumerated(EnumType.STRING)
@Column(name = "type")
CustomerLicenseType type;

@Enumerated(EnumType.STRING)
@Column(name = "source")
CustomerSource source;

@Column(name = "quickbooks_id")
String quickbooksId;

// ... relationships and other fields
}

Service Implementation: CustomerService​

What Is the Customer Service?​

The CustomerService encapsulates the business logic for managing customers. It handles validation, persistence, and event publication.

Why Is It Needed?​

  • Abstraction: Hides data access details
  • Consistency: Enforces rules before saving
  • Events: Triggers side effects (e.g., sync) via events

How/When Is It Used?​

  • API Calls: Invoked by the Controller layer
  • Internal: Used by other services (e.g., OrderService)

Service Operation Flow​

Code Example (Java)​

// filepath: /sureink-customer/src/main/java/com/sureink/customer/service/CustomerService.java
@Service
@RequiredArgsConstructor(access = AccessLevel.PACKAGE)
public class CustomerService extends UserInfoAware {

private final CustomerRepository customerRepository;
private final CustomerChangeEventPublisher customerChangeEventPublisher;

@Transactional
public Customer save(Customer customer) {
Preconditions.checkNotNull(customer, "Cannot save empty customer");
Customer saved = customerRepository.save(customer);
// Event publishing logic would typically go here or in an aspect
return saved;
}

@Transactional
public Optional<Customer> findOne(Long id) {
Preconditions.checkNotNull(id, "Unable to find customer for empty id");
return customerRepository.findById(id);
}

// ... other methods
}

Usage Examples​

Creating a New Customer​

What Is Customer Creation?​

The process of onboarding a new customer into the system.

Code Example (Java)​

Customer customer = new Customer();
customer.setName("Acme Corp");
customer.setFullName("Acme Corporation International");
customer.setType(CustomerLicenseType.ENTERPRISE);
customer.setSource(CustomerSource.WEB);
customer.setCreated(LocalDate.now());

Customer saved = customerService.save(customer);

Updating Customer Address​

What Is Address Update?​

Adding or modifying the billing/shipping address for a customer.

Code Example (Java)​

CustomerAddress address = new CustomerAddress();
address.setCustomer(customer);
address.setAddressLine1("123 Tech Blvd");
address.setCity("San Francisco");
address.setState("CA");
address.setZipCode("94105");
address.setType(AddressType.BILLING);

customerService.saveCustomerAddress(address);

Verification​

Customer Service Tests​

What Are Customer Service Tests?​

Unit and integration tests to verify the correctness of customer operations.

Code Example (Java)​

@SpringBootTest
class CustomerServiceTest {

@Autowired
private CustomerService customerService;

@Test
void shouldCreateCustomer() {
Customer customer = new Customer();
customer.setName("Test Corp");

Customer saved = customerService.save(customer);

assertNotNull(saved.getId());
assertEquals("Test Corp", saved.getName());
}
}