This is a backend service built for the [BiteSpeed Identity Resolution Challenge]. The API helps unify user identity by linking contacts with the same email or phone number across multiple records.
Base URL: https://bitespeed-assignment-2u07.onrender.com
- Tech Stack
- API Endpoints
- Identity Resolution Logic
- How to Run Locally
- Soft Delete & Restore Feature
- Database Schema
- Swagger API Docs
- Author
- Backend: Node.js, Express.js
- Database: PostgreSQL (via Prisma ORM)
- Deployment: Render
- API Docs: Swagger (OpenAPI 3.0)
- Purpose: Resolves identity based on email and/or phone number.
- Body:
{
"email": "john.doe@example.com",
"phoneNumber": "9876543210"
}- Response:
{
"contact": {
"primaryContactId": 1,
"emails": ["john.doe@example.com", "another@example.com"],
"phoneNumbers": ["9876543210"],
"secondaryContactIds": [2, 3]
}
}- Purpose: Soft deletes the contact with given ID.
- Response:
{
"message": "Contact soft deleted",
"contact": {
"id": 11,
"email": "john.doe@example.com",
"phoneNumber": "9876543210",
"linkPrecedence": "primary",
"deletedAt": "timestamp"
}
}- Purpose: Restores a soft-deleted contact.
- Response:
{
"message": "Contact restored",
"contact": {
"id": 11,
"email": "john.doe@example.com",
"phoneNumber": "9876543210",
"linkPrecedence": "primary"
}
}- A primary contact is created if neither email nor phone exists.
- If either matches an existing contact, a secondary contact is created or linked to the existing primary.
- All linked contacts are grouped by a
linkedId, ensuring a unified identity across duplicates. - Conflicts are resolved by assigning the oldest contact as
primary.
git clone https://github.com/yourusername/bitespeed-assignment.git
cd bitespeed-assignment
npm install
npx prisma generate
npx prisma migrate dev --name init
npm run devEnsure .env is configured with:
DATABASE_URL="postgresql://<user>:<password>@localhost:5432/<dbname>"
| Field | Type | Description |
|---|---|---|
| id | Integer | Primary key |
| phoneNumber | String | User's phone number |
| String | User's email address | |
| linkedId | Integer | Link to primary contact |
| linkPrecedence | Enum | 'primary' or 'secondary' |
| createdAt | Timestamp | Auto-generated |
| updatedAt | Timestamp | Auto-generated |
| deletedAt | Timestamp | Nullable (for soft delete) |
- Contacts are soft deleted using a
deletedAttimestamp. - Deleted contacts can be restored using the
/identify/restore/{id}endpoint. - Identity resolution ignores soft-deleted contacts by default.
You can explore the full API documentation via Swagger UI:
Aryan Bachute Full Stack Developer | IEEE Treasurer