@loanpal/adf
v0.3.187
Published
Goodleap api data factory
Downloads
9,518
Maintainers
Keywords
Readme
api-data-factory (adf)
Generate Loans / TPOs leveraging DEV API
Current Capabilities
- Generate default payloads
- Loan submission via DEV API
- TPOs submission via DEV API , progression to ProjectInfo complete
- Standardized Documents API wrappers with consistent parameter patterns
- Catalog Service integration for loan offers, products, organizations, and TPO offers
- Submission Service integration for finance accounts, TPO applications, shared applications, disclosures, pricing, and evaluations
Usage
Requirements for host:
- TypeScript >= 4.7
- tsconfig.json
{ "compilerOptions": { "module": "Node16" } }
- tsconfig.json
- Node.js >= 18
- as host, import / require { FinanceAccountManager } from '@loanpal/adf';
- you can generate default payloads with FinanceAccountManager.init().getDefaultPayload() or FinanceAccountManager.getDefaultDevApiPayload();
- check dev-api.tests.ts file on how to submit a Loan/TPO, this module is based on postman collection workflows
- Main classes from dev api to work with are:
import { CategoriesApi, DisclosuresApi, HealthApi, LoansApi, OffersApi } from '@loanpal/adf/api/openapi-generated/dev-api/sdk/api'; - Environment to be passed via configuration param on classes instantiation:
import { Configuration } from '@loanpal/adf/api/openapi-generated/dev-api/sdk'; import { envSetup } from '@loanpal/adf'; const currentEnv = envSetup(process.env.STAGE === 'stage' ? 'stage' : 'devint01'); const loansApi = new LoansApi(new Configuration({ username: 'username', password: 'password' }), currentEnv.DEV_API_BASE_URL); - sample TPO submission:
import { LoansApi } from '@loanpal/adf/api/openapi-generated/dev-api/sdk/api'; import { genDefaultDevApiTPOSubmissionPayload } from '@loanpal/adf/api/openapi-generated/dev-api/templates/tpo-templates/tpo-template'; import { envSetup } from '@loanpal/adf'; const currentEnv = envSetup(process.env.STAGE === 'stage' ? 'stage' : 'devint01'); const tpoService = FinanceAccountManager.init(FinanceAccountType.TPO, {stage: 'stage'}) as TpoService; tpoPayload = genDefaultDevApiTPOSubmissionPayload(); tpoPayload.subjectProperty.address.state = 'CA'; tpoPayload.applicant.address.state = 'CA'; tpoPayload.categoryId = installCategories.find((installCategory) => installCategory.name === 'SOLAR LEASES / PPAS')?.id || ''; // Set offer based on .env, over default one tpoPayload.offerId = offers.data?.length ? offers.data[0].id : ''; if (!tpoPayload.offerId.length) throw new Error('No offers found'); let result: SchemaObject65 = {} as SchemaObject65; tpoPayload.disclosureToken = disclosures.data?.[0].token || ''; try { result = ( await new LoansApi( new Configuration({ username: tpoOrgApiData.orgId, password: tpoOrgApiData.orgSecret, } as Configuration), currentEnv.DEV_API_BASE_URL, ).posfinancingRestV2LoansPost({ postApplicationRequest: tpoPayload }) ).data; } catch (error) { if (axios.isAxiosError(error)) { throw Error(JSON.stringify(error.response?.data)); } } - sample TPO progression to ProjectInfo
- Generate TPO using LoansApi class
- Progress generated TPO to required state using TpoService class
import { Env, envSetup, FinanceAccountManager, TpoService} from '@loanpal/adf'; const tpoService = FinanceAccountManager.init(FinanceAccountType.TPO, { stage: process.env.STAGE === 'stage' ? 'stage' : 'devint01'}) as TpoService; await tpoService.toProjectInfoComplete( { orgId: tpoOrgApiData.orgId, orgKey: tpoOrgApiData.orgSecret }, { financeAccount: id }, );
Documents API
The Documents API wrappers have been standardized to follow a consistent pattern across all endpoints. All API classes now use:
Standardized Parameter Pattern
All methods now accept a single params object that combines:
- Request-specific parameters (from OpenAPI generated types)
TokenAuthfor authentication ({ accessToken: string })- Optional
optionsfor Axios request configuration
import { DocsDocumentsApi } from '@loanpal/adf/api/documents/documents-api';
// Example usage
const documentsApi = new DocsDocumentsApi(baseService);
const result = await documentsApi.sendCpc({
referenceId: 'loan-123',
sendCpcDocumentInputDto: { /* ... */ },
xDocumentInformation: 'optional-header',
xLoanInformation: 'optional-header',
accessToken: 'your-access-token',
options: { timeout: 5000 } // optional
});Available Documents API Classes
All following classes follow the same standardized pattern:
DocsAATsApi- Automated Approval & Testing ServicesDocsAchApi- ACH payment processingDocsDocumentsApi- Core document operationsDocsInternalApi- Internal document operationsDocsInternalIDVApi- Identity verification (supports version parameters)DocsLifecycleEventsApi- Document lifecycle eventsDocsLoanEventsApi- Loan-related eventsDocsSalesforceDocumentDeliveryApi- Salesforce document deliveryDocsSalesforceIntegrationTestApi- Salesforce integration testingDocsSalesforceUnifiedDocumentIntegrationApi- Unified Salesforce integrationDocsServiceApi- Service health and version endpointsDocsVaultingApi- Document vaulting operations
Response Format
All methods now return response.data.payload directly instead of the full Axios response, providing cleaner access to the actual data.
Import Example
import {
DocsDocumentsApi,
DocsAATsApi,
DocsVaultingApi
} from '@loanpal/adf/api/documents/apis';
import { BaseService } from '@loanpal/adf/services/base-service';
const baseService = new BaseService(/* configuration */);
const documentsApi = new DocsDocumentsApi(baseService);
const aatsApi = new DocsAATsApi(baseService);
const vaultingApi = new DocsVaultingApi(baseService);Migration from Previous Versions
If you're upgrading from a previous version, note these breaking changes:
Parameter Changes
Before:
await documentsApi.sendCpc(auth, requestParameters, options);After:
await documentsApi.sendCpc({
...requestParameters,
accessToken: 'your-token',
options
});Return Value Changes
Before:
const response = await documentsApi.sendCpc(params);
const data = response.data.payload; // Had to access nested propertiesAfter:
const data = await documentsApi.sendCpc(params); // Direct access to payloadAuthentication Changes
All private API methods now expect TokenAuth ({ accessToken: string }) instead of AuthType. The public methods handle the token extraction automatically.
Recent Updates
December 2024
- API Standardization: All Documents API classes now follow a consistent parameter pattern
- Simplified Authentication: Unified token-based authentication across all endpoints
- Cleaner Response Handling: Direct access to
response.data.payloadwithout manual extraction - Type Safety Improvements: Better TypeScript support with proper parameter destructuring
- Consistent Error Handling: Standardized error logging and propagation across all APIs
Configuration for package development
Follow these steps to configure the project:
Install project using:
yarn install --frozen-lockfileCreate a
.envfile in the root directory of the project and add the following environment variable:APOLLO_KEY=your_apollo_keyGenerate all codegen: Execute the following command to generate all API codegen (includes dev-api, project-info-service, lender-app-status-service, catalog-service, submission-service, workflow-service, workday-api, inventory-tracking-service, and GraphQL schema):
yarn codegen:allAlternatively, you can generate individual service codegen if needed:
yarn dev-api:openapi:codegen- Dev APIyarn project-info:openapi:codegen- Project Info Serviceyarn lender-app-status:openapi:codegen- Lender App Status Serviceyarn catalog:openapi:codegen- Catalog Serviceyarn submission:openapi:codegen- Submission Serviceyarn ws:openapi:codegen- Workflow Serviceyarn workday-api:openapi:codegen- Workday APIyarn inventory-tracking:openapi:codegen- Inventory Tracking Serviceyarn type:generate- GraphQL schema only
Build the project: Use this command to build the project:
yarn buildRun the tests: Use this command to run the tests:
yarn jest
Package Versioning and Release Workflow
This project follows industry-standard best practices for package versioning using Semantic Versioning (SemVer) and Conventional Commits.
Versioning Strategy
We use a two-commit approach for releases:
- Feature Commit: Contains your actual code changes with a descriptive conventional commit message
- Version Commit: Automated version bump that updates
package.jsonand creates a git tag
Step-by-Step Release Process
1. Create Feature Branch
Create a new branch for your feature development:
# Create and switch to feature branch
git checkout -b feature/file-locking-utilities
# Or for bug fixes
git checkout -b fix/authentication-timeout2. Commit Your Changes
Use conventional commit format to describe your changes:
git add .
git commit -m "feat: add file locking utilities and update GraphQL schema
- Add comprehensive file locking system with proper-lockfile integration
- Implement acquireFileLock, safeReleaseLock, and withFileLock utilities
- Add manual lock cleanup with stale lock detection and safety checks
- Support configurable lock options (timeout, retries, backoff)
- Update GraphQL schema and regenerate types
- Enhance auth and dev-api services"3. Test Using Yarn Link (Optional)
Test your changes in consumer projects before publishing:
# Build your changes
yarn build
# Link the package locally
yarn link
# In consumer project (e.g., zebra-framework)
yarn remove @loanpal/adf
yarn link @loanpal/adf
# Test your changes, then unlink when done
yarn unlink @loanpal/adf # In consumer project
yarn unlink # In adf project4. Bump Version and Publish (Before PR Merge)
Once development and testing is complete, bump version on your feature branch:
# Bump package version on feature branch
yarn adf:patch
# Build and publish the new version
yarn publish:latest
# Push feature branch with version bump
git push origin feature/file-locking-utilities5. Test Published Package on ZEBRA Framework
MANDATORY: Test the published package version on ZEBRA framework as consumer:
# In ZEBRA framework project
yarn add @loanpal/[email protected] # Use the newly published version
# Run smoke tests from GithubActions using your branch to validate integrationRequired Evidence for PR:
- 📸 Screenshot of successful test run/smoke test results
- 🔗 Link to test results (CI/CD pipeline, test report, etc.)
- ✅ Confirmation that ZEBRA framework works with new ADF version
6. Create Pull Request with Test Evidence
# Create pull request through GitHub UI
# The PR now includes both your changes AND the version bumpPR Description Template:
## Changes
- Add file locking utilities and update GraphQL schema
- [Detailed list of changes]
## Testing Evidence
**Published Version:** `@loanpal/[email protected]`
**ZEBRA Framework Integration Test:**
- ✅ Smoke tests passed
- 📸 Screenshot: [attach screenshot of test results]
- 🔗 Test Results: [link to CI/CD run or test report]
- 📋 Test Command: `yarn test:smoke` or `yarn test:adf-integration`
**Consumer Validation:**
- [ ] ZEBRA framework successfully uses new ADF version
- [ ] No breaking changes detected
- [ ] All existing functionality works as expectedConventional Commit Format
This project uses @commitlint/config-conventional. Follow these commit message formats:
feat:- New featuresfix:- Bug fixesdocs:- Documentation changesstyle:- Code style changes (formatting, etc.)refactor:- Code refactoringtest:- Adding or updating testschore:- Maintenance tasks
Example:
feat: add new authentication method
fix: resolve memory leak in file processing
docs: update API documentation
chore: update dependenciesWhy Two Commits?
This approach follows industry standards because it:
- ✅ Separates concerns: Feature changes vs. version metadata
- ✅ Clean git history: Easy to see what changed vs. when it was released
- ✅ Better rollbacks: Can revert features without affecting version history
- ✅ Tool compatibility: Works with automated release tools and CI/CD
- ✅ Team collaboration: Reviewers focus on code, not version bumps
Git History Example
Merge pull request #108 from user/feature/file-locking ← PR merge (main branch)
v0.3.129 ← Version bump (feature branch)
feat: add file locking utilities and update GraphQL schema ← Your feature commit (feature branch)
Merge pull request #107 from user/fix/auth-timeout ← Previous PR merge (main branch)
v0.3.128 ← Previous version bump (feature branch)
fix: resolve authentication timeout issue ← Previous feature commit (feature branch)Branch Protection and PR Requirements
This workflow ensures:
- ✅ Code Review: All changes go through pull request review process
- ✅ Branch Protection: Main branch is protected from direct pushes
- ✅ Pre-merge Testing: Package is published and tested before merging to main
- ✅ Consumer Validation: Changes can be tested in consumer projects via yarn link
- ✅ ZEBRA Framework Testing: Mandatory smoke testing on consumer framework
- ✅ Evidence Documentation: Screenshots and test result links required in PR
- ✅ Clean History: Merge commits clearly show when features were integrated
- ✅ Published Versions: Every merged PR has an associated published package version
Quality Gates
Before any PR can be merged, the following must be provided:
- 📸 Test Evidence: Screenshot of successful ZEBRA framework smoke tests
- 🔗 Test Results: Link to CI/CD pipeline or test report showing success
- ✅ Version Confirmation: Confirmation that ZEBRA works with the new ADF version
- 📋 No Regressions: Evidence that existing functionality remains intact
Available Scripts
yarn adf:patch- Bump patch version (recommended for most changes)yarn build- Build the package before publishingyarn publish:latest- Build and publish to npm registry
Publishing to NPM
After version bumping:
yarn publish:latestThis will build the package and publish it to the npm registry.
Link @loanpal/adf package without generating a new package version while development
Follow these steps to test a Newer version using yarn link:
- On the
api-data-factoryside open a console terminal window from the root project folder - Run the build command
tsc -b ./tsconfig.cjs.json ./tsconfig.esm.jsonor run it from the package.json scripts => build - After a success build, in the console terminal run link comand
yarn link - On the e.g.:
zebra-frameworkside open a console terminal window from the root project folder - Remove the existing
@loanpal/adfto avoid conflicsyarn remove @loanpal/adf - Make sure that the
@loanpal/adffolder does not exists innode_modulese.g.:ls -la node_modules/@loanpal/adf - Link the newer unpublished adf build to the
zebra-frameworkby running this commandyarn link @loanpal/adf - Make sure that a symbolic(symlink) link pointing to your local package
ls -la node_modules/@loanpal/adfif the symlink to the adf folder exists then you are good to go - (Optional) Handle Dependencies Conflicts
yarn install --check-files yarn dedupe rm -rf node_modules/.yarn-integrity yarn install - Rebuild and Watch for Changes
yarn build --watch - Unlink When Done on the
zebra-frameworksideyarn unlink @loanpal/adf, on theloanpal/adfsideyarn unlink - To build a new adf version follow the steps ->
4. **Build the project**: - Install newly created
@loanpal/adfpackageyarn add @loanpal/adf@<version>
