This project provides a RESTful API to manage and identify customer contacts based on phone numbers and emails. It consolidates contacts by distinguishing between primary and secondary contact records, ensuring clean and reliable customer data management.
Features
-
Create and retrieve customer contacts.
-
Identify customers by phone number and/or email.
-
Automatically link secondary contacts to a primary contact.
-
Consolidated contact response including all associated emails and phone numbers.
-
Handles edge cases such as multiple primary contacts and contact updates.
Customers often place multiple orders using different contact details (email/phone). This leads to fragmented identities. Our service reconciles them into a single unified identity, ensuring a seamless and personalized customer journey.
🚀 Live Endpoint:
https://identity-reconciliation-api-go9n.onrender.com/api/v1/identify
📬 Method:POST
📄 Content-Type:application/json
- Backend: Node.js, Express.js
- Language: JavaScript
- Database: MySQL
- ORM: Sequelize
- VALIDATION: Joi
- Testing: Postman (10 structured test cases)
- Deployment: Render.com
-
Modular Code Structure
Separated service logic (contactService.js), (identifyService.js) from controller/handler for better maintainability and testability. -
Consistent Error Handling
Used try-catch blocks and proper transaction rollback to handle errors gracefully without data corruption. Errors are logged or re-thrown with meaningful context to debugging. -
Clear Function Responsibilities
Each function has a single responsibility, such ascreateContact,findExistingContacts,updateToSecondaryBatch, andformatConsolidatedResponse, improving readability and reusability. -
Use of Async/Await
Asynchronous operations are handled cleanly with async/await, avoiding callback hell and improving code clarity. -
Descriptive Variable Naming
Variables and functions are named meaningfully for easy understanding of their purpose. -
Transaction Management
Used database transactions to group multiple related queries ensuring atomicity and consistency, preventing partial updates and race conditions. -
Immutability in Data Handling
Avoided mutating input data directly by using copies and filtered arrays for safer operations, reducing side effects and bugs.
-
Indexed Search Fields
IndexedphoneNumber,emailandlinkedIdcolumns in MySQL for fast lookups on common query parameters. -
Efficient Querying
Combined queries using Sequelize’sOp.orto fetch contacts matching either phone or email in a single optimized query. -
Batch Updates
Updated multiple primary contacts to secondary in one batch query (updateToSecondaryBatch), reducing the number of queries and improving performance. -
Minimized Database Calls
Reused data and fetched all related contacts in one go rather than multiple redundant queries. -
Use of Transactions
Wrapped create and update operations inside transactions to prevent partial updates, race conditions, and maintain data integrity. -
Ordering by Creation Date
Used ordered queries bycreatedAtto easily determine the oldest (primary) contact efficiently.
- Separation of concerns promotes scalability and ease of testing.
- Leveraged Sequelize ORM features to abstract complex SQL logic while maintaining performance.
- Meaningful naming and modularization reduce cognitive load, speeding up onboarding and reviews.
- Immutability enhances code safety in asynchronous flows.
- Indexing and batch processing directly improve response time and scalability under load.
git clone https://github.com/bibek1123/Identity-Reconciliation-API.git
cd identity-reconciliationnpm installCreate a .env file in the root:
PORT=3000
DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306
DB_USERNAME=root
DB_PASSWORD=yourpassword
DB_DATABASE=bitespeed
NODE_ENV=developmentnpm run migrate # or use sequelize-cliOr if you're using sync with Sequelize:
sequelize.sync({ alter: true });npm run devThe server runs at
http://localhost:3000Base url ishttp://localhost:3000/api/v1
{
"email": "doc@fluxkart.com",
"phoneNumber": "1234567890"
}- Either
emailorphoneNumbermust be present (or both). - Validates contact, checks for existing entries, reconciles identity.
{
"contact": {
"primaryContatctId": 1,
"emails": ["doc@fluxkart.com", "emmett@fluxkart.com"],
"phoneNumbers": ["1234567890"],
"secondaryContactIds": [2, 3]
}
}📁 postman/IdentityReconciliation.postman_collection.json
This project includes 10+ test cases that are covered in detail in the provided Postman collection.
You can find them inside the postman_collections/ folder
| Field | Type | Description |
|---|---|---|
| id | INT | Auto-incremented primary key |
| VARCHAR | Optional email | |
| phoneNumber | VARCHAR | Optional phone number |
| linkedId | INT | Points to primary contact's ID |
| linkPrecedence | ENUM | primary or secondary |
| createdAt | TIMESTAMP | Auto-managed |
| updatedAt | TIMESTAMP | Auto-managed |
| deletedAt | TIMESTAMP | For soft deletes |
You can deploy this app using:
📦 Ensure the
.envvalues for production are set appropriately.
- ✅ Functional
/identifyendpoint - ✅ Used MySQL with Sequelize
- ✅ Hosted publicly
- ✅ Postman collection added with 10+ test cases
- ✅ Structured professional README