8byte.ai
📘 Part 1 of 3 — Frontend Documentation

8byte LOS
Frontend Documentation

A comprehensive breakdown of the React-based partner portal — covering every page, component, state slice, routing strategy, API layer, and role-based access pattern.

React 19
Framework
39
Pages
4
Redux Slices
9
Role Types
58
API Services
13+
Custom Hooks
6
Contexts
🎯

About Frontend

The partner-facing SPA powering all internal staff operations

The 8byte LOS Frontend is a single-page application (SPA) built with React 19 that serves as the internal operations portal for lending company staff. It is the interface through which loan executives, collection teams, sanction managers, and administrators manage the entire loan lifecycle — from customer onboarding to final repayment.

🏦 Who Uses This?

Internal staff — not customers. This is used by Loan Executives, Collection Agents, Sanction Managers, Credit Executives, and Administrators of lending brands to manage the full loan workflow.

🏷️ Multi-Brand Support

The platform supports multiple lending brands simultaneously (Qualoan, PaisaPop, Salary4Sure, etc.). Every route is scoped under /:brandId/ so the same codebase serves many separate lenders.

🔐 Role-Based Interface

The entire UI changes based on the logged-in user's role. A Collection Executive sees collection queues; a Sanction Head sees approval queues. Navigation, buttons, and data all reflect permissions.

📊 Ops Dashboard

Real-time dashboards show disbursement stats, collection metrics, user performance, and geographic breakdowns. Two dashboard versions (v1, v2) serve different operational needs.

⚙️

Tech Stack

Libraries, frameworks and build tools used in the frontend

🏗️ Core Framework

React 19.0.0 TypeScript Vite 6.3.1 ESLint Prettier

React 19 brings the latest features. Vite provides lightning-fast HMR and build times. TypeScript enforces strict typing across all components and API calls.

🗄️ State Management

Redux Toolkit 2.10.1 React Redux Immer

Redux Toolkit is the single source of truth for auth state, brand config, partner user data, and user data. Slices are organized by domain.

🛣️ Routing

React Router v7.5.3

React Router v7 with nested routes. Brand-scoped routes pattern: /:brandId/[feature]. Protected routes wrap all authenticated pages with token validation guards.

🎨 Styling

TailwindCSS 4.1.5 Framer Motion CSS Modules

TailwindCSS utility classes for rapid styling. Framer Motion for smooth animations and transitions. Each brand has its own color theme loaded dynamically.

📡 HTTP & API

Axios Interceptors Token Refresh

A single Axios instance with request/response interceptors handles auth headers, token refresh on 401, error normalization, and base URL switching per brand.

📊 Data Visualization

Chart.js Recharts

Chart.js for bar/line/pie charts on dashboards. Recharts for React-idiomatic composable charts in collection analytics and performance views.

📄 PDF & File Handling

pdf-lib PDFjs-dist React Dropzone

pdf-lib for in-browser PDF editing. PDFjs-dist for rendering PDFs. React Dropzone for drag-and-drop file uploads (documents, bank statements, payslips).

🛠️ Other Libraries

FingerprintJS React Toastify TipTap React Icons lodash.debounce dayjs

FingerprintJS for device registration. Toastify for notifications. TipTap rich-text editor for notes/comments. lodash.debounce for search inputs. dayjs for all date formatting (not date-fns — confirmed in lib/utils.ts).

🎛️ UI Utilities

@headlessui/react clsx tailwind-merge react-markdown

@headlessui/react for accessible unstyled UI primitives (dropdowns, dialogs, switches). clsx + tailwind-merge combined into the cn() utility in lib/utils.ts for safe conditional Tailwind class merging. react-markdown for rendering markdown content in help center and notification bodies.

🔐 Google OAuth

VITE_GOOGLE_CLIENT_ID Google Sign-In SDK

Google OAuth is configured via the VITE_GOOGLE_CLIENT_ID environment variable. Allows partner staff to log in using their Google workspace accounts in addition to email/password.

🛣️

Routing System

React Router v7 — all routes and how they're protected

All authenticated routes follow the pattern /:brandId/[feature-path]. This means every page knows which lending brand it is operating under. The brandId is extracted from the URL, used to fetch brand-specific configs, and sent with every API request.

🔓 Public Routes

PathComponentPurpose
/loginLoginPageEmail + password login for partner staff
/reset-passwordResetPasswordPagePassword reset via email token
/RedirectRedirects to /login if unauthenticated

🔒 Protected Routes (require JWT + brandId)

PathPageRole Required
/:brandId/dashboardDashboard V1/V2VIEW_DASHBOARD permission
/:brandId/loansLoans ListLOANS permission
/:brandId/loans/:loanIdLoan DetailLOANS permission
/:brandId/loans/unallocatedUnallocated LoansADMIN / LOAN_OPS
/:brandId/customersCustomer ListONBOARDING_IN_PROGRESS
/:brandId/customers/:userIdCustomer DetailONBOARDING_IN_PROGRESS
/:brandId/customers/unallocatedUnallocated CustomersADMIN
/:brandId/collectionCollectionsCOLLECTIONS
/:brandId/pre-collectionPre-CollectionPRE_COLLECTIONS
/:brandId/post-collectionPost-CollectionPOST_COLLECTIONS
/:brandId/collection/v2Collection V2COLLECTIONS
/:brandId/completedCompleted LoansCOMPLETED_LOANS
/:brandId/loans-opsLoan OperationsLOAN_OPS
/:brandId/payment-approvalPayment ApprovalLOAN_OPS
/:brandId/payment-rejectedRejected PaymentsLOAN_OPS
/:brandId/payment-approvedApproved PaymentsLOAN_OPS
/:brandId/sanction-managerSanction ManagerSANCTION_MANAGER
/:brandId/sanction-headSanction HeadSANCTION_HEAD
/:brandId/credit-executiveCredit ExecutiveCREDIT_EXECUTIVE
/:brandId/global-searchGlobal SearchGLOBAL_SEARCH
/:brandId/userPartner UsersPARTNER_USER_MANAGEMENT
/:brandId/settingsBrand SettingsBRAND_SETTINGS
/:brandId/reportsReportsMASTER_REPORTS
/:brandId/remindersRemindersADMIN
/:brandId/help-centerHelp CenterAny authenticated
/adminAdmin PanelSUPER_ADMIN
/admin/settingsAdmin SettingsSUPER_ADMIN
🗄️

Redux State Management

Global state structure and how it flows through the app

The Redux store is the single source of truth for data that must persist across navigations: authentication tokens, the logged-in partner user's profile, brand configuration, and customer user data. Feature-level data (loan lists, dashboards, etc.) is fetched on-demand via Axios and stored locally in components or feature slices.

auth slice

accessTokenJWT string | null
refreshTokenJWT string | null
data.idPartner user ID
data.emailStaff email
data.roles[]Role array
data.permissions[]Permission array
data.brandIds[]Accessible brands
loadingboolean
errorstring | null

brand slice

brandConfig.idBrand ID
brandConfig.nameBrand display name
brandConfig.themeColors, fonts
brandConfig.logoS3 logo URL
brandConfig.rulesLoan rules config
brandConfig.evaluationItemsEval criteria
brandConfig.policyLinksT&C / privacy URLs
loadingboolean

partnerUser slice

data.idPartner user ID
data.nameStaff name
data.rolePrimary role
data.globalRoleSuper admin role
permissions[]Resolved permissions
data.reportingToManager user ID
data.phoneNumberStaff phone

user slice (customer)

data.idCustomer user ID
data.nameCustomer name
data.phoneMobile number
data.onboardingStepCurrent KYC step
data.brandIdWhich brand they're on
loadingboolean

common slice

Shared UI state across all pages.

isFiltersVisibleboolean — global filter panel toggle

Actions: setFiltersVisible(bool), toggleFiltersVisible(). Used to show/hide the filter sidebar on list pages from anywhere in the component tree.

📡

API Services Layer

How the frontend communicates with the backend

🔧 Axios Configuration (shared/services/axios.ts)

A single Axios instance is created with:

baseURL from env Authorization header injection 401 → auto token refresh Request deduplication Error normalization Brand ID injection

Every outgoing request automatically receives the JWT access token in Authorization: Bearer <token>. On a 401 response, the interceptor calls the refresh-token endpoint, updates the Redux store, and retries the original request.

🔑 auth.api

Login, logout, reset password, refresh token. Called at startup to validate stored tokens.

👥 customer.api

List customers, fetch customer details, allocate, reloan, update status.

📋 loan.api

List loans, loan details, status updates, CSV export, force-bypass, rule changes.

💰 collection.api

Pre/post collection queues, repayment timelines, settlement, write-off actions.

💳 payment.api

Payment processing, autopay setup, payment approval/rejection.

📊 dashboard.api

Stats, summary, geographic breakdown, collection analysis, disbursement metrics.

🏦 disbursement.api

Disbursement requests, status checks, IDFC/ICICI integrations.

👔 partner-user.api

Staff CRUD, role assignment, loan allocation, secure code generation.

🔐 partner-permissions.api

Permission fetching, role-permission matrix management.

📈 evaluation.api

Evaluation criteria, evaluation results, manual overrides.

🔎 bre.api

Business Rules Engine triggers and result fetching.

⚙️ brand.api

Brand config, theme, evaluation items, loan rules, targets.

The following 46 additional API service files exist in shared/services/api/ but were not previously documented:

🏦 Account Aggregation (aa.api.ts)

Full AA consent lifecycle: createConsentRequest, createManualConsentRequest, getUserConsentRequests, updateConsentStatus, sendConsentRequestEmail, generateConsentUrl, fetchPeriodicData. Integrates with FINDUIT/CART providers (RBI-regulated framework).

📞 Acefone Dialer (acefone.dialer.service.ts)

initiateCall (click-to-dial with userId, partnerUserId, brandId, loanId), getUserCalls, getPartnerUserCalls, getCustomerUserCalls, getCallDetails, endCall, getUserCallStats, getPartnerUserCallStats. Full VoIP call management.

📊 Activity Tracking (activityTracking.service.ts)

Sends user activity pings to the backend. Tracks mouse, keyboard, scroll events. Linked to the ActivityTrackerContext for idle detection and session logging.

🔑 API Key Management (apiKey.api.ts)

CRUD for brand API keys used by external systems to call the LOS backend. Create, list, revoke, and rotate API keys from the settings panel.

📋 Agreement (agreament.api.ts)

Loan agreement generation, e-sign initiation, e-sign status polling, final agreement PDF download. Works with the e-sign docket system configured per brand.

🚗 Autopay (autopay.api.ts)

Razorpay subscription management: create autopay mandate, get mandate status, cancel mandate, create autopay transaction, skip autopay consent. Linked to loan repayment scheduling.

⭐ Brand Rating Matrix (brand-rating-matrix.api.ts)

Fetch and update the brand-level rating matrix used to score customers. GET/POST/PUT endpoints for matrix configurations per brand.

🧮 CAM Calculator (cam-calculator.api.ts)

saveCAMCalculator (POST with salary dates, amounts, FOIR, ROI, repayment data), getCAMCalculator by loanId, getCAMCalculatorByUser by userId+brandId, deleteCAMCalculator. Used by credit executives to fill Credit Appraisal Memo.

🌐 Common (common.api.ts)

Miscellaneous shared API calls: IFSC lookup, state/city lists, pincode details, generic dropdown data used across forms.

💸 Disbursement (disbursement.api.ts)

Initiate bank disbursement, check NEFT/IMPS status, IDFC/ICICI bank integration, pending disbursement queue management, NDC (No Due Certificate) generation.

📈 Evaluation V2 (evaluationV2.api.ts)

Enhanced evaluation engine endpoints. Supports a newer evaluation flow with more criteria, weighted scoring, and automated rule checks. Used alongside evaluationV1 based on brand config evaluationVersion flag.

💱 Penny Drop (external/pennyDrop.api.ts)

Trigger penny drop bank verification for a customer's bank account. Polls verification status. Used in customer onboarding to confirm bank account ownership.

📬 Lead Management (leads/leads.api.ts)

uploadLeadFormsCsv (multipart), getLeadForms (paginated+filtered), getLeadFormsStats, syncLeadForms, deleteLeadForms (bulk), updateLeadFormStatus, exportLeadFormsCsv. Manages CSV lead imports from Facebook ads and other marketing channels.

📜 Loan Comments (loanComments.api.ts)

Add, list, and delete comments/remarks on a specific loan. Comments are timestamped and attributed to the partner user who made them. Used in the remarks modal on loan detail pages.

📏 Loan Rules (loan-rule.api.ts)

Fetch active loan rules for a brand, update rule parameters (min/max amount, tenure, rate), and create new rules per product type. Used in the settings panel.

🔔 Notification (notification.api.ts)

Fetch unread notifications for the logged-in partner user, mark as read (single or bulk), delete notifications. Feeds the notification bell in the header.

🔐 Partner Permissions (partner-permissions.api.ts)

Get all available permissions for a brand, get permissions assigned to a specific partner user, update permissions for a partner user. Core of the RBAC system UI.

📞 Partner User Dialer Config (partner-user-dialer-config.api.ts)

Get/set Acefone and Stringee dialer configurations for individual partner users. Maps the staff member's SIP extension to their account.

⭐ Partner User Rating Matrix (partner-user-rating-matrix.api.ts)

Individual staff performance rating matrix. Different from brand-level matrix. Tracks each partner user's collection/sales performance scores over time.

💳 Payment Approval (payment-approval.api.ts)

List pending payment approvals, approve a payment (with UTR confirmation), reject a payment (with reason). Used by Loan Ops staff in the payment approval queue.

💰 Payment (payment.api.ts)

Record manual payments, fetch payment history for a loan, payment gateway status lookups, trigger payment confirmations. Core payment processing API.

⏰ Reminder (reminder.api.ts)

getUserReminders (paginated, filters: channel/status/dateRange), getReminderAuditLogs, createUserReminder (with channel, templateCode, scheduledAt), getReminderDashboardMetrics, refreshReminderDashboardMetrics. Manages automated payment reminder scheduling.

📊 Report (report.api.ts)

getReport (by reportType + dateRange), exportReportToCSV, downloadReport. Supports 29 backend report types. Frontend type-asserts responses as MasterReportUser[], MarketingReportItem[], CompletedNoRepaymentReportItem[], or BaseReportItem[].

🧠 ScoreMe BDA (scoreMeBDA.ts)

ScoreMe Bureau Data Analysis integration. Fetches credit bureau data augmented with ScoreMe's scoring model. Used in the customer detail Credit Report tab for enhanced bureau analysis.

📤 Upload (upload.api.ts)

Generic S3 file upload service. Generates pre-signed URLs for direct browser-to-S3 uploads. Used for KYC docs, bank statements, payslips, profile photos, and agreement PDFs.

📱 User Devices (user-devices.api.ts)

Register and list devices for a partner user. Each device has a fingerprint ID. Admins can revoke device access. Used for the device-based login policy.

📝 User Logs (user-logs.api.ts)

Fetch activity logs for a customer user — what they did in the app, when, from which device. Shown in the Activity tab of the customer detail page.

🔎 User Search (user-search.api.ts)

Global search across customers by name, phone, PAN, email, loan ID. Powers the global search page with real-time debounced results.

Settings-specific API files (20 in shared/services/api/settings/):

🎨 Appearance (appearance.setting.api.ts)

Update brand colors, fonts, logo URL, favicon. Theme changes reflect immediately via ThemeProviderContext.

📝 Blogs (blogs.setting.api.ts)

CRUD for brand blog posts shown in the customer-facing app. Title, content, published flag, featured image.

📞 Brand Acefone (brandAcefone.setting.api.ts)

Configure the brand's Acefone VoIP account credentials, SIP settings, and agent extension assignments.

🏦 Brand Bank Account (brandBankAccount.setting.api.ts)

Manage the brand's own bank accounts used for disbursements and repayment collection. IFSC, account number, beneficiary name.

🚫 Brand Block List (brandBlockList.setting.api.ts)

Manage list of blocked PAN/Aadhaar/phone numbers. Applications from blocked identities are auto-rejected.

🃏 Brand Cards (brandCards.setting.api.ts)

Configure brand card products shown to customers. Card types, limits, eligibility criteria, and interest rates.

📋 Evaluation Items (brandEvaluationItems.setting.api.ts)

Add/update/delete evaluation criteria and their weights. Supports V1 and V2 evaluation engines.

🛤️ Brand Paths (brandPaths.api.ts)

Configure URL paths/subdomains for the brand's customer-facing app. Each brand can have custom app routes.

📜 Brand Policy (brandPolicy.setting.api.ts)

Update T&C URL, privacy policy URL, FAQ URL shown to customers during onboarding and in the app.

🔌 Brand Provider (brandProvider.setting.api.ts)

Manage third-party provider configurations per brand: credit bureau, bank statement analysis, e-sign, SMS, email providers. isPrimary, isActive, isDisabled flags.

🌐 Brand Sub-Domains (brandSubDomains.api.ts)

Configure custom subdomains for the brand's partner dashboard and customer portal. Domain verification status.

🎯 Brand Targets (brandTargets.setting.api.ts)

Set monthly/quarterly disbursement and collection targets at brand, team, and individual executive levels.

⚙️ General Settings (general.setting.api.ts)

Core brand config: salary threshold, rejection duration, bank statement months, e-sign settings, section manager details, CAM requirement flag, auto-allocation type, field visit flag, dashboard/loan-ops/collection version flags.

📏 Loan Rules Settings (loanRules.setting.api.ts)

CRUD for loan rules (min/max amount, tenure, interest, processing fee) per product/risk category. BRE rules configuration.

📅 Non-Repayment Dates (nonRepaymentDates.api.ts)

Configure public holidays and non-working days when repayments cannot be processed. Affects due date calculations.

🏖️ Partner Unavailability Dates (partnerUnavailabilityDates.api.ts)

Mark dates when partner operations are suspended (holidays, maintenance). Affects auto-allocation and reminder scheduling.

🔐

Authentication Flow

How partner staff log in and stay authenticated

Enter Email
+ Password
LoginPage
POST /auth/login
auth.api
Receive JWT
accessToken + refreshToken
Redux Store
auth.slice updated
LocalStorage
Tokens persisted
Redirect to
/:brandId/dashboard
React Router

🔄 Token Refresh

When any API call returns 401, the Axios interceptor automatically calls POST /auth/refresh-token with the stored refresh token. On success, both tokens are updated in Redux and localStorage, and the failed request is retried. On failure, the user is redirected to /login.

📱 Device Fingerprinting

On login, FingerprintJS generates a unique device ID. This is sent to the backend which registers the device under the partner user's account. Future logins from unrecognized devices can be flagged or blocked per brand policy.

🏷️ Brand Access Check

After login, the frontend checks if the partner user has access to the requested brandId in the URL. If not, they're redirected to their first accessible brand. This prevents staff from accessing brands they weren't given access to.

⏱️ Activity Tracking

The activityTrackerContext monitors mouse movement, keyboard input, and scroll events. After a configurable period of inactivity, it sends an alert to the backend. A warning modal can appear asking the user to confirm they're still active.

🔑

Login Page

Entry point for all partner staff

The login page is brand-agnostic — it shows a generic 8byte/LOS login form. Staff enter their registered email and password. On success, the API returns the user's accessible brand IDs, roles, and JWT tokens. The frontend redirects to the first accessible brand's dashboard. For forgotten passwords, a "Reset Password" link sends an email with a one-time reset token link.

📊

Dashboard Pages

Real-time operational metrics (V1 and V2)

📈 Dashboard V1

Overview stats: total applications, disbursements today, active loans, pending collections. Bar charts for loan volume by month. Pie charts for loan status distribution. Table of recent applications and their current status. Filters for date range and loan type.

📊 Dashboard V2

Enhanced analytics: per-user performance tables, geographic breakdown (users by city/state/company), collection analysis with recovery rates, disbursement analysis with amount trends. Partner user lead stats showing each agent's conversion rates.

Dashboard data is fetched on mount via dashboard.api calls. Charts are rendered with Chart.js (V1) and Recharts (V2). Both dashboards support date range filters that re-fetch data on change.
👤

Customers Pages

Customer listing and full detail view

📋 Customer List

Paginated table of all customers for the current brand. Each row shows: name, phone, PAN, onboarding step, allotted executive, current status, and last activity date. Filters: by status, onboarding step, assigned executive, date range. Supports CSV export.

Debounced search Pagination CSV Export Status filters Executive filter

👁️ Customer Detail Page (Tabs)

The most information-dense page in the app. When you open a customer, you see multiple tabs:

Personal Details

Name, DOB, address, PAN, Aadhaar status, alternate addresses and phone numbers

Employment

Employer name, salary, UAN, EPFO verification status, payslips

Bank Account

Account details, penny drop status, bank statements uploaded

KYC Documents

PAN card, Aadhaar, selfie, salary slip — status + preview

Loans History

All loans for this customer, their statuses and amounts

Credit Report

CIBIL / Equifax scores, report download, credit history

Bank Statement

CART / Finbox / ScoreMe analysis results, BSA report

Evaluation

Evaluation results, criteria scores, manual override options

Activity / Calls

Call history, recordings, Acefone dialer, activity timeline

📄

Loans Pages

Full loan lifecycle management

📋 Loan List

Paginated list of all loans for the brand. Shows loan ID, customer name, amount, status, disbursal date, due date, assigned executive. Filterable by status, amount range, date, executive. Supports bulk status changes and CSV export.

📑 Loan Detail

Complete loan view: loan amount, tenure, interest rate, disbursement details, repayment timeline, all status changes, payment history, signed agreement PDF viewer, evaluation results, and action buttons based on role.

🔄 Status Update Modal

A role-gated modal allowing authorized staff to change loan status. Each transition requires a reason selection from a predefined list. Some transitions (e.g., DISBURSED → COMPLETED) require additional confirmation.

⚙️ Loan Operations

Dedicated section for: pending disbursements awaiting bank transfer confirmation, payment approval/rejection queue, and no-due certificate (NDC) generation for fully repaid loans.

💼

Collections Pages

Pre-collection, active collection, post-collection

⏰ Pre-Collection

Loans approaching due date. Staff send reminders via SMS/WhatsApp/Email directly from the UI. Bulk reminder sends supported. Repayment timeline displayed.

🔴 Active Collection

Overdue loans. Collection executives see their assigned loans. Can initiate calls via Acefone VoIP dialer, log outcomes, set follow-up dates, create repayment timelines.

📞 Post-Collection

Severely overdue or post-settlement loans. Can initiate settlement discussions, propose write-off amounts, and escalate to collection managers.

📊 Collection V2

Enhanced collection view with more granular filters, allocation management (assign/reassign collection executives), bulk actions, and detailed recovery metrics per executive.

💳

Payment Pages

Payment approval, autopay, and disbursement

✅ Payment Approval

Loan Ops staff review incoming payment requests that need manual approval before processing. Can approve or reject with reason. Shows payment amount, UTR, gateway, and customer details.

🔁 Autopay Management

Setup recurring Razorpay subscriptions for customers. Shows active autopay mandates, their status, next collection dates, and allows cancellation or amount modification.

👔

Partner Users Page

Internal staff management

Administrators can create, update, and deactivate internal staff accounts. Each staff member can have:

Role Assignment

Select from 9 pre-defined roles. Each role pre-loads a default permission set.

Custom Permissions

Override individual permissions beyond what the role provides.

Brand Access

Assign staff to one or more brands. They'll only see data for their brands.

Loan Allocation

Manually or auto-allocate loans and customers to specific executives.

Also includes: secure code generation (temporary access codes for field agents), audit logs showing every action taken by each user, and activity tracking for monitoring inactivity.

⚙️

Settings Pages

Brand configuration and operational parameters

🎨 Brand Appearance

Primary/secondary colors, fonts, logo upload, favicon. Changes apply instantly via ThemeProviderContext CSS variable injection.

📏 Loan Rules

Min/max loan amounts, tenures, interest rates, processing fees. Rule types per product/risk category. Linked to BRE engine.

📋 Evaluation Items

Configure which criteria are checked during loan evaluation and assign weights/scores for V1 and V2 evaluation engines.

🎯 Targets

Monthly disbursement and collection targets at brand, team, and individual executive levels.

📧 Policy Links

T&C URL, privacy policy URL, FAQ URL shown to customers during onboarding and in the app.

⚙️ General Config

Salary threshold, rejection duration, bank statement months, auto-allocation type, dashboard version (V1/V2), loan-ops version, collection version, CAM requirement flag, field visit flag, e-sign settings.

🚫 Block List

Manage list of blocked PAN/Aadhaar/phone numbers. Applications from blocked identities are auto-rejected at the BRE stage.

🃏 Brand Cards

Configure card products shown to customers. Card types, limits, eligibility criteria, and interest rates.

🌐 Sub-Domains

Configure custom subdomains for the brand's partner dashboard and customer portal. Domain verification status.

📅 Non-Repayment Dates

Public holidays and non-working days when repayments cannot be processed. Affects due date calculations and reminder scheduling.

🏖️ Partner Unavailability

Mark dates when partner operations are suspended. Affects auto-allocation and reminder scheduling.

🔑 API Key Management

Create, list, revoke, and rotate API keys used by external systems to call the LOS backend. Per-brand key scoping.

🛤️ Brand Paths

Configure URL paths for the brand's customer-facing app and partner dashboard. Each brand can have custom routing.

📝 Blog Management

CRUD for brand blog posts shown in the customer-facing app. Title, content, published flag, featured image.

🔌 Brand Providers

Third-party provider configurations: credit bureau, bank statement analysis, e-sign, SMS, email providers. isPrimary/isActive/isDisabled flags per provider.

❌ Rejection Reasons

Configurable list of rejection reasons shown during evaluation and status updates. Brand-specific reasons beyond the system defaults.

📞 Acefone / Dialer Settings

Configure brand's Acefone VoIP account credentials, SIP settings, and Stringee fallback configuration.

🏦 Brand Bank Accounts

Manage the brand's own bank accounts for disbursements and repayment collection. IFSC, account number, beneficiary name.

🔄 Reloan Config

Configure reloan rules: eligibility criteria for customers to take a new loan, reloan product settings, minimum time between loans.

🎫 Coupons

Configure discount/waiver coupons that can be applied to loan processing fees or interest amounts.

🛡️

Admin Panel

Super admin — cross-brand management

The Super Admin panel at /admin is only accessible to users with the SUPER_ADMIN global role. From here they can:

🏢

Brand Management

Create, update, and configure all lending brands on the platform.

👥

Cross-Brand User Mgmt

Create and manage partner users across all brands simultaneously.

⚙️

Admin Settings

System-level configuration, API key management, and global policies.

📊

Platform-wide Reports

Aggregate reports across all brands and all staff.

🧩

Shared Components

Reusable UI building blocks used across all features

📱

Sidebar Navigation

Dynamic sidebar that renders navigation links based on the user's permissions. Items not permitted are hidden entirely.

Permission-gatedBrand-scoped
🗃️

Data Tables

Sortable, paginated, filterable tables with row selection, bulk actions, and column visibility toggles.

SortablePaginated
🔍

Filter Components

Date range pickers, status dropdowns, user selects, and amount range inputs. All filters sync to URL query params.

URL syncDebounced
💬

Dialog / Modals

Confirmation dialogs, form modals, image preview modals, and PDF viewer modals with Framer Motion animations.

AnimatedAccessible
📤

File Uploader

React Dropzone based uploader with preview, type validation, size limits, and progress indicators. Used for documents, statements, payslips.

Drag-and-dropPreview
🔔

Notification Bell

Header bell icon showing unread count. Dropdown lists recent notifications with type icons and timestamps.

Real-timeRedux-driven
🍞

Breadcrumbs (common/ui/breadcrumbs.tsx)

Navigation trail showing current location in the app hierarchy. Clickable segments to navigate back. Used on detail pages and nested settings.

Navigation
🏷️

LoanStatusBadge (common/ui/LoanStatusBadge.tsx)

Color-coded pill badge displaying loan status (ACTIVE, DISBURSED, COMPLETED, REJECTED, etc.). Consistent status colors used across all list and detail pages.

Status display

AddRemarksButton (common/ui/AddRemarksButton.tsx)

Button that opens the RemarksCommentModal. Appears on loan detail and customer detail pages. Allows partner staff to add timestamped remarks to a loan/customer record.

Loan action
💬

RemarksCommentModal (common/ui/RemarksCommentModal.tsx)

Modal dialog for adding and viewing remarks/comments on loans and customers. Lists existing remarks with author and timestamp. Submits new remarks to loanComments.api.

loanComments.api
👁️

ColumnVisibilityDropdown (common/ui/columnVisibilityDropdown.tsx)

Dropdown control that lets users show/hide individual table columns. State persisted per page. Used on all major list pages (customers, loans, collections, etc.).

Table UX
🔄

Dynamic Filters (common/filter/dynamicFilters.tsx)

Configurable filter panel that renders different filter inputs based on configuration. Syncs all filters to URL query params. Used by most list pages.

URL syncConfigurable
🗃️

Dialogs (common/dialog/)

Specific pre-built dialog components: createAutopayTransactionDialog, loanAgreementDetailsDialog, resendConfirmationDialog, sendBackToCEDialog, skipAutopayConsentDialog.

Action dialogs
🌐

React Context Providers

Cross-cutting concerns shared via Context API

🎨 ThemeProviderContext

Loads the current brand's theme (colors, fonts) from the Redux brand slice and injects CSS custom properties into the document root. Every component automatically uses the brand's color scheme.

🍞 ToastContext

Wraps React Toastify configuration. Provides a showToast(message, type) helper usable anywhere. Success/error/info/warning variants with auto-dismiss.

⏱️ ActivityTrackerContext

Listens to DOM events (mousemove, keypress, scroll, click). Tracks the last-active timestamp and sends pings to the backend's activity tracking endpoint. Shows an inactivity warning modal after threshold.

📞 AcefoneDialerContext (features/acefone/context/)

Manages the Acefone VoIP dialer widget state: current call session, call controls (mute, hold, end), call log, and the floating dialer UI shown when a call is active. Available globally via AcefoneDialerProvider in App.tsx for any page to initiate calls.

👤 RoleContext (context/roleContext.tsx)

Provides { role, setRole } to the component tree. Initialised from auth.data.role[0] in Redux. Re-syncs via useEffect when auth data changes. Uses getCurrentRoleAndPermissions() lib to validate the current role. Consumed via the useRole() hook.

🔒 PermissionContext

Companion to RoleContext. Exposes the resolved permission set for the logged-in partner user. Components can check specific permissions without reading Redux directly. Gates sidebar items, action buttons, table columns, and route access.

🪝

Custom Hooks

Reusable logic extracted into hooks

📱 useDevice (hooks/useDevice.ts)

Uses FingerprintJS to generate a stable device fingerprint on first load. Calls the backend device-registration API. Returns the device ID for use in login requests and session tracking.

🔄 useVersionGuard (hooks/useVersionGuard.ts)

Polls a version endpoint periodically. If the deployed frontend version is newer than what the user has, shows a "New version available" banner with a force-reload button. Prevents users from running stale code.

⏱️ useActivityMonitor (hooks/useActivityMonitor.ts)

Exports three hooks: useActivityMonitor(thresholdSeconds) returns isActive, isIdle, inactiveSeconds, inactiveMinutes, lastActivityTime, activityLogs, sessionDuration. usePageVisibility() tracks tab active/hidden state. useRecentActivity(thresholdSeconds) returns boolean if user interacted in last N seconds.

🔗 useAwsSignedUrl (hooks/useAwsSignedUrl.ts)

Takes an S3 object key and fetches a time-limited pre-signed URL for secure document viewing. Used throughout the app wherever KYC docs, agreements, or statements need to be displayed without exposing the raw S3 path.

🏢 useBrandMeta (hooks/useBrandMeta.ts)

Reads brand metadata from the Redux brand slice. Returns brand name, logo URL, theme colors, and config flags (isAA, isCamRequired, dashboardVersion, etc.) as a convenient destructured object.

💾 usePersistedSearch (hooks/usePersistedSearch.ts)

Persists the user's last search term and filters for a given page key in sessionStorage. When the user navigates away and returns, the previous search state is restored — preventing loss of context when opening a detail record.

🔍 useQueryParams (hooks/useQueryParams.ts)

Read and write URL query parameters as typed values. Used by list pages to sync filters, page number, and sort order to the URL so they survive a browser refresh and can be shared as links.

📤 useResendConfirmation (hooks/useResendConfirmation.ts)

Manages resend cooldown timer for confirmation emails (e.g., password reset, email verification). Prevents spam by enforcing a cooldown period with a countdown displayed in the UI.

🚪 handelLogout (hooks/handelLogout.ts)

Centralized logout handler. Calls POST /auth/partner/logout, clears Redux state (auth, brand, partnerUser), removes tokens from localStorage, and redirects to /login. Used in the sidebar profile menu and session expiry handler.

📞 useAcefoneDialer (hooks/useAcefoneDialer.ts)

Convenience hook that wraps the AcefoneDialerContext. Returns call state (isCallActive, currentCall) and action methods (initiateCall, endCall, muteCall). Used by collection pages to embed click-to-dial in customer rows.

🏷️ useLoanStatus (hooks/useloanStatus.ts)

Returns valid next status transitions for a given loan's current status and the logged-in user's role+permissions. Ensures the status update dropdown only shows transitions the current user is authorized to perform.

Feature-specific hooks (within feature folders):

📊 useDashboardStats (features/dashboard/hooks/)

Fetches and memoizes dashboard summary statistics for the selected date range. Returns loading state, error, and the stats object (total applications, disbursements, active loans, collections due).

📈 useCollectionAnalysis (features/dashboard/hooks/)

Fetches collection analysis data for Dashboard V2. Returns recovery rates, overdue buckets, and executive-level collection performance for the selected period.

💸 useDisbursementAnalysis (features/dashboard/hooks/)

Fetches disbursement trend data for Dashboard V2 charts. Returns daily/weekly/monthly disbursement amounts and counts for the selected date range.

📋 useLoanAllocationDetails (features/dashboard/hooks/)

Fetches loan allocation breakdown by executive for Dashboard V2. Returns per-agent loan counts, amounts, and allocation rates for the team performance table.

🔔 useNotifications (features/notification/useNotifications.ts)

Polls the notification API at regular intervals. Returns unread count, notification list, and markAsRead(id) / markAllRead() actions. Feeds the notification bell component.

📞 useDialerConfig (features/partnerUsers/hooks/useDialerConfig.ts)

Fetches the dialer configuration for the current partner user (Acefone SIP extension, Stringee settings). Returns config and a updateConfig mutation method. Used in the partner user settings dialog.

🛡️

Roles & Permissions (RBAC)

How the frontend enforces access control

The frontend uses a dual-layer access control system: Roles define the job function (e.g., Collection Executive) and Permissions define what actions/views are unlocked. A user can have a base role but also have additional permissions granted on top.
👑

SUPER_ADMIN

Cross-brand access, brand creation, system settings, all permissions unlocked.

Global role
🏢

ADMIN

Full access within their brand: users, settings, reports, loans, collections.

Brand-scoped
📋

LOAN_EXECUTIVE

Customer onboarding, loan management, evaluation. Cannot access collections or settings.

Brand-scoped
💼

COLLECTION_EXECUTIVE

Active collections, pre/post collection queues. Can initiate calls and log outcomes.

Brand-scoped
👔

COLLECTION_MANAGER

All collection executive access plus team management, allocation, escalations.

Brand-scoped
🏅

COLLECTION_HEAD

Supervisory view over all collections, settlement authority, write-off approvals.

Brand-scoped

SANCTION_MANAGER

Reviews applications for sanctioning. Can approve/reject with conditions.

Brand-scoped
🎖️

SANCTION_HEAD

Final sanctioning authority. Overrides sanction manager decisions.

Brand-scoped
💰

CREDIT_EXECUTIVE

Credit analysis, BRE results review, evaluation overrides, credit decisions.

Brand-scoped

🔒 How Permissions Work in the UI

The lib/role.ts utility provides helper functions like hasPermission(user, 'COLLECTIONS') and hasRole(user, 'ADMIN'). These are used in:

Route guards (redirect if no permission) Sidebar items (hide if no access) Action buttons (disable or hide) Table columns (hide sensitive data) Status update options (filter valid transitions)
🔌

Frontend Third-Party Integrations

External SDKs embedded in the frontend

📞 Acefone VoIP

VoIP dialer widget embedded in the frontend. Allows collection staff to make calls directly from the browser. Call sessions tracked, recordings linked to customer profiles.

📱 Stringee

Alternative call center platform integration. Provides call queuing, IVR, and agent management for larger collection teams.

🤝 Lendbox

Partner lender UI components. Loan creation requests sent to Lendbox, their disbursement status synced back and shown in the frontend.

🔏 FingerprintJS

Browser fingerprinting for device registration. Runs invisibly on login, generates stable device ID.

📝 TipTap Editor

Rich-text editor for notes, comments, and rejection reason descriptions. Supports bold, lists, links.

📊 Chart.js + Recharts

Two charting libraries for different dashboard needs. Chart.js for standard charts, Recharts for more complex React-integrated charts.

🔐 Google OAuth

Google Sign-In integrated via VITE_GOOGLE_CLIENT_ID env variable. Allows partner staff to authenticate using Google Workspace accounts. Token validation delegated to the backend auth service.

🧠 ScoreMe BDA

ScoreMe Bureau Data Analysis SDK. Fetches enriched credit bureau data with ScoreMe's proprietary scoring model. Embedded in the customer detail Credit Report tab. Results include bureau score, repayment history, and risk flags. API handled via scoreMeBDA.ts.

Completed Loans Page

4 sub-tabs for fully closed loan lifecycle management

Route: /:brandId/completed. Split into 4 sub-tabs, each with its own page file in pages/loanCompleted/. Accessible to LOAN_OPS role and above.

📋 All Completed (all.tsx)

Unified view of all loans that have reached a terminal status. Paginated table with filters for status, date, executive, amount. Supports CSV export. Shows loan ID, customer name, amount, closure date, and closure type.

🔒 Closed (closed.tsx)

Loans fully repaid by the customer with no outstanding balance. NDC (No Due Certificate) generation available. Shows repayment date, total paid, any waiver given. NDC can be emailed to the customer directly from this view.

🤝 Settlement (settlement.tsx)

Loans settled at a negotiated amount less than the full outstanding balance. Shows original outstanding, settlement amount agreed, settlement date, and the partner user who authorized it. Settlement requires COLLECTION_HEAD permission.

📉 Write-Off (write-off.tsx)

Loans written off as uncollectable. Shows write-off date, outstanding at write-off, reason, and authorizing manager. Write-off requires both COLLECTION_HEAD and ADMIN approval. Once written off, the loan is archived but remains visible for audit.

⚙️

Loan Operations Pages

All sub-pages under /:brandId/loans-ops

Route: /:brandId/loans-ops. Dedicated workspace for the LOAN_OPS role. 5 sub-pages handle the full disbursement and repayment verification workflow. Files in pages/loanOps/.

⏳ Pending Disbursement (pendingDisbursement.tsx)

Loans sanctioned and waiting for bank transfer. Shows loan ID, customer name, bank account details, amount, and NEFT/IMPS transfer reference. Loan Ops confirms disbursement once bank transfer is done, triggering status change to DISBURSED.

📄 No Due Pending (noDuePending.tsx)

Fully repaid loans waiting for NDC (No Due Certificate) generation. Loan Ops verifies all payments are received, then generates and emails the NDC. Moves loan to CLOSED status on completion.

🔍 Payment Approval (paymentApproval.tsx)

Incoming payment records that need manual Loan Ops review before being confirmed. Shows customer, loan, payment amount, UTR/reference number, payment gateway, and submission date. Can approve or reject.

✅ Payment Approved (paymentApproved.tsx)

Historical view of all payments that have been approved by Loan Ops. Audit trail with who approved, when, and the UTR confirmed. Used for reconciliation and reporting.

❌ Payment Rejected (paymentRejected.tsx)

Historical view of payments rejected by Loan Ops with rejection reasons. Shows rejected amount, reason given, and the partner user who rejected. Customer support can use this to explain payment issues to customers.

📊

Reports Page

Data export and analytics for management and compliance

Route: /:brandId/reports. File: pages/report/index.tsx. Requires MASTER_REPORTS permission. All reports support date range filters and CSV/download export via report.api.ts.

📋 Master Report

Complete customer-level data export. Includes: Customer ID, Name, Mobile, DOB, Gender, PAN verified, Aadhaar verified, employment type, monthly income, company name, bank account, address, references, all loan IDs, loan statuses, loan amounts, status history, and brand rejection reasons. Used for regulatory filings and portfolio analysis.

📢 Marketing Report

Lead and acquisition funnel data. Fields: Lead ID, Domain/source, Lead Stage, Rejection Remarks, Created At. Tracks which marketing channels are converting to applications. Used by the marketing team to measure campaign ROI.

📉 Completed No-Repayment Report

Loans that reached a terminal status (closed/written-off/settled) without any payment being made. Shows loan ID, formatted loan ID, status, creation date, customer ID, and due date. Used for NPA (Non-Performing Asset) analysis.

📊 Other Reports (29 Total)

The backend exposes 29 report types across three categories: User/Loan reports (e.g. disbursed-loan-report, reject-report, outstanding-data-report), Collection reports (e.g. master-collection-report, collection-due-report, field-visit-report), and Marketing/Credit reports (e.g. marketing-report, cic-report, daily-marketing-mis-report). All are date-range filtered and support CSV export.

Reminders Page

Automated communication scheduling and monitoring

Route: /:brandId/reminders. File: pages/reminders/RemindersPage.tsx. Feature component: features/Reminders/index.tsx. API: reminder.api.ts.

📊 Reminder Dashboard Metrics

Summary card showing total reminders sent today, this week, this month. Delivery rate per channel (SMS/WhatsApp/Email). Fetched via getReminderDashboardMetrics. A refresh button manually triggers a data refresh via refreshReminderDashboardMetrics. Includes a matrix graph (features/Reminders/components/matrixGraph.tsx) visualizing reminder performance over time.

📋 Reminder List

Paginated table of all reminders. Columns: customer name, channel (SMS/WhatsApp/Email), template code, scheduled time, status (PENDING/SENT/FAILED/CANCELLED). Filters: channel, status, created date range, scheduled date range, search by customer. Each row shows audit logs link.

📝 Create Reminder

Modal form to schedule a new reminder. Fields: select customer (userId), channel (SMS/WhatsApp/Email), template code, scheduled date/time, optional providerMessageId, and custom payload variables. Submits to createUserReminder.

🔍 Reminder Audit Logs

Per-reminder audit trail showing every status change: when it was created, when it was dispatched to the provider, provider acknowledgement, delivery confirmation, and any failure reasons with error codes.

🔍

Global Search Page

Cross-entity search across customers, loans, and users

Route: /:brandId/global-search. File: pages/gloabalSearch/index.tsx. API: user-search.api.ts.

A dedicated search page that allows partner staff to search across the entire brand's data in one place. The search input is debounced and queries the user-search.api which searches across:

Customer name Phone number PAN number Email address Loan ID Formatted User ID

Results are displayed in grouped sections (Customers, Loans). Clicking a result navigates to the respective customer detail or loan detail page. Results load in real time as the user types.

✍️

Sanctions Pages

Sanction Manager and Sanction Head queues

📋 Sanction Manager (pages/sanctionsManager/index.tsx)

Route: /:brandId/sanction-manager. Shows applications that have passed credit evaluation and are awaiting manager-level sanction approval. Lists customer name, loan amount, evaluation score, credit executive who evaluated, and days waiting. Manager can: Sanction (approve with conditions), Send Back to Credit Executive, or Reject with reason. Requires SANCTION_MANAGER role.

🏅 Sanction Head (pages/sanctionsHead/index.tsx)

Route: /:brandId/sanction-head. Higher-level sanction queue for applications that Sanction Managers have escalated or that meet criteria requiring Head-level approval (e.g., high loan amounts beyond manager threshold). Final sanction authority. Can override Sanction Manager decisions. Requires SANCTION_HEAD role.

💳

Credit Executive Page

Credit analysis and loan evaluation queue

Route: /:brandId/credit-executive. File: pages/creditExecutive/index.tsx. Requires CREDIT_EXECUTIVE role.

Dedicated queue for Credit Executives showing loans that have completed onboarding and are awaiting credit analysis. The Credit Executive reviews:

BRE Results

Business Rules Engine output, score breakdown, and rule pass/fail details.

CAM Calculator

Fill/review Credit Appraisal Memo with salary data, FOIR, and loan recommendation.

Evaluation V2

Enhanced evaluation criteria scoring with manual override capability.

Credit Report

CIBIL/Equifax score, ScoreMe BDA analysis, and repayment history.

After analysis, the Credit Executive submits an evaluation decision (Approve/Conditional/Reject) which moves the loan to the Sanction Manager queue.

Help Center Page

Internal knowledge base and support resources

Route: /:brandId/help-center. File: pages/helpCenter/index.tsx. Accessible to any authenticated partner user.

Internal help and documentation page for partner staff. Content rendered using react-markdown. Provides:

How-to guides for each role FAQ for common operations Process flowcharts Contact support links
🧮

CAM Calculator Feature

Credit Appraisal Memo — used by Credit Executives to assess loan eligibility

Enabled per brand via brandConfig.is_cam_calculation_required = true. Component: features/customerDetails/components/ (CAM tab on customer detail). API: cam-calculator.api.ts.

📋 What it does

The CAM Calculator is a structured form that credit executives fill when analysing a loan application. It captures 3 months of salary data, calculates average salary, determines eligible FOIR (Fixed Obligation to Income Ratio), computes eligible loan amount, and generates a recommendation.

📐 Data Fields

Salary Credit Date 1/2/3 Salary Amount 1/2/3 Avg Salary Eligible FOIR Actual Salary Loan Applied Eligible Loan Loan Recommended Disbursal Date Repay Date Tenure / Tenure ID ROI Obligations FOIR Achieved Proposed FOIR

⚙️ API Operations

saveCAMCalculator(brandId, data) — POST to save/update. getCAMCalculator(loanId) — GET existing CAM for a loan. getCAMCalculatorByUser(userId, brandId) — GET all CAMs for a user. deleteCAMCalculator(loanId) — DELETE. The saved CAM data is visible to Sanction Managers when reviewing the loan.

👥 Roles

CREDIT_EXECUTIVE fills the CAM. SANCTION_MANAGER and SANCTION_HEAD can view it (read-only) during their review. The CAM tab is only visible on the customer detail page when is_cam_calculation_required is true for the brand.

🏦

Account Aggregation (AA) Feature

RBI-regulated financial data sharing via consent framework

Enabled per brand via brandConfig.isAA = true. Component: features/customerDetails/components/aa/ (AA tab on customer detail). API: aa.api.ts. Providers: FINDUIT, CART.

📜 What is AA

Account Aggregation is an RBI-regulated framework that allows customers to securely share their bank statement data with lenders via a consent-based mechanism. The customer approves a consent request through their bank's AA-enabled app. The lender then receives structured financial data without manually uploading bank statements.

🔄 Consent Flow

1. Partner creates consent request (createConsentRequest). 2. Consent link sent to customer via email (sendConsentRequestEmail) or shared manually (generateConsentUrl). 3. Customer approves via their bank's AA app. 4. System polls consent status (updateConsentStatus). 5. On approval, periodic data fetch (fetchPeriodicData) pulls bank statements.

📊 AA Components (features/customerDetails/components/aa/)

customerFinancialBreakdown.tsx customerFinancialComparison.tsx customerReportOverview.tsx customerStatementOverview.tsx

These components render income analysis, transaction categorisation, balance trends, and month-over-month comparison from the AA-fetched data.

📋 API Operations

createConsentRequest(userId, brandId), createManualConsentRequest(userId, mobile, brandId), getConsentRequest(id), getUserConsentRequests(userId), getDataSessions(consentRequestId), updateConsentStatus(id, {status, clientTransactionId, consentHandle}), sendConsentRequestEmail(userId), generateConsentUrl(userId, brandId), fetchPeriodicData({userId, consentRequestId}).

📬

Lead Management Feature

Import and manage marketing leads from Facebook Ads and other channels

API: leads/leads.api.ts. Accessible from the Settings area or a dedicated leads section. Used by marketing/admin staff to import leads generated by ad campaigns.

📤 CSV Upload

uploadLeadFormsCsv(brandId, file) — accepts a CSV file (multipart/form-data). The CSV contains lead data from Facebook Lead Ads: full name, phone, email, city, platform, monthly salary, PAN, employment status, campaign metadata (adId, adName, adsetId, campaignId, formId). Backend processes and deduplicates against existing users.

📋 Lead List & Filtering

Paginated table of all uploaded leads. Each lead shows: name, phone, status (PENDING/PROCESSED/FAILED/DUPLICATE), platform, campaign, and uploaded timestamp. Filters by status and platform. Supports bulk delete and CSV export of filtered leads.

🔄 Sync & Processing

syncLeadForms(brandId) — triggers backend processing to match unprocessed leads against existing users or create new user records. Returns counts of processed, failed, and duplicate leads.

📊 Lead Stats

getLeadFormsStats(brandId) — returns totals: total leads, pending, processed, failed, duplicates. Displayed as summary cards at the top of the leads view for quick overview.

Rating Matrix Feature

Performance scoring for brands and partner users

🏢 Brand Rating Matrix (brand-rating-matrix.api.ts)

Brand-level scoring matrix used to evaluate loan applications. Configurable criteria with weightings. Fetched as part of brand setup. Admins can update matrix criteria and weights from the settings panel. Affects how the BRE engine scores applications for the brand.

👤 Partner User Rating Matrix (partner-user-rating-matrix.api.ts)

Individual staff performance rating system. Tracks each partner user's metrics (conversion rates, collection efficiency, TAT). Managers can view and update staff performance scores. Used for performance reviews and allocation priority decisions.

🛠️

Utilities (lib/ folder)

Shared helper functions used across the frontend

🔗 cn() — clsx + tailwind-merge (lib/utils.ts)

The cn(...inputs) function combines clsx and tailwind-merge for safe conditional class merging. Also exports: formatDate(date), formatDateWithTime(date) (using dayjs), formatDocumentType(type), maskAadhaar(aadhaar) (shows only last 4 digits as XXXX-XXXX-NNNN), maskPan(pan) (shows first 2 + last 1 chars).

✅ canUpdateLoanStatus (lib/canUpdateLoanStatus.ts)

Given the current loan status, user role, and permissions, returns a boolean whether the user can trigger a status transition. Also returns the list of valid target statuses. Used by the status update modal to filter the dropdown options.

🏦 fetchIFSCDetails (lib/fetchIFSCDetails.ts)

Fetches bank branch details (bank name, branch, address, city, state) for a given IFSC code from the Razorpay IFSC API or the backend IFSC lookup. Used in bank account forms to auto-fill branch details when the user enters an IFSC code.

👤 getCurrentRoleAndPermissions (lib/getCurrentRoleAndPermissions.ts)

Reads the current user's role and permissions from Redux or localStorage and returns them in a normalised format { roleId, permissions }. Used by RoleContext and throughout the app for permission checks without hitting Redux directly.

📄 pdfMetadataExtractor (lib/pdfMetadataExtractor.ts)

Uses PDFjs-dist to extract metadata from uploaded PDF files (title, author, page count, creation date). Also validates PDF integrity. Used when partner staff upload loan agreements and bank statements to verify the file is a valid PDF.

📄 getPdfVersionFromUrl (lib/getPdfVersionFromUrl.ts)

Extracts the PDF version identifier from an S3 URL. Used to determine whether to render a PDF with the old viewer or the new enhanced viewer based on version number.

🎨 theme.ts (lib/theme.ts)

Theme configuration helper. Maps brand theme fields (primaryColor, secondaryColor, fontFamily, etc.) to CSS custom property names. Used by ThemeProviderContext to inject brand colors into the document root.

🔒 role.ts (lib/role.ts)

Role utility functions: hasPermission(permissions, permKey), hasRole(roles, roleKey), role hierarchy checks. Used throughout the app for conditional rendering and route guarding.