# Architecture Overview

## System Overview

The UBI Beneficiary system enables beneficiaries to manage their benefit applications through UBI / ONEST Network protocol. It consists of four main parts:<br>

1. **Beneficiary UI**: React frontend for beneficiaries to register, upload documents, and manage benefit application
2. **Beneficiary Backend**: NestJS backend handling business logic, authentication, and data management
3. **External Services**: UBI / ONEST Network , Verification and Eligibility SDKs for document processing and benefit eligibility checking&#x20;

## **1. High Level Architecture Diagram**

{% @mermaid/diagram content="graph TB
subgraph "Frontend"
UI\[Beneficiary App <br/>React + TypeScript]
style UI fill:#e1f5fe,stroke:#01579b
end
subgraph "External Services"
VER\[Verification SDK<br/>Document Verification]
ELIG\[Eligibility SDK<br/>Benefit Eligibility]
EXT\[External Services<br/>Document Issuer APIs]
UBI\_ONEST\[UBI / ONEST Network]
style VER fill:#e0f2f1,stroke:#00695c
style ELIG fill:#e0f2f1,stroke:#00695c
style EXT fill:#fce4ec,stroke:#c2185b
style UBI\_ONEST fill:#f1f8e9,stroke:#689f38
end

```
subgraph "Backend"
    MW[Beneficiary Backend<br/>NestJS API]
    DB[(PostgreSQL<br/>Database)]
    KC[Keycloak<br/>Authentication]
    H[Hasura<br/>GraphQL Engine]
    style MW fill:#fff8e1,stroke:#ffa000
    style DB fill:#e8f5e9,stroke:#2e7d32
    style KC fill:#fff3e0,stroke:#f57c00
    style H fill:#e3f2fd,stroke:#1976d2
end



UI --> MW
MW --> DB
MW --> KC
MW --> H
MW --> VER
MW --> ELIG
MW --> EXT
MW --> UBI_ONEST
H --> DB
```

" %}

## **2. Sequence Diagrams**

### 2.1 Registration Flow : Registration with OTR certificate

{% @mermaid/diagram content="sequenceDiagram
participant User as User
participant Frontend as Beneficiary App
participant Backend as Beneficiary Backend
participant Keycloak as Keycloak
participant Database as PostgreSQL Database

```
Note over User, Frontend: Step 1: Document Upload or Capture
User->>Frontend: Upload OTR Certificate (Image/PDF) OR Capture Photo
Frontend->>Frontend: Basic file validation (type, size)

Note over User, Backend: Step 2: Registration API Call
Frontend->>Backend: POST /auth/register_with_document<br/>{OTR Certificate Document}

Note over Backend: Step 3: OCR Extraction & VC Field Mapping (Backend)
Backend->>Backend: Perform OCR on document
Backend->>Backend: Extract text
Backend->>Backend: Apply VC JSON field mapping
Backend->>Backend: Validate required fields (admin config)

alt Required VC Field Missing
    Backend-->>Frontend: 400 Bad Request<br/>"Required field not present in certificate"
    Frontend->>User: Show validation error
else VC Mapping Successful
    Note over Backend: Step 4: Registration Payload Creation
    Backend->>Backend: Create payload (username = OTR number)

    Note over Backend, Keycloak: Step 5: Keycloak Integration
    Backend->>Keycloak: getAdminKeycloakToken()
    Keycloak-->>Backend: Admin token

    alt Admin Token Failure
        Backend-->>Frontend: 500 Internal Server Error
        Frontend->>User: Show error message
    else Admin Token Success
        Backend->>Keycloak: Create user in Keycloak
        Keycloak-->>Backend: User created (keycloak_id)

        alt User Already Exists
            Backend-->>Frontend: 409 Conflict<br/>"User already exists"
            Frontend->>User: Show duplicate user error
        else Keycloak User Created
            Note over Backend, Database: Step 6: Database Persistence
            Backend->>Database: Save user (keycloak_id, VC data)
            Database-->>Backend: User saved

            Note over Backend, Database: Step 7: OTR Certificate Persistence
            Backend->>Database: Store OTR certificate & link to user
            Database-->>Backend: Certificate stored

            Note over Backend, Frontend: Step 8: Success Response
            Backend-->>Frontend: 200 OK<br/>{Registration Successful}
            Frontend->>User: Show success message
        end
    end
end
```

" %}

### 2.2 Document Upload Flow Based

> <mark style="color:$info;">For each document type, the admin panel defines:</mark>
>
> * <mark style="color:$info;">**Issuer**</mark> <mark style="color:$info;"></mark><mark style="color:$info;">– Issuer of the document</mark>
> * **Document Has OR Code** <mark style="color:$info;">– Yes/No, whether the document contains QR code</mark>
> * <mark style="color:$info;">**Required fields and validation rules**</mark> <mark style="color:$info;"></mark><mark style="color:$info;">in JSON mapping</mark>

> <mark style="color:$info;">Based on these configurations, there are</mark> <mark style="color:$info;"></mark><mark style="color:$info;">**three main flows**</mark> <mark style="color:$info;"></mark><mark style="color:$info;">for uploading documents:</mark>
>
> 1. <mark style="color:$info;">IssueVC = Yes</mark>
> 2. <mark style="color:$info;">IssueVC = No,</mark> Document Has OR Code <mark style="color:$info;">= No</mark>
> 3. <mark style="color:$info;">IssueVC = No,</mark> Document Has OR Code <mark style="color:$info;">= Yes</mark>

#### Flow 1: IssueVC = Yes&#x20;

{% @mermaid/diagram content="sequenceDiagram
participant User as User
participant Frontend as Beneficiary App
participant Backend as Backend Backend
participant Database as PostgreSQL Database
participant Issuer as Document Issuer

```
Note over User, Frontend: User uploads document (image/PDF) or captures photo
User->>Frontend: Upload document
Frontend->>Backend: POST /documents/upload {file}

Note over Backend, Issuer: Backend Processing
Backend->>Backend: OCR extraction
Backend->>Backend: JSON field mapping
Backend->>Backend: Validate JSON fields (required, matching, rules)

alt Validation Failed
    Backend-->>Frontend: 400 Bad Request {error details}
    Frontend->>User: Show error toast
else Validation Success
    Backend->>Issuer: Create draft
    Issuer-->>Backend: Draft created
    Issuer->>Backend: Issue VC
    Backend->>Backend: Validate issued VC
    Backend->>Database: Store document linked to user
    Backend->>Database: Update user profile
    Database-->>Backend: Profile updated
    Backend-->>Frontend: 200 OK {Document uploaded successfully}
    Frontend->>User: Show success toast
end

Note over User, Frontend: Frontend Errors
Note over Frontend: - Invalid file type/size

Note over Backend: Backend Errors
Note over Backend: - OCR failure, JSON mapping failure, validation failure, profile update failure
```

" %}

#### Flow 2: IssueVC = No, Document Has OR Code = No

{% @mermaid/diagram content="sequenceDiagram
participant User as User
participant Frontend as Beneficiary App
participant Backend as Backend Backend
participant Database as PostgreSQL Database

```
Note over User, Frontend: User uploads document (image/PDF) or captures photo
User->>Frontend: Upload document
Frontend->>Backend: POST /documents/upload {file}

Note over Backend: Backend Processing
Backend->>Backend: OCR extraction
Backend->>Backend: JSON field mapping
Backend->>Backend: Validate JSON fields

alt Validation Failed
    Backend-->>Frontend: 400 Bad Request {error details}
    Frontend->>User: Show error toast
else Validation Success
    Backend->>Database: Store document linked to user
    Backend->>Database: Update user profile
    Database-->>Backend: Profile updated
    Backend-->>Frontend: 200 OK {Document uploaded successfully}
    Frontend->>User: Show success toast
end

Note over User, Frontend: Frontend Errors
Note over Frontend: - Invalid file type/size

Note over Backend: Backend Errors
Note over Backend: - OCR failure, JSON mapping failure, validation failure, profile update failure
```

" %}

#### Flow 3: IssueVC = No, Document Has OR Code = Yes

{% @mermaid/diagram content="sequenceDiagram
participant User as User
participant Frontend as Beneficiary App
participant Backend as Backend Backend
participant Database as PostgreSQL Database

```
Note over User, Frontend: User scans QR code
User->>Frontend: Scan QR code
Frontend->>Backend: POST /documents/scan-qr {qr_data}

Note over Backend: Backend Processing
Backend->>Backend: Process QR data based on admin panel config
Backend->>Backend: OCR extraction if document included
Backend->>Backend: JSON field mapping
Backend->>Backend: Validate JSON fields

alt Validation Failed
    Backend-->>Frontend: 400 Bad Request {error details}
    Frontend->>User: Show error toast
else Validation Success
    Backend->>Database: Store document linked to user
    Backend->>Database: Update user profile
    Database-->>Backend: Profile updated
    Backend-->>Frontend: 200 OK {Document uploaded successfully}
    Frontend->>User: Show success toast
end

Note over User, Frontend: Frontend Errors
Note over Frontend: - QR code not detected in 15 sec

Note over Backend: Backend Errors
Note over Backend: - QR processing failure, OCR failure, JSON mapping failure, validation failure, profile update failure
```

" %}

### 2.3 Benefit application submission flow

{% @mermaid/diagram content="sequenceDiagram
participant U as User
participant BA as Beneficiary App
participant BE as Beneficiary Backend
participant PB as Provider Backend

```
Note over U,PB: Benefit Application Flow

%% Step 1: User initiates application
U->>BA: Clicks "Apply" on benefit
BA->>BA: Validate prerequisites<br/>(documents, expiry, eligibility)

alt Prerequisites validation fails
    BA->>U: Show error dialog
else Prerequisites validation passes

    %% Step 2: Get benefit schema and details
    BA->>PB: GET /select<br/>{benefit_id}
    PB->>BA: Return benefit details<br/>+ form schema

    %% Step 3: Build form on beneficiary side
    BA->>BA: Generate form from schema<br/>Prefill with user profile data
    BA->>U: Display form<br/>(prefilled with user data)

    %% Step 4: User completes form
    U->>BA: Fill form fields
    U->>BA: select documents
    U->>BA: Submit form

    %% Step 5: Form validation and create application
    BA->>BA: Validate form data
    alt Validation fails
        BA->>U: Show validation errors
    else Validation passes
        %% Step 6: Create application on beneficiary side
        BA->>BE: Create application<br/>(status: "initiated")
        BE->>BA: Application created

        %% Step 7: Initialize with provider
        BA->>PB: POST /init<br/>{benefit_id, form_data, VCs}
        PB->>BA: Application created on provider side

        %% Step 8: Confirm and get order ID
        BA->>PB: POST /confirm<br/>{application_id}
        PB->>BA: Return order_id

        %% Step 9: Update application with order ID
        BA->>BE: Update application<br/>(order_id, status: "submitted")
        BE->>BA: Application updated
        BA->>U: Show success message<br/>with order ID
    end
end

%% Form resubmission flow
Note over BA,PB: Form Resubmission Flow
alt User resubmits form
    U->>BA: Modify and resubmit form
    BA->>PB: POST /update<br/>{application_id, updated_data}
    PB->>BA: Application updated
    BA->>U: Show update confirmation
end

%% Error handling flows
Note over BA,PB: Error Scenarios
alt Network/Service Failure
    PB-->>BA: Error response
    BA->>U: Show error message
end

alt Eligibility Issues
    PB-->>BA: Ineligible response
    BA->>U: Show eligibility reasons
end" %}
```
