{"id":23175879,"url":"https://github.com/pintu544/identityreconciliation","last_synced_at":"2026-05-07T11:33:08.624Z","repository":{"id":235483637,"uuid":"790785941","full_name":"pintu544/IdentityReconciliation","owner":"pintu544","description":"Bitespeed needs a way to identify and keep track of a customer's identity across multiple purchases. We know that orders on FluxKart.com will always have either an email or phoneNumber in the checkout event. Bitespeed keeps track of the collected contact information in a relational database table named Contact.","archived":false,"fork":false,"pushed_at":"2024-04-23T14:33:39.000Z","size":71,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-10T09:33:20.795Z","etag":null,"topics":["nodejs-express","postgresql","typescript"],"latest_commit_sha":null,"homepage":"https://identity-reconciliation-eta.vercel.app","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pintu544.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2024-04-23T14:23:47.000Z","updated_at":"2024-04-23T14:36:11.000Z","dependencies_parsed_at":"2024-04-23T15:43:55.586Z","dependency_job_id":"e17060bf-d32c-42e5-b17d-fce17560cb27","html_url":"https://github.com/pintu544/IdentityReconciliation","commit_stats":null,"previous_names":["pintu544/identityreconciliation"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pintu544%2FIdentityReconciliation","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pintu544%2FIdentityReconciliation/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pintu544%2FIdentityReconciliation/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pintu544%2FIdentityReconciliation/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pintu544","download_url":"https://codeload.github.com/pintu544/IdentityReconciliation/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247272805,"owners_count":20911812,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["nodejs-express","postgresql","typescript"],"created_at":"2024-12-18T06:10:16.712Z","updated_at":"2026-05-07T11:33:03.593Z","avatar_url":"https://github.com/pintu544.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"```markdown\n# Bitespeed Customer Identification Service\n\nBitespeed needs a way to identify and keep track of a customer's identity across multiple purchases. We know that orders on FluxKart.com will always have either an email or phoneNumber in the checkout event. Bitespeed keeps track of the collected contact information in a relational database table named Contact.\n\n## Database Schema\n\n```typescript\n{\n  id: number;\n  phoneNumber?: string;\n  email?: string;\n  linkedId?: number | null; // the ID of another Contact linked to this one\n  linkPrecedence: \"secondary\" | \"primary\"; // \"primary\" if it's the first Contact in the link\n  createdAt: Date;\n  updatedAt: Date;\n  deletedAt?: Date | null;\n}\n```\n\nOne customer can have multiple Contact rows in the database against them. All of the rows are linked together with the oldest one being treated as \"primary” and the rest as “secondary”. Contact rows are linked if they have either of email or phone as common.\n\nFor example:\n\nIf a customer placed an order with:\n\n- email=lorraine@hillvalley.edu \u0026 phoneNumber=123456 \n- and later came back to place another order with \n- email=mcfly@hillvalley.edu \u0026 phoneNumber=123456,\n\nthe database will have the following rows:\n\n```json\n[\n  {\n    \"id\": 1,\n    \"phoneNumber\": \"123456\",\n    \"email\": \"lorraine@hillvalley.edu\",\n    \"linkedId\": null,\n    \"linkPrecedence\": \"primary\",\n    \"createdAt\": \"2023-04-01T00:00:00.374Z\",\n    \"updatedAt\": \"2023-04-01T00:00:00.374Z\",\n    \"deletedAt\": null\n  },\n  {\n    \"id\": 23,\n    \"phoneNumber\": \"123456\",\n    \"email\": \"mcfly@hillvalley.edu\",\n    \"linkedId\": 1,\n    \"linkPrecedence\": \"secondary\",\n    \"createdAt\": \"2023-04-20T05:30:00.110Z\",\n    \"updatedAt\": \"2023-04-20T05:30:00.110Z\",\n    \"deletedAt\": null\n  }\n]\n```\n\n## Requirements\n\nYou are required to design a web service with an endpoint `/identify` that will receive HTTP POST requests with a JSON body of the following format:\n\n```typescript\n{\n  \"email\"?: string;\n  \"phoneNumber\"?: string;\n}\n```\n\nThe service should:\n\n- Accept requests with either email or phoneNumber, but at least one of them must be provided.\n- Identify the customer based on the provided email or phoneNumber.\n- If the customer is found, return the details of the customer including all linked contacts.\n- If the customer is not found, create a new contact with the provided email or phoneNumber.\n- If a customer is identified and a different email or phoneNumber is provided in subsequent requests, update the contact details and link them to the existing customer.\n\n## Endpoint\n\n### `POST /identify`\n\n#### Request Body\n\n```typescript\n{\n  \"email\"?: string;\n  \"phoneNumber\"?: string;\n}\n```\n\n#### Response\n\n```typescript\n{\n  \"customer\": {\n    \"id\": number;\n    \"primaryContactId\": number;\n    \"emails\": string[];\n    \"phoneNumbers\": string[];\n    \"secondaryContactIds\": number[];\n  }\n}\n```\n\n## Project Structure\n\n```\nbitespeed-customer-identification/\n├── src/                     # Source code\n│   ├── models/              # TypeScript models/interfaces\n│   │   └── contact.ts\n│   ├── services/            # Business logic\n│   │   └── contactService.ts\n│   ├── utils/               # Helper functions\n│   │   └── database.ts\n│   ├── controllers/         # Endpoint route handlers\n│   │   └── identifyController.ts\n│   ├── app.ts               # Application entry point\n├── tests/                   # Unit and integration tests\n│   ├── services/\n│   │   └── contactService.test.ts\n├── .env                     # Environment variables\n├── ormconfig.json           # ORM configuration (if using an ORM)\n├── package.json             # Project dependencies\n├── tsconfig.json            # TypeScript configuration\n└── README.md                # Project documentation\n```\n\n## Installation\n\n1. Clone the repository:\n\n```bash\ngit clone https://github.com/pintu544/IdentityReconciliation\n```\n\n2. Install dependencies:\n\n```bash\ncd IdentityReconciliation\nnpm install\n```\n\n3. Set up environment variables:\n\nCreate a `.env` file in the root directory of your project and add the following:\n\n```plaintext\nDB_HOST=localhost\nDB_PORT=5432\nDB_USER=postgres\nDB_PASSWORD=pintu123\nDB_NAME=postgres\n```\n\n4. Start the application:\n\n```bash\nnpm start\n```\n\n## Testing\n\nTo run tests, use the following command:\n\n```bash\nnpm test\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpintu544%2Fidentityreconciliation","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpintu544%2Fidentityreconciliation","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpintu544%2Fidentityreconciliation/lists"}