From c29eabdf444522f589686bb29e6455a6e2ec01bc Mon Sep 17 00:00:00 2001 From: Chris Risner Date: Tue, 4 Jun 2024 08:58:50 -0500 Subject: [PATCH] feat(SlackMessage): udpated slack message cleaner, concise with stronger typescript --- src/app/api/credit-app/route.ts | 4 +- src/lib/actions/slack.helpers.ts | 84 +++++++++++ src/lib/actions/slack.message.ts | 57 ++++++++ src/utils/slackMsg.ts | 231 ------------------------------- typings.d.ts | 48 +------ 5 files changed, 144 insertions(+), 280 deletions(-) create mode 100644 src/lib/actions/slack.helpers.ts create mode 100644 src/lib/actions/slack.message.ts delete mode 100644 src/utils/slackMsg.ts diff --git a/src/app/api/credit-app/route.ts b/src/app/api/credit-app/route.ts index 7649dca..5314cd7 100644 --- a/src/app/api/credit-app/route.ts +++ b/src/app/api/credit-app/route.ts @@ -1,7 +1,7 @@ import { formatApplicant } from '@/utils/formatApplicant' -import { slackMsgRequest } from '@/utils/slackMsg' import { NextResponse } from 'next/server' import { withAppRouterHighlight } from '@/utils/withAppRouterHighlight' +import { slackMessageCredit } from '@/lib/actions/slack.message' type RouteOnePayload = { primaryBuyer: Record @@ -46,7 +46,7 @@ export const POST = withAppRouterHighlight(async (request: Request) => { console.log('🚀 ~ CREDIT_API_DRIVLY ~ payload:', payload) try { - await slackMsgRequest({ url: slackUrl, data }) + await slackMessageCredit({ url: slackUrl, data }) const d = await fetch(`${process.env.CREDIT_API_DRIVLY}/applications`, { method: 'POST', body: JSON.stringify(payload), diff --git a/src/lib/actions/slack.helpers.ts b/src/lib/actions/slack.helpers.ts new file mode 100644 index 0000000..42582f5 --- /dev/null +++ b/src/lib/actions/slack.helpers.ts @@ -0,0 +1,84 @@ +import type { CreditApplicant } from 'typings' + +export type SlackBlocks = Array | { type: 'divider' }> + +export function createSlackSection(text: string) { + return { + type: 'section', + text: { + type: 'mrkdwn', + text, + }, + } +} + +export function formatSlackApplicant(applicant: CreditApplicant, role: 'Primary' | 'Joint') { + const blocks: SlackBlocks = [] + blocks.push({ type: 'divider' }) + blocks.push( + createSlackSection( + `*${role} Applicant:*\n*Full name:* ${applicant.firstName} ${applicant.middleName || ''} ${ + applicant.lastName + }\n*Phone:* ${applicant.phone} ${applicant.phoneType}\n*Email:* ${ + applicant.email + }\n*Date of Birth:* ${applicant.dateOfBirth}\n*SSN:* ${applicant.ssn}` + ) + ) + blocks.push( + createSlackSection( + `*Residence*\n*Address:* ${applicant.addressLine1}\n*City:* ${applicant.city}\n*State:* ${ + applicant.state + }\n*Zip Code:* ${applicant.zipCode}\n*Time at address:* ${applicant.addressYears} yrs ${ + applicant.addressMonths ? applicant.addressMonths + 'mo' : '' + }\n*Monthly payment/rent:* ${applicant.rentMortgagePaymentAmount}` + ) + ) + if (Number(applicant.addressYears) < 2) { + blocks.push( + createSlackSection( + `*Previous Residence*\n*Address:* ${applicant.prevAddressLine1}\n*City:* ${ + applicant.prevCity + }\n*State:* ${applicant.prevState}\n*Zip Code:* ${ + applicant.prevZipCode + }\n*Time at address:* ${applicant.prevAddressYears} yrs ${ + applicant.prevAddressMonths ? applicant.prevAddressMonths + 'mo' : '' + }\n*Monthly payment/rent:* ${applicant.prevRentMortgagePaymentAmount}` + ) + ) + } + blocks.push( + createSlackSection( + `*Drivers License*\n*License number:* ${applicant.licenseNumber}\n*State:* ${applicant.licenseState}` + ) + ) + blocks.push( + createSlackSection( + `*Employment History*\n*Employer name:* ${applicant.employerName}\n*Employment Status:* ${ + applicant.employmentStatusCode + }\n*Employer phone:* ${applicant.employerPhone}\n*Occupation:* ${ + applicant.employmentTitle + }\n*Time on job:* ${applicant.timeOnJobYears} yrs ${ + applicant.timeOnJobMonths ? applicant.timeOnJobMonths + 'mo' : '' + }\n*Monthly income:* ${applicant.incomeAmount}` + ) + ) + if (Number(applicant.timeOnJobYears) < 2) { + blocks.push( + createSlackSection( + `*Previous Employment*\n*Employer name:* ${ + applicant.previousEmployerName + }\n*Employer phone:* ${applicant.prevEmployerPhone}\n*Occupation:* ${ + applicant.prevEmploymentTitle + }\n*Time on job:* ${applicant.prevTimeOnJobYears} yrs ${ + applicant.prevTimeOnJobMonths ? applicant.prevTimeOnJobMonths + 'mo' : '' + }\n*Monthly income:* ${applicant.prevIncomeAmount}` + ) + ) + } + blocks.push( + createSlackSection( + `*Other Income*\n*Description:* ${applicant.otherIncomeSourceDescription}\n*Monthly Amount:* ${applicant.otherIncomeAmount}` + ) + ) + return blocks +} diff --git a/src/lib/actions/slack.message.ts b/src/lib/actions/slack.message.ts new file mode 100644 index 0000000..23fe77c --- /dev/null +++ b/src/lib/actions/slack.message.ts @@ -0,0 +1,57 @@ +'use server' + +import formatDate from '@/utils/formatDate' +import type { CreditApplicant, VehicleOfInterest } from 'typings' +import { createSlackSection, formatSlackApplicant, type SlackBlocks } from './slack.helpers' + +interface SlackParams { + url: string | undefined + data: { + primary: CreditApplicant + secondary: CreditApplicant + vehicle: VehicleOfInterest + tradeIn: { + id: string + lienholder: string + allowance: number + } + } +} + +export async function slackMessageCredit({ url, data }: SlackParams) { + const date = formatDate(new Date(), true) + const blocks: SlackBlocks = [] + + blocks.push( + createSlackSection( + `*${data.primary.firstName} ${data.primary.lastName}* | ${date} :moneybag:\n* ${data.primary.email} | ${date}*` + ) + ) + blocks.push(...formatSlackApplicant(data.primary, 'Primary')) + + if (data.secondary) { + blocks.push(...formatSlackApplicant(data.secondary, 'Joint')) + } + + blocks.push({ type: 'divider' }) + blocks.push( + createSlackSection( + `*Vehicle of Interest*\n*Cash Down:* ${data?.vehicle?.cashDown}\n*VIN:* ${data.vehicle.vin}\n*Year:* ${data.vehicle.year}\n*Make:* ${data.vehicle.make}\n*Model:* ${data.vehicle.model}\n*Odometer:* ${data.vehicle.mileage}\n*Price:* ${data.vehicle.price}` + ) + ) + + if (data.tradeIn) { + blocks.push({ type: 'divider' }) + blocks.push( + createSlackSection( + `*Trade Information*\n*Record Id:* ${data.tradeIn.id}\n*Lender:* ${data.tradeIn.lienholder}\n*Trade In Allowance:* ${data.tradeIn.allowance}` + ) + ) + } + + await fetch(url!, { + method: 'POST', + body: JSON.stringify({ blocks }), + headers: { 'Content-Type': 'application/json' }, + }) +} diff --git a/src/utils/slackMsg.ts b/src/utils/slackMsg.ts deleted file mode 100644 index 8335cb1..0000000 --- a/src/utils/slackMsg.ts +++ /dev/null @@ -1,231 +0,0 @@ -import { PrimaryApplicant, VehicleOfInterest } from '../../typings' -import formatDate from './formatDate' - -interface SlackMsgRequest { - url: string | undefined - data: { - primary: PrimaryApplicant - secondary: PrimaryApplicant - vehicle: VehicleOfInterest - tradeIn: { - id: string - lienholder: string - tradeInAllowance: number - } - } -} - -export async function slackMsgRequest({ url, data }: SlackMsgRequest) { - const date = formatDate(new Date(), true) - - const blocks = [] - - for (const key in data) { - if (key === 'primary') { - blocks.push({ - type: 'section', - text: { - type: 'mrkdwn', - text: `*${data.primary.firstName} ${data.primary.lastName}* | ${date} :moneybag:\n* ${data.primary.email} | ${date}*`, - }, - }) - blocks.push({ - type: 'divider', - }) - blocks.push({ - type: 'section', - text: { - type: 'mrkdwn', - text: `*Primary Applicant:*\n*Full name:* ${data.primary.firstName} ${ - data.primary?.middleName || '' - } ${data.primary.lastName}\n*Phone:* ${data.primary.phone} ${ - data.primary.phoneType - }\n*Email:* ${data.primary.email}\n*Date of Birth:* ${data.primary.dateOfBirth}\n*SSN:* ${ - data.primary.ssn - }`, - }, - }) - blocks.push({ - type: 'section', - text: { - type: 'mrkdwn', - text: `*Residence*\n*Address:* ${data.primary.addressLine1} \n*City:* ${ - data.primary.city - }\n*State:* ${data.primary.state}\n*Zip Code:* ${ - data.primary.zipCode - }\n*Time at address:* ${data.primary.addressYears} yrs ${ - data.primary.addressMonths ? data.primary.addressMonths + 'mo' : '' - }\n*Monthly payment/rent:* ${data.primary.rentMortgagePaymentAmount}`, - }, - }) - Number(data.primary.addressYears) < 2 && - blocks.push({ - type: 'section', - text: { - type: 'mrkdwn', - text: `*Previous Residence*\n*Address:* ${data.primary.prevAddressLine1} \n*City:* ${ - data.primary.prevCity - }\n*State:* ${data.primary.prevState}\n*Zip Code:* ${ - data.primary.zipCode - }\n*Time at address:* ${data.primary.prevAddressYears} yrs ${ - data.primary.prevAddressMonths ? data.primary.prevAddressMonths + 'mo' : '' - }\n*Monthly payment/rent:* ${data.primary.prevRentMortgagePaymentAmount}`, - }, - }) - blocks.push({ - type: 'section', - text: { - type: 'mrkdwn', - text: `*Drivers License*\n*License number:* ${data.primary.licenseNumber} \n*State:* ${data.primary.licenseState}\n*Expiration:* ${data.primary.licenseExp}`, - }, - }) - blocks.push({ - type: 'section', - text: { - type: 'mrkdwn', - text: `*Employment History*\n*Employer name:* ${ - data.primary.employerName - }\n*Employment Status:* ${data.primary.employmentStatusCode}\n*Employer phone:* ${ - data.primary?.employerPhone - }\n*Occupation:* ${data.primary?.employmentTitle}\n*Time on job:* ${ - data.primary?.timeOnJobYears - } yrs ${ - data.primary?.timeOnJobMonths ? data.primary?.timeOnJobMonths + 'mo' : '' - }\n*Monthly income:* ${data.primary?.incomeAmount}`, - }, - }) - Number(data.primary?.timeOnJobYears) < 2 && - blocks.push({ - type: 'section', - text: { - type: 'mrkdwn', - text: `*Previous Employment*\n*Employer name:* ${ - data.primary?.previousEmployerName - }\n*Employer phone:* ${data.primary?.prevEmployerPhone}\n*Occupation:* ${ - data.primary?.prevEmploymentTitle - }\n*Time on job:* ${data.primary?.prevTimeOnJobYears} yrs ${ - data.primary?.prevTimeOnJobMonths ? data.primary?.prevTimeOnJobMonths + 'mo' : '' - }\n*Monthly income:* ${data.primary?.prevIncomeAmount}`, - }, - }) - blocks.push({ - type: 'section', - text: { - type: 'mrkdwn', - text: `*Other Incomet*\n*Description:* ${data.primary?.otherIncomeSourceDescription}\n*Monthly Amount:* ${data.primary?.otherIncomeAmount}\n`, - }, - }) - } else if (data?.secondary !== null && key === 'secondary') { - blocks.push({ - type: 'divider', - }) - blocks.push({ - type: 'section', - text: { - type: 'mrkdwn', - text: `*Joint Applicant:*\n*Full name:* ${data.secondary.firstName} ${data.secondary?.middleName} ${data.secondary.lastName}\n*Phone:* ${data.secondary.phone} ${data.secondary.phoneType}\n*Email:* ${data.secondary.email}\n*Date of birth:* ${data.secondary.dateOfBirth} \n*SSN:* ${data.secondary.ssn}`, - }, - }) - blocks.push({ - type: 'section', - text: { - type: 'mrkdwn', - text: `*Residence*\n*Address:* ${data.secondary.addressLine1} \n*City:* ${ - data.secondary.city - }\n*State:* ${data.secondary.state}*Zip Code:* ${ - data.secondary.zipCode - }\n*Time at address:* ${data.secondary.addressYears} yrs ${ - data.secondary.addressMonths ? data.secondary.addressMonths + 'mo' : '' - }\n*Monthly payment/rent:* ${data.secondary.rentMortgagePaymentAmount}`, - }, - }) - Number(data.secondary.addressYears) < 2 && - blocks.push({ - type: 'section', - text: { - type: 'mrkdwn', - text: `*Previous Residence*\n*Address:* ${data.secondary.prevAddressLine1} \n*City:* ${ - data.secondary.prevCity - }\n*State:* ${data.secondary.prevState}\n*Zip Code:* ${ - data.secondary.prevZipCode - }\n*Time at address:* ${data.secondary.prevAddressYears} yrs ${ - data.secondary.prevAddressMonths ? data.secondary.prevAddressMonths + 'mo' : '' - }\n*Monthly payment/rent:* ${data.secondary.prevRentMortgagePaymentAmount}`, - }, - }) - blocks.push({ - type: 'section', - text: { - type: 'mrkdwn', - text: `*Drivers License*\n*License number:* ${data.secondary.licenseNumber} \n*State:* ${data.secondary.licenseState}\n*Expiration:* ${data.secondary.licenseExp}`, - }, - }) - blocks.push({ - type: 'section', - text: { - type: 'mrkdwn', - text: `*Employment History*\n*Employer name:* ${ - data?.secondary?.employerName - }\n*Employment Status:* ${data?.secondary?.employmentStatusCode}\n*Employer phone:* ${ - data?.secondary?.employerPhone - }\n*Occupation:* ${data?.secondary?.employmentTitle}\n*Time on job:* ${ - data?.secondary?.timeOnJobYears - } yrs ${ - data?.secondary?.timeOnJobMonths ? data?.secondary?.timeOnJobMonths + 'mo' : '' - }\n*Monthly income:* ${data?.secondary?.incomeAmount}`, - }, - }) - Number(data.secondary.timeOnJobYears) < 2 && - blocks.push({ - type: 'section', - text: { - type: 'mrkdwn', - text: `*Previous Employment*\n*Employer name:* ${ - data?.secondary?.previousEmployerName - }\n*Employer phone:* ${data?.secondary?.prevEmployerPhone}\n*Occupation:* ${ - data?.secondary?.prevEmploymentTitle - }\n*Time on job:* ${data?.secondary?.prevTimeOnJobYears} yrs ${ - data?.secondary?.prevTimeOnJobMonths - ? data?.secondary?.prevTimeOnJobMonths + 'mo' - : '' - }\n*Monthly income:* ${data?.secondary?.prevIncomeAmount}`, - }, - }) - blocks.push({ - type: 'section', - text: { - type: 'mrkdwn', - text: `*Other Incomet*\n*Description:* ${data.secondary?.otherIncomeSourceDescription}\n*Monthly Amount:* ${data.secondary?.otherIncomeAmount}\n`, - }, - }) - } else if (key === 'vehicle') { - blocks.push({ - type: 'divider', - }) - blocks.push({ - type: 'section', - text: { - type: 'mrkdwn', - text: `*Vehicle of Interest*\n*Cash Down:* ${data?.vehicle?.cashDown}\n*VIN:* ${data.vehicle.vin}\n*Year:* ${data.vehicle.year}\n*Make:* ${data.vehicle.make}\n*Model:* ${data.vehicle.model}\n*Odometer:* ${data.vehicle.mileage}\n*Price:* ${data.vehicle.price}`, - }, - }) - } else if (data?.tradeIn && key === 'tradeIn') { - blocks.push({ - type: 'divider', - }) - blocks.push({ - type: 'section', - text: { - type: 'mrkdwn', - text: `*Trade Information*\n*Record Id:* ${data?.tradeIn?.id}\n*Lender:* ${data.tradeIn.lienholder}\n*Trade In Allowance:* ${data.tradeIn.tradeInAllowance}\n`, - }, - }) - } - } - - await fetch(url!, { - method: 'POST', - body: JSON.stringify({ blocks }), - headers: { 'Content-Type': 'application/json' }, - }) -} diff --git a/typings.d.ts b/typings.d.ts index c881e48..e365a7d 100644 --- a/typings.d.ts +++ b/typings.d.ts @@ -7,7 +7,7 @@ export interface VehicleOfInterest { vin: string cashDown: string } -export interface PrimaryApplicant { +export interface CreditApplicant { employedPrimary: string firstName: string middleName: string @@ -26,7 +26,6 @@ export interface PrimaryApplicant { rentMortgagePaymentAmount: string licenseNumber: string licenseState: string - licenseExp: string employerName: string employmentStatusCode: string employerPhone: string @@ -51,48 +50,3 @@ export interface PrimaryApplicant { otherIncomeAmount: string otherIncomeSourceDescription: string } - -export interface CoApplicant { - employedJoint: string - co_firstName: string - co_middleName: string - co_lastName: string - co_phone: string - co_phoneType: string - co_email: string - co_dateOfBirth: string - co_ssn: string - co_addressLine1: string - co_city: string - co_state: string - co_zipCode: string - co_addressYears: string - co_addressMonths: string - co_rentMortgagePaymentAmount: string - co_licenseNumber: string - co_licenseState: string - co_licenseExp: string - co_employerName: string - co_employmentStatusCode: string - co_employerPhone: string - co_employmentTitle: string - co_timeOnJobYears: string - co_timeOnJobMonths: string - co_monthlyIncome: string - co_previousEmployerName: string - co_prevEmployerPhone: string - co_prevEmploymentTitle: string - co_prevTimeOnJobYears: string - co_prevTimeOnJobMonths: string - co_prevIncomeAmount: string - co_prevAddressLine1: string - co_prevCity: string - co_prevState: string - co_prevZipCode: string - co_prevAddressYears: string - co_prevAddressMonths: string - co_prevRentMortgagePaymentAmount: string - co_otherIncomeSourceCode: string - co_otherIncomeAmount: string - co_otherIncomeSourceDescription: string -}