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());
}
}