Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
171 changes: 171 additions & 0 deletions src/entityTypeAndEntityOnboarding/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
# 🧱 Entity Management - Creation Flow

This guide provides comprehensive and step-by-step instructions for managing entities within the SAAS platform, tailored to different user roles and environments. It covers authentication, creation, and mapping of entities to ensure a seamless onboarding and operational experience.

---

## 🔐 Auth Keys & Tokens

Authentication headers required for API calls, based on user roles and the environment.

### 🔸 Org Admin - QA

| Key | Value |
| ----------------------- | ------------------------- |
| `internal-access-token` | `{internal-access-token}` |
| `X-auth-token` | `{Token}` |

### 🔸 Super Admin - QA

| Key | Value |
| ----------------------- | ------------------------- |
| `internal-access-token` | `{internal-access-token}` |
| `X-auth-token` | `{Token}` |
| `admin-auth-token` | `{admin-auth-token}` |
| `tenantId` | `shikshagraha` |
| `orgId` | `blr` |

---

## 🌐 Origin URLs (Per Organization)

Domain URLs to be passed as the `origin` header during login requests.

| Organization | Origin URL |
| ------------ | ------------------------------- |
| Shikshalokam | `shikshalokam-qa.tekdinext.com` |
| Shikshagraha | `shikshagrah-qa.tekdinext.com` |
| Super Admin | `default-qa.tekdinext.com` |

---

## 🔑 Login API

Use this API to authenticate the user and generate a session token (`X-auth-token`). The token is mandatory for all secured API requests.

<details>
<summary>Login API</summary>

```bash
curl --location '{{baseURL}}/user/v1/account/login' \
--header 'Content-Type: application/json' \
--header 'origin: shikshalokam-qa.tekdinext.com' \
--data-raw '{
"identifier": "email/phone",
"password": "password"
}'
```

</details>

---

**NOTE**:

- If you are an **Organization Admin**, please ensure that the headers match the values listed under _Org Admin - QA_.
- If you are a **Super Admin**, use the credentials and headers mentioned under _Super Admin - QA_.

---

## 🧱 Add Entity Type

Use this API to create a new entity type in the system. An entity type represents a category like `school`, `cluster`, `block`, etc.

<details>
<summary>Add Entity Type API</summary>

```bash
curl --location '{{baseURL}}/entity-management/v1/entityTypes/create' \
--header 'internal-access-token: {internal-access-token}' \
--header 'content-type: application/json' \
--header 'X-auth-token: {{tokenToPass}}' \
--header 'admin-auth-token: {admin-auth-token}' \
--header 'tenantId: shikshagraha' \
--header 'orgid: blr' \
--data '{
"name": "professional_role",
"registryDetails": {
"name": "schoolRegistry"
},
"isObservable": true,
"toBeMappedToParentEntities": true
}'
```

</details>

---

## 🏫 Bulk Upload Entities

Use this API to bulk create entities of a specific type (e.g., schools, teachers) by uploading a formatted CSV file.

📄 **CSV File**: [Karnataka School Upload CSV](https://drive.google.com/file/d/1SwOh11gmhehhrKH7SygA40DpYRE6IIjI/view)

<details>
<summary>Bulk Upload API</summary>

```bash
curl --location '{{baseURL}}/entity-management/v1/entities/bulkCreate?type=school' \
--header 'internal-access-token: {internal-access-token}' \
--header 'content-type: multipart/form-data' \
--header 'x-auth-token: {{TokenToPass}}' \
--form 'entities=@"/home/user4/Downloads/Karnata-upload data SG prod - schoolUpload.csv"'
```

</details>

---

## 🧾 Generate Mapping CSV

This API helps generate a base mapping CSV from the bulk uploaded entity data. The generated CSV will be used to create mappings between parent and child entities.

📄 **CSV File**: [Download Template CSV](https://drive.google.com/file/d/1n9pFGfZKaj77OBXfsDnwL5WEOHzpq6jr/view?usp=sharing)

<details>
<summary>Generate Mapping CSV API</summary>

```bash
curl --location '{{baseURL}}/entity-management/v1/entities/createMappingCsv' \
--header 'x-auth-token: {{TokenToPass}}' \
--header 'content-type: multipart/form-data' \
--header 'internal-access-token: {internal-access-token}' \
--form 'entityCSV=@"/home/user4/Downloads/chunk_0.csv"'
```

</details>

---

## 🔗 Upload Entity Mapping

This API maps child entities to their respective parent entities using the result CSV generated from the previous step (`createMappingCsv`).

📄 **CSV File**: [Sample Mapping Upload CSV](https://drive.google.com/file/d/1SVvi-F0y2YcwNfBpAOYzMZVeh4TbJCxd/view?usp=sharing)

📌 **Note**: Always use the result CSV from the `createMappingCsv` step.

<details>
<summary>Mapping Upload API</summary>

```bash
curl --location '{{baseURL}}/entity-management/v1/entities/mappingUpload' \
--header 'internal-access-token: {internal-access-token}' \
--header 'x-auth-token: {{TokenToPass}}' \
--form 'entityMap=@"/home/user4/Downloads/base64-to-csv-converter (8).csv"'
```

</details>

---

## ✅ Summary of Steps

1. **Login** – Authenticate and retrieve your `X-auth-token`.
2. **Create Entity Type** – Define the category (type) of the entities you want to manage.
3. **Bulk Upload Entities** – Upload a list of entities using a formatted CSV file.
4. **Generate Mapping CSV** – Create a base CSV that outlines relationships between entities.
5. **Upload Entity Mapping** – Finalize the entity hierarchy by uploading the mapping CSV.

---
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
const fs = require('fs')
const csv = require('csv-parser')
const createCsvWriter = require('csv-writer').createObjectCsvWriter

const inputFilePath = 'input.csv' // Your input CSV
const outputFilePath = 'output_unique.csv' // Output with unique rows

const seen = new Set()
const uniqueRows = []

fs.createReadStream(inputFilePath)
.pipe(csv())
.on('data', (row) => {
const parentEntityId = row['parentEntityId'].trim()
const childEntityId = row['childEntityId'].trim()
const key = `${parentEntityId}-${childEntityId}`

if (!seen.has(key)) {
seen.add(key)
uniqueRows.push({ parentEntityId, childEntityId })
}
})
.on('end', () => {
const csvWriter = createCsvWriter({
path: outputFilePath,
header: [
{ id: 'parentEntityId', title: 'parentEntityId' },
{ id: 'childEntityId', title: 'childEntityId' },
],
})

csvWriter.writeRecords(uniqueRows).then(() => {
console.log(`✅ Deduplicated data written to: ${outputFilePath}`)
})
})
42 changes: 42 additions & 0 deletions src/entityTypeAndEntityOnboarding/utilityScripts/splitEntities.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
const fs = require('fs')
const csv = require('csv-parser')
const { createObjectCsvWriter } = require('csv-writer')

const inputFilePath = 'input.csv' // Input file name
const rowsPerFile = 5000 // Split size
const allRows = []

let headers = []

// Step 1: Read CSV data
fs.createReadStream(inputFilePath)
.pipe(csv())
.on('headers', (csvHeaders) => {
// Ensure fixed header names
headers = ['parentEntiyId', 'childEntityId'].map((header) => ({
id: header,
title: header,
}))
})
.on('data', (row) => {
// Optional: only keep required fields to avoid extra columns
allRows.push({
parentEntiyId: row.parentEntiyId,
childEntityId: row.childEntityId,
})
})
.on('end', async () => {
const totalFiles = Math.ceil(allRows.length / rowsPerFile)

for (let i = 0; i < totalFiles; i++) {
const chunk = allRows.slice(i * rowsPerFile, (i + 1) * rowsPerFile)

const csvWriter = createObjectCsvWriter({
path: `data${i + 1}.csv`,
header: headers,
})

await csvWriter.writeRecords(chunk)
console.log(`data${i + 1}.csv written with ${chunk.length} records`)
}
})
7 changes: 7 additions & 0 deletions src/module/entities/helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -1460,6 +1460,13 @@ module.exports = class UserProjectsHelper {
// Fetch entity documents based on constructed query
let entityDocument = await entitiesQueries.entityDocuments(query, 'all')

if (!entityDocument.length) {
throw {
status: HTTP_STATUS_CODE.bad_request.status,
message: CONSTANTS.apiResponses.ENTITY_NOT_FOUND,
}
}

// Initialize variables for parent entity details
let entityDocumentForParent
let parentInformation = {}
Expand Down