All pages
Powered by GitBook
1 of 57

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Low Level Design

The articles in this section include:

RegistriesServices

Registries

Registries in DIGIT are trusted data stores that manage core entities like individuals, households, facilities, and products. They provide APIs to create, update, and search these records, ensuring consistent and reusable data across all services.

Individual
Household
Product
Facility
Attendance
Expense

Individual

Overview

The Individual Registry is a core component of the DIGIT platform’s registry system. The registry offers APIs to create, update, delete, and search individual records—either individually or in bulk.

API Spec

Sequence Diagrams

V1 Deprecated Data Apis

Individual - Create
Individual - Bulk Create
Individual - Update
Individual - Bulk Update
Individual - Search
Individual - Delete
Individual - Bulk Delete

Register Inbox

Overview

Enables supervisors to view attendance registers filtered by selected boundaries (e.g., district).

Interface Elements

Services

Services are the functional building blocks of DIGIT, each designed as a microservice to handle a specific piece of business logic. They sit on top of registries, integrate via APIs and events, and together enable scalable, modular health campaign systems.

Enumeration

Overview

Enumeration changes include capturing additional information for household, individual and member linking as children or other relationships. To capture the additional details, we are rendering the new checklists and capturing the details.

Key Features

Project
Stock
Referral
Muster Roll
Expense Calculator
Attendance
Generate Bill
Enumeration
Beneficiary IDGen
Transit Post
Peer To Peer Transfer
Project Factory
Admin Console
Central Instance

Manage Campaign APIs

The section of the documentation details the API endpoints for creating, updating, and searching project type campaigns. It includes request and response structures, validation steps, and flow diagrams.

Admin Console

Element
Description

Filters

Boundary selection dropdown (e.g., district) and "Apply" button to filter results.

Results Display

Shows registers with details such as Project Name, Status, Supervisor Name, and Entries.

Status Filters

Groups results by register status (e.g., Pending for Approval, Approved).

User Actions Flow

  1. Select Boundary: Choose a district from the dropdown.

  2. Apply Filter: Click "Apply" to filter results.

  3. View Results: Access filtered attendance registers for the selected district.

API Endpoints

Endpoint
Purpose
Role

/registers-inbox/v2/filters/_search

Search registers by filter (district)

PROXIMITY_SUPERVISOR

/registers-inbox/v2/registers/{boundary}/_search

Retrieve registers for a selected boundary

PROXIMITY_SUPERVISOR

New checklist type rendering HCM.CHECKLIST_TYPES HOUSEHOLD, INDIVIDUAL to capture additional data

  • Option to add children to an individual's HOUSEHOLD_MEMBER_RELATIONSHIP_TYPES

  • Added parent overview page to render parent details and children under the individual

  • Added downsync of service to fetch submitted checklists of HOUSEHOLD and INDIVIDUAL checklists.

  • Role

    DISTRIBUTOR

    Sequence Diagram

    Facility

    Overview

    The Facility Registry manages facility-related data within the HCM system. It supports the key operations of creating, updating, deleting, and searching for facilities, along with their bulk counterparts.

    API Spec

    Sequence Diagrams

    Expense Calculator

    Overview

    The expense calculator is an implementation-specific service that works in tandem with the expense service. This service holds all the specific business logic for computing expenses and calls the billing service with the correct payload to create a bill. Once the bill is generated, Excel and PDF are generated by the calculator service.

    There are three types of bills in HCM:

    • Wage bill - generated from an approved muster roll and to be paid to wage seekers on completion of work

    API Specifications

    Base path: /health-expense-calculator/v1/

    The API specification is available . To view it in the Swagger editor, click below.

    Dependencies

    • DIGIT backbone services

    • Persister

    • MDMS

    • Attendance

    Master Data

    • Worker rates

    Sequence Diagrams

    DB Diagram

    MDMS data

    Related Topics

    Expense

    Overview

    The Expense service allows users to capture the details for expense bills and payments.

    API Specifications

    Base path: /health-expense/bill/

    API Contract Link

    The API specification is available . To view it in the Swagger editor, click below.

    Data Model

    DB Schema Diagram

    Web Sequence Diagrams

    Persister

    Persister configuration:

    Related Topics

    Beneficiary IDGen

    Overview

    The Beneficiary IDGenId feature is to link a unique ID to an individual. UniqueId’s are fetched from the server with the unique DeviceId and user.

    Key Feature

    1. Fetching UniqueID’s from the server with device and user combination

    2. Added new ID_TYPE - UNIQUE_BENEFICIARY_ID to link individuals

    3. Added search with UNIQUE_BENEFICIARY_ID

    Sequence Diagram

    Role: DISTRIBUTOR

    Search Data API

    Endpoint

    • Endpoint: /data/_search

    • Method: POST

    Request Structure

    • RequestInfo: Object containing request information.

    • SearchCriteria: Object containing search criteria.

      • id: (Optional) ID of the resource.

      • tenantId: Tenant identifier.

    Response Structure

    • ResponseInfo: Object containing response information.

    • ResourceDetails: Array containing the details object of the searched resource.

    Flow

    1. Client Request: The client sends a POST request to /data/_search.

    2. Request Content: Includes RequestInfo and SearchCriteria.

    3. Validation: The server validates request structure and content.

    4. Response Creation: The server creates a response with info and resource details.

    Flow Diagram

    Attendance

    Update & approve attendance

    Overview

    The Proximity Supervisor Flow for managing attendance registers is designed to provide supervisors with a seamless experience for selecting projects, viewing associated attendance records, and managing the details effectively. The flow emphasises ease of navigation, quick access to project and register information, and actionable steps to edit or approve attendance records.

    Features

    • Project Selection: Enables supervisors to pick a specific project to manage.

    • Registers Inbox: Displays filtered attendance registers for selected boundaries.

    • View Attendance: Provides detailed attendance information for campaigns and projects.

    • Edit Attendance: Allows supervisors to update attendee records.

    Role
    Description

    Each step in this flow ensures user-friendly interactions and adheres to the necessary validation rules and role-based permissions for supervisors and project managers.

    Note: In Payments version 0.1, each user will be associated with only one project.

    Sequence Diagram

    Stock

    Overview

    The Stock Service is responsible for managing stock and inventory workflows. It handles all operations related to stock records and their reconciliation in health campaigns.

    API Spec

    Sequence Diagrams

    Generate Bill

    Overview

    The Campaign Supervisor Flow is designed to streamline the management of attendance registers and bill generation processes for supervisors overseeing specific projects and boundaries. This flow ensures efficient selection, filtering, and approval of registers and simplifies the generation and tracking of bills. It focuses on clear workflows, actionable feedback, and validation mechanisms to enhance usability and accuracy.

    Features

    • Project and Bill Aggregation Selection: Supervisors select a project and boundary aggregation level to narrow down the scope for attendance registers and billing.

    • Registers Filtering and Bill Generation: Enables supervisors to filter registers based on boundaries, view attendance data, and generate bills only when all registers are approved.

    • Bill Management (My Bills): Provides a centralised view of all generated bills, with tools for searching, filtering, and downloading them in preferred formats.

    Role
    Responsibility

    This structured approach empowers supervisors to manage attendance registers and related billing tasks with ease while adhering to necessary validations and role-based permissions.

    Sequence Diagram

    Select Project

    Overview

    The Select Project allows supervisors to select a project and view or manage attendance registers associated with that project.

    Interface Elements

    Attendance

    Description of the attendance service

    Overview

    The Attendance Service is a comprehensive back-end solution designed to support health campaigns by providing efficient and transparent attendance management. It facilitates the streamlined tracking of health campaign workers, volunteers, and contractors, ensuring accurate participation records and enabling informed decision-making.

    Note: Deletion of attendees from the system is not recommended, even in cases where participation in the campaign has ceased. Attendance records should instead reflect the status of absent for all days following the departure. This practice ensures the integrity of attendance data, preserves historical records, and supports accurate reporting and auditing processes.

    Key functionalities include:

    Project & Bill Aggregation

    Overview

    This is the initial screen where the user selects:

    1. Project: The specific project they are managing.

    2. Bill Aggregation Level: The boundary level at which the bill should be generated (Country, Province, or District).

    Download Data API

    Endpoint

    • Endpoint: /data/_download

    • Method: POST

    Muster roll
  • Project

  • Individual

  • Expense

  • Localization

  • PdfService

  • Filestore

  • here
    Swagger Editor
    Expense calculator configuration
    Bill generation
    Excel/PDF generation

    type: (Optional) Type of the resource (boundary, facility, user, boundaryWithTarget).

  • status: (Optional) Status of the resource.

  • Response Dispatch: Sends response back to client.

  • Error Handling: If errors occur, generate an error response and send it.

  • Approve Attendance: Facilitates approval with clear validation and comment requirements.

    PROXIMITY_SUPERVISOR

    manage attendance registers, approving and editing the attendance data

    Attendance Edit and Approval By Proximity Supervisor
    Element
    Description

    Project Selection

    • Dropdown to select the project

    Action Buttons

    • Back: Navigate to the previous page.

    • Next: Proceed to the attendance registers for the selected project.

    User Actions Flow

    1. Select a Project: Choose a project from the dropdown list.

    2. Proceed to Next Screen: Click "Next" to access the registers associated with the project.

    Maintaining attendance registers.

  • Enrolling and managing individuals.

  • Creating, updating, and searching attendance logs.

  • Managing staff permissions for attendance-related operations.

  • API Specifications

    Base Path: /health-attendance/

    API Contract Link

    https://editor.swagger.io/?url=https://raw.githubusercontent.com/egovernments/DIGIT-Works/f525b183782a353812f7e2432a2989a86c498810/backend/attendance/Attendance-Service-1.0.0.yaml

    Data Model

    DB Schema Diagram

    Attendance with Offline Enablement of Logs

    Web Sequence Diagrams

    Attendance Register

    Staff

    Attendee

    Attendance Log

    Users cannot proceed without filling out these fields.

    Interface Elements

    Element
    Details

    Project Selection

    Dropdown menu to select the project.

    Bill Aggregation Level

    Dropdown menu to select the aggregation level (Country, Province, District).

    Action Buttons

    - Back: Navigate to the previous screen. - Next: Proceed to view registers mapped to the selected project.

    User Actions Flow

    1. Use the dropdown menu to select the project.

    2. Select one of the available aggregation levels (Country, Province, or District) from the dropdown.

    3. Click the "Next" button to navigate to the register filtering screen.


    Validations

    • Both fields are mandatory:

    • If either the Project or Bill Aggregation Level is not selected, an error toast message is displayed if you try to proceed.

    Request Structure
    • RequestInfo: Object containing request information.

    • Type: (Optional) Type of the resource being downloaded.

    • TenantId: Tenant identifier.

    • HierarchyType: Type of hierarchy.

    • Id: (Optional) ID of the resource being downloaded.

    • Filters: (Optional) Additional filters for the download request.

    • campaignId : campaignId

    Response Structure

    • ResponseInfo: Object containing response information.

    • ResourceDetails: Array containing the details object of the downloaded resource.

    Flow

    1. Client Request: The client sends a POST request to download data.

    2. Request Validation: Upon receiving the request, the server validates the request structure and parameters.

    3. Data Download Process:

      • Validation: Validate the download request.

      • Fetch Data: Fetch existing data of the specified type from the data host service.

      • Processing: Process the retrieved data as necessary.

    4. Response Creation: After processing the request, the server creates a response containing the details of the latest resource, ensuring that only one result is fetched.

    5. Response Dispatch: The server sends the generated response back to the client.

    6. Error Handling: If errors occur during the process, an error response is generated and sent.

    Flow Diagram

    Handling Empty or Missing Downloaded Responses

    If the downloaded response is empty or not searched with the provided ID, the system automatically starts regenerating a template of the same type. The generation process is triggered by the backend, not through the UI.

    CAMPAIGN_SUPERVISOR

    aggregate the bill generation, based on district, province or country and download it for further processing

    here
    Swagger Editor
    Expense persister
    Functional specifications - Expense
    Expense service configuration
    Facility - Create
    Facility - Update
    Facility - Search
    Stock - Create
    Stock - Update
    Stock - Search
    Product Variant - Create
    Product Variant - Update
    Product Variant - Search

    Household

    Overview

    The Household Registry is a core microservice in DIGIT’s registry framework, enabling the management of households and their members within the Health Campaign Management (HCM) context. It provides structured APIs for CRUD operations and search capabilities, both at the household level and for individual household members.

    API Spec

    Sequence Diagrams

    Referral

    Overview

    The Referral Service manages both referrals and side effects linked to health campaign beneficiaries.

    API Spec

    Sequence DIagrams

    Search Project Type Campaign Endpoints

    Endpoint

    POST /project-type/search

    Request Structure

    Body Parameters

    • RequestInfo: Object containing RequestInfo.

    • CampaignDetails: Object containing the search criteria for campaigns.

    • tenantId: Tenant identifier.

    • ids: Array of campaign IDs to search for.

    Response Structure

    Success Response

    • ResponseInfo: Object containing ResponseInfo details.

    • CampaignDetails: Array containing details of matching campaigns.

    • totalCount: Total number of matching campaigns.

    Flow

    Client Initiates Request

    The client sends a searchCampaign request to the Project Factory Service.

    Validate Request

    The Project Factory Service validates the request schema and search criteria.

    Search Campaigns

    • The Project Factory Service constructs a search query based on the provided criteria.

    • It checks if there are specific search fields like start date, end date, campaign name, etc.

    • Depending on the campaignsIncludeDates flag, the service adjusts the search conditions accordingly.

    Response

    The Project Factory Service sends the response back to the client.

    • The response contains the matching campaign details along with the total count, if applicable.

    Flow Diagram

    Product

    Overview

    The Product Registry serves as one of the foundational registries, used to manage products and their variants within the Health Campaign Management (HCM) framework.

    API Spec

    Sequence Diagrams

    Muster Roll

    Overview

    The Muster Roll service aggregates attendance logs from the attendance service based on some rules and presents an attendance aggregate for a time period (week or month) per individual. This can then be used to compute payments or other semantics.

    Dependencies

    Code

    API Specifications

    Base Path: /health-muster-roll

    API Contract Link

    Data Model

    DB Schema Diagram

    Web Sequence Diagrams

    Master Data

    Related Topics

    Transit Post

    Overview

    The Transit Post Package is a Flutter module designed to streamline transit post operations, such as selecting posts, scanning resources, and tracking deliveries. Built for seamless integration in larger logistics and delivery systems, it leverages Bloc for robust state management and uses reactive forms for capturing user input efficiently. The module is structured for reusability, testability, and separation of concerns via repository patterns.


    Project

    Overview

    The Project Service orchestrates the logic around managing projects. It forms the bridge between high-level campaign workflows and underlying entity registries.

    API Spec

    Update Campaign API Endpoints

    Endpoint

    POST /project-type/update

    Request Structure

    My Bills

    The "My Bills" section serves as a centralised dashboard for campaign supervisors to view and manage all bills associated with their assigned projects. By default, the dashboard displays all bills related to the projects under their supervision. Supervisors can search for specific bills or filter them using date ranges or by bill ID.

    Interface Elements

    Search Filters

    1. Bill ID: Enter a specific Bill ID.

    2. Date Range: Select a start and end date to filter bills within a specific time frame.

    Target Data Upload API

    Base URL: project-factory/v1/

    Endpoint: /data/_create

    • Method: POST

    Request Structure

    Create Campaign

    Overview

    This document outlines the flow for creating a campaign using various services in the system. The process involves interactions between multiple services, including the Project Factory, Project Service, Boundary Service, Facility Service, HRMS Service, MDMS Service, FileStore Service, and the database. This flow ensures that the required resources are validated and correctly set up before finalizing the campaign creation.

    Create Campaign API Endpoints

    Endpoint

    POST /project-type/create

    Request Structure

    Household Member Bulk Update
    Household Member - Search
    Household Member - Delete
    Household Member - Bulk Delete
    Household Create
    Household Bulk create
    Household Update
    Household bulk update
    Household Search
    Household Delete
    Household Bulk Delete
    Household Member - Create
    Household Member Bulk Create
    Household Member - Update
    Referral Delete
    Referral Bulk Delete
    HFReferral Create
    HFReferral Bulk Create
    HFReferral Update
    HFReferral Bulk Update
    HFReferral Delete
    HFReferral Bulk Delete
    Swagger Editor
    Side Effect Create
    Side Effect Bulk Create
    Side Effect Update
    Side Effect Bulk Update
    Side Effect Delete
    Side Effect Bulk Delete
    Referral Create
    Referral Bulk Create
    Referral Update
    Referral Bulk Update

    startDate: The start date for the search.

  • endDate: End date for the search.

  • projectType: Type of the project.

  • campaignName: Name of the campaign.

  • status: Status of the campaign.

  • createdBy: Creator of the campaign.

  • campaignNumber: Number of the campaign.

  • campaignsIncludeDates: Flag to include campaigns based on dates.

  • pagination: Object containing pagination settings.

    • limit: Maximum number of results to return.

    • offset: Offset for paginated results.

    • sortOrder: Sort order for results (asc/desc).

    • sortBy: Field to sort results by.

  • If campaignsIncludeDates is true:
    • It shows only those campaigns whose start date is on or before the provided start date and whose end date is on or after the provided end date.

  • If campaignsIncludeDates is false:

    • It shows only those campaigns whose start date is on or after the provided start date and whose end date is on or before the provided end date.

  • The service executes the constructed query to retrieve matching campaign details from the database.

  • Workflow
  • User

  • Attendance

  • DIGIT backbone services
    Idgen
    Persister
    Indexer
    Module code
    Helm charts
    Muster Roll service configuration
    Key Features

    User Interface (Pages)

    The user interface is organised into modular pages, each responsible for a distinct step in the transit post workflow. These pages are designed to be simple, responsive, and directly integrated with Bloc state management for dynamic updates.

    • transit_post_selection.dart UI for displaying and selecting available transit posts. Initiates the delivery process and triggers navigation to the recording step.

    • transit_post_record_vaccination.dart UI for resource scanning (QR/barcode) and entry of delivery details using reactive forms. Performs validation and provides real-time feedback.

    • transit_post_acknowledgment.dart Displays a summary and acknowledgement after a successful delivery submission.

    • transit_post_wrapper.dart Acts as the parent widget, managing navigation and Bloc provisioning for the entire flow.

    State Management (Bloc Pattern)

    The application uses the Bloc pattern to ensure predictable state management, clear separation of concerns, and a responsive user interface throughout the transit post workflow. Each Bloc handles a specific stage of the process:

    • TransitPostSelectionBloc

      • Manages loading and selection of transit posts.

      • Events: LoadPosts, SelectPost

      • States: Loading, Loaded, Selected, Error

    • TransitPostRecordVaccinationBloc

      • Handles scanning, form input, and delivery validation.

      • Events: StartScan, SubmitDelivery, ValidateInput

      • States: Initial, Scanning, Validated, Delivered, Error

    • TransitPostAcknowledgmentBloc

      • Controls the acknowledgement and confirmation stage.

      • Events: Acknowledge, Reset

      • States: Pending, Acknowledged

    • Bloc Integration

      • Each page provides or consumes its relevant Bloc using BlocProvider or BlocConsumer.

      • UI reacts to state changes for navigation and updates.

    Data Layer (Repositories)

    The application follows the Repository pattern to keep business logic independent from data storage and networking, making the system modular, testable, and easy to extend. Two key repository abstractions are defined:

    • UserActionLocalRepository (abstract)

      • Handles local persistence (e.g., SQLite, Hive)

      • Methods: saveDelivery, getPendingDeliveries, markAsAcknowledged

    • UserActionRemoteRepository (abstract)

      • Handles remote persistence (API integration)

      • Methods: submitDelivery, fetchTransitPosts, fetchDeliveryHistory

    Reactive Forms

    The application uses the reactive_forms package to manage dynamic and validated data entry during the transit post flow. This approach ensures a structured way to capture delivery details while providing immediate feedback to users.

    • Dynamic Form Handling – Forms can adapt to different input types such as resource details, quantities, or delivery metadata, enabling flexible data capture for various scenarios.

    • Built-in Validation – Validation rules are applied directly within the form controls, ensuring data accuracy. Errors and invalid inputs are highlighted in real time, guiding the user to correct issues before submission.

    • Seamless UI Feedback – The form state is reactive, meaning any change in input instantly reflects in the UI. This creates a smooth user experience with live validation messages and input tracking.

    By combining dynamic fields, validation, and real-time feedback, Reactive Forms make the delivery recording process reliable, user-friendly, and less prone to data entry errors.


    Key Classes & Structure

    • UI Widgets:

      • TransitPostSelectionPage

      • TransitPostRecordVaccinationPage

      • TransitPostAcknowledgmentPage

      • TransitPostWrapper

    • Bloc Classes:

      • TransitPostSelectionBloc, TransitPostSelectionEvent, TransitPostSelectionState

      • TransitPostRecordVaccinationBloc, TransitPostRecordVaccinationEvent

    • Repositories (Abstract):

      • UserActionLocalRepository

      • UserActionRemoteRepository


    Note: The modular design makes the Transit Post Package extensible for other resource types and business rules by adding new pages, events, or repository implementations.

    Sequence Diagram

    Sequence Diagrams
    Project - Create

    Project - Update

    Project - Search

    Project Task - Create
    Project Task - Update

    Body Parameters
    • RequestInfo: Object containing RequestInfo.

    • CampaignDetails: Object containing the details of the campaign to be updated.

    • id: Unique identifier of the campaign.

    • tenantId: Tenant identifier.

    • hierarchyType: Type of hierarchy.

    • action: Action type (create or draft).

    • boundaries: Array of boundaries.

    • resources: Array of resources.

    • projectType: Type of the project.

    • deliveryRules: Array of delivery rules.

    Response Structure

    Success Response

    • ResponseInfo: Object containing ResponseInfo.

    • CampaignDetails: The updated campaign details.

    Flow

    Receive Request

    The ProjectFactoryService receives an updateCampaign request from the Client.

    Validate Request Schema

    The received request schema is validated to ensure it matches the expected format.

    Check Campaign Existence

    The system checks if the campaign specified in the request exists in the database.

    Conditional template generation call

    • If boundaries are different from the campaign in the database, call:

      • Facility template generate

      • User template generate

      • Target template generate

    • If delivery conditions are different, call:

      • Target template generate

    Check Campaign Status

    If the campaign exists, the system checks its status in the database.

    Handle Drafted Status

    If the campaign status is 'drafted':

    1. Validate Boundaries: Validate the request for hierarchyType and boundaries.

    2. Validate Project Type: It validates the request for the project type code from MDMS.

    3. Enrich Campaign Details: Enrich the campaign details and set the status to 'updating'.

    4. Update Campaign Details: Update the campaign details in the database.

    5. Update Resource Data: Update each resource data associated with the campaign through the /project-factory/v1/data/_update API.

    6. Enrich Boundaries: Enrich the boundaries for the project update.

    7. Update Projects: Update projects associated with each boundary.

    8. Persist Changes: Persist the updated campaign details in the database.

    9. Send to Kafka Topic: Send the updated CampaignDetails object to the Kafka topic for project mappings.

    10. Listen to Kafka: Listen for updates from the Kafka topic to get the updated CampaignDetails object for project mappings.

    Handle Campaign Status

    If the campaign status is not 'created':

    1. Do project mapping through /project-factory/v1/project-type/createCampaign API.

    2. Enrich the CampaignDetails and set the status to 'created'.

    3. Update the CampaignDetail in the database.

    Handle Project Mapping Error

    If the campaign status is 'created':

    1. Throw an error indicating that the project is already mapped for this campaign.

    2. Enrich the CampaignDetails and set the status to 'failed'.

    3. Update the CampaignDetail in the database.

    Handle Non-Drafted Status

    If the campaign status is not 'drafted', the system throws an error indicating that only drafted campaigns can be updated.

    Send Response

    The ProjectFactoryService sends a response to the Client based on the outcome of the update operation.

    Flow Diagram

    Action Buttons:

    • Search: Filters the results based on the provided criteria.

    • Clear Search: Resets the filters and shows all assigned bills.


    Bill List

    A table format displays the bills with the following columns:

    Field Name
    Description

    Bill ID

    A unique identifier assigned to each bill (e.g., WB-YYYY-MM-DD-XXXXX).

    Date

    The creation date of the bill.

    Boundary

    The geographic boundary associated with the bill (e.g., District, Province).

    Project Name

    The name of the project for which the bill was generated.

    Workers

    The total number of workers covered under the bill.

    No of Registers

    The total number of registers associated with the bill


    Status Descriptions

    • Generated: The bill has been successfully generated. The user can download it in PDF or Excel format.

    • In Progress: The report is still being generated. The user should wait for completion.

    • Failed: The report generation failed. The user can:

      • Retry the process.

      • Contact support if the issue persists.


    API Endpoints

    EndPoint
    Purpose

    /health-expense/bills/v1/_search

    Search bills by project id

    /filestore/v1/files/{id}

    Download details of a specific bill

    Body Parameters:

    • RequestInfo: Object Containing RequestInfo

    • ResourceDetails: Details of a given Resource

      • type: Type of resource to create (e.g., boundarywithTarget)

      • tenantId: Tenant

      • fileStoreId: FileStoreId of Target Upload Sheet

      • action: Action to perform (e.g., validate for target upload)

      • hierarchyType: Name of Boundary Hierarchy

      • campaignId: CampaignId

      • additionalDetails: Additional details (optional)

    Response Structure

    • Success Response:

      • ResponseInfo: Object Containing ResponseInfo

      • ResourceDetails: Details of the created resource

    Flow

    1. Client Initiates Request:

      • The client sends a POST request to /data/_create endpoint with action: validate.

    2. Validation of Request:

      • Resource Details Validation:

        • Check if request.body.ResourceDetails exists and is not empty.

        • Throw a validation error if missing or empty with the message "ResourceDetails is missing or empty or null".

      • Schema Validation:

        • Validate request.body.ResourceDetails against createRequestSchema.

      • Hierarchy Type Validation:

        • Validate hierarchyType in request.body.ResourceDetails using validateHierarchyType function.

      • Tenant ID Validation:

        • Ensure that request.body.ResourceDetails.tenantId matches request.body.RequestInfo.userInfo.tenantId.

        • Throw a validation error if they do not match with the message "tenantId is not matching with userInfo".

    3. Different Tab Headers Validation:

      • Validate whether headers are according to the template across all tabs of different districts.

    4. Target Sheet Validation:

      • All validations will be on Sheets other than the ReadMe Sheet and Boundary Data Sheet.

      • Immediate validations:

        • District Tabs Validation:

    Actors and Participants
    • Client: The entity (user or system) initiating the campaign creation request.

    • CampaignManager (Project Factory): The main controller managing the campaign creation process.

    • ProjectService: Manages project-related operations, including data creation and mapping.

    • BoundaryService: Handles fetching of boundary relationships based on hierarchy types.

    • FacilityService: Responsible for creating facility-related data.

    • HRMSService: Manages the creation of employee data.

    • MDMSService: Provides master data such as project types.

    • FileStoreService: Manages the storage and retrieval of resource files.

    • Database: Stores campaign-related data and status updates.

    Sequence Flow

    1. Initiate Campaign Creation

      • The Client sends a request to the CampaignManager to create a campaign with all required and valid resources.

    2. Fetch Boundary Relationship

      • The CampaignManager requests the BoundaryService to fetch the boundary relationship based on the hierarchy type.

      • The BoundaryService responds with the relevant boundary relationship data.

    3. Fetch Project Type Master

      • The CampaignManager requests the MDMSService to fetch the project type master data.

      • The MDMSService responds with the project type master.

    4. Validate Resource Files

      • The CampaignManager checks the Database to see if the input resource files have already been validated.

      • The Database responds with the validation status of the files.

    5. Validation Check

      • The CampaignManager checks if all file templates and data are validated:

        • If validation is successful, the CampaignManager informs the Client that the campaign creation process has started, and the user needs to track the status using an ID.

    6. Resource File Retrieval

      • The CampaignManager interacts with the FileStoreService to search for the resource based on the filestoreid.

      • The FileStoreService responds with the valid resource files.

    7. Process Resource Data

      • The CampaignManager processes the retrieved sheets and identifies any resource data that needs to be created.

    8. Facility Data Creation

      • The CampaignManager sends a request to the FacilityService to create facility data.

      • The FacilityService responds that the facilities have been created successfully.

    9. Employee Data Creation

      • The CampaignManager sends a request to the HRMSService to create employee data.

      • The HRMSService responds that the employees have been created successfully.

    10. Project Data Creation

      • The CampaignManager sends a request to the ProjectService to create project data with a parent-child relationship based on the project type and delivery configuration.

      • The ProjectService responds that the projects have been created successfully.

    11. Project-Facility Mapping Creation

      • The CampaignManager sends a request to the ProjectService to create mappings between projects and facilities.

      • The ProjectService responds that the project-facility mappings have been created successfully.

    12. Project-Staff Mapping Creation

      • The CampaignManager sends a request to the ProjectService to create mappings between projects and staff.

      • The ProjectService responds that the project-staff mappings have been created successfully.

    13. Update Campaign Creation Status

      • The CampaignManager updates the Database with the status of the campaign creation process.

    Error Handling

    • Validation Failure: If any validation step fails (e.g., invalid data in resource files), the CampaignManager sends an error message to the Client, indicating the failure. The user is required to fix the issues and resubmit the request.

    • Service Errors: If any of the service interactions (e.g., BoundaryService, MDMSService) return an error, the CampaignManager stops the process and informs the Client of the failure, specifying the nature of the error.

    • Database Errors: If the Database fails to update the campaign creation status, appropriate error handling and logging mechanisms should be triggered to handle the failure.

    API Sequence Diagram

    Create Campaign API Flow

    Conclusion

    This document provides an overview of the campaign creation flow, detailing each step and interaction between different services and the database. The flow ensures proper validation and creation of necessary resources, while error handling mechanisms provide robustness to the process.

    Body Parameters
    • RequestInfo: Object containing RequestInfo.

    • CampaignDetails: Object containing the details of the campaign to be created.

    • tenantId: Tenant identifier.

    • hierarchyType: Type of hierarchy.

    • action: Action type (create or draft).

    • boundaries: Array of boundaries.

    • resources: Array of resources.

    • projectType: Type of the project.

    • deliveryRules: Array of delivery rules.

    • Additional request info

    Response Structure

    Success Response

    • ResponseInfo: Object containing ResponseInfo.

    • CampaignDetails: The created campaign details.

    Flow

    Client Initiates Request

    The client initiates a createCampaign request to the Project Factory Service.

    Validate Request

    If the action is 'create':

    1. The Project Factory Service validates the request schema.

    2. It also validates the uniqueness of the campaign name in the database.

    3. If the campaign name exists, an error is thrown.

    If the action is 'draft':

    1. The Project Factory Service validates the request schema.

    2. It also validates the uniqueness of the campaign name in the database.

    3. If the campaign name exists, an error is thrown.

    Boundary and MDMS Validation

    For both 'create' and 'draft' actions:

    1. The Project Factory Service validates the request for hierarchy type and boundaries with the Boundary Service.

    2. It validates the request for the project type code from MDMS.

    Create Campaign

    If the action is 'create':

    1. The Project Factory Service validates the request for data resources.

    2. It enriches the CampaignDetails and sets the status to 'creating'.

    3. The CampaignDetails are persisted in the database.

    4. For each resource data, the Project Factory Service creates resources through the /project-factory/v1/data/_create API.

    5. It enriches boundaries for project creation and creates projects for each boundary with the Health Project Service.

    6. The enriched CampaignDetails are persisted in the database.

    7. The CampaignDetails object is sent to a Kafka topic for project mappings.

    8. If the campaign status is not "created", project mappings are performed through the /project-factory/v1/project-type/createCampaign API and the status is updated to 'created'.

    9. If the campaign status is already 'created', an error is thrown, and the status is updated to 'failed'.

    If the action is 'draft':

    1. The CampaignDetails are enriched, and the status is set to 'drafted'.

    2. The enriched CampaignDetails are persisted in the database.

    Response

    The Project Factory Service sends the response back to the client.

    Flow Diagram

    Product - Update
    Product - Search
    Product Variant - Create
    Product Variant - Update
    Product Variant - Search

    Attendance Revamp

    Overview

    The attendance revamp feature adds a tagging system to the attendance module. Tags help categorise and group attendees (e.g., by Skill, Project, Shift) and make it easier to search or filter attendance records. To support this, new APIs, search options, validation rules, and database changes have been introduced.


    Key Features

    1. Tagging Capability for Attendees

    • Tag Field: A new tag field is added to attendees, allowing teams to organise and filter data.

    • Bulk Tag Update API (POST /attendee/v1/_updateTag):

      • Allows you to update tags for multiple attendees at once.

    2. Tag-Based Attendee Search Enhancements

    • Search with Tags:

      • Tags can be used as an optional filter in /attendee/v1/_search.

      • Multiple tags supported, with AND/OR filtering.

    3. Database & Persistence Layer Changes

    • Schema:

      • Added a tag column to eg_wms_attendance_attendee.

      • Indexed for faster searches.

    4. Service, Repository & Model Enhancements

    • Service Layer:

      • New method updateAttendeeTag() in AttendeeService for bulk updates.

    • Repository:

    5. Code Cleanups & Improvements

    • Added new error messages for invalid tags, tenant mismatches, and missing attendees.

    • Removed unused constants/imports.

    • Updated version to 1.3.0 in pom.xml to reflect the new feature.


    Sequence Diagram

    Mobile User Flow

    Supervisor Flow

    Generate Bills

    Overview

    This screen allows Campaign Supervisors to:

    1. Filter attendance registers based on boundaries (Country, Province, and District) tied to the selected project and aggregation level.

    2. View the list of registers within the selected boundary.

    3. Generate bills for the selected boundary if all registers are approved.


    Interface Elements

    Filters Section

    no of levels will vary based on the aggregation level selection:

    • Country: Dropdown menu to select the country (e.g., Mbazi Highlands).

      • Mandatory Field: Must be selected before applying filters.

    • Province: Dropdown menu to select the province (e.g., Nampula).


    Register Inbox

    • Project Name: Displays the selected project name.

    • Aggregation Level: Displays the selected aggregation level (e.g., District level).

    • Register Status Summary:

      • Approved Registers

    Registers Table

    Displays a tabular list of attendance registers for the filtered boundary, with the following columns:

    Element
    Description

    Action Section

    • Generate Bill Button:

      • Enabled State: If all registers are approved, this button becomes active, allowing users to trigger the bill generation process and the bill is not already generated.

      • Disabled State: If any registers are pending approval, the button remains inactive.


    User Actions Flow:

    1. Filter Attendance Registers:

      • Mandatory Filters: The user must select a Country, Province, and District before clicking "Apply".

      • After clicking Apply, the attendance registers for the selected boundary are displayed.

    2. View Attendance Registers:


    Scenarios and System Responses:

    1. If all registers within the selected boundary are approved:

      • The Generate Bill button is enabled.

      • Upon clicking Generate Bill, an info message is displayed: "Bill generation in progress. Please wait."

    2. Bill Already Generated:


    Validations

    1. Boundary Selection:

      • All three boundary levels (Country, Province, and District) are mandatory for filtering attendance registers.

      • Error toast message if you click on apply without selecting all mandatory boundaries.

    2. The system verifies the approval status of all registers in the selected boundary before enabling the Generate Bill button.


    API Endpoints

    EndPoint
    Purpose

    View Attendance: Edit & Approve

    Overview

    Clicking on any register ID from the inbox displays detailed information about the attendance register. The screen includes information such as campaign details, attendance officer details, and attendee information. Users can perform two primary actions: Edit and Approve.

    Peer To Peer Transfer

    Overview

    This feature enables peer-to-peer (P2P) data exchange between devices without internet, leveraging Google Nearby Connections API and Wi-Fi Direct, Bluetooth, or Wi-Fi Hotspot. Data is securely transmitted using compression, AES encryption, and Base64 encoding.


    Project Factory - Campaign Manager

    Overview

    This service is used to create a Project (Campaign), create required resource data, and create a mapping relation between them based on the boundary data.

    Project Factory Flow

    Create Data API

    Endpoint

    • Endpoint: /data/_create

    • Method: POST

    Create Campaign Using Console

    Overview

    This document details the web flow for creating a new campaign using the Admin Console. The process involves interactions between various services, including the Project Factory, Boundary Service, MDMS Service, FileStore Service, and the Admin Console. This flow ensures that all necessary data is collected, validated, and processed to create a successful campaign.

    Central Instance

    Overview

    This release introduces the Central Instance Deployment Model for the Health Campaign Management (HCM) consolidating multi-tenant operations (can be multiple countries in one server or multiple states in one country) into a single Kubernetes cluster with namespace-level and database schema-level isolation.

    The goal is to reduce operational overhead, standardize configurations, and avoid service duplication while still supporting tenant-specific variations where necessary.

    Key areas of change include multi-schema database support, standardized Kafka topic conventions, updated Flyway migration scripts, and Helm/environment configuration adjustments to enable smooth centralized deployments across tenants.

    Main updates:

    Project Factory

    When dealing with large-scale data creation on a server based on Excel input, the choice between Python and Node.js depends on factors like performance, ecosystem support, scalability, and ease of development.

    Here’s a breakdown of both languages for this use case:


    1.Java

    Strengths:

    • Performance: Java delivers high performance for CPU-bound tasks due to its compiled nature and efficient memory management (JVM).

  • Validate whether all district tabs are present in the Target Sheet uploaded.

  • Empty Sheet Validation:

    • Throw a validation error if any Target Sheet is empty.

  • Root (District) level boundary validation:

    • Throw a validation error if the root column (District) is empty in any row.

  • Validations for each row:

    • Boundary Codes Validation:

      • Check for missing or empty boundary codes in any row of any sheet.

      • Check for boundary code columns to be of type string.

      • Check for the presence of more than one boundary code in a given row of a given Target Sheet.

      • Check for duplicacy of the boundary code within the given Target Sheet.

    • Boundary Targets Validation:

      • Ensure that Target values are not missing and are positive numbers less than 1 Million.

  • Multi-schema database support

  • Standardised Kafka topic naming

  • Updated Flyway migration scripts

  • Helm and environment configuration improvements for smooth multi-tenant deployments

  • Key Features

    1. Centralized Multi-Tenant Deployment

    • The new HCM server can now run campaigns for multiple countries in a single Kubernetes cluster, instead of spinning up a new server for every country or disease.

    • Introduced a common namespace hosting all shared and core services:

    • These are the services that are tenant agnostic in execution when and can be used by all different tenants configured in the server

    • Create dedicated tenant namespaces (e.g., tenantA, tenantB) for services requiring country-specific customizations

    • Encryption and id gen are currently tenant specific services

    2. Multi-Schema Database Support

    • A single PostgreSQL instance now hosts separate schemas (e.g. public, country1, country2) to isolate tenant data.

    • Updated Flyway migration process:

    • The new migrate.sh script loops through all configured schemas automatically.

    • Ensures all migrations execute across tenants without manual intervention.

    • Database schema lists and enablement flags are now configurable per service via Helm and environment YAML files.

    3. Standardized Kafka Topic Naming

    • All Kafka topics now use tenant-prefixed names to avoid cross-tenant collisions.

    Example:

    • country1: c1-save-household-topic

    • country2: c2-save-household-topic

    • country3: c3-save-household-topic

    4. Helm and Configuration Updates

    • Common values.yml now provides baseline DB and service configurations.

    • App-specific values.yml files override:

    • Schema lists (db-schemas).

    • Multi-schema enablement flags.

    • Most default configurations remain untouched, ensuring backward compatibility for services not requiring multi-schema support.

    6. Centralized Internal Gateway and MDMS v2

    • Internal Gateway configurations are now maintained centrally in a shared Git repository for easier updates.

    • MDMS v2 configurations for each tenant are consolidated, ensuring consistent metadata management.

    Breaking Changes

    Kafka Topic Renaming

    • All topics now follow a tenant-prefixed convention when the central instance is enabled.

    • Example: save-household-topic is now c1-save-household-topic(country1) or c2-save-household-topic(country2) if the central instance is enabled.

    • Persister, Indexer config files must be updated to have the correct topic name and use schema name.

    Flyway Migration Updates

    • Services running in the common namespace must now define their target schemas explicitly using:

    • SCHEMA_NAME (comma-separated schema list).

    • DB_URL (database url without schema name)

    • IS_ENVIRONMENT_CENTRAL_INSTANCE (boolean flag).

    • Helm and environment YAMLs must be updated for all multi-schema services.

    • The new migrate.sh script replaces manual schema-specific migrations.

    • Existing CI/CD pipelines must be updated to use the new script for deployments.

    Helm Chart Changes

    • values.yml for services must include overrides for:

    • Schema lists.

    • Enablement flags for multi-schema support.

    • Charts without overrides will default to single-schema mode (public schema).

    Namespace Restructuring

    • Some services must be redeployed into tenant-specific namespaces.

    • Any scripts or automation referencing old namespaces must be adjusted(public schema reference in database migrations are not allowed).

    Encryption Service

    Encryption Service is modified to not use default public schema for schema migration but use the db url defined in the environment properties.

    Scalability
    : Java is a proven choice for large-scale enterprise systems, supporting high concurrency via multi-threading and frameworks like
    Spring Boot
    and
    WebFlux
    .
  • Stability: Java is ideal for enterprise-grade applications requiring strict type safety and long-term stability.

  • Weaknesses:

    • Verbose Development: Java requires more boilerplate code and setup, slowing down initial development compared to Python or Node.js.

    • Complexity for I/O: Non-blocking I/O requires additional frameworks like Netty or reactive programming (WebFlux), adding complexity.

    • Startup Time: Java services have longer initialization times and higher memory usage compared to Node.js.

    • Excel Processing are often more complex and resource-intensive when processing large Excel datasets even with help of Libraries like Apache POI and JExcel .

    2. Node.js

    Advantages:

    • Event-Driven & Non-Blocking I/O: Node.js is excellent for I/O-heavy operations such as sending HTTP requests or interacting with APIs/servers concurrently.

    • Concurrency: With its single-threaded event loop and libraries like async/await, Node.js is efficient for tasks that involve network operations.

    • Excel Processing Libraries: Node.js has libraries like xlsx and exceljs for reading and writing Excel files. While they are performant, they are not as feature-rich as Python’s pandas.

    • Stream Support: Node.js natively supports streams, allowing large files to be processed in chunks without loading them fully into memory.

    • Scalability: Node.js performs well under high loads and can handle a massive number of concurrent connections due to its lightweight architecture.

    Disadvantages:

    • Data Processing: Node.js lacks the robust and mature data manipulation libraries Python offers (e.g., pandas), making it less efficient for complex data transformations.

    • CPU-Bound Operations: Node.js struggles with CPU-intensive tasks like large-scale data processing since it is single-threaded by default. This can be mitigated using worker threads.

    3. Python

    Advantages:

    • Excel Handling Libraries: Python has excellent libraries like pandas, openpyxl, and xlrd for reading, manipulating, and writing Excel files efficiently.

    • Data Manipulation: Python excels at processing and analyzing large datasets due to its data science-oriented libraries like pandas, NumPy, and Dask (for parallel processing).

    • Built-in Support for Parallelism: Libraries like multiprocessing or concurrent.futures allow Python to distribute processing of huge datasets across CPU cores.

    • Ease of Development: Python’s simplicity and extensive ecosystem make it easier to implement and test scripts for such tasks.

    • Data Export: Python can easily integrate with databases, APIs, or servers for data creation through libraries like requests (HTTP requests) or sqlalchemy (database connections).

    Disadvantages:

    • Slower Execution Speed: Python’s Global Interpreter Lock (GIL) can limit concurrency for I/O-heavy tasks, though libraries like asyncio and threading help mitigate this.

    • Memory Management: Python can use more memory for extremely large datasets compared to Node.js.

    • Scalability: If you need to process millions of concurrent requests, Python may require more effort to scale.

    When to Choose Node.js:

    • The task is I/O-intensive (e.g., creating data on other servers via HTTP APIs).

    • You need high concurrency and scalability.

    • You are working with large Excel files and want to leverage streaming to avoid loading entire files into memory.

    • You are already using a Node.js-based ecosystem and prefer to keep it consistent.


    When to Choose Python:

    • You need to process and transform huge datasets in Excel efficiently.

    • Your task involves heavy data manipulation or analytics.

    • You prefer working with established libraries like pandas and openpyxl.

    • Your use case is CPU-bound rather than I/O-bound (e.g., processing Excel locally before sending data to a server).

    Hybrid Approach (Optional)

    For complex use cases, you can use both:

    • Use Python for preprocessing and transforming large Excel files.

    • Use Node.js for efficient HTTP requests to create data on other servers.


    Final Recommendation:

    • If your task involves heavy Excel processing and transformations: Use Python.

    • If your task focuses on sending data concurrently to other servers: Use Node.js.

    If both Excel processing and data creation are important and you’re comfortable with Python, it’s often the better choice due to its ecosystem and ease of data manipulation


    Conclusion

    Considering the above points, we chose a Node.js implementation for the Project Factory Service. This service involves boundary creation based on the input Excel file, project creation for selected boundaries within a campaign, and the creation of entities such as facilities, users, and the necessary mappings between the created projects and these entities. We utilized the exceljs library to process the input Excel data for entity information, and we have observed that the total data creation like project, project mapping for 3000+ boundaries is completed within 15 minutes with high concurrency.

    If validation fails, the CampaignManager returns an error message, indicating which validation failed, and the user must resubmit the request.
    ,
    TransitPostRecordVaccinationState
  • TransitPostAcknowledgmentBloc, TransitPostAcknowledgmentEvent, TransitPostAcknowledgmentState

  • Validates attendees, tenant IDs, and tag values to ensure data integrity.

  • Tag Enrichment:

    • Only updates the tag field while keeping audit info (createdBy, createdTime) intact.

    • Supports idempotent and partial updates.

  • Validation Rules:

    • Requires tenantId in requests.

    • Attendees must exist in the system before updates.

    • Tags must be valid (non-empty).

    • Prevents cross-tenant updates or invalid inputs.

  • Model Update:
    • AttendeeSearchCriteria now includes a tags field (List<String>).

    • tenantId is mandatory when searching with tags.

    Persister Config:
    • Updated attendance-service-persister.yml to handle tags in insert, update, and mapping queries.

    Extended to support tag-based search and updates.

  • Model / DTOs:

    • Added tag field to IndividualEntry, Attendee, AttendeeUpdateTagRequest, AttendeeUpdateTagResponse, and AttendeeSearchCriteria.

    • Ensures tags flow consistently from request → service → DB → response.

  • Mandatory Field: Must be selected before applying filters.

  • District: Dropdown menu to select the district (e.g., Murrupula).

    • Mandatory Field: Must be selected before applying filters.

  • Apply Button: Triggers the filter to display attendance registers for the selected boundary.

  • : Shows the count of approved registers (e.g.,
    18
    ).
  • Pending Registers: Shows the count of pending registers (e.g., 0).

  • The filtered registers are shown in a tabular format.

  • Generate Bill:

    • The Generate Bill button is enabled only if all the registers within the selected boundary are approved and the bill has not been generated already.

    • Clicking Generate Bill triggers the bill generation process:

      • A confirmation pop-up appears with the warning.

      • Buttons:

        • Cancel: Returns to the register list.

        • Proceed: Starts the bill generation process.

    • A toast message will be shown whether the bill generation started or failed. And an info message will be displayed with the same.

  • If all registers within the selected boundary are approved, but a bill has already been generated:

  • An info message is displayed: "Bill has already been generated for this boundary."

  • Pending Registers:

    • If some registers within the selected boundary are still pending approval:

    • An info message is displayed: "Bill cannot be generated until all the registers are approved."

  • Register ID

    Unique identifier for each attendance register

    Boundary

    Indicates the boundary associated with the register

    Supervisor Name

    Displays the name of the supervisor associated with the register

    Number of Workers

    Displays the total number of workers in the register

    /health-attendance/v1/_search

    Retrieve attendance registers by boundary

    /health-expense/bill/v1/_search

    Checks if bill is already generated or not

    /health-expense-calculator/v1/_calculate

    Trigger bill generation for selected boundary

    Interface Elements
    • Campaign Details: Displays the campaign name, ID, and dates.

    • Attendance Officer Details: Name, ID, and contact information.

    • Attendee Information: Includes register ID, attendee names, and attendance data.

    • Action Buttons:

      • Edit Attendance: Allows editing attendance details.

      • Approve Attendance: Approve the attendance register.

    Element
    Description

    Register Details

    Displays Attendance ID, Campaign Name, Project Type, Boundary, and other metadata.

    Attendee Table

    Lists attendee details, including Name, ID, Designation, and Hours Worked.

    Action Button

    Enables editing or approving attendance (if conditions are met).

    Validation Message

    Informs users if the campaign is ongoing and actions are disabled.

    Validations & Conditions

    1. Campaign Status:

      • If the campaign is ongoing, the Edit and Approve buttons are disabled, and only a "Back" button is shown.

      • Administrators can override this behaviour through MDMS (configurable settings).

    2. Approved Registers:

      • If the register is already approved, the action buttons are disabled, and a "Back" button is displayed.

    3. Role-Based Permissions:

      • Only authorised supervisors can access the Edit/Approve features.

    Action Flows

    1. Edit Attendance Flow

    a. Step 1: Pop-Up Confirmation

    • Message: "Editing attendance will affect the number of days for attendees. Do you want to proceed?"

    • Buttons:

      • Cancel: Close the pop-up.

      • Proceed: Navigate to the Edit Attendance screen.

    b. Step 2: Edit Attendance Screen

    Columns
    Editable
    description

    Campaign Worker

    NO

    Name of attendee

    User Name

    NO

    Username of attendee

    Role

    NO

    Role of attendee

    Number of Days

    YES

    number of days worked by the attendee

    • Validation:

      • The number of days worked must be a positive integer and must not exceed the event duration.

    • Submit Button Behaviour:

      • Initially disabled until changes are made.

      • Upon submission:

        • Displays a success message: "Attendance updated successfully!"

        • Displays an error message if the update fails.

    1. Approve Attendance Flow

      1. Step 1: Add Comment

        • Message: "Please add a comment before approving."

        • Input Field: Allows users to enter comments (mandatory).

        • Buttons:

          • Cancel: Closes the pop-up and returns to the view screen.

          • Submit: Proceeds to the final warning.

    1. Step 2: Confirmation Pop-Up

      • Message: "Do you want to approve this attendance register?"

      • Buttons:

        • Cancel: Closes the pop-up and remains on the view screen.

        • Proceed: Opens a Comment Entry Pop-Up.

    1. Step 4: Success Page

      • Message: "Attendance approved"

      • Action: view another register or go back home.

    EndPoint
    Description

    health-attendance/v1/_search

    fetch the registers details

    health-individual/v1/_search

    fetch the attendee and staff details

    /health-muster-roll/v1/_update

    to update the attendee attendance and approve registers

    /health-muster-roll/v1/_estimate

    to fetch estimate data of registers

    /health-muster-roll/v1/_search

    fetch the muster role data for regiter

    Architecture Components

    Device Communication Layer

    Nearby Connections API (Google)

    • Discovery/Connection: Uses BLE for discovery, Wi-Fi Direct/Hotspot for transfer, and automatically selects the best medium.

    • Roles:

      • Advertiser: Device making itself available

      • Discoverer: Device searching for peers

    Supported Topologies

    • P2P_CLUSTER: Mesh, several devices, low bandwidth, suitable for multiplayer/gaming.

    • P2P_STAR: One hub, others connect to it, ideal for content sharing.

    • P2P_POINT_TO_POINT: Direct 1-to-1, highest speed, best for large files.

    • Wi_Fi_P2P: Wi-Fi Direct, long-range, for games or large files.

    Connection Selection Logic

    • On connection attempt, use:

      • BLE for initial discovery

      • Wi-Fi Direct/Hotspot for large/high-speed transfers

      • Fallback to Bluetooth if Wi-Fi is not available


    Secure Payload: Compression & Encryption

    Compression (zlib/GZipEncoder)

    • Input: JSON-encoded Dart Map

    • Process:

      • Convert JSON string to UTF-8 bytes

      • Compress using GZipEncoder

    • Output: Compressed byte array


    Encryption (AES-CBC via encrypt package)

    • Key Generation: 32-byte random key (AES-256)

    • IV Generation: 16-byte random IV

    • Algorithm: AES in CBC mode

    • Process:

      • Encrypt compressed bytes with AES-CBC using key & IV

    • Security Notes:

      • Unique IV per encryption for semantic security

      • Key+IV must be securely stored or sent with the payload


    Base64 Encoding

    • Purpose: Convert binary (key, IV, encrypted data) to URL/text/QR-compatible string

    • Process:

      • Encode each part (key, IV, data) as Base64 URL-safe

      • Wrap into a JSON:

      • Encode the full JSON as a final Base64 URL-safe string


    Decryption & Decompression Process

    1. Decode Base64:

      • Outer string → JSON

    2. Extract Payload:

      • Decode key, IV, data fields from JSON (Base64 → bytes)

    3. Decrypt:

      • Use AES-CBC with key & IV to decrypt data → compressed bytes

    4. Decompress:

      • GZipDecoder on decrypted bytes → UTF-8 JSON

    5. Deserialize:

      • Parse JSON to Dart Map


    Key Classes

    P2P Communication

    • NearbyConnectionManager

      • Handles advertising, discovery, connection, and data transfer

    • ConnectionStrategy

      • Enum: P2P_CLUSTER, P2P_STAR, P2P_POINT_TO_POINT, WI_FI_P2P

    • ConnectionEventListener

      • Handles state changes, errors, and received bytes

    Secure Payload Handling

    • SecurePayloadCompressor

      • compress(Map data): List<int>

      • decompress(List<int> compressed): Map

    • AESCipher

      • encrypt(List<int> data, key, iv): List<int>

      • decrypt(List<int> encrypted, key, iv): List<int>

    • Base64PayloadEncoder

      • encode(key, iv, data): String

      • decode(String): (key, iv, data)


    Data Flow: Send/Receive Sequence

    1. Sender:

      • Serialize Map → JSON → UTF-8 bytes

      • Compress (GZip) → compressed bytes

      • Generate AES key & IV

      • Encrypt (AES-CBC) compressed bytes → encrypted bytes

      • Base64-encode (key, IV, encrypted) → JSON → Base64-encode JSON

      • Send over a P2P connection

    2. Receiver:

      • Receive Base64-encoded string

      • Base64-decode → JSON → extract key, IV, encrypted data

      • AES decrypt → compressed bytes


    Sequence Diagram

    Dependencies
    1. Project

    2. Facility

    3. Product

    4. HRMS

    5. MDMS

    6. Boundary

    7. Localisation

    8. Access Control

    9. IdGen

    10. Individual

    11. User

    API Specification

    Base Path: /project-factory/

    API Contract Link

    Swagger Editor - Project Factory API Spec

    Data Model

    DB Schema Diagram

    Project Factory related tables

    Campaign Table

    Table Details

    Web Sequence Diagrams

    Request Structure
    • Body Parameters:

      • RequestInfo: Object containing request information.

      • Resource Details: Object containing the details of the resource to be created or validated.

        • type: Type of resource (boundary, facility, user, boundaryWithTarget).

        • tenantId: Tenant identifier.

        • fileStoreId: File store identifier.

        • action: Action type (create or validate).

        • hierarchyType: Type of hierarchy.

        • campaignId: Campaign identifier.

        • additionalDetails: Additional details object (optional).

    Response Structure

    • Success Response:

      - ResponseInfo: Object containing response information.

      - ResourceDetails: Array containing the detail objects of the created or validated resource.

    Flow

    1. Client Initiates Request: The client sends a createData request to the Project Factory service.

    2. Validation of Request: The Project Factory service validates the request schema and the provided resource details.

    3. Processing the Request:

      • If action is 'create':

        • Enrich resource details, set status to "data-accepted", and persist in the database.

        • Further creation process happens in the background.

        • After successful creation, set the status to 'completed' and persist resource details in the database.

      • If action is 'validate':

        • Enrich resource details, set the status to "validation-started", and persist in the database.

        • Further creation process happens in the background.

        • If file data is invalid, set the status to 'invalid' and persist in the database.

      • Fail case: If validation or creation fails, set the status to 'failed' and persist in the database with the error cause in additional details.

    4. Response: The Project Factory service sends the response back to the client containing the resource details and status.

    Flow Diagram

    Parsing Logic from sheet

    The getSheetData function retrieves and processes data from an Excel sheet, validating the structure according to the configuration provided in createAndSearchConfig. The key part of this process is the parseArrayConfig.parseLogic configuration, which specifies how to parse and validate the columns in the sheet. Here's a detailed explanation of how the function works, including the parsing logic:

    Parsing Logic Using parseArrayConfig.parseLogic

    The parseArrayConfig.parseLogic configuration specifies how each column in the sheet should be processed. Here's how the parsing logic works:

    Column Configuration

    Each column configuration specifies:

    • sheetColumn: The column letter in the sheet.

    • sheetColumnName: The expected name of the column in the sheet.

    • resultantPath: The path where the value will be stored in the resultant JSON.

    • type: The expected type of the value (e.g., string, number, or boolean).

    • conversionCondition: Optional conditions for converting values.

    Validating Column Names

    During the validation step, the function checks that the first-row value matches the expected column name.

    Processing Rows

    When mapping the rows to JSON, the function uses the resultantPath to place the values in the correct location in the JSON object. It converts values according to the specified type and conversionCondition.

    Example Conversion

    For a column configuration with type: "boolean" and conversionCondition, the function would convert "Permanent" to true and "Temporary" to an empty string.

    In summary, the getSheetData function retrieves and processes data from an Excel sheet, validating the structure and content according to the createAndSearchConfig configuration. The parseArrayConfig.parseLogic configuration specifies how each column should be validated and processed into the resultant JSON format.

    Actors and Participants
    • User: The person interacting with the Admin Console to set up and create a campaign.

    • CampaignManager (Admin Console): The main interface that the user interacts with to manage campaign creation.

    • ProjectFactory: Handles the creation and management of campaign objects and validation processes.

    • BoundaryService: Provides information about boundary hierarchy and relationships.

    • MDMSService: Supplies master data such as project types, hierarchy configurations, and operator details.

    • FileStoreService: Manages the storage and retrieval of files related to the campaign.

    Sequence Flow

    1. Campaign Setup Initialisation

    • User: Initiates the process by visiting the Admin Console to set up a new campaign.

    • CampaignManager: Receives the request to set up a campaign and starts interacting with various services to gather necessary information.

    2. Fetch Master Data

    • CampaignManager sends a request to MDMSService to fetch required master data, including:

      • Project types

      • Hierarchy type configuration

      • Operator templates

      • Other necessary templates

    • MDMSService responds with the requested master data, which is used to configure the campaign.

    3. Fetch Boundary Information

    • CampaignManager requests BoundaryService to fetch boundary hierarchy definitions based on the selected hierarchy type.

      • BoundaryService responds with the boundary hierarchy definition.

    • CampaignManager requests BoundaryService to fetch boundary relationship data based on the selected hierarchy type.

      • BoundaryService responds with the boundary relationship data.

    4. User Data Input

    • User: Fills in the required data, such as boundary delivery configuration and other campaign-specific details within the Admin Console.

    • CampaignManager: Sends the user-filled information to ProjectFactory to create a campaign object and stores it with an initial action status of "draft".

    5. Template Generation

    • ProjectFactory: Automatically triggers the generation of templates for different resources, including:

      • Target templates

      • Facility templates

      • User templates

    6. Template Download and Storage

    • User: Downloads the generated templates for each resource type through the Admin Console.

    • CampaignManager: Sends a request to FileStoreService to store the downloaded files.

      • FileStoreService responds with a filestoreid that uniquely identifies the stored file.

    7. Data Validation

    • CampaignManager: Sends the data and the filestoreid to ProjectFactory for validation.

      • ProjectFactory responds with a unique validation ID, as the validation process may take some time.

    • CampaignManager: Periodically checks the status of the validation using the unique validation ID.

    8. Validation Outcome

    • ProjectFactory:

      • If validation is successful:

        • Responds with a success message.

        • CampaignManager: Displays a success message to the user, indicating that they can proceed to the next step.

      • If validation fails:

        • Responds with an error message detailing the validation failure.

        • CampaignManager: Displays the error message to the user, prompting them to correct the errors and re-upload the files.

    9. Final Campaign Creation

    • User: Once all required data is filled in and validated, the user reviews the summary of the campaign data and clicks on the "Create Campaign" button.

    • CampaignManager: Sends a final request to ProjectFactory with the campaign creation API, marking the action as "create".

    10. Campaign Creation Outcome

    • ProjectFactory:

      • If the creation is successful:

        • Responds with a success message indicating that the campaign creation has started.

        • CampaignManager: Displays a success message to the user, confirming the campaign creation.

      • If the creation fails:

        • Responds with an error message detailing the failure.

        • CampaignManager: Displays the error message to the user, prompting them to correct any issues and try again.

    Error Handling

    • Validation Failures: If validation fails at any stage (e.g., during file validation or input data checks), the CampaignManager will notify the user of the specific issues. The user must resolve these issues and re-upload the necessary data to proceed.

    • Service Errors: If any of the services (e.g., BoundaryService, MDMSService, ProjectFactory) encounter an error during processing, the CampaignManager will display an error message, detailing the problem and suggesting corrective actions.

    Web Sequence Diagram

    Conclusion

    This document outlines the end-to-end flow for creating a new campaign using the Admin Console. It ensures that the user provides all required information and that data is validated and processed correctly to create the campaign. This structured approach minimises errors and ensures that all campaigns are set up with the required accuracy and completeness.

    Status

    The current status of the bill (e.g., Generated, In Progress, Failed).

    Project Staff - Create
    Project Staff - Update
    Project Beneficiary - Create
    Project Beneficiary - Update
    Project Beneficiary - Search
    Project Facility - Create
    Project Facility - Update
    Project Facility - Search
    Project Resource - Create
    Project Resource - Update
    Project Resource - Search
    User Action Flow
    Location Capture Flow

    Generate Data API

    Endpoint

    • Endpoint: /data/_generate

    • Method: POST

    Request Structure

    • RequestInfo: Object containing request information.

    • Query Parameters:

      • type: Type of the resource for which data needs to be generated.

      • tenantId: Tenant identifier.

    Response Structure

    • ResponseInfo: Object containing response information.

    • GeneratedResource: Array containing the details object of the generated resource.

    Flow

    1. Client Request: The client sends a POST request to /v1/data/_generate.

    2. Request Validation: After receiving the request, the server validates the request structure and parameters.

    3. Generate Data Process:

      • Validation: The server validates the generated request.

    Flow Diagram

    Data to Sheet Parsing Logic

    1. Fetch Required Columns from MDMS:

      • Use callMdmsData to get type schema columns in the correct order.

    2. Define Headers:

    Adding a New Column to the Generated Sheet

    To add a new column to the Generated sheet, follow these steps:

    1. Search Schema Details

      • Locate the type schema from the HCM-ADMIN-CONSOLE.adminSchema schema in the workbench.

    2. Identify Column Type

    Sheet Data Validation:

    This process is sufficient for validating the new column in the generated sheet.

    Column Change Reflection in APIs

    If there's a need to reflect the column in APIs, follow these additional steps:

    1. Update createAndSearch.ts File

      • Modify the createAndSearch.ts file under the defined type parseLogic object.

      • Integrate the new column into the appropriate data structures used for API operations.

    By following these steps, you can successfully add and validate a new column in the generated sheet and ensure its reflection in the associated APIs.

    Template Properties

    General Rules

    • Locked Headers: The headers in the templates for each data type (user, facility, target) are locked and cannot be changed.

    • Sheet Protection: Certain sheets within the templates will have specific locked areas to ensure data integrity.

    • README Sheet: Each type of template includes a README sheet which is read-only and locked.

    Target Template

    • Editable Columns: You can only modify the 'Target' column. All other columns are locked and cannot be edited.

    Facility Template

    • Adding Rows: You are allowed to add new rows to create new facilities.

    • Editable Columns: You can modify the "Boundary Code" and 'Usage' columns.

    • Locked Sheets: The boundary data sheet within the facility template is locked and cannot be modified.

    • Dropdown Columns: The following columns are dropdowns:

    User Template

    • Adding Rows: You are allowed to add new rows.

    • Locked Sheets: The boundary data sheet within the user template is locked and cannot be modified.

    • Dropdown Columns: The following columns are dropdowns:

      • Role

    Data for Dropdowns

    • The data for the dropdown columns comes from the mdms (Master Data Management System) under the adminSchema master.

    Generate Boundary API

    Overview

    Base URL: project-factory/v1/

    Endpoint: /data/_generate

    Method: POST

    Request Structure

    Body Parameters:

    • RequestInfo: Object containing RequestInfo

    • Query Parameters:

      • tenantId: Tenant

      • type: Type of Resource (e.g., boundary)

    Response Structure

    Success Response:

    Flow

    1. Client Initiates Request:

      • The client initiates a dataGenerate request to the Project Factory Service.

    2. Validation of Request:

      • Schema Validation: Validate against generateRequestSchema.

    • Fetch configurable columns from mdms present for each campaign type from schema -[HCM-ADMIN-CONSOLE.adminSchema].

    • Here is a sample data from the given schema, having configurable columns for Campaign SMC-

    1. Handle Error:

      • Update the status to failed, add error details, log the error, and produce a message to the update topic.

    2. Downloading the generated boundary template through /data/_generate API:

      • One can get the filestoreId through the /data/_download API, which will fetch from the database using the ID from the response of /data/_generate API.

    Note: The downloaded Template will have one ReadMe sheet, one Boundary Data Tab, and all other tabs on several unique districts (or whichever level is configured).

    Update Ongoing Campaign

    Overview

    This document details the low-level design for handling campaign creation and update flows when a parent campaign is present. The system supports hierarchical campaigns, boundary inheritance, resource template generation, and robust retry mechanisms. This design aims to ensure data consistency, correct parent-child relationships, and efficient error recovery.


    Data Model Changes

    Database: Campaign Details Table

    • New Columns

      • isActive (boolean): Indicates if the campaign is currently active.

      • parentId (string): References the parent campaign’s unique ID, if any.


    Request Validation Logic

    Parent Campaign Validation

    • If parentId is present in the request:

      • On create action:

        • Parent campaign (parentId


    Boundary Management Logic

    • For child campaigns:

      • The boundaries array in the request must contain only new boundaries.

      • Existing boundaries are fetched from the parent campaign.

      • Merged boundaries = parent boundaries + new boundaries (for use in template/resource generation).


    Resource & Template Generation

    On Campaign Creation (with Parent Campaign)

    • Generate templates for all three types: boundary, user, facility.

    • If actionInUrl = create and parentId is present, templates are generated freshly using both parent and new boundaries.

    On Campaign Update

    • For newly added boundaries, create new projects/resources only for those.

    • If existing targets are updated, call update on the respective project with new target mappings.

    • Facility and user sheets can be edited: updating these updates related mappings (ProjectFacility, ProjectStaff).


    Retry Mechanism

    • If campaign creation or update fails, a retry API allows the process to restart from the failure point.

    • Retry is stateful and resumes based on the persisted CampaignDetails and status.

    Retry API Example:


    Campaign Object Structure

    • See below for sample fields (simplified):

    • After each update and once the campaign is in the "Created" state, templates are consolidated for future updates.


    Update & Multiple Update Handling

    • After a campaign reaches the "Created" state:

      • Uploaded template sheets (Facility, User, Target) are consolidated back to the initial format.

      • Any subsequent update is handled as the first update (fresh diff against the current state).


    Edit Mappings in Update Flow

    • In the update flow, facility mappings to boundary codes can be edited and toggled (active/inactive).

    • Updates propagate to ProjectFacility and ProjectStaff mapping tables.


    Sequence Flow

    1. Request received with or without parentId.

    2. Validation:

      • If parentId present, validate parent state as per action.


    Error & Edge Case Handling

    • Validation Errors:

      • If the parent campaign is not in the required state, reject the request.

      • If new boundaries overlap with the parent, reject or merge as per the business rule.

    • Retry Errors:


    Points to consider:

    • All actions logged with audit details (user, timestamp).

    • Only authorised roles can create/update hierarchical campaigns.


    Sample Payload

    Multiple updates to a Campaign

    1. Once the ongoing campaign is updated and reaches the "Created" state, the updated sheet templates (i.e., Facility, User, and Target) are consolidated back into the format used during the initial "Create" flow.

    2. This ensures that when you attempt to update the campaign again, it will be treated as the first update.

    Retry API Payload

    Campaign Process flow

    🔄 Simplified Parent-Child Campaign Management Design Flow

    Core Principle

    At any point in time, only one campaign—either the parent or its successfully completed child—should be considered active and operational. A parent campaign remains active until a child campaign completes successfully and takes over its role.

    1️⃣ Initial Child Campaign Creation

    • Validation:

      • Before creating a new child campaign, verify whether the parent already has a child campaign with:

        • isActive: true

      • If such a child exists, reject the request

    2️⃣ During Child Campaign Processing (Update Phase)

    • The child campaign continues with:

      • isActive: true

      • status reflecting progress (e.g., inprogress, validating)

    • The parent campaign remains:

    3️⃣ On Successful Child Campaign Completion

    • Once the child campaign is fully processed and marked status: 'completed':

      • Child remains isActive: true

      • Parent's isActive is updated to false

    • Why: This marks the official handoff. The child becomes the sole operational campaign, and the parent is retired from active use.

    4️⃣ Cancelling a Child Campaign

    • If a child campaign is needed to be cancelled:

      • Set its isActive: false

    • Why: The child is clearly marked as non-operational. The parent continues as the active campaign, and a new child can be initiated later.

    5️⃣ On Failed Child Campaign Creation/Update

    • If a failure occurs during child creation/update:

      • Keep isActive: true

      • Set status: 'failed'

      • Parent remains isActive: true

    🔍 Campaign Search Functionality

    Approach: Enhance the existing searchProjectTypeCampaignService and searchProjectCampaignResourcData.

    Proposed Changes:

    File: src/server/config/models/searchCampaignDetails.ts

    • Add:

      • isChildCampaign?: boolean

      • parentId?: string

    File: src/server/utils/campaignUtils.ts → buildSearchQuery()

    • Modify query generation:

      • If isChildCampaign === true, add AND parentId IS NOT NULL

      • If isChildCampaign === false, add AND parentId IS NULL

      • If parentId is specified, add AND parentId = $X

    🔎 How to Search

    1. All child campaigns:

    {

    "tenantId": "yourTenantId",

    "isChildCampaign": true

    }

    2. Currently active (parent or completed child):

    {

    "tenantId": "yourTenantId",

    "isActive": true,

    "status": "completed" // optional

    }

    3. Cancelled or inactive child campaigns:

    {

    "tenantId": "yourTenantId",

    "isChildCampaign": true,

    "isActive": false

    }

    4. Parent campaigns not yet replaced:

    {

    "tenantId": "yourTenantId",

    "isChildCampaign": false,

    "isActive": true

    }

    ⚙️ Code-Level Integration

    ✅ Max One Active Child Validation

    • In createProjectTypeCampaignService or processBasedOnAction:

      • Query for existing active children (isActive: true) before proceeding.

    ✅ Deactivating Parent After Child Completion

    • On child status transition to completed:

      • Fetch parent campaign

      • Set isActive = false

      • Persist the update ( via Kafka)

    ✅ Campaign Cancellation API

    Endpoint: POST /project-factory/v1/project-type/cancel-campaign

    Purpose: Cancels a campaign by setting:

    • isActive = false

    • status = "cancelled" The update is sent via Kafka.

    🔧 Request Body

    🟢 Success Response (200)

    Returns updated campaign with:

    • isActive: false

    • status: "cancelled"

    🔁 Idempotency

    Safe to call multiple times. Same result is returned.

    🧩 Internals

    • Validates inputs

    • Fetches campaign

    • Updates status

    • Produces to Kafka topic

    Manage Resources

    Overview

    This document outlines the various API flows and interactions for the Project Factory, focusing on resource data creation with retry logic, template generation, campaign update flows, and data search and download processes. The aim is to manage and automate various aspects of resource and campaign data efficiently using the Project Factory services.

    Sequence Flow

    Project Factory Resources Data Create with Retry Logic

    Description: This flow describes how the Project Factory handles resource data creation with retry logic. It ensures data consistency and reliability by retrying operations if failures occur.

    Sequence of Operations

    1. Client Request Initiation:

      • The client sends a request to the Project Factory with filestoreid and type.

    2. MDMS Service Interaction:

    Template Generate API Flow (forceUpdate = true)

    Description: This flow is triggered when a client sends a generate request with forceUpdate = true. It checks for existing data and creates a new row with the status inProgress if necessary.

    Sequence of Operations:

    1. Client Request Initiation:

      • The client sends a generate request with the specified type and forceUpdate = true.

    2. Validation and Data Check:

    Template Generate API During Update Campaign Flow (forceUpdate = true)

    Description: This flow is initiated when a generate request is sent due to a boundary change in an ongoing campaign.

    Sequence of Operations:

    1. Boundary Change Trigger:

      • The Project Factory sends a generate request with campaignId, type, and forceUpdate = true.

    2. Validation and Data Check:

    Project Factory Resources Data Search and Download

    Description: This flow allows the client to search and download resource data based on a provided ID and type.

    Sequence of Operations:

    1. Client Request Initiation:

      • The client sends a request with the id and type.

    2. Database Query:

    Sequence Diagrams

    Conclusion

    The outlined API flows are crucial for handling resource data creation, management, and retrieval efficiently. They ensure data consistency, integrity, and seamless interaction between various services, making the Project Factory a robust system for managing campaign data. Implementing the retry logic, data validation, and template generation processes helps maintain a reliable and scalable architecture.

    Update Campaign

    Overview

    This document outlines the flow for updating an existing campaign using various services in the system. The process involves interactions between multiple services, including the Project Factory, Project Service, Boundary Service, Facility Service, HRMS Service, MDMS Service, FileStore Service, and the database. The update flow ensures that the required resources are validated and updated correctly before finalising the campaign update.

    Actors & Participants

    • Client: The entity (user or system) initiating the campaign update request.

    • CampaignManager (Project Factory): The main controller managing the campaign update process.

    • ProjectService: Manages project-related operations, including data creation and mapping updates.

    • BoundaryService: Handles fetching of boundary relationships based on hierarchy types.

    Sequence Flow

    1. Initiate Campaign Update

      • The Client sends an update request to the CampaignManager with all required and valid resources.

    2. Fetch Boundary Relationship

    Error Handling

    • Validation Failure: If any validation step fails (e.g., invalid data in resource files or missing required resources), the CampaignManager sends an error message to the Client, indicating the failure. The user is required to fix the issues and resubmit the request.

    • Service Errors: If any of the service interactions (e.g., BoundaryService, MDMSService, ProjectService) return an error, the CampaignManager stops the process and informs the Client of the failure, specifying the nature of the error.

    • Database Errors: If the Database fails to update the campaign update status or mark the parent campaign as inactive, appropriate error handling and logging mechanisms should be triggered to handle the failure.

    Sequence Diagram

    Update Campaign Flow

    Conclusion

    This document provides a comprehensive overview of the update campaign flow, detailing each step and interaction between different services and the database. The flow ensures proper validation and updating of necessary resources, while error handling mechanisms provide robustness to the process.

    Swagger Editoreditor.swagger.io
    SwaggerEditoreditor.swagger.io
    egov-mdms-data/data/mz/health/workerRates.json at UNIFIED-QA · egovernments/egov-mdms-dataGitHub
    Swagger Editoreditor.swagger.io

    End-to-End Process Flow

    The system supports an Excel-based workflow for various health campaign types (e.g., boundary, user, facility). It provides a dynamic, config-driven approach for template generation, data validation, and data processing.

    🔁 Overall Flow:

    Generate Template → Fill Data → Upload & Validate → Process Data

    Manage Boundary API

    Overview

    Base URL: project-factory/v1/

    Endpoint: /data/_generate

    Method: POST

    Boundary Management Through GeoJson

    Overview

    Base URL: project-factory/v1/

    Endpoint: /data/_generate

    Method: POST

    {
      "key": "<Base64-encoded AES key>",
      "iv": "<Base64-encoded IV>",
      "data": "<Base64-encoded encrypted data>"
    }
    Table eg_cm_campaign_details {
      id varchar(128) [primary key ,not null, unique]
      tenantid varchar(64) [not null ,note: 'Tenant identifier']
      campaignname varchar(250) [not null ,note: 'Name of the campaign']
      projecttype varchar(128) [not null ,note: 'Type of project']
      startdate bigint [note: 'Start date in epoch']
      enddate bigint [note: 'End date in epoch']
      campaigndetails jsonb [note: 'Campaign specific details']
      status varchar(128) [not null ,note: 'Status of the campaign']
      parentid varchar(128) [note: 'refering to the previous campaign id']
      action varchar(64) [not null ,note: 'Action type']
      campaignnumber varchar(128) [not null ,note: 'Campaign number']
      hierarchytype varchar(128) [not null ,note: 'Hierarchy type']
      boundarycode varchar(64) [note: 'Boundary code']
      projectid varchar(128) [note: 'Project identifier']
      createdby varchar(128) [not null ,note: 'Created by user ID']
      lastmodifiedby varchar(128) [note: 'Last modified by user ID']
      createdtime bigint [note: 'Creation timestamp']
      lastmodifiedtime bigint [note: 'Last modification timestamp']
      additionaldetails jsonb [note: 'Additional details']
    }
    Table eg_cm_campaign_process {
      id varchar(128) [primary key, not null, unique]
      campaignid varchar(128) [not null,note: 'Foreign key to eg_cm_campaign_details.id']
      type varchar(128) [not null,note: 'Type of campaign process']
      status varchar(128) [not null,note: 'Status of the campaign process']
      details jsonb [note: 'Detailed information of the process']
      createdtime bigint [note: 'Creation timestamp']
      lastmodifiedtime bigint [note: 'Last modification timestamp']
      additionaldetails jsonb [note: 'Additional details']
    }
    Ref: eg_cm_campaign_process.campaignid > eg_cm_campaign_details.id // many-to-one
    Table eg_cm_generated_resource_details {
      id varchar(128) [primary key,not null, unique]
      filestoreid varchar(128) [note: 'File store ID']
      status varchar(128) [not null,note: 'Status of the resource']
      type varchar(128) [not null,note: 'Type of resource']
      tenantid varchar(128) [not null,note: 'Tenant identifier']
      count bigint [note: 'Count of resources']
      createdby varchar(128) [note: 'Created by user ID']
      createdtime bigint [note: 'Creation timestamp']
      lastmodifiedby varchar(128) [note: 'Last modified by user ID']
      lastmodifiedtime bigint [note: 'Last modification timestamp']
      additionaldetails jsonb [note: 'Additional details']
      hierarchytype varchar(128) [not null,note: 'Hierarchy type']
      campaignid varchar(128) [note: 'Foreign key to eg_cm_campaign_details.id']
    }
    Ref: eg_cm_generated_resource_details.campaignid > eg_cm_campaign_details.id // many-to-one
    
    Table eg_cm_resource_activity {
      id varchar(128) [primary key,not null, unique]
      retrycount int [note: 'Number of retry attempts']
      type varchar(64) [not null,note: 'Type of activity']
      url varchar(128) [not null,note: 'URL for the activity']
      requestpayload jsonb [note: 'Request payload']
      tenantid varchar(128) [not null,note: 'Tenant identifier']
      responsepayload jsonb [note: 'Response payload']
      status bigint [note: 'Status code']
      createdby varchar(128) [note: 'Created by user ID']
      createdtime bigint [note: 'Creation timestamp']
      lastmodifiedby varchar(128) [note: 'Last modified by user ID']
      lastmodifiedtime bigint [note: 'Last modification timestamp']
      additionaldetails jsonb [note: 'Additional details']
      resourcedetailsid varchar(128) [not null,note: 'Foreign key to eg_cm_resource_details.id']
    }
    Ref: eg_cm_resource_activity.resourcedetailsid > eg_cm_resource_details.id // many-to-one
    
    
    
    Table eg_cm_resource_details {
      id varchar(128) [primary key,not null, unique]
      status varchar(128) [note: 'Status of the resource']
      tenantid varchar(128) [not null,note: 'Tenant identifier']
      filestoreid varchar(128) [note: 'File store ID']
      processedfilestoreid varchar(128) [note: 'Processed file store ID']
      action varchar(128) [not null,note: 'Action type']
      type varchar(64) [not null,note: 'Type of resource']
      createdby varchar(128) [note: 'Created by user ID']
      createdtime bigint [note: 'Creation timestamp']
      lastmodifiedby varchar(128) [note: 'Last modified by user ID']
      lastmodifiedtime bigint [note: 'Last modification timestamp']
      additionaldetails jsonb [note: 'Additional details']
      campaignid varchar(128) [note: 'Foreign key to eg_cm_campaign_details.id']
    }
    
    Ref: eg_cm_resource_details.campaignid > eg_cm_campaign_details.id // many-to-one
    
    
    parseLogic: [
        {
            sheetColumn: "A",
            sheetColumnName: "HCM_ADMIN_CONSOLE_FACILITY_CODE",
            resultantPath: "id",
            type: "string"
        },
        {
            sheetColumn: "B",
            sheetColumnName: "HCM_ADMIN_CONSOLE_FACILITY_NAME",
            resultantPath: "name",
            type: "string"
        },
        {
            sheetColumn: "C",
            sheetColumnName: "HCM_ADMIN_CONSOLE_FACILITY_TYPE",
            resultantPath: "usage",
            type: "string"
        },
        {
            sheetColumn: "D",
            sheetColumnName: "HCM_ADMIN_CONSOLE_FACILITY_STATUS",
            resultantPath: "isPermanent",
            type: "boolean",
            conversionCondition: {
                "Permanent": "true",
                "Temporary": ""
            }
        },
        {
            sheetColumn: "E",
            sheetColumnName: "HCM_ADMIN_CONSOLE_FACILITY_CAPACITY",
            resultantPath: "storageCapacity",
            type: "number"
        },
        {
            sheetColumn: "F",
            sheetColumnName: "HCM_ADMIN_CONSOLE_BOUNDARY_CODE_MANDATORY"
        }
    ]
    {
        "sheetColumn": "D",
        "sheetColumnName": "HCM_ADMIN_CONSOLE_FACILITY_STATUS",
        "resultantPath": "isPermanent",
        "type": "boolean",
        "conversionCondition": {
            "Permanent": "true",
            "Temporary": ""
        }
    }

    Project Factory retrieves the type schema from the MDMS Service.

  • MDMS Service returns the schema, which is then validated.

  • Data Validation:

    • The Project Factory validates the data against the MDMS schema.

    • If validation is successful, it informs the client that data processing has started.

    • If validation fails, an error message is returned, and the user must resubmit.

  • File Handling:

    • The Project Factory requests a file download from the FileStore Service.

    • Upon receiving the file, JSON data is created from the file of the desired type.

  • Data Creation and Retry Logic:

    • Data is validated according to the schema.

    • Normal Create:

      • Data is created in the respective service, and status is tracked.

      • A loop continues until retry attempts exceed the maximum retries, or no failed data remains.

    • Bulk Create with Retry:

      • Data is created in the respective service, and the status is checked.

      • A search is conducted using the generateApi search.

      • The loop continues under the same conditions as the normal create process.

  • Database Update:

    • The file is enriched with the created ID and sent back to the FileStore Service.

    • The updated file is received, and data is persisted in the database with a status of 'created' and the processed filestoreid.

  • The Project Factory validates the type against predefined types and hierarchytype.
  • A check is performed to see if previous data exists. If it does, the data is marked as expired.

  • Database and Response:

    • A new row is created with null fileStoreId and status inProgress.

    • The database is updated, and a successful response is sent back to the client.

  • Data Fetch and Storage:

    • The Project Factory fetches the template from the MDMS Service based on the type.

    • Data is consolidated and stored in the FileStore Service, which returns a filestoreid.

    • The database is updated with the new filestoreid.

  • The type is validated against predefined types and hierarchytype.

  • Previous data is checked, and if found, marked as expired.

  • The campaign is searched in the database based on the provided campaignId and its parent campaign ID.

  • Database and Response:

    • A new row is created with null fileStoreId and status inProgress.

    • The database is updated, and a response is provided.

  • File Update and Data Consolidation:

    • The Project Factory fetches file details from the FileStore Service using the parent campaign object.

    • The sheet is updated, freezing all the data.

    • If new boundaries are added, boundary relation data is fetched.

    • Data is consolidated and stored in the FileStore, and the database is updated with the new filestoreid.

  • The Project Factory checks the created resource based on the provided ID.

  • The corresponding resource details row is fetched from the database.

  • Response to Client:

    • The Project Factory sends back the created resource response to the client.

  • Create Campaign

    Update Campaign

    Manage Resources

    After successful creation, set the status to 'completed' and persist resource details in the database.

    GZip decompress → JSON string

  • Parse JSON → Map

  • 1. 📄 Template Generation Flow (generateFlowClasses)

    The template generation process creates structured Excel templates with localized headers, metadata, and placeholder content based on the campaign type.

    A. Configuration – generationTemplateConfigs.ts

    Defines the sheet structure and metadata for each campaign type:

    B. Generate Classes – e.g., boundary-generateClass.ts

    Purpose: Dynamically generate campaign-specific Excel templates.

    Key Method: TemplateClass.generate()

    Steps:

    1. Fetch campaign details from DB

    2. Load boundary hierarchy and relationships

    3. Localize boundary data and headers

    4. Generate readme and metadata sheets

    5. Create SheetMap with structured data

    6. Return data to generate Excel

    C. Template Generation Process – sheetManageUtils.ts

    2. 🧩 Data Processing Flow (processFlowClasses)

    Handles the uploaded Excel file, validates it, and processes the data to create or update entities in the system.

    A. Configuration – processTemplateConfigs.ts

    Defines how to process uploaded Excel files:

    B. Process Classes – e.g., boundary-processClass.ts

    Purpose: Validate and persist uploaded data.

    Key Method: TemplateClass.process()

    Steps:

    1. Validate resource details (file, campaign)

    2. Extract data from uploaded sheets

    3. Enrich data using boundary hierarchy

    4. Create/update boundary records

    5. Generate mapping and project data

    6. Process in topological (dependency-resolved) order

    C. Validation Classes – e.g., boundaryValidation-processClass.ts

    Purpose: Perform schema-based and business-rule validations.

    Key Method: TemplateClass.process()

    Steps:

    1. Validate against schema (column names, types)

    2. Check required vs optional columns

    3. Validate logical integrity (parent-child)

    4. Mark errors in Excel (cell comments, color)

    5. Return annotated Excel for user corrections

    D. Data Processing Utility – sheetManageUtils.ts

    3. 🔄 Complete End-to-End Flow

    ✅ Step 1: Template Generation

    • Trigger: User requests a template for a specific campaign type (e.g., boundary, user, facility)

    • Process:

      1. Load configuration from generationTemplateConfigs

      2. Fetch campaign data and related hierarchy

      3. Dynamically import *-generateClass.ts

      4. Call TemplateClass.generate() to generate data

      5. Generate Excel file with formatting, validation, and localization

      6. Upload to file store

    • Response: Returns fileStoreId and generation status

    ✅ Step 2: Data Upload & Processing

    • Upload: User uploads the filled Excel template

    🔍 Validation Phase (Optional)

    • Load validation class (e.g., boundaryValidation-processClass)

    • Validate against schema and business rules

    • Annotate errors directly in Excel file

    • Return Excel for correction

    ⚙️ Processing Phase

    • Load processing config and class (e.g., boundary-processClass)

    • Call TemplateClass.process() to:

      • Extract and validate data

      • Enrich using hierarchy

      • Persist via Kafka (batch insert/update)

    • Response: Returns processed Excel and summary

    4. 🧠 Key Features

    🔧 Dynamic Class Loading

    const className = `${type}-generateClass`; // or `${type}-processClass`

    const classFilePath = path.join(__dirname, '..', 'generateFlowClasses', `${className}.ts`);

    const { TemplateClass } = await import(classFilePath);

    • Plug-and-play support for new types (boundary, user, etc.)

    • Reduces code duplication

    🌐 Localization Support

    • Detects locale from Excel metadata

    • Supports multilingual sheet names and headers

    • Error messages and field names localized dynamically

    ⚡ Kafka Integration

    • Asynchronous, scalable data ingestion

    • Sends status, logs, and errors to Kafka

    • Enables reliable batch processing

    ✅ Validation Framework

    • Schema-driven validation

    • Business rule enforcement

    • Marks errors with cell comments and styles

    • Supports required vs optional fields

    🏗️ Hierarchical Data Processing

    • Handles parent-child boundary relationships

    • Uses topological sorting to maintain dependency order

    • Supports complex graph-based boundary structures

    5. 📦 Supported Sheet types

    Type

    Description

    boundary

    Geographic boundary and hierarchy

    user

    User onboarding and management

    facility

    Healthcare facility setup

    userCredential

    Authentication data for users

    Each type has:

    • A generate class for template creation

    • A process class for data ingestion

    • A validation class for pre-checking data

    boundary: {
    sheets: [
    {
    sheetName: "HCM_README_SHEETNAME",
    schemaName: "target-readme",
    lockWholeSheet: true
    }
    ]
    }
    
    export async function generateResource(responseToSend: any, templateConfig: any) {
    // 1. Get localization maps
    // 2. Load generate class dynamically
    // 3. Generate SheetMap using TemplateClass.generate()
    // 4. Create Excel file with localized structure
    // 5. Upload to file store
    // 6. Send status/event to Kafka
    }
    boundary: {
    sheets: [
    {
    sheetName: "HCM_README_SHEETNAME",
    lockWholeSheet: true
    }
    ],
    enrichmentFunction: "enrichTargetProcessConfig"
    }
    export async function processResource(ResourceDetails: any, templateConfig: any) {
    // 1. Download Excel file from file store
    // 2. Extract locale and sheet structure
    // 3. Load localization maps
    // 4. Dynamically load process/validation class
    // 5. Perform validation and/or processing
    // 6. Annotate sheet with validation results
    // 7. Upload processed file
    // 8. Send status/event to Kafka
    }

    hierarchyType: Type of hierarchy.

  • forceUpdate: (Optional) Boolean indicating whether to force update existing data.

  • Data Processing:

    • Fetch Data: Fetches existing data from the database.

    • Modify Data: Modify the retrieved data as necessary.

    • Generate New ID: Generates a new random ID and sets the file store ID to null.

    • Expire Old Data: Marks existing data status as expired.

    • Generate New Data: Generates new data based on the request parameters.

    • Update and Persist: Updates and persists the generated request along with the new data.

  • Force Update Logic:

    • If the forceUpdate parameter is set to true:

      • Search and Update: Searches for existing data of the specified type and updates the existing data information.

    • If the forceUpdate parameter is not provided or set to false:

      • Fetch Existing Data: Retrieves already persisted data from the database of the specified type.

  • Response Creation: After processing the request, the server creates a response containing the details of the generated resource.

  • Response Dispatch: The server sends the generated response back to the client.

  • Error Handling: If errors occur, generate an error response and send it.

  • MDMS schema required columns are headers and ensures column orders.
  • Localise Headers:

    • Use getLocalizedHeaders with localizationMap.

  • Localise Sheet Name:

    • Use getLocalizedName with localizationMap and generate a sheet.

  • Determine the column type based on the properties defined in the schema:
    • stringProperties for string-based columns.

    • numberProperties for numeric-based columns.

    • enumProperties for enumerated columns.

  • Define New Column

    • Add the new column to the schema under the appropriate properties section:

      • String Column: Include attributes such as name, type, maxLength, minLength, isUnique, isRequired, description, and orderNumber.

      • Number Column: Include attributes such as name, type, maximum, minimum, isRequired, description, orderNumber, and errorMessage.

      • Enum Column: Include attributes such as name, enum, isRequired, description, and orderNumber.

  • Ensure Column Uniqueness

    • Ensure that the isUnique property is correctly set for string columns to enforce uniqueness.

  • Column Visibility (Future Implementation)

    • Note that hideColumn and freezeColumn features will be implemented in the next version.

  • Example :

    • sheetColumn: A

    • sheetColumnName: HCM_ADMIN_CONSOLE_FACILITY_CODE

    • resultantPath: id

    • type: string

    • Mapping: Data from column A (HCM_ADMIN_CONSOLE_FACILITY_CODE) in the sheet will be mapped to id in the API data.

  • Facility Type

  • Facility Status

  • Facility Usage

  • Facility Usage: Facility usage can be 'Active' or 'Inactive'. Active facilities are used in the campaign and require a boundary code to map.

  • Employment Type

    forceUpdate: Boolean type (either true or false)

  • hierarchyType: Name of Boundary Hierarchy

  • campaignId: CampaignId

  • Tenant ID Validation: Ensure tenantId matches in query and RequestInfo.userInfo.

  • Force Update: Default to "false" if missing.

  • Hierarchy Type Validation: Validate hierarchyType for the tenantId.

  • Processing of Generate Request:

    • Fetch Data from DB:

      • Retrieve data using getResponseFromDb(request).

    • Modify Response Data:

      • Modify the fetched data with getModifiedResponse(responseData).

    • Generate New Entry:

      • Create a new entry with getNewEntryResponse(request).

    • Expire Old Data:

      • Update the status of old data to expired using getOldEntryResponse(modifiedResponse, request).

    • Persist Data Changes:

      • Call updateAndPersistGenerateRequest(newEntryResponse, oldEntryResponse, responseData, request).

        • Purpose:

          • If forceUpdate is true and data exists: Mark existing data as expired and create new data.

  • Boundary Data Processing:

    • Generate new Boundary Data:

      • Fetch Boundary Relationships.

      • If no boundary is found, generate an empty boundary sheet.

      • Fetch Filters from CampaignId and generate Boundary Data based on those Filters.

        • If Filters is null, it will generate the whole Boundary Data.

    • After the Boundary Sheet has been generated, append the ReadMeSheet.

    • Generate different tabs based on any boundary level configured (here District).

  • Generating Different Boundary Templates based on Campaign Type

  • ) must exist and
    isActive = true
    .
  • On update action:

    • Parent campaign (parentId) must exist and isActive = false (inactive).

  • Boundary merge:
    • To create, merge the parent and new boundaries.

    • For updates, only new boundaries are considered for new projects.

  • Template/Resource Generation:

    • Generate templates for relevant types (boundary, user, facility).

    • Edit and manage sheets/mappings as per user input.

  • Retry:

    • On failure, retry resumes from the last state using the latest CampaignDetails object.

  • If the retry fails repeatedly, log the state and escalate for manual intervention.

  • Parent-child relationships can be extended to deeper hierarchies if needed.
  • Additional resource/template types can be added.

  • Retry logic can be enhanced for partial retries and granular checkpoints.

  • with an appropriate error.
  • On Validation Pass:

    • Create the child campaign with:

      • isActive: true (indicating it's currently being usable)

      • status: 'draft' (or 'started'/'inprogress' based on next steps)

      • parentId: set to the parent campaign's ID

    • The parent campaign remains isActive: true.

  • Why: This ensures only one active child can exist at a time. The parent retains operational status while the child is in development.

  • isActive: true

  • Why: The child is actively being updated, but hasn't yet taken over. The parent remains the official operational campaign.

  • Why: The failed child still exists and can be retried. The parent remains active. If it’s decided not to retry the child, it can later be cancelled (setting isActive: false).

  • FacilityService: Responsible for creating and updating facility-related data.

  • HRMSService: Manages the creation and updating of employee data.

  • MDMSService: Provides master data such as project types.

  • FileStoreService: Manages the storage and retrieval of resource files.

  • Database: Stores campaign-related data and status updates.

  • The CampaignManager requests the BoundaryService to fetch the boundary relationship based on the hierarchy type.
  • The BoundaryService responds with the relevant boundary relationship data.

  • Fetch Project Type Master

    • The CampaignManager requests the MDMSService to fetch the project type master data.

    • The MDMSService responds with the project type master.

  • Validate Resource Files

    • The CampaignManager queries the Database to check if the input resource files have already been validated.

    • The Database responds with the validation status of the files.

  • Fetch Parent Campaign Object

    • The CampaignManager queries the Database to fetch the parent campaign object based on the parentCampaignId.

    • The Database responds with the parent campaign object.

  • Validation Check

    • The CampaignManager checks if all file templates and data are validated:

      • If validation is successful, the CampaignManager informs the Client that the campaign update process has started, and the user needs to track the status using an ID.

      • If validation fails, the CampaignManager returns an error message, indicating which validation failed, and the user must resubmit the request.

  • Deactivate Parent Campaign

    • The CampaignManager updates the Database to mark the parent campaign object as inactive.

  • Retrieve Resource Files

    • The CampaignManager interacts with the FileStoreService to search for the resource based on the filestoreid.

    • The FileStoreService responds with the valid resource files.

  • Process Resource Data

    • The CampaignManager processes the retrieved sheets to identify any resource data that needs to be created.

  • Facility Data Creation

    • The CampaignManager sends a request to the FacilityService to create facility data.

    • The FacilityService responds that the facilities have been created successfully.

  • Employee Data Creation

    • The CampaignManager sends a request to the HRMSService to create employee data.

    • The HRMSService responds that the employees have been created successfully.

  • Search for Parent Project

    • The CampaignManager sends a request to the ProjectService to search for the previous or parent project.

    • The ProjectService responds with the project object.

  • Create New Projects for Added Boundaries

    • The CampaignManager copies the project content from the parent project while creating new projects for newly added boundaries.

    • The CampaignManager sends a request to the ProjectService to create project data for newly added boundary data and map it according to its parent.

    • The ProjectService responds that the projects have been created successfully.

  • Update Facility Data

    • The CampaignManager identifies what exact data needs to be updated for facilities.

    • The CampaignManager sends a request to the ProjectService to create project-facility mapping if any new facilities are added.

    • The ProjectService responds that the project-facility mapping has been created successfully.

    • The CampaignManager sends a request to the ProjectService to search for the previous project-facility mapping.

    • The ProjectService responds with the project-facility mapping data.

    • The CampaignManager sends a request to the ProjectService to update the project-facility mapping.

    • The ProjectService responds that the project-facility mapping has been updated successfully.

  • Update Staff Data

    • The CampaignManager identifies what exact data needs to be updated for staff.

    • The CampaignManager sends a request to the ProjectService to create project-staff mapping if any new staff are added.

    • The ProjectService responds that the project-staff mapping has been created successfully.

    • The CampaignManager sends a request to the ProjectService to search for the previous project-staff mapping.

    • The ProjectService responds with the project-staff mapping data.

    • The CampaignManager sends a request to the ProjectService to update the project-staff mapping.

    • The ProjectService responds that the project-staff mapping has been updated successfully.

  • Update Campaign Status

    • The CampaignManager updates the Database with the campaign update status.

  • Request Structure

    Body Parameters:

    • RequestInfo: Object containing RequestInfo

    • Query Parameters:

      • tenantId: Tenant

      • type: Type of Resource (e.g., boundaryManagement)

      • forceUpdate: Boolean type (either true or false)

      • hierarchyType: Name of Boundary Hierarchy

      • campaignId: default (Mandatory)

    Response Structure

    Success Response:

    Flow

    1. Client Initiates Request:

      • The client initiates a dataGenerate request to the Project Factory Service.

    2. Validation of Request:

      • Schema Validation: Validate against generateRequestSchema.

      • Tenant ID Validation: Ensure tenantId matches in query and RequestInfo.userInfo.

      • Force Update: Default to "false" if missing.

      • Hierarchy Type Validation: Validate hierarchyType for the tenantId.

    3. Processing of Generate Request:

      • Fetch Data from DB:

        • Retrieve data using getResponseFromDb(request).

      • Modify Response Data:

    4. Boundary Data Processing:

      • Generate new Boundary Data:

        • Fetch Boundary Relationships.

        • If no boundary is found, generate an empty boundary sheet.

    5. Generating Different Boundary Templates based on Campaign Type

    • Fetch configurable columns from mdms present for each campaign type from schema -[HCM-ADMIN-CONSOLE.adminSchema].

    • Here is a sample data from the given schema having configurable columns for Campaign SMC-

    1. Handle Error:

      • Update status to failed, add error details, log the error, and produce a message to the update topic.

    2. Downloading the generated boundary template through /data/_generate API:

      • One can get the filestoreId through the /data/_download API, which will fetch from the database using the ID from the response of /data/_generate API.

    After successfully generating the sheet, you will get from filestoreId will be like.

    Note:

    Downloaded Template will have one ReadMe sheet, one Boundary Data Tab, and all other tabs on a number of unique districts(or whichever level configured).

    147KB
    BoundaryGenerationData.xlsx
    Open
    Boundary Generation Data
    Request Structure

    Body Parameters:

    • RequestInfo: Object containing RequestInfo

    • Query Parameters:

      • tenantId: Tenant

      • type: Type of Resource (e.g., boundaryManagement)

      • forceUpdate: Boolean type (either true or false)

      • hierarchyType: Name of Boundary Hierarchy

      • campaignId: default (Mandatory)

    Response Structure

    Success Response:

    In this API the filestore ID will be the ID the geoJson file which will be:

    Flow

    1. Client Initiates Request:

      • The client initiates a dataGenerate request to the Project Factory Service.

    2. Validation of Request:

      • Schema Validation: Validate against generateRequestSchema.

      • Tenant ID Validation: Ensure tenantId matches in query and RequestInfo.userInfo.

      • Force Update: Default to "false" if missing.

      • Hierarchy Type Validation: Validate hierarchyType for the tenantId.

    3. Processing of Generate Request:

      • Fetch Data from DB:

        • Retrieve data using getResponseFromDb(request).

      • Modify Response Data:

    4. Boundary Data Processing:

      • Generate new Boundary Data:

        • Fetch Boundary Relationships.

        • If no boundary is found, generate an empty boundary sheet.

    5. Generating Different Boundary Templates based on Campaign Type

    • Fetch configurable columns from mdms present for each campaign type from schema - (HCM-ADMIN-CONSOLE.adminSchema).

    • Here is a sample data from the given schema having configurable columns for the SMC campaign:

    1. Handle Error:

      • Update status to failed, add error details, log the error, and produce a message to the update topic.

    2. Downloading the generated boundary template through /data/_generate API:

      • One can get the filestoreId through the /data/_download API which will fetch from db using the id from the response of /data/_generate API.

    After successful generation, the sheet you will get from filestoreId will be:

    Note: The downloaded template will have one ReadMe sheet, one Boundary Data tab, and all other tabs on a number of unique districts (or whichever level is configured).

    147KB
    BoundaryGenerationData.xlsx
    Open
    Boundary Generation Data
    Swagger Editoreditor.swagger.io
    Swagger Editoreditor.swagger.io
    SwaggerEditoreditor.swagger.io
    releasekit/mdms/HCM/v1.8/MusterRoll.json at master · egovernments/releasekitGitHub
    releasekit/mdms/HCM/v1.8/IdFormat.json at master · egovernments/releasekitGitHub
    releasekit/mdms/HCM/v1.8/workerRates.json at master · egovernments/releasekitGitHub
    SwaggerEditoreditor.swagger.io
    {
       "ResponseInfo": {
           "apiId": "egov-bff",
           "ver": "0.0.1",
           "ts": 1716878176955,
           "status": "successful",
           "desc": "new-response"
       },
       "GeneratedResource": [
           {
               "id": "5ef5547e-414f-4164-9c12-644716e4fa71",
               "fileStoreid": null,
               "type": "boundary",
               "status": "inprogress",
               "hierarchyType": "ADMIN",
               "tenantId": "mz",
               "auditDetails": {
                   "lastModifiedTime": 1716878176947,
                   "createdTime": 1716878176947,
                   "createdBy": "867ba408-1b82-4746-8274-eb916e625fea",
                   "lastModifiedBy": "867ba408-1b82-4746-8274-eb916e625fea"
               },
               "additionalDetails": {
                   "Filters": null
               },
               "count": null
           }
       ]
    }
     "mdms": [
            {
                "id": "536f6de8-8c90-4631-b401-5a3beabf4893",
                "tenantId": "mz",
                "schemaCode": "HCM-ADMIN-CONSOLE.adminSchema",
                "uniqueIdentifier": "boundary.MR-DN",
                "data": {
                    "title": "boundary",
                    "$schema": "http://json-schema.org/draft-07/schema#",
                    "properties": {
                        "numberProperties": [
                            {
                                "name": "HCM_ADMIN_CONSOLE_TARGET_SMC_AGE_3_TO_11",
                                "type": "number",
                                "isRequired": true,
                                "description": "Target at village level - Age 3 to 11 Months (Mandatory and to be entered by the user)",
                                "orderNumber": 2
                            },
                            {
                                "name": "HCM_ADMIN_CONSOLE_TARGET_SMC_AGE_12_TO_59",
                                "type": "number",
                                "isRequired": true,
                                "description": "Target at village level - Age 12 to 59 Months (Mandatory and to be entered by the user)",
                                "orderNumber": 3
                            }
                        ],
                        "stringProperties": [
                            {
                                "name": "HCM_ADMIN_CONSOLE_BOUNDARY_CODE",
                                "type": "string",
                                "isRequired": true,
                                "description": "Boundary Code",
                                "orderNumber": 1,
                                "freezeColumn": true
                            }
                        ]
                    },
                    "campaignType": "MR-DN"
                },
                "isActive": true,
                "auditDetails": {
                    "createdBy": "63a21269-d40d-4c26-878f-4f4486b1f44b",
                    "lastModifiedBy": "63a21269-d40d-4c26-878f-4f4486b1f44b",
                    "createdTime": 1718171965428,
                    "lastModifiedTime": 1718171965428
                }
            }
        ]
    ALTER TABLE CampaignDetails
      ADD COLUMN isActive BOOLEAN DEFAULT TRUE,
      ADD COLUMN parentId VARCHAR(64) NULL;
    POST /project-factory/v1/project-type/retry
    Body: {
      CampaignDetails: { ... }, // Full campaign object
      RequestInfo: { ... }
    }
    {
      "id": "campaign-uuid",
      "tenantId": "mz",
      "status": "drafted",
      "action": "create",
      "campaignNumber": "...",
      "isActive": true,
      "parentId": "parent-campaign-uuid",
      "campaignName": "...",
      "projectType": "...",
      "hierarchyType": "...",
      "boundaries": [...],
      "resources": [
        { "type": "facility", "filename": "...", "resourceId": "...", "filestoreId": "..." },
        { "type": "boundaryWithTarget", "filename": "...", "resourceId": "...", "filestoreId": "..." },
        { "type": "user", "filename": "...", "resourceId": "...", "filestoreId": "..." }
      ],
      "deliveryRules": [...],
      "auditDetails": { ... }
    }
    {
       "ResponseInfo": {
           "apiId": "egov-bff",
           "ver": "0.0.1",
           "ts": 1716878176955,
           "status": "successful",
           "desc": "new-response"
       },
       "GeneratedResource": [
           {
               "id": "5ef5547e-414f-4164-9c12-644716e4fa71",
               "fileStoreid": null,
               "type": "boundaryManagement",
               "status": "inprogress",
               "hierarchyType": "ADMIN",
               "tenantId": "mz",
               "auditDetails": {
                   "lastModifiedTime": 1716878176947,
                   "createdTime": 1716878176947,
                   "createdBy": "867ba408-1b82-4746-8274-eb916e625fea",
                   "lastModifiedBy": "867ba408-1b82-4746-8274-eb916e625fea"
               },
               "additionalDetails": {
                   "Filters": null
               },
               "count": null
           }
       ]
    }
     "Mdms": {
            "tenantId": "mz",
            "schemaCode": "HCM-ADMIN-CONSOLE.adminSchema",
            "uniqueIdentifier": "boundaryManagement.all",
            "data":{
                    "title": "boundaryManagement",
                    "$schema": "http://json-schema.org/draft-07/schema#",
                    "properties": {
                        "numberProperties": [
                            {
                                "name": "HCM_ADMIN_CONSOLE_LAT",
                                "type": "number",
                                "isRequired": true,
                                "description": "Latitude",
                                "orderNumber": 2
                            },
                            {
                                "name": "HCM_ADMIN_CONSOLE_LONG",
                                "type": "number",
                                "isRequired": true,
                                "description": "Longitude",
                                "orderNumber": 3
                            }
                        ],
                        "stringProperties": [
                            {
                                "name": "HCM_ADMIN_CONSOLE_BOUNDARY_CODE",
                                "type": "string",
                                "isRequired": true,
                                "description": "Boundary Code",
                                "orderNumber": 1,
                                "freezeColumn": true
                            }
                        ]
                    },
                    "campaignType": "all"
                },
            "isActive": true
        }
    {
       "ResponseInfo": {
           "apiId": "egov-bff",
           "ver": "0.0.1",
           "ts": 1716878176955,
           "status": "successful",
           "desc": "new-response"
       },
       "GeneratedResource": [
           {
               "id": "5ef5547e-414f-4164-9c12-644716e4fa71",
               "fileStoreid": null,
               "type": "boundaryGeometryManagement",
               "status": "inprogress",
               "hierarchyType": "ADMIN",
               "tenantId": "mz",
               "auditDetails": {
                   "lastModifiedTime": 1716878176947,
                   "createdTime": 1716878176947,
                   "createdBy": "867ba408-1b82-4746-8274-eb916e625fea",
                   "lastModifiedBy": "867ba408-1b82-4746-8274-eb916e625fea"
               },
               "additionalDetails": {
                   "Filters": null
               },
               "count": null
           }
       ]
    }
    {
       "type":"FeatureCollection",
       "name":"boundary_country_default",
       "crs":{
          "type":"name",
          "properties":{
             "name":"urn:ogc:def:crs:EPSG::3857"
          }
       },
       "features":[
          {
             "type":"Feature",
             "properties":{
                "country_name":"India",
                "country_code":"IND",
                "global_id":"3c1b3b06-3958-424b-a160-3e25998cd027",
                "source":"WFP, INE",
                "source_date":"2007-01-01",
                "properties":{
                   "ADM0_EN":"Mozambique",
                   "OBJECTID":1,
                   "ADM0_PCODE":"MZ",
                   "Shape_Area":67.04187953610,
                   "Shape_Leng":96.65781689320
                },
                "population_1":26876090.0
             },
             "geometry":{
                "type":"",
                "coordinates":[
                   100,
                   200
                ]
             }
          }
       ]
    }
    ```postman_json
     "Mdms": {
            "tenantId": "mz",
            "schemaCode": "HCM-ADMIN-CONSOLE.adminSchema",
            "uniqueIdentifier": "boundaryGeometryManagement.all",
            "data":{
                    "title": "boundaryGeometryManagement",
                    "$schema": "http://json-schema.org/draft-07/schema#",
                    "properties": {
                        "numberProperties": [
                            {
                                "name": "HCM_ADMIN_CONSOLE_LAT",
                                "type": "number",
                                "isRequired": true,
                                "description": "Latitude",
                                "orderNumber": 2
                            },
                            {
                                "name": "HCM_ADMIN_CONSOLE_LONG",
                                "type": "number",
                                "isRequired": true,
                                "description": "Longitude",
                                "orderNumber": 3
                            }
                        ],
                        "stringProperties": [
                            {
                                "name": "HCM_ADMIN_CONSOLE_BOUNDARY_CODE",
                                "type": "string",
                                "isRequired": true,
                                "description": "Boundary Code",
                                "orderNumber": 1,
                                "freezeColumn": true
                            }
                        ]
                    },
                    "campaignType": "all"
                },
            "isActive": true
        }
    ```
  • No data exists, or force update is true: Generate new data.

  • If forceUpdate is false and data exists: Return the old data.

  • Modify the fetched data with getModifiedResponse(responseData).

  • Generate New Entry:

    • Create a new entry with getNewEntryResponse(request).

  • Expire Old Data:

    • Update the status of old data to expired using getOldEntryResponse(modifiedResponse, request).

  • Persist Data Changes:

    • Call updateAndPersistGenerateRequest(newEntryResponse, oldEntryResponse, responseData, request).

      • Purpose:

        • If forceUpdate is true and data exists: Mark existing data as expired and create new data.

        • No data exists or force update is true: Generate new data.

        • If forceUpdate is false and data exists: Return the old data.

  • Fetch Filters from CampaignId and generate Boundary Data based on those Filters.

    • If Filters is null, it will generate the whole Boundary Data.

  • After the Boundary Sheet has been generated, append the ReadMeSheet.

  • Generate different tabs based on any boundary level configured (here District).

  • Modify the fetched data with getModifiedResponse(responseData).

  • Generate New Entry:

    • Create a new entry with getNewEntryResponse(request).

  • Expire Old Data:

    • Update the status of old data to expired using getOldEntryResponse(modifiedResponse, request).

  • Persist Data Changes:

    • Call updateAndPersistGenerateRequest(newEntryResponse, oldEntryResponse, responseData, request).

      • Purpose:

        • If forceUpdate is true and data exists: Mark existing data as expired and create new data.

        • No data exists or force update is true: Generate new data.

        • If forceUpdate is false and data exists: Return the old data.

  • Fetch Filters from CampaignId and generate Boundary Data based on those filters.

    • If the filter is null, it will generate the whole Boundary Data.

  • After the Boundary Sheet has been generated, append the ReadMeSheet.

  • Generate different tabs based on any boundary level configured (here District).

  • Logo

    Manage Checklists Using Console

    Overview

    This document details the low-level design for managing checklists in a campaign via a web-based UI. The flow includes viewing, creating, enabling/disabling, and localising checklists, with coordinated backend integrations for robust and extensible checklist management.


    Logo
    Logo
    Key Actors & Services
    • User: The individual interacting with the checklist management UI to view, create, and modify checklists.

    • Checklist View UI (CurrentScreen): This is the user interface for viewing existing checklists and initiating the creation of new ones.

    • Checklist Create UI (CurrentScreen): The user interface for creating and configuring checklists.

    • Service Request Service (ServiceRequestService): Manages service requests and updates related to checklists.

    • MDMS Service (MDMSAPI): Provides master data management services for roles, checklist types, and other configurations.

    • Localisation Service (LOCAPI): Manages the localisation of checklist questions.


    Sequence Flow

    Checklist Viewing Flow

    1. Access Checklist View UI

      • The user accesses the Checklist View UI after a campaign has been created.

    2. Fetching Configured Service Requests

      • CurrentScreen sends a request to ServiceRequestService to fetch configured service requests.

        • ServiceRequestService filters and returns checklists using the campaign name, role, and type, or just the campaign name (if the service is enhanced).

      • ServiceRequestService returns the relevant checklists to CurrentScreen.

    3. Display Checklists

      • CurrentScreen displays the checklists received from ServiceRequestService to the User.

    4. Creating a New Checklist

      • The user clicks on "Create Checklist" in the Checklist View UI.

      • CurrentScreen sends a request to MDMSAPI to fetch role and checklist type master data relevant to the campaign type.

      • MDMSAPI returns the master data to CurrentScreen

    5. Enable/Disable Checklist

      • The user clicks on the enable/disable option for any checklist.

      • CurrentScreen sends an update call to ServiceRequestService to toggle the active/inactive status of the checklist.

      • ServiceRequestService returns the updated response.

    Checklist Creation Flow

    1. Access Checklist Create UI

      • The user accesses the Checklist Create UI.

      • CurrentScreen parses URL query parameters to determine the campaign name, role, and checklist type.

    2. Fetching Draft Service Requests

      • CurrentScreen sends a request to MDMSAPI to fetch draft service requests based on the role and type.

      • MDMSAPI returns the configured draft service requests.

    3. Loading Default Checklist Questions

      • CurrentScreen checks if there is a template available for the checklist and loads default checklist questions.

    4. User Interaction for Checklist Questions

      • Users can add, delete, or modify any checklist questions in the UI.

      • The user clicks on "Create" to finalise the checklist.

    5. Generating Unique Codes and Creating Service Requests

      • CurrentScreen generates a unique code for every checklist question.

      • CurrentScreen sends a create service request with the list of all questions to ServiceRequestService.

      • ServiceRequestService returns a successful response indicating that the checklist has been created.

    6. Localisation of Checklist Questions

      • CurrentScreen sends a request to LOCAPI to create localisation for all checklist questions.

        • Each question is assigned a generated code, a user-entered message, and is associated with the hcm-checklist module.

    7. Completion and Feedback

      • CurrentScreen displays a toast notification to the User indicating the successful creation of the checklist.

      • User is redirected back to the Checklist View screen, where they can see the newly created checklist.


    Error Handling

    • Service Request Failures: If a service request fails at any point, the CurrentScreen will display an error message to the User. Users must resolve the issues and retry the operation.

    • Validation Errors: During checklist creation, if validation errors are detected, the CurrentScreen will notify the User with specific details, and the user must correct the issues before proceeding.


    Sequence Diagram

    Conclusion

    This documentation provides a comprehensive overview of the checklist management process within a campaign. The structured sequence ensures that all checklist-related activities are handled correctly, from viewing existing checklists to creating and localising new ones. By adhering to this flow, users can manage checklists efficiently, ensuring consistency and accuracy in their campaign management activities.

    Logo
    Logo
    Logo
    Logo

    Manage Boundary APIs

    Overview

    This documentation outlines the process and components of bulk uploading boundaries for a campaign. It covers the proper format of the Excel sheet, unique code generation, functions for boundary entity creation, boundary relationship creation, localisation, and API details.

    Sequence Diagram

    Excel Format - Boundary Bulk Upload

    The Excel sheet should be formatted as follows:

    Country
    Província
    Distrito
    Posto Administrativo
    Localidade
    Aldeia

    Unique Code Generation

    Unique codes are auto-generated for each boundary level as follows:

    Boundary
    Code

    If there are two districts (boundaries at the same level) with the same name (for example, BLR) under different parent-level boundaries, the names will be updated to BLR, BLR-01, and so on.

    getAutoGeneratedBoundaryCodes Function

    Purpose:

    Generate auto-generated boundary codes based on boundary list, child-parent mapping, element codes map, count map, and request information.

    Parameters:

    • boundaryList: List of boundary data.

    • childParentMap: Map of child-parent relationships.

    • elementCodesMap: Map of boundaries to its corresponding auto-generated unique codes.

    Returns:

    • Updated element codes map.

    Steps:

    1. Initialise Column Data:

      • Initialise an array to store column data.

    2. Extract Unique Elements:

      • Iterate through each row of the boundary list.

    Boundary Entities Creation

    Boundary entities are created chunk-wise, with each chunk consisting of 200 codes.

    Create Boundary Entities

    Purpose:

    To create new boundary entities in the system from the provided boundary codes.

    Steps:

    1. Convert Boundary Map:

      • Change the boundary map to a list of objects with key and value.

    2. Prepare Request:

    Boundary Relationship Creation

    Create Boundary Relationship

    Purpose:

    To create boundary relationships in the system from the provided boundary codes and their parent-child mappings.

    Steps:

    1. Convert Boundary Map:

      • Transform the boundary map into a list of {key, value} objects.

    2. Initialise Request:

    Localisation Upsert of Codes

    Boundary codes are localised to their corresponding names as specified in the uploaded Excel sheet.

    Boundary Bulk Upload Upsertion

    To add more boundaries after the initial upload, use an Excel sheet that includes existing boundary codes. New boundaries without codes will be created in the same way as the first upload.

    API for Boundary Bulk Upload

    API request for boundary bulk upload:

    Note: Ensure the API endpoint, headers, and payload are customised as per your environment and requirements.

    Update Campaign Using Console

    Overview

    This document describes the low-level web flow for updating an existing campaign using the Admin Console. The process involves coordinated interactions between the frontend (Admin Console) and backend services to ensure campaign data is correctly updated, validated, and finalised.


    Logo
    .
  • The user selects the desired role and checklist type.

  • CurrentScreen redirects to the checklist creation screen based on the selected campaign name, role, and type.

  • CurrentScreen updates the checklist status based on the response.

    LOCAPI processes the localisation request and returns a response.

    INDIA

    KARNATAKA

    BLR

    INDIA

    KARNATAKA

    BLR

    KORAMANGALA

    INDIA

    KARNATAKA

    BLR

    KORAMANGALA

    3RD BLOCK

    INDIA

    KARNATAKA

    BLR

    KORAMANGALA

    3RD BLOCK

    EGOV

    INDIA

    BIHAR

    INDIA

    BIHAR

    PATNA

    countMap: Map of counts for each boundary.
  • request: HTTP request object.

  • Extract unique elements from each column.

  • Generate Boundary Codes:

    • Iterate over columns to generate boundary codes.

    • Check if the element code exists in the element codes map.

    • If not, generate a new code based on parent-child mapping and sequence.

    • Store the code of the element in the element codes map.

  • Default Code Generation:

    • Generate default code if parent code is not found.

  • Updated Element Codes Map

    Return Updated Boundary Data - Auto-Generated Code Map.

  • Set up the request details and initialise lists for boundaries and existing codes.

  • Chunk Boundary Codes:

    • Divide the boundary codes into smaller groups.

  • Fetch Existing Boundaries:

    • Check the system for existing boundary codes and collect them.

  • Identify New Boundaries:

    • Determine which boundary codes are new and add them to the list of boundaries to create.

  • Create New Boundaries:

    • If there are new boundaries, send them to the system in groups and log the results.

  • Handle Existing Boundaries:

    • Log a message if all boundaries already exist.

  • Error Handling:

    • Manage any errors that occur and provide a relevant error message.

  • Prepare the request details and activity messages array.
  • Fetch Existing Relationships:

    • Retrieve existing boundary relationships and extract their codes.

  • Identify and Create Relationships:

    • For each boundary code, check if it exists. If not:

      • Prepare the boundary relationship data.

      • Confirm the parent boundary creation.

      • Create the boundary relationship.

  • Handle Existing Relationships:

    • If all relationships already exist, log a validation error.

  • Attach Activity Messages:

    • Add activity messages to the request body.

  • Error Handling:

    • Catch, log, and handle errors appropriately.

  • INDIA

    INDIA

    KARNATAKA

    INDIA

    ADMIN_IN

    KARNATAKA

    ADMIN_IN_01_KARNATAKA

    BLR

    ADMIN_IN_01_01_BLR

    KORAMANGALA

    ADMIN_IN_01_01_01_KORMANGALA

    BIHAR

    ADMIN_IN_02_BIHAR

    PATNA

    ADMIN_IN_02_01_PATNA

    curl --location 'http://localhost:8080/project-factory/v1/data/_create' \
    --header 'authority: unified-dev.digit.org' \
    --header 'accept: application/json, text/plain, */*' \
    --header 'accept-language: en-GB,en-US;q=0.9,en;q=0.8' \
    --header 'content-type: application/json' \
    --header 'cookie: _ga_XBQP06FR8V=GS1.1.1691570094.3.1.1691570094.60.0.0; _ga=GA1.1.2124364284.1689669598; _ga_P1TZCPKF6S=GS1.1.1691648339.2.0.1691648339.60.0.0; __cuid=fe28d9c8c84c4d2487b9cb6c9e4cdec1; amp_fef1e8=f4a3f3ed-50f2-409b-be4f-a1ce1dbb59f2R...1hgs4r9gr.1hgs4robc.nu.1r.pp; _ga_H9YC8FEN6F=GS1.1.1701751656.77.1.1701751677.39.0.0' \
    --header 'origin: https://unified-dev.digit.org' \
    --header 'referer: https://unified-dev.digit.org/works-ui/employee/measurement/update?tenantId=pg.citya&workOrderNumber=WO/2023-24/000894&mbNumber=MB/2023-24/001252' \
    --header 'sec-ch-ua: "Chromium";v="116", "Not)A;Brand";v="24", "Google Chrome";v="116"' \
    --header 'sec-ch-ua-mobile: ?0' \
    --header 'sec-ch-ua-platform: "Linux"' \
    --header 'sec-fetch-dest: empty' \
    --header 'sec-fetch-mode: cors' \
    --header 'sec-fetch-site: same-origin' \
    --header 'user-agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36' \
    --data-raw '{
        "RequestInfo": {
            "apiId": "Rainmaker",
            "authToken": "e45445a1-6891-4a76-a4e6-528e1dd24946",
            "userInfo": {
                "id": 1284,
                "uuid": "867ba408-1b82-4746-8274-eb916e625fea",
                "userName": "EMP57",
                "name": "Jagan",
                "mobileNumber": "6667776662",
                "emailId": "[email protected]",
                "locale": "string",
                "type": "EMPLOYEE",
                "roles": [
                    {
                        "name": "System Administrator",
                        "code": "SYSTEM_ADMINISTRATOR",
                        "tenantId": "mz"
                    },
                    {
                        "name": "Campaign Manager",
                        "code": "CAMPAIGN_MANAGER",
                        "tenantId": "mz"
                    },
                    {
                        "name": "Localisation admin",
                        "code": "LOC_ADMIN",
                        "tenantId": "mz"
                    },
                    {
                        "name": "MDMS Admin",
                        "code": "MDMS_ADMIN",
                        "tenantId": "mz"
                    }
                ],
                "active": true,
                "tenantId": "mz",
                "permanentCity": "Amritsar"
            },
            "msgId": "1710912592752|en_IN",
            "plainAccessRequest": {}
        },
        "ResourceDetails": {
            "type": "boundary",
            "tenantId": "mz",
            "fileStoreId": "be52ce1a-bc25-4328-91bc-a682079abb59",
            "action": "create",
            "hierarchyType": "ADMIN",
            "additionalDetails": {},
            "campaignId": "5d721d03-bdf5-4021-86ff-107e61eb7abb"
        }
    }'
    Key Actors & Services
    • User: Admin user interacting with the Admin Console to update campaigns.

    • CampaignManager (Admin Console): The web UI/controller handling orchestration of campaign updates.

    • ProjectFactory: Backend service that manages campaign object lifecycle, including updates and validation.

    • BoundaryService: Provides boundary hierarchy and relationship data for the campaign.

    • MDMSService: Supplies master data (project types, hierarchies, templates).

    • FileStoreService: Stores and retrieves campaign-related files.


    Sequence Flow

    Initiating Campaign Update

    • User: Begins the update process by selecting an existing campaign from the "My Campaign" screen within the Admin Console.

    • CampaignManager: Receives the request to update a specific campaign and retrieves the campaign object using its unique ID.

    2. Fetching Campaign Data

    • CampaignManager sends a request to ProjectFactory to fetch the campaign object based on the provided campaign ID.

      • ProjectFactory responds with the campaign object containing the current campaign details.

    3. Fetching Boundary Information

    • CampaignManager requests BoundaryService to fetch boundary hierarchy definitions based on the campaign's hierarchy type.

      • BoundaryService responds with the boundary hierarchy definition.

    • CampaignManager requests BoundaryService to fetch boundary relationship data based on the hierarchy type.

      • BoundaryService responds with the boundary relationship data.

    4. User Data Input

    • User: Updates the necessary fields, such as boundary delivery configuration and other campaign-specific details, using the Admin Console.

    • CampaignManager: Sends the updated information to ProjectFactory to create or update the campaign object, storing it with an action status of "draft".

    5. Template Generation

    • ProjectFactory: Automatically triggers the generation of templates for different resources, including:

      • Target templates

      • Facility templates

      • User templates

    6. Template Download and Storage

    • User: Downloads the generated templates for each resource type via the Admin Console.

    • CampaignManager: Sends a request to FileStoreService to store the downloaded files.

      • FileStoreService responds with a filestoreid that uniquely identifies the stored file.

    7. Data Validation

    • CampaignManager: Sends the data and the filestoreid to ProjectFactory for validation.

      • ProjectFactory responds with a unique validation ID, as the validation process may take some time.

    • CampaignManager: Periodically checks the validation status using the unique validation ID.

    8. Validation Outcome

    • ProjectFactory:

      • If validation is successful:

        • Responds with a success message.

        • CampaignManager: Displays a success message to the user, indicating that they can proceed to the next step.

      • If validation fails:

        • Responds with an error message detailing the validation failure.

        • CampaignManager: Displays the error message to the user, prompting them to correct the errors and re-upload the files.

    9. Final Campaign Update

    • User: Once all required data is filled in and validated, the user reviews the summary of the campaign data and clicks on the "Update Campaign" button.

    • CampaignManager: Sends a request to ProjectFactory with the campaign update API, marking the action as "update".

    10. Campaign Update Outcome

    • ProjectFactory:

      • If the update is successful:

        • Responds with a success message, indicating that the campaign update has started.

        • CampaignManager: Displays a success message to the user, confirming that the campaign has been updated successfully.

      • If the update fails:

        • Responds with an error message detailing the failure.

        • CampaignManager: Displays the error message to the user, prompting them to correct any issues and try again.


    Error Handling

    • Validation Failures: If validation fails at any stage (e.g., during file validation or input data checks), the CampaignManager will notify the user of the specific issues. The user must resolve these issues and re-upload the necessary data to proceed.

    • Service Errors: If any of the services (e.g., BoundaryService, ProjectFactory) encounter an error during processing, the CampaignManager will display an error message, detailing the problem and suggesting corrective actions.


    Sequence Diagram


    Conclusion

    This document outlines the flow for updating an existing campaign using the Admin Console. The structured sequence ensures that any changes to the campaign are thoroughly validated and processed, minimising errors and ensuring the integrity of the campaign data. By following this flow, users can confidently update campaigns, knowing that all necessary steps are taken to verify and finalise their changes.

    Sample Payload
    ```
       "CampaignDetails":  {
                "id": "2b68a3aa-fca2-462e-8d59-8821c9a56132",
                "tenantId": "mz",
                "status": "drafted",
                "action": "create",
                "campaignNumber": "CMP-2024-10-15-004031",
                "isActive": true,
                "parentId": "43503755-db1d-4cef-9851-72360ee6eaa1",
                "campaignName": "LLIN-OCT15a",
                "projectType": "LLIN-mz",
                "hierarchyType": "HIERARCHYTEST",
                "boundaryCode": "",
                "projectId": null,
                "startDate": 1727202600000,
                "endDate": 1727720999000,
                "additionalDetails": {
                    "key": 10,
    

    Sample Payload
    ```
       "CampaignDetails":  {
                "id": "2b68a3aa-fca2-462e-8d59-8821c9a56132",
                "tenantId": "mz",
                "status": "drafted",
                "action": "create",
                "campaignNumber": "CMP-2024-10-15-004031",
                "isActive": true,
                "parentId": "43503755-db1d-4cef-9851-72360ee6eaa1",
                "campaignName": "LLIN-OCT15a",
                "projectType": "LLIN-mz",
                "hierarchyType": "HIERARCHYTEST",
                "boundaryCode": "",
                "projectId": null,
                "startDate": 1727202600000,
                "endDate": 1727720999000,
                "additionalDetails": {
                    "key": 10,
    

    Sample Payload
    ```
       "CampaignDetails":  {
                "id": "2b68a3aa-fca2-462e-8d59-8821c9a56132",
                "tenantId": "mz",
                "status": "drafted",
                "action": "create",
                "campaignNumber": "CMP-2024-10-15-004031",
                "isActive": true,
                "parentId": "43503755-db1d-4cef-9851-72360ee6eaa1",
                "campaignName": "LLIN-OCT15a",
                "projectType": "LLIN-mz",
                "hierarchyType": "HIERARCHYTEST",
                "boundaryCode": "",
                "projectId": null,
                "startDate": 1727202600000,
                "endDate": 1727720999000,
                "additionalDetails": {
                    "key": 10,
    
    "beneficiaryType": "HOUSEHOLD"
    },
    "resources": [
    {
    "type": "facility",
    "filename": "update-facility.xlsx",
    "resourceId": "42c04e62-4b7b-4697-b2bd-aa90a212164c",
    "filestoreId": "20420b29-d913-4412-b3bd-34b850e2677b"
    },
    {
    "type": "boundaryWithTarget",
    "filename": "updated-boundary.xlsx",
    "resourceId": "8567db53-450e-465d-a14a-46e2690cf728",
    "filestoreId": "30ae3fd6-b77c-42e7-9a33-e88e29369764"
    },
    {
    "type": "user",
    "filename": "updated-user.xlsx",
    "resourceId": "fcc4a423-6ac5-4ee4-80c2-0f915a95253f",
    "filestoreId": "3c531af7-d923-47cc-b58a-c501a73e749c"
    }
    ],
    "boundaries": [],
    "deliveryRules": [
    {
    "active": true,
    "cycleIndex": "1",
    "deliveries": [
    {
    "active": true,
    "deliveryIndex": "1",
    "deliveryRules": [
    {
    "ruleKey": 1,
    "delivery": {},
    "products": [
    {
    "key": 1,
    "count": 1,
    "value": "PVAR-2024-05-09-000333"
    }
    ],
    "attributes": [
    {
    "key": 1,
    "value": "1",
    "operator": {
    "code": "LESS_THAN_EQUAL_TO"
    },
    "attribute": {
    "code": "CAMPAIGN_BEDNET_INDIVIDUAL_LABEL"
    }
    },
    {
    "key": 2,
    "value": "3",
    "operator": {
    "code": "LESS_THAN_EQUAL_TO"
    },
    "attribute": {
    "code": "CAMPAIGN_BEDNET_HOUSEHOLD_LABEL"
    }
    }
    ]
    }
    ]
    }
    ]
    }
    ],
    "auditDetails": {
    "createdBy": "63a21269-d40d-4c26-878f-4f4486b1f44b",
    "lastModifiedBy": "63a21269-d40d-4c26-878f-4f4486b1f44b",
    "createdTime": 1728983362986,
    "lastModifiedTime": 1728983362995
    }
    },
    ```
    "beneficiaryType": "HOUSEHOLD"
    },
    "resources": [
    {
    "type": "facility",
    "filename": "update-facility.xlsx",
    "resourceId": "42c04e62-4b7b-4697-b2bd-aa90a212164c",
    "filestoreId": "20420b29-d913-4412-b3bd-34b850e2677b"
    },
    {
    "type": "boundaryWithTarget",
    "filename": "updated-boundary.xlsx",
    "resourceId": "8567db53-450e-465d-a14a-46e2690cf728",
    "filestoreId": "30ae3fd6-b77c-42e7-9a33-e88e29369764"
    },
    {
    "type": "user",
    "filename": "updated-user.xlsx",
    "resourceId": "fcc4a423-6ac5-4ee4-80c2-0f915a95253f",
    "filestoreId": "3c531af7-d923-47cc-b58a-c501a73e749c"
    }
    ],
    "boundaries": [],
    "deliveryRules": [
    {
    "active": true,
    "cycleIndex": "1",
    "deliveries": [
    {
    "active": true,
    "deliveryIndex": "1",
    "deliveryRules": [
    {
    "ruleKey": 1,
    "delivery": {},
    "products": [
    {
    "key": 1,
    "count": 1,
    "value": "PVAR-2024-05-09-000333"
    }
    ],
    "attributes": [
    {
    "key": 1,
    "value": "1",
    "operator": {
    "code": "LESS_THAN_EQUAL_TO"
    },
    "attribute": {
    "code": "CAMPAIGN_BEDNET_INDIVIDUAL_LABEL"
    }
    },
    {
    "key": 2,
    "value": "3",
    "operator": {
    "code": "LESS_THAN_EQUAL_TO"
    },
    "attribute": {
    "code": "CAMPAIGN_BEDNET_HOUSEHOLD_LABEL"
    }
    }
    ]
    }
    ]
    }
    ]
    }
    ],
    "auditDetails": {
    "createdBy": "63a21269-d40d-4c26-878f-4f4486b1f44b",
    "lastModifiedBy": "63a21269-d40d-4c26-878f-4f4486b1f44b",
    "createdTime": 1728983362986,
    "lastModifiedTime": 1728983362995
    }
    },
    ```
    "beneficiaryType": "HOUSEHOLD"
    },
    "resources": [
    {
    "type": "facility",
    "filename": "update-facility.xlsx",
    "resourceId": "42c04e62-4b7b-4697-b2bd-aa90a212164c",
    "filestoreId": "20420b29-d913-4412-b3bd-34b850e2677b"
    },
    {
    "type": "boundaryWithTarget",
    "filename": "updated-boundary.xlsx",
    "resourceId": "8567db53-450e-465d-a14a-46e2690cf728",
    "filestoreId": "30ae3fd6-b77c-42e7-9a33-e88e29369764"
    },
    {
    "type": "user",
    "filename": "updated-user.xlsx",
    "resourceId": "fcc4a423-6ac5-4ee4-80c2-0f915a95253f",
    "filestoreId": "3c531af7-d923-47cc-b58a-c501a73e749c"
    }
    ],
    "boundaries": [],
    "deliveryRules": [
    {
    "active": true,
    "cycleIndex": "1",
    "deliveries": [
    {
    "active": true,
    "deliveryIndex": "1",
    "deliveryRules": [
    {
    "ruleKey": 1,
    "delivery": {},
    "products": [
    {
    "key": 1,
    "count": 1,
    "value": "PVAR-2024-05-09-000333"
    }
    ],
    "attributes": [
    {
    "key": 1,
    "value": "1",
    "operator": {
    "code": "LESS_THAN_EQUAL_TO"
    },
    "attribute": {
    "code": "CAMPAIGN_BEDNET_INDIVIDUAL_LABEL"
    }
    },
    {
    "key": 2,
    "value": "3",
    "operator": {
    "code": "LESS_THAN_EQUAL_TO"
    },
    "attribute": {
    "code": "CAMPAIGN_BEDNET_HOUSEHOLD_LABEL"
    }
    }
    ]
    }
    ]
    }
    ]
    }
    ],
    "auditDetails": {
    "createdBy": "63a21269-d40d-4c26-878f-4f4486b1f44b",
    "lastModifiedBy": "63a21269-d40d-4c26-878f-4f4486b1f44b",
    "createdTime": 1728983362986,
    "lastModifiedTime": 1728983362995
    }
    },
    ```

    Integration with Microplan

    /project-factory/v1/project-type/fetch-from-microplan

    Overview

    This document describes the web flow for updating an existing campaign by integrating the existing microplan with the console. This process involves the integration of several backend services to update the data in the facility, target, and user sheet in the existing campaign object.

    Services Used

    • Core Services

    • Plan Service

    • Census Service

    Sequence Flow

    1. Initiate Request: The request body for the microplan integration will be:

    2. Validations: This request validates whether the campaignId and planConfigurationId exist in the system or are invalid.

    3. Update Facility Sheet: The process begins by searching for the facility associated with the planConfigurationId, which provides details about the facility code and the linked service boundaries. Next, a facility sheet is generated for the campaign. Once the facility sheet is obtained, the service boundaries are populated within the sheet where the specific facility code is present.

    The sample data for filling the target sheet is:

    Here, the type of the target sheet is constructed as Target-<projectType> of the campaign.

    • to: This specifies the key to be extracted from the census object.

    • from: These are the keys representing the headers that need to be enriched in the generated sheet.

    This mapping ensures that the data from the census object is correctly aligned and populated into the appropriate headers in the target sheet. After populating the worksheet with data from the census objects, the file is uploaded to the filestore. Next, the sheet is validated using the Validate API with the type boundaryWithTarget. Once the validation is completed, the campaign object is updated with the newly generatedfilestoreId and resourceId. We get data from the census search as follows:

    1. Update User Sheet: The process begins by fetching the plan associated with the planConfigurationId and retrieving the boundaries from the campaign details, specifically those of type LOCALITY. Next, for each locality, the count of all roles is obtained from the plan search response. This role count is then enriched in the corresponding sheet for that locality.

    To map the roles and their requirements for determining the role count in the plan facility response, the predefined MDMS schema for the target is utilised. In this schema:

    • to: Represents the role to be mapped.

    • from: Specifies an array of keywords that must be present in the key to identify the role.

    This ensures accurate and efficient mapping and population of role-related data in the sheet. Also used -

    Added a field consolidateUsersAt in the schema to filter for boundaries based on a particular hierarchy; Example: LOCALITY Sample Data:

    Sample MDMS data:

    After populating the sheet with the appropriate information, the sheet is validated by calling the Validate API with the type userWithBoundary. Once the validation is successful, the campaign object is updated accordingly. We get the data to fill in this sheet from this API:

    Conclusion

    This document outlines the process for updating an existing campaign by integrating a microplan through the admin console. It involves validating the campaignId and planConfigurationId and updating the facility, target, and user sheets using data from backend services.

    1. Facility Sheet: Generated using facility details from the planConfigurationId, enriched with service boundaries, validated, and updated in the campaign object.

    2. Target Sheet: Created by mapping census data to boundary codes using the MDMS schema. The sheet is populated, validated, uploaded, and updated in the campaign object.

    3. User Sheet: Locality boundaries are fetched, role counts are calculated and enriched using the MDMS schema, and the sheet is validated before updating the campaign object.

    This integration ensures accurate, automated updates and efficient campaign management.

    After completing the facility sheet, it is validated using the Validate API. Once validation is successful, the campaign object is updated with the new facilityId and resourceId. We get the data to fill in this sheet from plan-service/plan/facility/_search where data is like this and map the facilityId to the serviceBoundaries.

    Copy

  • Update Target Sheet: The process begins by performing a plan census search using the planConfigurationId, which retrieves details about the boundary code and its associated census data. After obtaining the mapping between the boundary code and the linked census, a target sheet of type boundary is generated for the campaign and hierarchy by invoking the Generate API.

    A predefined MDMS schema ensures accurate mapping between the headers in the target sheet and the fields in the data. This schema acts as a blueprint, defining the correspondence between the data fields and their respective headers in the generated sheet. For this sheet, we get the data from the census search API, where the data looks like this:

  •  {
            "id": "baece49c-a7fa-49e7-bddd-d19ba71b2b89",
            "tenantId": "mz",
            "code": "HCM-ADMIN-CONSOLE.microplanIntegration",
            "description": "HCM-ADMIN-CONSOLE.microplanIntegration",
            "definition": {
                "type": "object",
                "title": "HCM-ADMIN-CONSOLE.microplanIntegration",
                "$schema": "http://json-schema.org/draft-07/schema#",
                "required": [
                    "type",
                    "mappings"
                ],
                "x-unique": [
                    "type"
                ],
                "properties": {
                    "type": {
                        "type": "string"
                    },
                    "mappings": {
                        "type": "array",
                        "minItems": 1,
                        "items": {
                            "type": "object",
                            "properties": {
                                "to": {
                                    "type": "string"
                                },
                                "from": {
                                    "type": "array",
                                    "items": {
                                        "type": "string"
                                    }
                                },
                                "filter": {
                                    "type": "string",
                                    "enum": [
                                        "includes",
                                        "equal"
                                    ],
                                    "default": "includes"
                                }
                            }
                        }
                    }
                },
                "isActive": true,
                "auditDetails": {
                    "createdBy": null,
                    "lastModifiedBy": null,
                    "createdTime": 1697098069220,
                    "lastModifiedTime": 1697098069220
                }
            }
        }
    ```
    {
        "RequestInfo": {
            "apiId": "Rainmaker",
            "authToken": "{{auth}}",
            "msgId": "1730962198879|en_MZ",
            "plainAccessRequest": {}
        },
        "MicroplanDetails": {
            "tenantId": "mz",
            "campaignId": "58fb49a9-6772-4ecf-afc1-61f747e8c412",
            "planConfigurationId": "e314a0b1-648c-4f7b-8551-f9441df00eb4"
        }
    }
    
    Here campaignId will be the id of campaign for which the current plan is linked
    and planConfigurationId is the id of the microplan.
    {
                        "type": "Target-MR-DN",
                        "mappings": [
                            {
                                "to": "HCM_ADMIN_CONSOLE_TARGET_SMC_AGE_3_TO_11",
                                "from": [
                                    "CONFIRMED_HCM_ADMIN_CONSOLE_TARGET_POPULATION_AGE_3TO11"
                                ],
                                "filter": "equal"
                            },
                            {
                                "to": "HCM_ADMIN_CONSOLE_TARGET_SMC_AGE_12_TO_59",
                                "from": [
                                    "CONFIRMED_HCM_ADMIN_CONSOLE_TARGET_POPULATION_AGE_12TO59"
                                ],
                                "filter": "equal"
                            }
                        ]
                    }
     {
                "id": "dc8521c0-102f-4879-bca2-97ad96883b7d",
                "tenantId": "mz",
                "hierarchyType": "MICROPLAN",
                "boundaryCode": "MICROPLAN_MO_13_05_04_01_03_TOFFOI_TOWN",
                "assignee": null,
                "status": "VALIDATED",
                "type": "people",
                "totalPopulation": 987,
                "populationByDemographics": null,
                "additionalFields": [
                    {
                        "id": "8c66b784-212f-4771-9794-d554e0626466",
                        "key": "UPLOADED_HCM_ADMIN_CONSOLE_TARGET_POPULATION_AGE_3TO11",
                        "value": 432.00,
                        "showOnUi": true,
                        "editable": false,
                        "order": 3
                    },
                    {
                        "id": "bf0ba6b9-48e5-4545-b702-c6f97afdd604",
                        "key": "UPLOADED_HCM_ADMIN_CONSOLE_TOTAL_POPULATION",
                        "value": 987.00,
                        "showOnUi": true,
                        "editable": false,
                        "order": 1
                    },
                    {
                        "id": "5c16f657-f9b9-4100-b9a8-2a3898d2f89a",
                        "key": "CONFIRMED_HCM_ADMIN_CONSOLE_TOTAL_POPULATION",
                        "value": 987.00,
                        "showOnUi": true,
                        "editable": true,
                        "order": 2
                    },
                    {
                        "id": "8346d4a7-4e68-4481-a252-eb493fb08c42",
                        "key": "CONFIRMED_HCM_ADMIN_CONSOLE_TARGET_POPULATION_AGE_3TO11",
                        "value": 432.00,
                        "showOnUi": true,
                        "editable": true,
                        "order": 4
                    },
                    {
                        "id": "ca33c533-7abd-4325-a64a-52771a98857a",
                        "key": "UPLOADED_HCM_ADMIN_CONSOLE_TARGET_POPULATION_AGE_12TO59",
                        "value": 232.00,
                        "showOnUi": true,
                        "editable": false,
                        "order": 5
                    },
                    {
                        "id": "9e450a98-7229-4137-b93c-a6901e1561cc",
                        "key": "CONFIRMED_HCM_ADMIN_CONSOLE_TARGET_POPULATION_AGE_12TO59",
                        "value": 232.00,
                        "showOnUi": true,
                        "editable": true,
                        "order": 6
                    }
                ],
                "effectiveFrom": 1732614985701,
                "effectiveTo": 1732617841760,
                "source": "f44bffa1-653a-455a-998d-e556ac097d3b",
                "facilityAssigned": true,
                "workflow": null,
                "jurisdictionMapping": null,
                "additionalDetails": {
                    "facilityId": "F-2024-11-26-104824",
                    "facilityName": "angelic being 3714",
                    "UPLOADED_HCM_ADMIN_CONSOLE_TOTAL_POPULATION": 987,
                    "CONFIRMED_HCM_ADMIN_CONSOLE_TOTAL_POPULATION": 987,
                    "UPLOADED_HCM_ADMIN_CONSOLE_TARGET_POPULATION_AGE_3TO11": 432,
                    "CONFIRMED_HCM_ADMIN_CONSOLE_TARGET_POPULATION_AGE_3TO11": 432,
                    "UPLOADED_HCM_ADMIN_CONSOLE_TARGET_POPULATION_AGE_12TO59": 232,
                    "CONFIRMED_HCM_ADMIN_CONSOLE_TARGET_POPULATION_AGE_12TO59": 232
                },
                "auditDetails": {
                    "createdBy": "29f73f64-2f5b-4699-b92c-4b093ac65749",
                    "lastModifiedBy": "d3fcb513-622c-4b68-a6fa-073267397da0",
                    "createdTime": 1732614985701,
                    "lastModifiedTime": 1732619464507
                }
            }
    HCM-ADMIN-CONSOLE.HierarchySchema
    {
                        "type": "console",
                        "group": [
                            "MALARIA",
                            "PERFORMANCE",
                            "ADMINISTRATIVEPOST",
                            "DISTRICT"
                        ],
                        "hierarchy": "MICROPLAN",
                        "department": [],
                        "lowestHierarchy": "VILLAGE",
                        "splitBoundariesOn": "DISTRICT",
                        "consolidateUsersAt": "LOCALITY"
                    }
    {
                        "type": "user",
                        "mappings": [
                            {
                                "to": "Supervisor",
                                "from": [
                                    "PER_BOUNDARY_FOR_THE_CAMPAIGN",
                                    "PER_BOUNDARY",
                                    "TEAM",
                                    "SUPERVISORS"
                                ],
                                "filter": "includes"
                            },
                            {
                                "to": "Registrar",
                                "from": [
                                    "PER_BOUNDARY_FOR_THE_CAMPAIGN",
                                    "PER_BOUNDARY",
                                    "TEAM",
                                    "REGISTRATION"
                                ],
                                "filter": "includes"
                            },
                            {
                                "to": "Distributor",
                                "from": [
                                    "PER_BOUNDARY_FOR_THE_CAMPAIGN",
                                    "PER_BOUNDARY",
                                    "TEAM",
                                    "DISTRIBUTION"
                                ],
                                "filter": "includes"
                            }
                        ]
                    }
      {
                "id": "eb33e406-a94a-4862-be9b-10e89f7759a3",
                "tenantId": "mz",
                "locality": "MICROPLAN_MO_13_05_04_01_11_GREBO_VILLAGE_2",
                "campaignId": "fab0e988-c124-4b2b-9f28-adbbc0c0bbb4",
                "planConfigurationId": "bc6e5fab-fd25-4b05-8286-7c567e88507a",
                "status": "VALIDATED",
                "assignee": null,
                "additionalDetails": null,
                "activities": [],
                "resources": [
                    {
                        "id": "109745bf-e77e-42c6-ab33-32b5b2b591b9",
                        "resourceType": "NO_OF_BEDNETS_PER_BOUNDARY",
                        "estimatedNumber": 1.19,
                        "activityCode": null
                    },
                    {
                        "id": "07453754-16db-4884-bc88-f4e08d1a5e58",
                        "resourceType": "NO_OF_HOUSEHOLD_DISTRIBUTION_TEAMS_PER_BOUNDARY_FOR_THE_CAMPAIGN",
                        "estimatedNumber": 0.01,
                        "activityCode": null
                    },
                    {
                        "id": "2e803e3a-2735-426c-bdb0-b9556c20a8d3",
                        "resourceType": "NO_OF_BALES_PER_BOUNDARY",
                        "estimatedNumber": 0.01,
                        "activityCode": null
                    },
                    {
                        "id": "34007919-c5ed-4372-bcc5-2da8693d4972",
                        "resourceType": "NO_OF_MONITORS_FOR_HOUSEHOLD_DISTRIBUTION_TEAM_PER_BOUNDARY",
                        "estimatedNumber": 0.00,
                        "activityCode": null
                    },
                    {
                        "id": "95d1ed12-16d4-4c4f-94e9-e12289e6e634",
                        "resourceType": "NO_OF_HOUSEHOLD_DISTRIBUTION_TEAMS_PER_BOUNDARY_FOR_ONE_DAY",
                        "estimatedNumber": 1.23,
                        "activityCode": null
                    },
                    {
                        "id": "ef15c6d7-761a-494e-94d1-32dd1e5a2396",
                        "resourceType": "NO_OF_HOUSEHOLDS_PER_BOUNDARY",
                        "estimatedNumber": 1.28,
                        "activityCode": null
                    },
                    {
                        "id": "b8169c1f-eb9a-4329-97b5-8f2715af5832",
                        "resourceType": "NO_OF_FIXED_POST_REGISTRATION_TEAMS_PER_BOUNDARY_FOR_ONE_DAY",
                        "estimatedNumber": 0.88,
                        "activityCode": null
                    },
                    {
                        "id": "1e34c841-7f40-4fe2-9f44-e857ae1ee0df",
                        "resourceType": "NO_OF_FIXED_POST_REGISTRATION_TEAMS_PER_BOUNDARY_FOR_THE_CAMPAIGN",
                        "estimatedNumber": 0.01,
                        "activityCode": null
                    },
                    {
                        "id": "ce84ea0d-b670-4dad-b2b2-308da03af8fd",
                        "resourceType": "NO_OF_FIXED_POST_REGISTRATION_TEAM_SUPERVISORS_PER_BOUNDARY",
                        "estimatedNumber": 0.00,
                        "activityCode": null
                    },
                    {
                        "id": "96b60c74-6c0d-4f27-9192-51335d80fbce",
                        "resourceType": "NO_OF_STICKERS_ROLLS_PER_BOUNDARY",
                        "estimatedNumber": 0.01,
                        "activityCode": null
                    },
                    {
                        "id": "5c86bc8b-cd0f-41b3-bf4d-c30597559581",
                        "resourceType": "NO_OF_FIXED_POST_REGISTRATION_TEAM_MEMBERS_PER_BOUNDARY",
                        "estimatedNumber": 0.65,
                        "activityCode": null
                    },
                    {
                        "id": "29c5028d-2e78-433c-92bf-901d7d031677",
                        "resourceType": "NO_OF_HOUSEHOLD_DISTRIBUTION_TEAM_MEMBERS_PER_BOUNDARY",
                        "estimatedNumber": 0.32,
                        "activityCode": null
                    },
                    {
                        "id": "b0e007de-d437-4055-931c-181b0bf617bf",
                        "resourceType": "NO_OF_SUPERVISORS_FOR_HOUSEHOLD_DISTRIBUTION_TEAM_PER_BOUNDARY",
                        "estimatedNumber": 0.00,
                        "activityCode": null
                    }
                ],
                "targets": [],
                "auditDetails": {
                    "createdBy": "6c0fd096-60ec-45fd-b81c-526c3f1a3f0b",
                    "lastModifiedBy": "7c6714e9-72c8-46f7-a2c3-14edfe20cb1b",
                    "createdTime": 1732964373948,
                    "lastModifiedTime": 1732965150594
                },
                "jurisdictionMapping": null,
                "workflow": null
            }
    {
                "id": "01a6cdc9-f777-4792-ad17-6dc7042fe1fd",
                "tenantId": "mz",
                "planConfigurationId": "f44bffa1-653a-455a-998d-e556ac097d3b",
                "planConfigurationName": "Malaria-SMC Campaign-M1x3d-1-26 Nov 24",
                "facilityId": "F-2024-11-26-104823",
                "facilityName": "angelic being 3713",
                "residingBoundary": "MICROPLAN_MO_13_05_02_02_07_ZAYBAY_TOWN",
                "serviceBoundaries": [
                    "MICROPLAN_MO_13_05_01_03_04_GORBO_COMMUNITY",
                    "MICROPLAN_MO_13_05_01_03_03_FDA_COMMUNITY",
                    "MICROPLAN_MO_13_05_01_03_01_BARLAVILLE",
                    "MICROPLAN_MO_13_05_01_02_12_GARLOVILLE_COMMUNITY",
                    "MICROPLAN_MO_13_05_01_02_11_SUAH_COMMUNITY",
                    "MICROPLAN_MO_13_05_01_02_10_KANNAH_ROAD_COMMUNITY",
                    "MICROPLAN_MO_13_05_01_02_09_ZWEDRU_CENTRAL_MARKET",
                    "MICROPLAN_MO_13_05_01_02_08_ZOE_BUSH",
                    "MICROPLAN_MO_13_05_01_02_07_CITY_HALL_COMMUNITY",
                    "MICROPLAN_MO_13_05_01_02_06_WELBO_QUARTER",
                    "MICROPLAN_MO_13_05_01_02_05_TRIANGLE_COMMUNITY",
                    "MICROPLAN_MO_13_05_01_02_04_SPS_COMMUNITY",
                    "MICROPLAN_MO_13_05_01_02_03_BAPTIST_COMMUNITY",
                    "MICROPLAN_MO_13_05_01_02_02_TOWAH_COMMUNITY",
                    "MICROPLAN_MO_13_05_01_02_01_A_G__COMMUNITY",
                    "MICROPLAN_MO_13_05_01_01_09_NAO_COMMUNITY",
                    "MICROPLAN_MO_13_05_01_01_07_GBAGBAVILLE",
                    "MICROPLAN_MO_13_05_01_01_06_ELRZ_COMMUNITY",
                    "MICROPLAN_MO_13_05_01_01_05_MANDINGO_QUARTER",
                    "MICROPLAN_MO_13_05_01_01_04_ZANBO_QUARTER",
                    "MICROPLAN_MO_13_05_01_01_03_KYNE_QUARTER",
                    "MICROPLAN_MO_13_05_01_01_02_GBOE_QUARTER",
                    "MICROPLAN_MO_13_05_01_01_01_BOWEN_QUARTER"
                ],
                "additionalDetails": {
                    "capacity": 1280,
                    "fixedPost": "No",
                    "facilityName": "angelic being 3713",
                    "facilityType": "Storing Resource",
                    "facilityStatus": "Temporary",
                    "assignedVillages": [],
                    "servingPopulation": 15272
                },
                "active": true,
                "auditDetails": {
                    "createdBy": "29f73f64-2f5b-4699-b92c-4b093ac65749",
                    "lastModifiedBy": "bae97a73-8c70-4e09-92fd-d1ae97321cb5",
                    "createdTime": 1732615033646,
                    "lastModifiedTime": 1732619625034
                }
            }

    Manage Data APIs

    This section of the documentation details APIs for creating, searching, generating, and downloading data, including request/response structures, flows, and error handling. Campaign Creation V2 Flow – Documentation

    Overview

    The Campaign Creation V2 flow improves upon the earlier V1 implementation by introducing a type-aware, config-driven, and extensible architecture for handling Excel-based data uploads.

    This change simplifies how Excel sheets are parsed, validated, transformed, and annotated, making the flow scalable and easier to maintain.


    V1 vs V2 – Key Differences


    🛠️ API: POST /v2/data/_process

    🔹 Purpose

    Processes uploaded Excel files for validation-type sheets. This API is exposed to the client UI through role-action mapping.

    🔹 Supported Types

    🔹 Sample Payload

    🔹 Processing Behavior

    • Sheet Parsing: Extracts data from each sheet using configured schema.

    • Data Transformation: Applies field-level or row-level transformations (e.g., date parsing, ID lookup).

    • Validation: Enforces rules defined in MDMS.

    • Error Annotation: Errors are annotated row-wise and can be returned in response or in the processed Excel file.


    🔄 API: POST /v2/data/_process-any

    🔹 Purpose

    Processes any sheet type (both validation and data entry).

    Internal Use Only – this API is not exposed via role-action mapping. It is used internally by services like project-factory-service.

    🔹 Differences from /v2/data/_process

    🔹 Sample Payload

    Same structure as /v2/data/_process, e.g.,


    ✅ When to Use Which API?


    🔐 Role Access Mapping


    🧠 Internal Flow – How Processing Works

    The V2 system uses a dynamic, type-based processing mechanism to ensure clean separation of concerns and better maintainability.

    🔧 Step 1: Type-Based Class Resolution

    The system uses the type field in the request to determine the processing class:

    const className = `${ResourceDetails?.type}-processClass`;

    This maps to a file like

    processFlowClasses/userValidation-processClass.ts

    processFlowClasses/facility-processClass.ts

    🔄 Step 2: Dynamic Class Import and Execution

    const { TemplateClass } = await import(classFilePath);

    const sheetMap = await TemplateClass.process(ResourceDetails, wholeSheetData, localizationMap);

    Each class implements a static process() method that:

    • Accepts the parsed sheet data

    • Performs transformation + validation

    • Returns a SheetMap object with data, errors, and annotations

    🧩 Inside Each Type Class

    Each class (e.g., userValidation-processClass) encapsulates all logic for that type:

    • Data cleanup or enrichment

    • Business rule validation

    • Conditional field logic

    • Return of structured, annotated sheet data


    🌟 Why This Approach?


    📄 Campaign Template Generation V2 Flow – Documentation


    🧾 Overview

    The Template Generation V2 flow is an upgrade over the earlier /v1/data/_generate implementation. It enables a loosely coupled, type-driven, and config-based Excel template generation system, ensuring better maintainability and extensibility.

    The legacy endpoint:

    http

    POST /v1/data/_generate

    has now been replaced with:

    http

    POST /v2/data/_generate


    🔁 V1 vs V2 – Key Differences

    ⚙️ Earlier most things were hardcoded. Now, ~80% is config-driven via MDMS or file-based config, and ~20% uses dynamic functions for specialized transformation logic.


    🛠️ API: POST /v2/data/_generate

    🔹 Purpose

    Generates Excel templates for campaign resource types such as user, facility, boundary, etc., using MDMS-driven config and dynamic logic. UI integrates with this endpoint to export downloadable templates for upload flows.


    🔹 Required Query Parameters


    🔹 Sample cURL Request

    🔧 Internal Flow – How Generation Works

    🔹 Step 1: Type-Based Class Resolution

    const className = `${responseToSend?.type}-generateClass`;

    let classFilePath = path.join(__dirname, '..', 'generateFlowClasses', `${className}.js`);

    if (!fs.existsSync(classFilePath)) {

    classFilePath = path.join(__dirname, '..', 'generateFlowClasses', `${className}.ts`);

    }

    Expected files (per type):

    • user-generateClass.ts

    • facility-generateClass.ts

    • boundary-generateClass.ts


    🔄 Step 2: Dynamic Import and Execution

    const { TemplateClass } = await import(classFilePath);

    const sheetMap = await TemplateClass.generate(ResourceDetails, localizationMap);

    Returns an object with:

    • ✅ Sheet Name(s)

    • ✅ Header Row(s)

    • ✅ Pre-filled Data (if any)

    • ✅ Column metadata (dropdowns, styles, widths)


    🔃 Transform Configuration (transformConfigs)

    This configuration defines how API response data maps to Excel sheets and how sheet uploads map back to request payloads.

    🔹 Driven By

    • MDMS config

    • File-based transformConfigs

    • Optional dynamic transformation functions (transformBulkX, transformX)


    🧩 Sample: employeeHrms

    HRMS Config

    🧩 Sample: Facility

    🔹 Field Properties


    🌟 Why This Approach?

    🔁 Retry Mechanism During Campaign Creation


    🧾 Overview

    The retry mechanism allows safe re-triggering of campaign creation only if the campaign is in a drafted or failed state. It uses the existing /v1/project-type/update API with action: "create" inside CampaignDetails. There is no dedicated retry API.

    ⚠️ Not fully idempotent 🔁 Re-uses creation API ✅ Works only for failed/drafted campaigns


    🚫 When Retry Does NOT Work

    • If the campaign is already created and active, and a retry (action: "create") is attempted, it will throw an error.

    • Only campaigns in the following statuses are allowed to be re-processed:

    ["drafted", "failed"]


    🚀 Retry API (Same as Create)

    http

    CopyEdit

    POST /project-factory/v1/project-type/update

    🔹 Required Query Params


    📦 Sample Request Body

    {

    "RequestInfo": {

    "apiId": "Rainmaker",

    "authToken": "your-auth-token",

    "userInfo": {

    "uuid": "user-uuid",

    "roles": [{ "code": "CAMPAIGN_MANAGER", "tenantId": "mz" }],

    "tenantId": "dev"

    }

    },

    "CampaignDetails": {

    "campaignId": "5c845eb8-f8b2-43d0-a301-8e24692499f1",

    "campaignNumber": "HCMP-CAM-00001",

    "action": "create",

    ...

    }

    }


    📊 Internal Tables Used


    📁 eg_cm_campaign_data — Sheet Row Status

    Tracks each data row uploaded from sheet.

    export const dataRowStatuses = {

    failed: "failed",

    completed: "completed",

    pending: "pending"

    }


    🔗 eg_cm_campaign_mapping_data — Mapping Status

    Stores mapping status per row and boundary.

    export const mappingStatuses = {

    toBeMapped: "toBeMapped",

    mapped: "mapped",

    toBeDeMapped: "toBeDeMapped",

    deMapped: "deMapped"

    }


    🧩 eg_cm_campaign_process_data — Process Flow Status

    Tracks which steps of campaign creation are done/pending/failed.

    ts

    CopyEdit

    export const processStatuses = {

    failed: "failed",

    pending: "pending",

    completed: "completed"

    }

    👇 Process Names

    export const allProcesses = {

    facilityCreation: "CAMPAIGN_FACILITY_CREATION_PROCESS",

    userCreation: "CAMPAIGN_USER_CREATION_PROCESS",

    projectCreation: "CAMPAIGN_PROJECT_CREATION_PROCESS",

    facilityMapping: "CAMPAIGN_FACILITY_MAPPING_PROCESS",

    userMapping: "CAMPAIGN_USER_MAPPING_PROCESS",

    resourceMapping: "CAMPAIGN_RESOURCE_MAPPING_PROCESS",

    userCredGeneration: "CAMPAIGN_USER_CRED_GENERATION_PROCESS"

    }


    🔁 Retry Logic Summary


    ✅ Final Notes

    • This approach provides partial re-execution based on current statuses.

    • Helps in recovery from partial failure (e.g., during bulk upload).

    • Prevents overwriting already created resources.

    • Make sure to validate campaign status before retrying.

    📘 Document: App Config & Localisation Setup During Campaign Creation

    🧩 Overview

    When a new campaign is created using the /project-factory/v1/project-type/create API, the backend asynchronously triggers:

    • Creation of campaign-specific MDMS module configs

    • Copying of base localisations to campaign-localised keys

    This happens in the background and does not block the campaign creation response.


    ⚙️ Trigger Point

    API Endpoint

    bash

    CopyEdit

    POST /project-factory/v1/project-type/create

    Trigger Logic

    ts

    CopyEdit

    createAppConfig(tenantId, campaignNumber, campaignType); // No await

    • createAppConfig(...) runs without await

    • The API returns immediately while config generation runs in parallel


    🔧 Internal Flow: createAppConfig(...)

    1. Fetch Enabled Template Modules

    From schema: HCM-ADMIN-CONSOLE.FormConfigTemplate

    ts

    CopyEdit

    const templateModules = (templateResponse?.mdms || [])

    .map(item => item?.data || [])

    .flat()

    .filter(module => !module?.disabled);

    ✔️ Only modules where disabled !== true are processed.


    2. Localisation Copy

    For each module:

    • Base Key: hcm-base-{moduleName}-{campaignType}

    • Target Key: hcm-{moduleName}-{campaignNumber}

    For each locale:

    • Fetch localisation entries using the base key

    • Replace module with the new target key

    • Upload entries in chunks of 100

    await localisation.createLocalisation(chunk, tenantId);

    🧩 RequestInfo is not passed 💡 Failures are logged but do not interrupt other locale uploads


    3. Insert MDMS Module Config

    Target schema: HCM-ADMIN-CONSOLE.FormConfig

    Each module:

    • Is enriched with:

    • project: campaignNumber

    • isSelected: true

    • Is posted to MDMS v2 API:

    ts

    CopyEdit

    await httpRequest(mdms_create_or_update_url, requestBody);

    🧱 Module configs are associated with the campaign being created.


    ✅ Summary Table


    📝 Additional Notes

    • Ensures every campaign has its own set of configuration modules and localised messages

    • Localisation is cloned and renamed from base templates for each campaign

    • This system supports high performance and reliability through async background execution


    Limited

    Easily extendable by adding type-specific logic

    Client (UI)

    Internal services

    In chunks of 100, per locale

    Error Handling

    Errors logged per module or locale, but execution continues gracefully

    Feature

    V1 (/v1/data/_create)

    V2 (/v2/data/_process)

    API Endpoint

    /v1/data/_create

    /v2/data/_process

    Sheet Type Support

    Embedded in sheet

    Explicit in API payload (type)

    Validation Support

    Manual/Inline

    Automated via MDMS config

    Flexibility

    Rigid, fixed structure

    Modular, type-based flow

    Category

    Types

    Data Entry

    user, facility, boundary

    Validation

    userValidation, facilityValidation, boundaryValidation

    Feature

    /v2/data/_process

    /v2/data/_process-any

    Scope

    Validation-only

    All types (data + validation)

    Use Case

    UI pre-submission checks

    Backend ingestion, internal flows

    Config Handling

    Strict type filtering

    Dynamic resolution based on type

    Role Access

    ✅ Yes

    ❌ No (internal only)

    Scenario

    Recommended API

    Validate uploaded sheet via UI

    /v2/data/_process

    Internal data ingestion (backend)

    /v2/data/_process-any

    API Endpoint

    Role Mapping

    Intended Caller

    /v2/data/_process

    ✅ Yes

    UI / client-facing

    /v2/data/_process-any

    ❌ No

    Internal service use

    Feature

    Benefit

    🔌 Low Coupling

    Each type is self-contained – changes don't affect others

    🔧 Easily Extendable

    Adding a new type is as simple as creating a new class

    🧼 Clean Architecture

    Sheet logic lives in its own file, not the main service

    ⚙️ Config-Driven

    Sheet schema, headers, validation rules all come from MDMS

    🧑‍💻 Developer Friendly

    Developers only need to work on their type-specific class

    Feature

    V1 (/v1/data/_generate)

    V2 (/v2/data/_generate)

    API Endpoint

    /v1/data/_generate

    /v2/data/_generate

    Sheet Type Support

    Embedded logic

    Passed via type query param

    Logic Coupling

    Tightly coupled

    Type-based, dynamic classes

    Extensibility

    Hard to extend

    Add new types via config + class

    Parameter

    Type

    Description

    tenantId

    string

    Tenant under which the campaign runs

    type

    string

    Type of template to generate (user, facility, etc.)

    hierarchyType

    string

    Hierarchy code associated with the campaign

    campaignId

    string

    ID of the campaign

    Property

    Description

    path

    JSON path in request/response

    source.header

    Column name in Excel sheet

    value

    Static value or dynamic reference like ${metadata.tenantId}

    splitBy

    Delimiter for multi-valued fields

    transform

    Mapping to normalize values (e.g., from "Permanent" to boolean true)

    Feature

    Benefit

    🔌 Low Coupling

    Per-type logic and config separation

    ⚙️ Config-Driven

    Most headers, styles, mappings are externalized

    🔧 Easily Extendable

    Drop in a class + config entry for new types

    🧼 Clean Architecture

    Controller remains generic; logic lives in type handlers

    🧩 Reusable Logic

    Same config powers both generation and upload parsing

    Parameter

    Type

    Required

    Description

    tenantId

    string

    ✅

    Tenant ID

    campaignId

    string

    ✅

    Campaign UUID (external)

    Column

    Description

    campaignNumber

    Campaign ref

    type

    Template type (user, facility)

    uniqueIdentifier

    Unique row key

    data

    Original sheet data (JSONB)

    uniqueIdAfterProcess

    Generated ID (after success)

    status

    ✅ pending, completed, failed

    Column

    Description

    type

    Mapping type (userMapping, etc.)

    uniqueIdentifierForData

    FK to campaign data

    boundaryCode

    Boundary associated

    mappingId

    Generated ID post-mapping

    status

    ✅ toBeMapped, mapped, toBeDeMapped, deMapped

    Column

    Description

    processName

    Each campaign step name

    status

    ✅ pending, completed, failed

    Step

    Logic

    ✅ Allowed Status

    Retry only works if campaign is in drafted or failed

    ❌ Disallowed

    Retry fails if campaign is already active or completed

    Sheet Rows

    Retries only rows with status pending or failed

    Mapping Rows

    Retries only rows with status toBeMapped or toBeDeMapped

    Process Steps

    Retries only steps with status pending or failed

    Completed Work

    Skipped entirely

    Step

    Description

    Trigger API

    POST /project-factory/v1/project-type/create

    Async Execution

    createAppConfig(...) runs in background, no delay to API response

    Template Schema

    HCM-ADMIN-CONSOLE.FormConfigTemplate

    Target Schema

    HCM-ADMIN-CONSOLE.FormConfig

    Localisation Source Key

    hcm-base-{moduleName}-{campaignType}

    Localisation Target Key

    hcm-{moduleName}-{campaignNumber}

    Sample Payload
    ```
       "CampaignDetails":  {
                "id": "2b68a3aa-fca2-462e-8d59-8821c9a56132",
                "tenantId": "mz",
                "status": "drafted",
                "action": "create",
                "campaignNumber": "CMP-2024-10-15-004031",
                "isActive": true,
                "parentId": "43503755-db1d-4cef-9851-72360ee6eaa1",
                "campaignName": "LLIN-OCT15a",
                "projectType": "LLIN-mz",
                "hierarchyType": "HIERARCHYTEST",
                "boundaryCode": "",
                "projectId": null,
                "startDate": 1727202600000,
                "endDate": 1727720999000,
                "additionalDetails": {
                    "key": 10,
    

    Extensibility

    Intended Caller

    Upload Method

    App Configuration

    Overview

    This document outlines the UI design and configuration of screens and components for the application. It includes schema requirements, support for dynamic sections, and the necessary master data to facilitate data flow.

    {
      "ResourceDetails": {
        "tenantId": "dev",
        "type": "userValidation",
        "fileStoreId": "{{fileId}}",
        "hierarchyType": "NEWTEST00222",
        "additionalDetails": {},
        "campaignId": "5c845eb8-f8b2-43d0-a301-8e24692499f1"
      },
      "RequestInfo": {
        "apiId": "Rainmaker",
        "authToken": "{{Auth}}",
        "userInfo": {
          "id": 1052,
          "uuid": "8b110055-330f-4e7b-b4c0-f618f29b9d47"
        }
      }
    }
    {
      "ResourceDetails": {
        "tenantId": "dev",
        "type": "facility",
        "fileStoreId": "{{fileId}}",
        "hierarchyType": "NEWTEST00222",
        "additionalDetails": {},
        "campaignId": "5c845eb8-f8b2-43d0-a301-8e24692499f1"
      },
      "RequestInfo": {
        "apiId": "Rainmaker",
        "authToken": "{{Auth}}",
        "userInfo": {
          "id": 1052,
          "uuid": "8b110055-330f-4e7b-b4c0-f618f29b9d47"
        }
      }
    
    
    curl --location 'http://localhost:8080/project-factory/v2/data/_generate?tenantId=dev&type=user&hierarchyType=NEWTEST00222&campaignId=5c845eb8-f8b2-43d0-a301-8e24692499f1' \
    --header 'Content-Type: application/json;charset=UTF-8' \
    --data '{
      "RequestInfo": {
        "apiId": "Rainmaker",
        "authToken": "your-auth-token",
        "userInfo": {
          "id": 1052,
          "uuid": "8b110055-330f-4e7b-b4c0-f618f29b9d47",
          "userName": "UATMZ",
          "name": "UATMZ",
          "mobileNumber": "8998988112",
          "type": "EMPLOYEE",
          "roles": [
            {
              "code": "CAMPAIGN_MANAGER",
              "tenantId": "mz"
            }
          ],
          "active": true,
          "tenantId": "dev"
        }
      }
    }'
    
    
    employeeHrms: {
      metadata: { tenantId: "dev", hierarchy: "MICROPLAN" },
      fields: [
        { path: "$.user.name", source: { header: "HCM_ADMIN_CONSOLE_USER_NAME" } },
        { path: "$.user.mobileNumber", source: { header: "HCM_ADMIN_CONSOLE_USER_PHONE_NUMBER" } },
        { path: "$.user.roles[*].name", source: { header: "HCM_ADMIN_CONSOLE_USER_ROLE", splitBy: "," } },
        { path: "$.user.roles[*].code", source: { header: "HCM_ADMIN_CONSOLE_USER_ROLE", splitBy: "," } },
        { path: "$.user.roles[*].tenantId", value: "${metadata.tenantId}" },
        { path: "$.user.userName", source: { header: "UserName" } },
        { path: "$.user.password", source: { header: "Password" } },
        { path: "$.user.tenantId", value: "${metadata.tenantId}" },
        { path: "$.user.dob", value: 0 },
        {
          path: "$.employeeType",
          source: {
            header: "HCM_ADMIN_CONSOLE_USER_EMPLOYMENT_TYPE",
            transform: {
              mapping: {
                Permanent: "PERMANENT",
                Temporary: "TEMPORARY",
                "%default%": "TEMPORARY"
              }
            }
          }
        },
        {
          path: "$.jurisdictions[*].boundary",
          source: { header: "HCM_ADMIN_CONSOLE_BOUNDARY_CODE_MANDATORY", splitBy: "," }
        },
        { path: "$.jurisdictions[*].tenantId", value: "${metadata.tenantId}" },
        { path: "$.jurisdictions[*].hierarchy", value: "${metadata.hierarchy}" },
        { path: "$.jurisdictions[*].boundaryType", value: "${metadata.hierarchy}" },
        { path: "$.tenantId", value: "${metadata.tenantId}" },
        { path: "$.code", source: { header: "UserName" } }
      ],
      transFormSingle: "transformEmployee",
      transFormBulk: "transformBulkEmployee"
    }
    "beneficiaryType": "HOUSEHOLD"
    },
    "resources": [
    {
    "type": "facility",
    "filename": "update-facility.xlsx",
    "resourceId": "42c04e62-4b7b-4697-b2bd-aa90a212164c",
    "filestoreId": "20420b29-d913-4412-b3bd-34b850e2677b"
    },
    {
    "type": "boundaryWithTarget",
    "filename": "updated-boundary.xlsx",
    "resourceId": "8567db53-450e-465d-a14a-46e2690cf728",
    "filestoreId": "30ae3fd6-b77c-42e7-9a33-e88e29369764"
    },
    {
    "type": "user",
    "filename": "updated-user.xlsx",
    "resourceId": "fcc4a423-6ac5-4ee4-80c2-0f915a95253f",
    "filestoreId": "3c531af7-d923-47cc-b58a-c501a73e749c"
    }
    ],
    "boundaries": [],
    "deliveryRules": [
    {
    "active": true,
    "cycleIndex": "1",
    "deliveries": [
    {
    "active": true,
    "deliveryIndex": "1",
    "deliveryRules": [
    {
    "ruleKey": 1,
    "delivery": {},
    "products": [
    {
    "key": 1,
    "count": 1,
    "value": "PVAR-2024-05-09-000333"
    }
    ],
    "attributes": [
    {
    "key": 1,
    "value": "1",
    "operator": {
    "code": "LESS_THAN_EQUAL_TO"
    },
    "attribute": {
    "code": "CAMPAIGN_BEDNET_INDIVIDUAL_LABEL"
    }
    },
    {
    "key": 2,
    "value": "3",
    "operator": {
    "code": "LESS_THAN_EQUAL_TO"
    },
    "attribute": {
    "code": "CAMPAIGN_BEDNET_HOUSEHOLD_LABEL"
    }
    }
    ]
    }
    ]
    }
    ]
    }
    ],
    "auditDetails": {
    "createdBy": "63a21269-d40d-4c26-878f-4f4486b1f44b",
    "lastModifiedBy": "63a21269-d40d-4c26-878f-4f4486b1f44b",
    "createdTime": 1728983362986,
    "lastModifiedTime": 1728983362995
    }
    },
    ```
    Flow Summary

    🧾 Campaign Number Generation

    • Each Campaign Number (e.g., CMP-2025-05-22-005961) is unique and derived from the Campaign object.

    • This campaign number acts as a reference ID in the Project object once a user logs in.


    Template Data

    Template Base Config

    • Present in: HCM-ADMIN-CONSOLE.TemplateBaseConfig

    • Maintains default configurations for each campaign type.

    • Serves as the source of truth to derive actual config data based on module/feature selection.

    Base Localisation Data

    • Module: hcm-registration-project

    • Maintains default localisation data per campaign type.

    • Used as a template to generate project-specific localisation.


    App Configuration

    📌 On Module & Feature Selection

    When a user selects a specific:

    • Module(s)

    • Feature(s) ...then the system:

    1. Reads template from TemplateBaseConfig.

    2. Creates config entries in: HCM-ADMIN-CONSOLE.SimpleAppConfiguration

    3. App config keys are uniquely identified by:

      • campaign number

      • flow key (e.g., REGISTRATION, INVENTORY)

    Example:


    Generate Localisation Data

    🌍 Based on Flow and Campaign

    • Localisation keys are generated using the flow name and campaign number.

    Example:


    🧠 Project Object After Login

    When the user logs in and a Project is identified:

    • project.referenceId = CMP-2025-05-22-005961

    • Configuration version keys look like:

      • REGISTRATION_CMP-2025-05-22-005961

      • INVENTORY_CMP-2025-05-22-005961

      • OTHERFLOWS_CMP-2025-05-22-005961

    • Localisation entries:

      • hcm-registration-cmp-2025-05-22-005961

      • hcm-inventory-cmp-2025-05-22-005961

    App Config Sequence Diagram

    Sequence Diagram

    Key Points to Consider:

    1. Schema Integration Based on Project Type

      • The UI design should incorporate schemas that vary depending on the selected project type.

      • Dynamic rendering of components and fields based on schema definitions.

    2. Enable AddSection Functionality

      • Provide an option to dynamically add sections to the screen configuration.

      • Ensure sections can be personalised and managed efficiently.

    3. Master Data Requirements The following master data sets are required to support the UI design and component configurations:

      • AppScreenConfigTemplate Predefined templates for application screen configurations based on project type.

      • AppScreenConfigPersonalized Personalised configurations for screens, tailored to specific user roles or preferences.

      • ComponentMetaDataMaster

    Master Data: AppScreenConfigTemplate

    Schema Overview

    The AppScreenConfigTemplate defines the configuration and structure of application screens. It supports dynamic field addition, sections, comments, and card-based layouts.

    UPDATE

    Output Data Structure For App Config

    Field Type Master Data

    This provides the configuration and metadata for various input field types used in the application. Each field type is mapped to a specific appType and includes metadata such as data types, validation rules, and other properties.

    Drawer Master Data

    The Drawer Master Data defines the configuration for the list of fields to be displayed in the drawer. Each field includes a label for identification and a fieldType that determines the type of input control to be rendered in the UI.

    Localisation Master data

    Flow Overview

    1. Fetching the App Configuration from MDMSv2:

      • Step Description: The app configuration master data is fetched from the MDMSv2 (Master Data Management System version 2). This data includes the settings, components, field types, and other configurations that dictate the structure and behaviour of the app’s screens and components.

      • Flow Detail:

        • The data is fetched asynchronously via an API call to the MDMSv2.

        • Once the data is fetched, it is stored in the application’s global state using React’s useContext. This ensures the data is accessible across various components throughout the app.

        • The data might look like:

          • Screen configurations (e.g., component layout, form field types).

          • Master data for field types, component metadata, drawer configurations, etc.

      • Considerations:

        • Ensure that proper error handling is in place if the API call fails (e.g., retry logic or fallback UI).

        • The context should be memoised or optimised for performance if the app grows large.

    2. User Interactions (Editing, Adding, Deleting Components):

    • Step Description: Once the data is loaded and the UI is rendered based on the fetched configuration, users can interact with the UI by editing, adding, or deleting fields and components.

    • Flow Detail:

      • Editing: Users can modify the existing field values or configurations. For example, changing field labels, modifying validation rules, or adjusting layout properties.

      • Adding: Users can add new components, fields, or sections to the form. The UI should dynamically update to accommodate new fields or components.

      • Deleting: Users can delete specific components, fields, or entire sections, and the UI should reflect these changes instantly.

      • The updates made by the user are stored in the local state (managed by React’s useState or within the useContext).

    • Considerations:

      • The system must handle edge cases, such as removing fields that are required or have dependencies.

      • Ensure that updates are validated locally before sending them back to MDMSv2, to prevent inconsistencies.


    1. Restructuring Data for Web or Mobile Outputs:

      • Step Description: After the user makes changes, the data must be restructured based on the target platform (e.g., web or mobile). This restructuring ensures that the configuration is correctly formatted to match the specifications required by the platform.

      • Flow Detail:

        • Once the data is updated, it is transformed according to the specific platform’s output format. For example:

          • For web applications, the configuration might need to be structured in a way that fits the web component framework (e.g., React).

          • For mobile applications, it may need to follow mobile-specific guidelines (e.g., using mobile UI components or formats).

        • The restructuring process may involve:

          • Converting configuration fields to fit the layout constraints of mobile screens (e.g., adjusting padding, margins).

          • Changing input types or validations for mobile responsiveness.

          • Adapting field types and labels based on the platform (e.g., dropdowns might be replaced with modals on mobile).

      • Considerations:

        • This step may require conditional logic to determine which platform the configuration is being prepared for.

        • No data must be lost during the restructuring process, so careful testing is needed.

    2. Updating MDMSv2 (Client Master Data Structure):

      • Step Description: After the changes are made and the data has been restructured for the appropriate platform, the final updated configuration needs to be sent back to MDMSv2. This update is stored as the ClientMasterData structure.

      • Flow Detail:

    Sequence Diagram

    Flow Diagram

    App Integration

    Once the config is created, if it is directly for MDMS v2, we will enrich it with additional metadata and send it directly to MDMS v2.

    If code generation is required based on the alternative approach, we will convert the config into code changes and push it to GitHub for app generation.

    App Config - Data Creation flow
    Key: REGISTRATION_CMP-2025-05-22-005961
    Key: INVENTORY_CMP-2025-05-22-005961
    Localisation key: hcm-registration-cmp-2025-05-22-005961
    Localisation key: hcm-inventory-cmp-2025-05-22-005961
    {
      // Array of screens for the application
      "screens": [
        {
          // Unique name for the screen
          "name": "screen1",
          // Parent category of the screen
          "parent": "Registration",
          // Screen headers and descriptions
          "headers": [
            {
              // Header label
              "label": "KJHSJKDHKJH",
              // Type of the header (e.g., header, info, description)
              "type": "header"
            },
            {
              "label": "KJHSJKDHKJH",
              "type": "info"
            },
            {
              "label": "KJHSJKDHKJH",
              "type": "description"
            }
          ],
          // Screen configuration settings
          "config": {
            // Allows adding fields dynamically to the screen
            "enableFieldAddition": true,
            // Allows adding sections dynamically to the screen
            "enableSectionAddition": true,
            // Enables commenting functionality on the screen
            "enableComment": true,
            // Specifies where fields can be added (e.g., body, header, footer)
            "allowFieldsAdditionAt": [
              "body"
            ],
            // Specifies where comments can be added
            "allowCommentsAdditionAt": [
              "body"
            ]
          },
          // Cards within the screen (UI components grouped into cards)
          "cards": [
            {
              // Card header text
              "header": "Header",
              // Card description text
              "description": "Desc",
              // Fields inside the card
              "fields": [
                {
                  // Path for binding data in the field
                  "jsonPath": "Screen heading",
                  // Type of the field (e.g., text, dropdown)
                  "type": "text",
                  // Label for the field
                  "label": "dzdzddadadad",
                  // Specifies if the field is mandatory
                  "required": true,
                  // Indicates if the field is active
                  "active": true,
                  // Additional metadata for the field
                  "metaData": {
                    // Field is read-only
                    "readOnly": true,
                    // Field supports comments
                    "isComment": true
                  }
                },
                {
                  "jsonPath": "Description",
                  "type": "text",
                  "label": "dzdzddadadad",
                  "required": true,
                  "active": true,
                  "metaData": {
                    "isComment": true
                  }
                },
                {
                  "jsonPath": "Description",
                  "type": "text",
                  "label": "Address Line 1",
                  "required": true,
                  "active": true,
                  "metaData": {}
                },
                {
                  // Unique ID for the field
                  "id": "field2",
                  // Field type is dropdown
                  "type": "dropdown",
                  // Label for the dropdown field
                  "label": "Beneficiary Status",
                  // Additional metadata for dropdown field
                  "metaData": {
                    // Field is mandatory
                    "required": true,
                    // Options available for the dropdown
                    "options": [
                      {
                        // Label for the dropdown option
                        "label": "Beneficiary Absent",
                        // Value associated with the dropdown option
                        "value": "absent"
                      },
                      {
                        "label": "Delivery Successful",
                        "value": "successful"
                      }
                    ]
                  }
                }
              ]
            }
          ]
        },
        {
          // Placeholder for additional screen configurations
        }
      ]
    }
    
    ```json
    {
      "screens": [
        {
          "name": "HOUSEHOLD_LOCATION",
          "parent": "REGISTRATION",
          "headers": [
            {
              "jsonPath": "SCREEN_HEADING",
              "type": "header",
              "label": "SCREEN_HEADING_LABEL",
              "required": true,
              "active": true,
              "metaData": {
                "fieldType": "text"
              }
            },
            {
              "jsonPath": "DESCRIPTION",
              "type": "description",
              "label": "DESCRIPTION_LABEL",
              "required": true,
              "active": true,
              "metaData": {
                "fieldType": "text"
              }
            }
          ],
          "config": {
            "enableFieldAddition": true,
            "enableSectionAddition": true,
            "enableComment": true,
            "allowFieldsAdditionAt": [
              "body"
            ],
            "allowCommentsAdditionAt": [
              "body"
            ]
          },
          "cards": [
            {
              "header": "HEADER_CODE",
              "description": "DESCRIPTION_CODE",
              "fields": [
                {
                  "jsonPath": "ADDRESS_LINE_1",
                  "type": "text",
                  "label": "ADDRESS_LINE_1_LABEL",
                  "required": true,
                  "active": true,
                  "metaData": {}
                },
                {
                  "jsonPath": "ADDRESS_LINE_2",
                  "type": "text",
                  "label": "ADDRESS_LINE_2_LABEL",
                  "required": true,
                  "active": true,
                  "metaData": {}
                }
              ]
            }
          ]
        }
      ]
    }
    ```
    [
      {
        "name": "HouseholdLocation",
        "type": "page",
        "components": [
          {
            "title": "Household Location",
            "description": "Make sure the village name matches the one where you are today.",
            "order": 1,
            "attributes": [
              {
                "name": "administrationArea",
                "type": "field",
                "isEnabled": true,
                "attribute": "textField",
                "readOnly": true,
                "isRequired": false,
                "order": 1,
                "source": "DEFAULT"
              },
              {
                "name": "accuracy",
                "isEnabled": true,
                "readOnly": true,
                "attribute": "textField",
                "isRequired": true,
                "order": 2
              },
              {
                "name": "addressLine1",
                "isEnabled": true,
                "readOnly": false,
                "attribute": "textField",
                "isRequired": false,
                "validation": [
                  {
                    "pattern": "^\\d+$",
                    "key": "onlyDigits",
                    "errorMessage": "Digits only"
                  }
                ],
                "order": 1
              },
              {
                "name": "postalCode",
                "isEnabled": true,
                "readOnly": false,
                "attribute": "textField",
                "isRequired": false,
                "order": 1
              },
              {
                "name": "TextField",
                "type": "additionalField",
                "label": "TextField",
                "attribute": "textField",
                "formDataType": "String",
                "isEnabled": true,
                "readOnly": false,
                "isRequired": false,
                "keyboardType": "number",
                "validation": [
                  {
                    "pattern": "^\\d+$",
                    "key": "onlyDigits",
                    "errorMessage": "Digits only"
                  }
                ],
                "order": 1
              },
              {
                "name": "SelectionBox",
                "type": "additionalField",
                "label": "SelectionBox",
                "attribute": "selectionbox",
                "formDataType": "List<String>",
                "menuItems": [
                  "a",
                  "b",
                  "c",
                  "d"
                ],
                "allowMultipleSelection": true,
                "isEnabled": true,
                "readOnly": false,
                "isRequired": false,
                "order": 2
              },
              {
                "name": "dateForm",
                "type": "additionalField",
                "label": "dateForm",
                "attribute": "dateFormPicker",
                "formDataType": "DateTime",
                "isEnabled": true,
                "readOnly": false,
                "isRequired": false,
                "order": 5
              },
              {
                "name": "DropDown",
                "type": "additionalField",
                "label": "DropDown",
                "attribute": "dropdown",
                "formDataType": "String",
                "menuItems": [
                  "a",
                  "b"
                ],
                "isEnabled": true,
                "readOnly": false,
                "isRequired": false,
                "order": 3
              },
              {
                "name": "dobPicker",
                "type": "additionalField",
                "label": "dobPicker",
                "attribute": "dobPicker",
                "formDataType": "DateTime",
                "isEnabled": true,
                "readOnly": false,
                "isRequired": false,
                "order": 4
              },
              {
                "name": "integerFormPicker",
                "type": "additionalField",
                "label": "integerFormPicker",
                "attribute": "integerFormPicker",
                "formDataType": "int",
                "initialValue": 0,
                "minimum": 0,
                "maximum": 10,
                "isEnabled": true,
                "readOnly": false,
                "isRequired": false,
                "order": 6
              }
            ]
          }
        ]
      }
    ]
    {
      "fieldType": [
        {
          "type": "textInput",
          "appType": "textField",
          "metadata": {
            "formDataType": "String",
            "validation": [
              {
                "pattern": "^\\d+$",
                "key": "onlyDigits",
                "errorMessage": "Digits only"
              }
            ]
          }
        },
        {
          "type": "number",
          "appType": "textField",
          "metadata": {
            "formDataType": "String",
            "keyboardType": "number",
            "validation": [
              {
                "pattern": "^\\d+$",
                "key": "onlyDigits",
                "errorMessage": "Digits only"
              }
            ]
          }
        },
        {
          "type": "dropDown",
          "appType": "dropdown",
          "metadata": {
            "formDataType": "String",
          },
         "attributeToRename": {
            "from": "options", 
            "to": "menuItems" // Rename "options" to "menuItems" when restructuring
            "optionalFunction": null
          }
          "attributeToDelete": [],
          }
        {
          "type": "checkbox",
          "appType": "selectionbox",
          "metadata": {
            "formDataType": "List<String>",
            "allowMultipleSelection": true,
          },
          "fieldRenameMap": {
            "options": "menuItems" // Rename "options" to "menuItems" when restructuring
          }
        },
        {
          "type": "counter",
          "appType": "integerFormPicker",
          "metadata": {
            "formDataType": "int",
            "initialValue": 0,
            "minimum": 0,
            "maximum": 10
          }
        },
        {
          "type": "datePicker",
          "appType": "dobPicker",
          "metadata": {
            "formDataType": "DateTime"
          }
        },
        {
          "type": "dobPicker",
          "appType": "dateFormPicker",
          "metadata": {
            "formDataType": "DateTime"
          }
        }
      ]
    }
    {
      "drawerData": [
        {
          "label": "componentType",
          "fieldType": "dropdown",
          "defaultValue": false,
          "visibilityEnabledFor": []
        },
        {
          "label": "Mandatory",
          "fieldType": "toggle",
          "defaultValue": false,
          "visibilityEnabledFor": ["textField", "dropDown"]
        },
        {
          "label": "label",
          "fieldType": "toggle",
          "defaultValue": false,
          "visibilityEnabledFor": ["textField", "dropDown"]
        },
        {
          "label": "helpText",
          "fieldType": "toggle",
          "defaultValue": false,
          "visibilityEnabledFor":[]
        },
        {
          "label": "innerLabel",
          "fieldType": "toggle",
          "defaultValue": false,
          "visibilityEnabledFor": []
        }
      ]
    }
    {
      "LocalisationData": {
        "screen": "appScreenConfig"
        "LocalisationModule":"configure-app",
        "moduleVersion": "3",
        "minModuleVersion": "1",
        "fields": [
          {
            "fieldType": "dropdown",
            "localisableProperties": ["label", "options", "placeholder"]
          },
          {
            "fieldType": "toggle",
            "applicableFieldTypes": ["textField", "dropDown"]
          },
          {
            "fieldType": "toggle",
            "applicableFieldTypes": ["textField", "dropDown"]
          },
          {
            "fieldType": "toggle",
            "applicableFieldTypes": []
          }
        ]
      }
    }
    
    Metadata defining the components, such as type, properties, and behaviour.
  • FieldTypeMaster Master data for supported field types, including their attributes (e.g., input, dropdown, date picker).

  • The modified data is packaged into a ClientMasterData structure, which conforms to the MDMSv2 schema.
  • An API call is made to send the updated data back to MDMSv2, where it is stored.

  • The ClientMasterData structure typically includes:

    • Updated configuration for screens, components, fields, and other UI elements.

    • Any changes to validation rules, field types, or component properties.

  • The system should notify the user once the update has been successfully pushed to MDMSv2, ideally with a confirmation message or toast notification.

  • Considerations:

    • Ensure data integrity is maintained during the update process.

    • The system should handle error scenarios (e.g., failed updates, validation errors) and provide appropriate feedback to users.

    • Implementing a versioning system for the configuration data could help manage updates and rollback scenarios, ensuring consistency over time.

  • registration_delivery | Flutter packageDart packages
    Logo