Contact Service is the central contact store for the Nexivo platform. It manages contacts, call history, contact lists, teams, dispositions, tags, and custom properties. All other services look up contacts by phone number, email, or ACS identity against this service.
Deployment
communication-services/contact-service — Spring Boot 4.0.5 / Java 25 · 3 pods in nexivo namespace
Tech Stack
| Layer |
Technology |
| Framework |
Spring Boot 4.0.5 |
| Language |
Java 25 |
| Database |
PostgreSQL (Flyway migrations) |
| Cache / Pub-Sub |
Redis |
| ACS integration |
Azure Communication Services SDK |
| Batch import |
Spring Batch (JDBC job store) |
| Export |
OpenPDF 1.3.30 · Apache POI 5.2.5 · OpenCSV 5.9 |
| Mapping |
ModelMapper · msl-core 2.0.0 |
Key Entities
| Field |
Type |
Notes |
id |
Long |
Primary key |
objectId |
String |
External reference |
firstName, lastName |
String |
|
email |
String |
|
phoneNumber |
String |
|
whatsappNumber |
String |
|
acsIdentity |
String |
Raw ACS identity ID |
genderId, typeId |
FK |
|
properties |
JSON Map |
Custom key-value pairs |
groups |
M2M |
Group join table |
contactTags |
Collection |
ContactTag |
contactLanguages |
Collection |
Language preferences |
active |
boolean |
|
dnb |
boolean |
Do-not-call flag |
Other Core Entities
| Entity |
Key Fields |
CallHistory |
callId, calledContact, callingContact, startTime, connectedTime, endTime, status (FAILED / ANSWERED / DECLINED / MISSED), type (ACS / ACS_PHONE) |
ContactList |
id UUID, name, description, contactType FK, group 1:1, contactCount formula, variableKeys JSON |
Team |
id UUID, name unique, description, aiAgent bool |
Group |
id, groupName unique, contacts M2M, properties JSON |
Tag / ContactTag |
Tag taxonomy assigned to contacts |
Disposition / DispositionGroup |
Outcome classifications with channel flags |
ContactType |
name, label, roleId, properties JSON |
Address |
Embedded: addressLine1/2, city, postalCode, countryCode |
Property (sealed hierarchy)
| Subtype |
Extra Field |
IdentityProperty |
sid |
TextProperty |
— |
URLProperty |
— |
LocationProperty |
— |
All entities that support soft-delete extend Trashable. Hibernate filter: @SQLRestriction("deleted_date is null").
REST API
| Endpoint |
Methods |
Description |
/contacts |
GET, POST, PUT, DELETE |
CRUD, search/paginate, bulk delete |
/contacts/export |
GET |
Export contact list (CSV / Excel / PDF) |
/contacts/{id}/groups |
GET, POST, DELETE |
List, add, remove group membership |
/acs/{acsIdentity} |
GET |
Look up contact by ACS identity |
/contact-lists |
GET, POST, PUT, DELETE |
Contact list CRUD |
/contact-lists/{id}/members |
GET, POST, DELETE |
Manage list membership |
/contact-lists/{id}/csv-upload |
POST |
Upload CSV file → FileUpload entity |
/contact-lists/{id}/csv-submit |
POST |
Async batch import job launch |
/call-history |
POST |
Log a call event |
/call-history/{callLogId} |
GET |
Retrieve a single call log |
/dispositions |
GET, POST, PUT, DELETE |
Disposition CRUD |
/disposition-groups |
GET, POST, PUT, DELETE |
Disposition group CRUD |
/contact-tags |
GET, POST, PUT, DELETE |
Tag CRUD, assign to contacts |
/teams |
GET, POST, PUT, DELETE |
Team CRUD, property management |
/contact-types |
GET, POST, PUT, DELETE |
Contact type CRUD, property management |
/contact-types/csv-upload |
POST |
Validate CSV against contact type schema |
/countries |
GET |
Reference data |
/genders |
GET |
Reference data |
/languages |
GET |
Reference data |
/roles |
GET |
Reference data |
| Format |
Enum Value |
Library |
| Comma-separated values |
CSV |
OpenCSV 5.9 |
| Excel workbook |
EXCEL |
Apache POI 5.2.5 |
| PDF document |
PDF |
OpenPDF 1.3.30 |
CSV Batch Import (Spring Batch)
The import pipeline runs as a Spring Batch Job backed by a JDBC job store.
flowchart TD
A["POST /contact-lists/{id}/csv-upload\n(store file → FileUpload entity)"]
B["POST /contact-lists/{id}/csv-submit\n(launch async Job)"]
C["ItemReader\n(parse CSV rows)"]
D["ItemProcessor\n(match contact by configured columns\ncreate or update Contact\nadd to list Group)"]
E["ItemWriter\n(persist chunk of 50)"]
F["Skip handler\n(up to 100 bad rows)"]
G["Job complete\n(ContactList updated)"]
A --> B
B --> C
C --> D
D --> E
E -->|next chunk| C
D -->|bad row| F
F -->|skip-limit reached → abort| G
E --> G
Job Parameters
| Parameter |
Description |
tenantId |
Owning tenant |
listId |
Target ContactList ID |
uploadId |
FileUpload entity ID |
contactIdVariable |
CSV column mapped to contact external ID |
phoneNumberVariable |
CSV column mapped to phone number |
emailVariable |
CSV column mapped to email |
firstNameVariable |
CSV column mapped to first name |
lastNameVariable |
CSV column mapped to last name |
clear |
If true, clears existing list members before import |
Tuning
| Config Key |
Default |
Description |
csv.batch.chunk-size |
50 |
Rows per transaction chunk |
csv.batch.skip-limit |
100 |
Max rows skipped before job aborts |
ACS Integration
AzureCommunicationServiceImpl creates an ACS user identity whenever a contact is created and stores the raw identity ID in Contact.acsIdentity. Microsoft Teams user references are resolved via microsoftTeamsUserIdentifier().
ACS Presence Status Values
| Status |
Meaning |
AVAILABLE |
Agent is online and ready |
AWAY |
Agent is signed in but away |
BUSY |
Agent is occupied |
IN_A_CALL |
Active voice call in progress |
OFFLINE |
Agent is not connected |
Live presence changes are broadcast over the Redis topic contact-acs-status:update.
Key Configuration
| Property |
Description |
azure.services.acs.enabled |
Enable / disable ACS user provisioning |
acs.endpoint |
Azure Communication Services endpoint URL |
acs.access-key |
ACS access key |
csv.batch.chunk-size |
Import chunk size (default 50) |
csv.batch.skip-limit |
Import skip limit (default 100) |
redis.keys.teams-users |
Redis key for Teams user index (default teams-users) |