A robust Node.js TypeScript service for linking customer identities across multiple purchases using email and phone number reconciliation.
- Identity Reconciliation: Links customer contacts across multiple purchases
- Primary/Secondary Contact System: Hierarchical contact linking with oldest contact as primary
- Automatic Contact Merging: Intelligently merges separate contact groups when connections are discovered
- RESTful API: Clean
/identifyendpoint following industry standards - Type Safety: Full TypeScript implementation with strict type checking
- Comprehensive Testing: Unit tests with 80%+ coverage using Jest
- Production Ready: Docker containerization with health checks
- Database Integration: PostgreSQL with Prisma ORM
- Logging & Monitoring: Winston logging with structured output
- Error Handling: Comprehensive error handling with proper HTTP status codes
First
Second
- Node.js 18+
- PostgreSQL 13+
- Docker & Docker Compose (for containerized setup)
-
Clone the repository
git clone <repository-url> cd bitespeed-identity-reconciliation
-
Install dependencies
npm install
-
Set up environment variables
cp .env.example .env # Edit .env with your database credentials -
Start PostgreSQL database
# Using Docker docker run --name bitespeed-postgres \ -e POSTGRES_DB=bitespeed_db \ -e POSTGRES_USER=bitespeed_user \ -e POSTGRES_PASSWORD=bitespeed_password \ -p 5432:5432 -d postgres:15-alpine -
Run database migrations
npx prisma db push npx prisma generate
-
Start the development server
npm run dev
The service will be available at http://localhost:3000
-
Production deployment
docker-compose up --build
-
Development with hot reload
docker-compose --profile dev up --build
Production: https://contactbridge-production.up.railway.app
Development: http://localhost:3000
Identifies and consolidates customer contacts based on email and/or phone number.
Request Body:
{
"email": "string (optional)",
"phoneNumber": "string (optional)"
}Response:
{
"contact": {
"primaryContactId": "number",
"emails": ["string"],
"phoneNumbers": ["string"],
"secondaryContactIds": ["number"]
}
}Status Codes:
200 OK: Successfully processed request400 Bad Request: Invalid request data500 Internal Server Error: Server error
Health check endpoint for monitoring.
Response:
{
"status": "healthy",
"timestamp": "2023-12-01T10:00:00Z",
"service": "bitespeed-identity-reconciliation"
}Returns the complete contact chain for a given contact ID.
Response:
{
"contact": {
"primaryContactId": "number",
"emails": ["string"],
"phoneNumbers": ["string"],
"secondaryContactIds": ["number"]
}
}# Local Development
curl -X POST http://localhost:3000/api/v1/identify \
-H "Content-Type: application/json" \
-d '{
"email": "lorraine@hillvalley.edu",
"phoneNumber": "123456"
}'
# Production
curl -X POST https://contactbridge-production.up.railway.app/api/v1/identify \
-H "Content-Type: application/json" \
-d '{
"email": "lorraine@hillvalley.edu",
"phoneNumber": "123456"
}'Response:
{
"contact": {
"primaryContactId": 1,
"emails": ["lorraine@hillvalley.edu"],
"phoneNumbers": ["123456"],
"secondaryContactIds": []
}
}# Local Development
curl -X POST http://localhost:3000/api/v1/identify \
-H "Content-Type: application/json" \
-d '{
"email": "mcfly@hillvalley.edu",
"phoneNumber": "123456"
}'
# Production
curl -X POST https://contactbridge-production.up.railway.app/api/v1/identify \
-H "Content-Type: application/json" \
-d '{
"email": "mcfly@hillvalley.edu",
"phoneNumber": "123456"
}'Response:
{
"contact": {
"primaryContactId": 1,
"emails": ["lorraine@hillvalley.edu", "mcfly@hillvalley.edu"],
"phoneNumbers": ["123456"],
"secondaryContactIds": [23]
}
}# Local Development
curl -X POST http://localhost:3000/api/v1/identify \
-H "Content-Type: application/json" \
-d '{
"email": "george@hillvalley.edu",
"phoneNumber": "717171"
}'
# Production
curl -X POST https://contactbridge-production.up.railway.app/api/v1/identify \
-H "Content-Type: application/json" \
-d '{
"email": "george@hillvalley.edu",
"phoneNumber": "717171"
}'This will merge two previously separate primary contacts into a single chain.
Test your deployed API:
# Health Check
curl https://contactbridge-production.up.railway.app/health
# Test Identify Endpoint
curl -X POST https://contactbridge-production.up.railway.app/api/v1/identify \
-H "Content-Type: application/json" \
-d '{"email": "test@example.com", "phoneNumber": "1234567890"}'# Run all tests
npm test
# Run tests with coverage
npm run test:coverage
# Run tests in watch mode
npm run test:watchtests/services/: Business logic teststests/controllers/: API endpoint teststests/models/: Data model teststests/repositories/: Database operation tests
- Minimum 80% coverage across all metrics
- Business logic (ContactService) has comprehensive scenario testing
- API validation and error handling fully tested
Create a .env file with the following variables:
# Server Configuration
PORT=3000
NODE_ENV=production
# Database Configuration
DATABASE_URL="postgresql://username:password@host:port/database"
# Logging
LOG_LEVEL=info
# CORS Configuration
CORS_ORIGIN=*
# API Configuration
API_PREFIX=/api/v1-
Build and deploy
docker-compose up --build -d
-
View logs
docker-compose logs -f app
-
Scale the application
docker-compose up --scale app=3
-
Connect to Railway
# Install Railway CLI npm install -g @railway/cli # Login to Railway railway login
-
Deploy to Railway
# Initialize Railway project railway init # Deploy your application railway up
-
Set Environment Variables In Railway dashboard, add these environment variables:
DATABASE_URL: Your PostgreSQL connection stringNODE_ENV:productionPORT: Railway will set this automaticallyLOG_LEVEL:infoCORS_ORIGIN:*
-
Database Setup
# Run database migrations railway run npx prisma db push
Live Demo: https://contactbridge-production.up.railway.app
- Connect your GitHub repository to Render
- Create a new Web Service
- Set the following build settings:
- Build Command:
npm install && npm run build && npx prisma generate - Start Command:
npm start
- Build Command:
- Add environment variables in Render dashboard
- Deploy!
For production deployments:
# Generate Prisma client
npx prisma generate
# Push schema to database
npx prisma db push
# Or run migrations
npx prisma migrate deployβββ src/
β βββ config/ # Configuration files
β βββ controllers/ # HTTP request handlers
β βββ middleware/ # Express middleware
β βββ models/ # Data models and validation
β βββ repositories/ # Database operations
β βββ routes/ # API route definitions
β βββ services/ # Business logic
β βββ types/ # TypeScript type definitions
β βββ utils/ # Utility functions
βββ tests/ # Test files
βββ prisma/ # Database schema and migrations
βββ docker-compose.yml # Container orchestration
- Repository Pattern: Data access abstraction
- Service Layer: Business logic separation
- Dependency Injection: Loose coupling between components
- Error Handling: Centralized error management
- Configuration Management: Environment-based configuration
CREATE TABLE contacts (
id SERIAL PRIMARY KEY,
phone_number VARCHAR,
email VARCHAR,
linked_id INTEGER REFERENCES contacts(id),
link_precedence VARCHAR NOT NULL CHECK (link_precedence IN ('primary', 'secondary')),
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW(),
deleted_at TIMESTAMP
);- ESLint: Code linting and style enforcement
- Prettier: Code formatting
- TypeScript: Static type checking
- Husky: Git hooks for pre-commit checks
npm run dev # Start development server
npm run build # Build for production
npm run start # Start production server
npm test # Run tests
npm run lint # Run ESLint
npm run format # Format code with Prettier- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Commit your changes:
git commit -m 'Add amazing feature' - Push to the branch:
git push origin feature/amazing-feature - Open a Pull Request
- Follow TypeScript best practices
- Write tests for new functionality
- Update documentation for API changes
- Use conventional commit messages
This project is licensed under the MIT License - see the LICENSE file for details.
- Live Demo: https://contactbridge-production.up.railway.app
- Health Check: https://contactbridge-production.up.railway.app/health
- API Base URL: https://contactbridge-production.up.railway.app/api/v1
- GitHub Repository: https://github.com/uphargaur/ContactBridge
Made with β€οΈ