Additional drizzle cleanup. Move scrub transformation to server side.
This commit is contained in:
93
REFACTORING_NOTES.md
Normal file
93
REFACTORING_NOTES.md
Normal file
@@ -0,0 +1,93 @@
|
||||
# Refactoring Summary: Server-Side Transformation
|
||||
|
||||
## Overview
|
||||
Moved the job transformation logic from the Electron app to the Lambda function to enable server-side processing and sharing of types between codebases.
|
||||
|
||||
## Changes Made
|
||||
|
||||
### 1. Shared Types Directory (`/shared/types/`)
|
||||
Created a shared types directory that both the Electron app and serverless Lambda can use:
|
||||
|
||||
- **`raw-job-data.interface.ts`** - Defines the `RawJobDataObject` interface with all fields from the decoded job data
|
||||
- **`es-job-object.interface.ts`** - Defines the `ESJobObject` interface for the transformed estimate scrubber format
|
||||
- **`index.ts`** - Exports all shared types for easy importing
|
||||
|
||||
### 2. Serverless Changes
|
||||
|
||||
#### `serverless/src/lib/transformEstimate.ts`
|
||||
- Moved transformation logic from `src/main/estimate-scrubber/es-transformer.ts`
|
||||
- Exports `transformJobForEstimateScrubber()` function
|
||||
- Imports shared types from `../../../shared/types`
|
||||
- Handles all field omissions and transformations server-side
|
||||
|
||||
#### `serverless/src/handlers/scrub.ts`
|
||||
- Updated to receive `rawJob` instead of pre-transformed `estimate`
|
||||
- Calls `transformJobForEstimateScrubber()` to transform on the server
|
||||
- Sets `v_type` using the existing `getVehicleType()` function
|
||||
- Updated TypeScript interfaces to use shared types
|
||||
|
||||
#### `serverless/package.json`
|
||||
- Added `lodash` dependency
|
||||
- Added `@types/lodash` dev dependency
|
||||
|
||||
#### `serverless/tsconfig.json`
|
||||
- Updated `include` to add `"../shared/**/*"` for shared types access
|
||||
|
||||
### 3. Electron App Changes
|
||||
|
||||
#### `src/main/estimate-scrubber/estimate-scrubber.ts`
|
||||
- Removed call to `TransformJobForEstimateScrubber()`
|
||||
- Now sends raw job object directly to Lambda as `rawJob`
|
||||
- Removed import of `es-transformer`
|
||||
- Transformation now happens server-side
|
||||
|
||||
#### `tsconfig.node.json`
|
||||
- Updated `include` array to add `"shared/**/*"` for shared types access
|
||||
|
||||
### 4. Files That Can Be Deprecated (Optional)
|
||||
- `src/main/estimate-scrubber/es-transformer.ts` - Logic moved to serverless
|
||||
- `src/main/estimate-scrubber/es-job-object.interface.ts` - Moved to shared types
|
||||
|
||||
## Benefits
|
||||
|
||||
1. **Single Source of Truth**: Types are defined once in `/shared/types/` and used by both codebases
|
||||
2. **Server-Side Processing**: Transformation logic runs on Lambda, reducing client-side processing
|
||||
3. **Easier Maintenance**: Updates to transformation logic or types only need to be made in one place
|
||||
4. **Type Safety**: Both Electron app and Lambda use the same TypeScript interfaces
|
||||
5. **Reduced Bundle Size**: Electron app no longer includes transformation logic
|
||||
|
||||
## API Contract Changes
|
||||
|
||||
### Before
|
||||
```typescript
|
||||
POST /scrub
|
||||
{
|
||||
esApiKey: string,
|
||||
estimate: ESJobObject, // Pre-transformed
|
||||
fileName: string
|
||||
}
|
||||
```
|
||||
|
||||
### After
|
||||
```typescript
|
||||
POST /scrub
|
||||
{
|
||||
esApiKey: string,
|
||||
rawJob: RawJobDataObject // Raw, untransformed
|
||||
}
|
||||
```
|
||||
|
||||
## Migration Notes
|
||||
|
||||
- The Lambda function now handles all transformation logic
|
||||
- Ensure both codebases have access to the `/shared/types/` directory
|
||||
- Run `npm install` in the serverless directory to get new dependencies
|
||||
- The `fileName` parameter is now generated server-side based on the raw job data
|
||||
|
||||
## Testing Recommendations
|
||||
|
||||
1. Test that raw job objects are correctly sent from Electron to Lambda
|
||||
2. Verify transformation logic produces identical output to previous version
|
||||
3. Ensure PDF generation and report URLs are working correctly
|
||||
4. Check that error handling still works as expected
|
||||
5. Validate that logs are being written correctly with transformed data
|
||||
1972
serverless/package-lock.json
generated
1972
serverless/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -19,24 +19,25 @@
|
||||
"license": "ISC",
|
||||
"type": "commonjs",
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-s3": "^3.965.0",
|
||||
"@aws-sdk/client-secrets-manager": "^3.965.0",
|
||||
"@aws-sdk/s3-request-presigner": "^3.965.0",
|
||||
"@aws-sdk/client-s3": "^3.971.0",
|
||||
"@aws-sdk/client-secrets-manager": "^3.971.0",
|
||||
"@aws-sdk/s3-request-presigner": "^3.971.0",
|
||||
"axios": "^1.13.2",
|
||||
"drizzle-orm": "^0.44.5",
|
||||
"form-data": "^4.0.1"
|
||||
"form-data": "^4.0.5",
|
||||
"lodash": "^4.17.21"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^9.39.2",
|
||||
"@types/aws-lambda": "^8.10.159",
|
||||
"@types/node": "^25.0.8",
|
||||
"@typescript-eslint/eslint-plugin": "^8.53.0",
|
||||
"@typescript-eslint/parser": "^8.53.0",
|
||||
"@types/aws-lambda": "^8.10.160",
|
||||
"@types/lodash": "^4.17.23",
|
||||
"@types/node": "^25.0.9",
|
||||
"@typescript-eslint/eslint-plugin": "^8.53.1",
|
||||
"@typescript-eslint/parser": "^8.53.1",
|
||||
"esbuild": "^0.27.2",
|
||||
"eslint": "^9.39.2",
|
||||
"eslint-config-prettier": "^10.1.8",
|
||||
"eslint-plugin-prettier": "^5.5.4",
|
||||
"prettier": "^3.7.4",
|
||||
"eslint-plugin-prettier": "^5.5.5",
|
||||
"prettier": "^3.8.0",
|
||||
"serverless-esbuild": "^1.57.0",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.9.3"
|
||||
|
||||
@@ -2,43 +2,55 @@ service: esdp-api
|
||||
app: esdp-api-app
|
||||
frameworkVersion: '4'
|
||||
|
||||
# Common parameters shared across all stages
|
||||
custom:
|
||||
commonParams:
|
||||
es_user: Imex2
|
||||
es_password: Patrick
|
||||
hasura_secret_arn: arn:aws:secretsmanager:ca-central-1:714144183158:secret:esdp-hasura-credentials-s81i1u-BDFgPi
|
||||
|
||||
stages:
|
||||
prod:
|
||||
# Enables observability in the prod stage
|
||||
observability: true
|
||||
|
||||
# Stage-specific parameter values for prod
|
||||
# Sepcify parameter values to be used in the prod stage
|
||||
params:
|
||||
es_endpoint: https://insurtechtoolkit.com
|
||||
domain: es.imex.online
|
||||
es_user: Imex2
|
||||
es_password: Patrick
|
||||
beta:
|
||||
# Enables observability in the prod stage
|
||||
observability: false
|
||||
|
||||
# Stage-specific parameter values for beta
|
||||
# Sepcify parameter values to be used in the prod stage
|
||||
params:
|
||||
es_endpoint: https://4284-79073.el-alt.com
|
||||
domain: beta.es.imex.online
|
||||
es_user: Imex2
|
||||
es_password: Patrick
|
||||
alpha:
|
||||
# Enables observability in the prod stage
|
||||
observability: false
|
||||
|
||||
# Stage-specific parameter values for alpha
|
||||
# Sepcify parameter values to be used in the prod stage
|
||||
params:
|
||||
es_endpoint: https://4284-79287.el-alt.com
|
||||
domain: alpha.es.imex.online
|
||||
es_user: Imex2
|
||||
es_password: Patrick
|
||||
dev:
|
||||
# Enables observability in the prod stage
|
||||
observability: false
|
||||
|
||||
# Stage-specific parameter values for dev
|
||||
# Sepcify parameter values to be used in the prod stage
|
||||
params:
|
||||
es_endpoint: https://4284-79287.el-alt.com
|
||||
domain: dev.es.imex.online
|
||||
es_user: Imex2
|
||||
es_password: Patrick
|
||||
|
||||
# params:
|
||||
# dev:
|
||||
# domain: dev.es.imex.online
|
||||
# alpha:
|
||||
# domain: alpha.es.imex.online
|
||||
# beta:
|
||||
# domain: beta.es.imex.online
|
||||
# prod:
|
||||
# domain: es.imex.online
|
||||
|
||||
provider:
|
||||
name: aws
|
||||
@@ -69,8 +81,8 @@ functions:
|
||||
handler: src/handlers/scrub.handler
|
||||
environment:
|
||||
ES_ENDPOINT: ${param:es_endpoint}
|
||||
ES_USER: ${self:custom.commonParams.es_user}
|
||||
ES_PASSWORD: ${self:custom.commonParams.es_password}
|
||||
ES_USER: ${param:es_user}
|
||||
ES_PASSWORD: ${param:es_password}
|
||||
events:
|
||||
- httpApi:
|
||||
path: /scrub
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
import { AnyPgColumn, boolean, pgTable, text, timestamp, uuid, index } from 'drizzle-orm/pg-core';
|
||||
|
||||
export const shops = pgTable('shops', {
|
||||
id: uuid('id').defaultRandom().primaryKey(),
|
||||
createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
|
||||
esApiKey: text('es_api_key').notNull().unique(),
|
||||
active: boolean('active').notNull().default(true),
|
||||
});
|
||||
|
||||
export const jobs = pgTable(
|
||||
'jobs',
|
||||
{
|
||||
id: uuid('id').defaultRandom().primaryKey(),
|
||||
shopId: uuid('shopId')
|
||||
.references((): AnyPgColumn => shops.id)
|
||||
.notNull(),
|
||||
createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
|
||||
clm_no: text('clm_no'),
|
||||
ciecaid: text('ciecaid'),
|
||||
},
|
||||
(table) => [index('clm_no_idx').on(table.clm_no)]
|
||||
);
|
||||
|
||||
export const joblines = pgTable('joblines', {
|
||||
id: uuid('id').defaultRandom().primaryKey(),
|
||||
createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
|
||||
jobId: uuid('jobId')
|
||||
.references((): AnyPgColumn => jobs.id)
|
||||
.notNull(),
|
||||
line_desc: text('line_desc'),
|
||||
});
|
||||
@@ -1,22 +0,0 @@
|
||||
import { APIGatewayProxyResult } from 'aws-lambda';
|
||||
import { migrate } from 'drizzle-orm/node-postgres/migrator';
|
||||
|
||||
import { getDb } from '../lib/db';
|
||||
|
||||
export const handler = async (): Promise<APIGatewayProxyResult> => {
|
||||
try {
|
||||
const db = await getDb();
|
||||
await migrate(db, { migrationsFolder: 'drizzle' });
|
||||
|
||||
return {
|
||||
statusCode: 200,
|
||||
body: JSON.stringify({ success: true, message: 'Migrations applied.' }),
|
||||
};
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
||||
return {
|
||||
statusCode: 500,
|
||||
body: JSON.stringify({ success: false, error: errorMessage }),
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -1,94 +0,0 @@
|
||||
import { APIGatewayProxyResult } from 'aws-lambda';
|
||||
|
||||
import { sql } from 'drizzle-orm';
|
||||
|
||||
import { getDb } from '../lib/db';
|
||||
|
||||
export const handler = async (): Promise<APIGatewayProxyResult> => {
|
||||
try {
|
||||
const db = await getDb();
|
||||
const ping = await db.execute(sql`select 1 as ok`);
|
||||
|
||||
const schemaRows = await db.execute(sql`
|
||||
select
|
||||
table_schema,
|
||||
table_name,
|
||||
column_name,
|
||||
data_type,
|
||||
is_nullable,
|
||||
ordinal_position
|
||||
from information_schema.columns
|
||||
where table_schema not in ('pg_catalog', 'information_schema')
|
||||
order by table_schema, table_name, ordinal_position
|
||||
`);
|
||||
|
||||
type ColumnInfo = {
|
||||
name: string;
|
||||
type: string;
|
||||
nullable: boolean;
|
||||
position: number;
|
||||
};
|
||||
|
||||
type TableInfo = {
|
||||
schema: string;
|
||||
name: string;
|
||||
columns: ColumnInfo[];
|
||||
};
|
||||
|
||||
const tableMap = new Map<string, TableInfo>();
|
||||
const rows = (schemaRows as unknown as { rows?: unknown[] })?.rows ?? [];
|
||||
for (const row of rows as Array<Record<string, unknown>>) {
|
||||
const tableSchema = String(row.table_schema ?? '');
|
||||
const tableName = String(row.table_name ?? '');
|
||||
if (!tableSchema || !tableName) continue;
|
||||
|
||||
const key = `${tableSchema}.${tableName}`;
|
||||
const existing = tableMap.get(key);
|
||||
const tableInfo: TableInfo = existing ?? {
|
||||
schema: tableSchema,
|
||||
name: tableName,
|
||||
columns: [],
|
||||
};
|
||||
|
||||
tableInfo.columns.push({
|
||||
name: String(row.column_name ?? ''),
|
||||
type: String(row.data_type ?? ''),
|
||||
nullable: String(row.is_nullable ?? '') === 'YES',
|
||||
position: Number(row.ordinal_position ?? 0),
|
||||
});
|
||||
|
||||
if (!existing) tableMap.set(key, tableInfo);
|
||||
}
|
||||
|
||||
const tables = [...tableMap.values()];
|
||||
|
||||
return {
|
||||
statusCode: 200,
|
||||
body: JSON.stringify({ success: true, ping, schema: { tables } }),
|
||||
};
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
||||
const maybeAny = error as unknown as { cause?: unknown; code?: unknown };
|
||||
const causeMessage =
|
||||
maybeAny?.cause instanceof Error
|
||||
? maybeAny.cause.message
|
||||
: typeof maybeAny?.cause === 'string'
|
||||
? maybeAny.cause
|
||||
: undefined;
|
||||
const causeCode =
|
||||
typeof (maybeAny?.cause as { code?: unknown } | undefined)?.code === 'string'
|
||||
? (maybeAny.cause as { code?: string }).code
|
||||
: typeof maybeAny?.code === 'string'
|
||||
? maybeAny.code
|
||||
: undefined;
|
||||
return {
|
||||
statusCode: 500,
|
||||
body: JSON.stringify({
|
||||
success: false,
|
||||
error: errorMessage,
|
||||
cause: causeMessage,
|
||||
code: causeCode,
|
||||
}),
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -1,23 +1,18 @@
|
||||
import { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda';
|
||||
import axios, { AxiosError } from 'axios';
|
||||
import FormData from 'form-data';
|
||||
|
||||
import { ESJobObject, RawJobDataObject } from '../../../shared/types';
|
||||
import { transformJobForEstimateScrubber } from '../lib/transformEstimate';
|
||||
import { getVehicleType } from '../lib/vehicleTypes/vehicleType';
|
||||
|
||||
const ES_USER = process.env.ES_USER || '';
|
||||
const ES_PASSWORD = process.env.ES_PASSWORD || '';
|
||||
const ES_ENDPOINT = process.env.ES_ENDPOINT || '';
|
||||
|
||||
interface Estimate {
|
||||
v_type?: string;
|
||||
v_model: string;
|
||||
clm_no: string;
|
||||
sendingEntityId?: string;
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
interface ScrubRequest {
|
||||
esApiKey: string;
|
||||
estimate: Estimate;
|
||||
rawJob: RawJobDataObject;
|
||||
}
|
||||
|
||||
interface ScrubResponse {
|
||||
@@ -27,13 +22,16 @@ interface ScrubResponse {
|
||||
|
||||
export const handler = async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {
|
||||
try {
|
||||
const { esApiKey, estimate } = JSON.parse(event.body || '{}') as ScrubRequest;
|
||||
const { esApiKey, rawJob } = JSON.parse(event.body || '{}') as ScrubRequest;
|
||||
|
||||
// Transform the raw job object to ES format
|
||||
const estimate: ESJobObject = await transformJobForEstimateScrubber(rawJob);
|
||||
|
||||
// Set vehicle type and sending entity ID
|
||||
estimate.v_type = getVehicleType(estimate.v_model).type;
|
||||
estimate.sendingEntityId = '87330f61-412b-4251-baaa-d026565b23c5';
|
||||
estimate.v_type = getVehicleType(estimate.v_model || '').type;
|
||||
estimate.sending_entity_id = '87330f61-412b-4251-baaa-d026565b23c5';
|
||||
|
||||
const fileName = `${esApiKey}-${estimate.clm_no}-${Date.now()}`;
|
||||
const fileName = `${esApiKey}-${rawJob.clm_no}-${Date.now()}`;
|
||||
const formData = new FormData();
|
||||
const jsonString = JSON.stringify(estimate);
|
||||
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
import { SecretsManagerClient, GetSecretValueCommand } from '@aws-sdk/client-secrets-manager';
|
||||
import { drizzle, NodePgDatabase } from 'drizzle-orm/node-postgres';
|
||||
import { Pool } from 'pg';
|
||||
|
||||
import * as schema from '../db/schema';
|
||||
|
||||
type DbSecret = {
|
||||
username: string;
|
||||
password: string;
|
||||
};
|
||||
|
||||
let cachedSecret: DbSecret | undefined;
|
||||
let cachedPool: Pool | undefined;
|
||||
let cachedDb: NodePgDatabase<typeof schema> | undefined;
|
||||
|
||||
function requireEnv(name: string): string {
|
||||
const value = process.env[name];
|
||||
if (!value) {
|
||||
throw new Error(`Missing required env var: ${name}`);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
async function getDbSecret(): Promise<DbSecret> {
|
||||
if (cachedSecret) return cachedSecret;
|
||||
|
||||
const secretArn = requireEnv('DB_SECRET_ARN');
|
||||
const client = new SecretsManagerClient({});
|
||||
const result = await client.send(
|
||||
new GetSecretValueCommand({
|
||||
SecretId: secretArn,
|
||||
})
|
||||
);
|
||||
|
||||
if (!result.SecretString) {
|
||||
throw new Error('SecretString was empty for DB_SECRET_ARN');
|
||||
}
|
||||
|
||||
const parsed = JSON.parse(result.SecretString) as Partial<DbSecret>;
|
||||
if (!parsed.username || !parsed.password) {
|
||||
throw new Error('DB secret missing username/password');
|
||||
}
|
||||
|
||||
cachedSecret = { username: parsed.username, password: parsed.password };
|
||||
return cachedSecret;
|
||||
}
|
||||
|
||||
export async function getPool(): Promise<Pool> {
|
||||
if (cachedPool) return cachedPool;
|
||||
|
||||
const host = requireEnv('DB_HOST');
|
||||
const port = Number.parseInt(requireEnv('DB_PORT'), 10);
|
||||
const database = requireEnv('DB_NAME');
|
||||
const { username: user, password } = await getDbSecret();
|
||||
|
||||
cachedPool = new Pool({
|
||||
host,
|
||||
port,
|
||||
database,
|
||||
user,
|
||||
password,
|
||||
ssl: {
|
||||
rejectUnauthorized: true,
|
||||
},
|
||||
max: 5,
|
||||
idleTimeoutMillis: 30_000,
|
||||
connectionTimeoutMillis: 10_000,
|
||||
});
|
||||
|
||||
return cachedPool;
|
||||
}
|
||||
|
||||
export async function getDb(): Promise<NodePgDatabase<typeof schema>> {
|
||||
if (cachedDb) return cachedDb;
|
||||
const pool = await getPool();
|
||||
cachedDb = drizzle(pool, { schema });
|
||||
return cachedDb;
|
||||
}
|
||||
239
serverless/src/lib/transformEstimate.ts
Normal file
239
serverless/src/lib/transformEstimate.ts
Normal file
@@ -0,0 +1,239 @@
|
||||
import _ from 'lodash';
|
||||
import { RawJobDataObject, ESJobObject } from '../../../shared/types';
|
||||
|
||||
export async function transformJobForEstimateScrubber(job: RawJobDataObject): Promise<ESJobObject> {
|
||||
// Take the job object and strip off everything we don't need.
|
||||
const omittedJob = _.omit(job, [
|
||||
'cat_no',
|
||||
'ciecaid',
|
||||
'agt_co_id',
|
||||
'agt_co_nm',
|
||||
'agt_addr1',
|
||||
'agt_addr2',
|
||||
'agt_city',
|
||||
'agt_st',
|
||||
'agt_zip',
|
||||
'agt_ctry',
|
||||
'agt_ph1',
|
||||
'agt_ph1x',
|
||||
'agt_ph2',
|
||||
'agt_ph2x',
|
||||
'agt_fax',
|
||||
'agt_faxx',
|
||||
'agt_ct_ln',
|
||||
'agt_ct_fn',
|
||||
'agt_ct_ph',
|
||||
'agt_ct_phx',
|
||||
'agt_ea',
|
||||
'agt_lic_no',
|
||||
'adj_g_disc',
|
||||
'adj_strdis',
|
||||
'adj_towdis',
|
||||
'asgn_date',
|
||||
'asgn_no',
|
||||
'asgn_type',
|
||||
'clm_addr1',
|
||||
'clm_addr2',
|
||||
'clm_city',
|
||||
'clm_ct_fn',
|
||||
'clm_ct_ln',
|
||||
'clm_ct_ph',
|
||||
'clm_ct_phx',
|
||||
'clm_ctry',
|
||||
'clm_ea',
|
||||
'clm_fax',
|
||||
'clm_faxx',
|
||||
'clm_ofc_id',
|
||||
'clm_ofc_nm',
|
||||
'clm_ph1',
|
||||
'clm_ph1x',
|
||||
'clm_ph2',
|
||||
'clm_ph2x',
|
||||
'clm_st',
|
||||
'clm_title',
|
||||
'clm_zip',
|
||||
'cust_pr',
|
||||
'date_estimated',
|
||||
'ded_status',
|
||||
'depreciation_taxes',
|
||||
'est_addr1',
|
||||
'est_addr2',
|
||||
'est_city',
|
||||
'est_co_nm',
|
||||
'est_ct_fn',
|
||||
'est_ct_ln',
|
||||
'est_ctry',
|
||||
'est_ea',
|
||||
'est_ph1',
|
||||
'est_st',
|
||||
'est_zip',
|
||||
'federal_tax_rate',
|
||||
'ins_addr1',
|
||||
'ins_addr2',
|
||||
'ins_city',
|
||||
'ins_co_id',
|
||||
'ins_ct_fn',
|
||||
'ins_ct_ln',
|
||||
'ins_ct_ph',
|
||||
'ins_ct_phx',
|
||||
'ins_ctry',
|
||||
'ins_ea',
|
||||
'ins_fax',
|
||||
'ins_faxx',
|
||||
'ins_ph1',
|
||||
'ins_ph1x',
|
||||
'ins_ph2',
|
||||
'ins_ph2x',
|
||||
'ins_st',
|
||||
'ins_title',
|
||||
'ins_zip',
|
||||
'insd_fax',
|
||||
'insd_faxx',
|
||||
'kmin',
|
||||
'loss_cat',
|
||||
'loss_type',
|
||||
'ownr_addr2',
|
||||
'ownr_co_nm',
|
||||
'ownr_ctry',
|
||||
'ownr_ea',
|
||||
'ownr_ph2',
|
||||
'ownr_st',
|
||||
'ownr_title',
|
||||
'ownr_zip',
|
||||
'pay_amt',
|
||||
'pay_chknm',
|
||||
'pay_date',
|
||||
'pay_type',
|
||||
'payee_nms',
|
||||
'plate_no',
|
||||
'plate_st',
|
||||
'policy_no',
|
||||
'rate_la1',
|
||||
'rate_la2',
|
||||
'rate_la3',
|
||||
'rate_la4',
|
||||
'rate_laa',
|
||||
'rate_lab',
|
||||
'rate_lad',
|
||||
'rate_lae',
|
||||
'rate_laf',
|
||||
'rate_lag',
|
||||
'rate_lam',
|
||||
'rate_lar',
|
||||
'rate_las',
|
||||
'rate_lau',
|
||||
'rate_ma2s',
|
||||
'rate_ma2t',
|
||||
'rate_ma3s',
|
||||
'rate_mabl',
|
||||
'rate_macs',
|
||||
'rate_mahw',
|
||||
'rate_mapa',
|
||||
'rate_mash',
|
||||
'tax_lbr_rt',
|
||||
'tax_levies_rt',
|
||||
'tax_paint_mat_rt',
|
||||
'tax_predis',
|
||||
'tax_prethr',
|
||||
'tax_pstthr',
|
||||
'tax_shop_mat_rt',
|
||||
'tax_str_rt',
|
||||
'tax_sub_rt',
|
||||
'tax_thramt',
|
||||
'tax_tow_rt',
|
||||
'theft_ind',
|
||||
'v_color',
|
||||
'tlos_ind',
|
||||
'v_make_desc',
|
||||
'v_model_desc',
|
||||
'shopid',
|
||||
'est_system',
|
||||
// Object fields
|
||||
'owner',
|
||||
'vehicle',
|
||||
'bodyshop',
|
||||
'area_of_damage',
|
||||
'joblines',
|
||||
'clm_total',
|
||||
// CIECA Fields
|
||||
'cieca_pft',
|
||||
'cieca_pfl',
|
||||
'cieca_pfm',
|
||||
'cieca_pfo',
|
||||
'cieca_stl',
|
||||
'cieca_ttl',
|
||||
'parts_tax_rates',
|
||||
'materials',
|
||||
]);
|
||||
|
||||
// Apply the ES specific transformations needed.
|
||||
const rates = [
|
||||
...(job.cieca_pfm?.map((pfm) => ({
|
||||
cal_prethr: pfm.cal_prethr,
|
||||
mat_type: pfm.matl_type, // Rename required - presumed typo in ES API.
|
||||
})) || []),
|
||||
...(Object.keys(job.cieca_pfl || {}).map((key) =>
|
||||
_.pick(job.cieca_pfl![key], ['lbr_desc', 'lbr_rate', 'lbr_type'])
|
||||
) || []),
|
||||
];
|
||||
|
||||
const supp_amt = job.cieca_ttl?.data?.supp_amt || 0;
|
||||
const totals =
|
||||
job.cieca_stl?.data?.map((ttl) =>
|
||||
_.pick(ttl, ['nt_hrs', 't_amt', 't_hrs', 'ttl_typecd'])
|
||||
) || [];
|
||||
|
||||
const now = new Date().toISOString();
|
||||
|
||||
return {
|
||||
...omittedJob,
|
||||
impact_1: job.area_of_damage?.impact1,
|
||||
impact_2: job.area_of_damage?.impact2,
|
||||
close_date: null,
|
||||
created_at: now,
|
||||
id: '00000000-0000-0000-0000-000000000000', // Placeholder ID
|
||||
updated_at: now,
|
||||
v_age: -1, // Needed? RPS calc.
|
||||
v_type: 'TBD', // Will be set by caller
|
||||
v_makedesc: job.v_make_desc,
|
||||
v_model: job.v_model_desc,
|
||||
rates,
|
||||
supp_amt,
|
||||
totals,
|
||||
ro_number: null,
|
||||
requires_reimport: false,
|
||||
v_mileage: job.kmin?.toString() || '',
|
||||
sending_entity_id: '',
|
||||
sending_entity_accept_terms_of_use: true,
|
||||
association_switch: 'ATAM',
|
||||
rf_ph1: '2043792253',
|
||||
rf_zip: 'R0G 1Z0',
|
||||
g_ttl_amt: job.clm_total || 0,
|
||||
source_system: job.est_system || 'M',
|
||||
joblines:
|
||||
job.joblines?.data?.map((line) => ({
|
||||
..._.omit(line, [
|
||||
'lbr_tax',
|
||||
'lbr_typ_j',
|
||||
'line_ref',
|
||||
'misc_sublt',
|
||||
'misc_tax',
|
||||
'prt_dsmk_m',
|
||||
'prt_dsmk_p',
|
||||
'tran_code',
|
||||
'unq_seq',
|
||||
'alt_co_id',
|
||||
'alt_overrd',
|
||||
'alt_part_i',
|
||||
'alt_partm',
|
||||
'bett_type',
|
||||
'bett_pctg',
|
||||
'bett_amt',
|
||||
'bett_tax',
|
||||
'op_code_desc',
|
||||
'paint_stg',
|
||||
'paint_tone',
|
||||
]),
|
||||
})) || [],
|
||||
} as ESJobObject;
|
||||
}
|
||||
@@ -1,24 +1,24 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"module": "commonjs",
|
||||
"lib": ["ES2022"],
|
||||
"moduleResolution": "node",
|
||||
"rootDir": "./src",
|
||||
"outDir": "./dist",
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"resolveJsonModule": true,
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"sourceMap": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules", "dist", ".serverless"]
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"module": "commonjs",
|
||||
"lib": ["ES2022"],
|
||||
"moduleResolution": "node",
|
||||
"rootDir": "./src",
|
||||
"outDir": "./dist",
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"resolveJsonModule": true,
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"sourceMap": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
"include": ["src/**/*", "../shared/**/*"],
|
||||
"exclude": ["node_modules", "dist", ".serverless"]
|
||||
}
|
||||
|
||||
243
shared/types/es-job-object.interface.ts
Normal file
243
shared/types/es-job-object.interface.ts
Normal file
@@ -0,0 +1,243 @@
|
||||
import { JobLine, RawJobDataObject } from "./raw-job-data.interface";
|
||||
|
||||
// ES Job Object with transformed fields
|
||||
export interface ESJobObject extends Omit<
|
||||
RawJobDataObject,
|
||||
// Agent fields
|
||||
| "cat_no"
|
||||
| "ciecaid"
|
||||
| "agt_co_id"
|
||||
| "agt_co_nm"
|
||||
| "agt_addr1"
|
||||
| "agt_addr2"
|
||||
| "agt_city"
|
||||
| "agt_st"
|
||||
| "agt_zip"
|
||||
| "agt_ctry"
|
||||
| "agt_ph1"
|
||||
| "agt_ph1x"
|
||||
| "agt_ph2"
|
||||
| "agt_ph2x"
|
||||
| "agt_fax"
|
||||
| "agt_faxx"
|
||||
| "agt_ct_ln"
|
||||
| "agt_ct_fn"
|
||||
| "agt_ct_ph"
|
||||
| "agt_ct_phx"
|
||||
| "agt_ea"
|
||||
| "agt_lic_no"
|
||||
// Adjustment fields
|
||||
| "adj_g_disc"
|
||||
| "adj_strdis"
|
||||
| "adj_towdis"
|
||||
// Assignment fields
|
||||
| "asgn_date"
|
||||
| "asgn_no"
|
||||
| "asgn_type"
|
||||
// Claim fields
|
||||
| "clm_addr1"
|
||||
| "clm_addr2"
|
||||
| "clm_city"
|
||||
| "clm_ct_fn"
|
||||
| "clm_ct_ln"
|
||||
| "clm_ct_ph"
|
||||
| "clm_ct_phx"
|
||||
| "clm_ctry"
|
||||
| "clm_ea"
|
||||
| "clm_fax"
|
||||
| "clm_faxx"
|
||||
| "clm_ofc_id"
|
||||
| "clm_ofc_nm"
|
||||
| "clm_ph1"
|
||||
| "clm_ph1x"
|
||||
| "clm_ph2"
|
||||
| "clm_ph2x"
|
||||
| "clm_st"
|
||||
| "clm_title"
|
||||
| "clm_zip"
|
||||
| "clm_total"
|
||||
// Misc fields
|
||||
| "cust_pr"
|
||||
| "date_estimated"
|
||||
| "ded_status"
|
||||
| "depreciation_taxes"
|
||||
// Estimator fields
|
||||
| "est_addr1"
|
||||
| "est_addr2"
|
||||
| "est_city"
|
||||
| "est_co_nm"
|
||||
| "est_ct_fn"
|
||||
| "est_ct_ln"
|
||||
| "est_ctry"
|
||||
| "est_ea"
|
||||
| "est_ph1"
|
||||
| "est_st"
|
||||
| "est_zip"
|
||||
| "federal_tax_rate"
|
||||
// Insurance fields
|
||||
| "ins_addr1"
|
||||
| "ins_addr2"
|
||||
| "ins_city"
|
||||
| "ins_co_id"
|
||||
| "ins_ct_fn"
|
||||
| "ins_ct_ln"
|
||||
| "ins_ct_ph"
|
||||
| "ins_ct_phx"
|
||||
| "ins_ctry"
|
||||
| "ins_ea"
|
||||
| "ins_fax"
|
||||
| "ins_faxx"
|
||||
| "ins_ph1"
|
||||
| "ins_ph1x"
|
||||
| "ins_ph2"
|
||||
| "ins_ph2x"
|
||||
| "ins_st"
|
||||
| "ins_title"
|
||||
| "ins_zip"
|
||||
| "insd_fax"
|
||||
| "insd_faxx"
|
||||
// Loss fields
|
||||
| "kmin"
|
||||
| "loss_cat"
|
||||
| "loss_type"
|
||||
// Owner fields
|
||||
| "ownr_addr2"
|
||||
| "ownr_co_nm"
|
||||
| "ownr_ctry"
|
||||
| "ownr_ea"
|
||||
| "ownr_ph2"
|
||||
| "ownr_st"
|
||||
| "ownr_title"
|
||||
| "ownr_zip"
|
||||
// Payment fields
|
||||
| "pay_amt"
|
||||
| "pay_chknm"
|
||||
| "pay_date"
|
||||
| "pay_type"
|
||||
| "payee_nms"
|
||||
// Vehicle fields
|
||||
| "plate_no"
|
||||
| "plate_st"
|
||||
| "policy_no"
|
||||
// Rate fields
|
||||
| "rate_la1"
|
||||
| "rate_la2"
|
||||
| "rate_la3"
|
||||
| "rate_la4"
|
||||
| "rate_laa"
|
||||
| "rate_lab"
|
||||
| "rate_lad"
|
||||
| "rate_lae"
|
||||
| "rate_laf"
|
||||
| "rate_lag"
|
||||
| "rate_lam"
|
||||
| "rate_lar"
|
||||
| "rate_las"
|
||||
| "rate_lau"
|
||||
| "rate_ma2s"
|
||||
| "rate_ma2t"
|
||||
| "rate_ma3s"
|
||||
| "rate_mabl"
|
||||
| "rate_macs"
|
||||
| "rate_mahw"
|
||||
| "rate_mapa"
|
||||
| "rate_mash"
|
||||
// Tax fields
|
||||
| "tax_lbr_rt"
|
||||
| "tax_levies_rt"
|
||||
| "tax_paint_mat_rt"
|
||||
| "tax_predis"
|
||||
| "tax_prethr"
|
||||
| "tax_pstthr"
|
||||
| "tax_shop_mat_rt"
|
||||
| "tax_str_rt"
|
||||
| "tax_sub_rt"
|
||||
| "tax_thramt"
|
||||
| "tax_tow_rt"
|
||||
// Additional vehicle fields
|
||||
| "theft_ind"
|
||||
| "v_color"
|
||||
| "tlos_ind"
|
||||
| "v_make_desc"
|
||||
| "v_model_desc"
|
||||
| "shopid"
|
||||
| "est_system"
|
||||
// Object fields
|
||||
| "owner"
|
||||
| "vehicle"
|
||||
| "bodyshop"
|
||||
| "area_of_damage"
|
||||
| "joblines"
|
||||
// CIECA fields
|
||||
| "cieca_pft"
|
||||
| "cieca_pfl"
|
||||
| "cieca_pfm"
|
||||
| "cieca_pfo"
|
||||
| "cieca_stl"
|
||||
| "cieca_ttl"
|
||||
| "parts_tax_rates"
|
||||
| "materials"
|
||||
> {
|
||||
// Fields added by the transformer
|
||||
impact_1?: string;
|
||||
impact_2?: string;
|
||||
close_date: string | null;
|
||||
created_at: string;
|
||||
id: string;
|
||||
group?: string;
|
||||
group_verified?: boolean;
|
||||
updated_at: string;
|
||||
v_age: number;
|
||||
v_type: string;
|
||||
v_makedesc?: string;
|
||||
v_model?: string;
|
||||
supp_amt: number;
|
||||
ro_number: string | null;
|
||||
requires_reimport: boolean;
|
||||
v_mileage: string;
|
||||
id_pro_nam?: string;
|
||||
g_ttl_amt: number;
|
||||
source_system: string;
|
||||
rf_ph1: string;
|
||||
rf_zip: string;
|
||||
association_switch: string;
|
||||
sending_entity_id: string;
|
||||
sending_entity_accept_terms_of_use: boolean;
|
||||
|
||||
// Transformed arrays
|
||||
joblines: Omit<
|
||||
JobLine,
|
||||
| "lbr_tax"
|
||||
| "lbr_typ_j"
|
||||
| "line_ref"
|
||||
| "misc_sublt"
|
||||
| "misc_tax"
|
||||
| "prt_dsmk_m"
|
||||
| "prt_dsmk_p"
|
||||
| "tran_code"
|
||||
| "unq_seq"
|
||||
| "alt_co_id"
|
||||
| "alt_overrd"
|
||||
| "alt_part_i"
|
||||
| "alt_partm"
|
||||
| "bett_type"
|
||||
| "bett_pctg"
|
||||
| "bett_amt"
|
||||
| "bett_tax"
|
||||
| "op_code_desc"
|
||||
| "paint_stg"
|
||||
| "paint_tone"
|
||||
>[];
|
||||
|
||||
totals: Array<{
|
||||
nt_hrs?: number;
|
||||
t_amt?: number;
|
||||
t_hrs?: number;
|
||||
ttl_typecd?: string;
|
||||
}>;
|
||||
|
||||
rates: Array<
|
||||
| { cal_prethr?: number; mat_type?: string }
|
||||
| { lbr_desc?: string; lbr_rate?: number; lbr_type?: string }
|
||||
>;
|
||||
}
|
||||
2
shared/types/index.ts
Normal file
2
shared/types/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from "./raw-job-data.interface";
|
||||
export * from "./es-job-object.interface";
|
||||
312
shared/types/raw-job-data.interface.ts
Normal file
312
shared/types/raw-job-data.interface.ts
Normal file
@@ -0,0 +1,312 @@
|
||||
import { UUID } from "crypto";
|
||||
|
||||
// Re-export interfaces needed for RawJobDataObject
|
||||
// Note: The decoder interfaces would need to be moved to shared as well
|
||||
// or we define the minimal structure here
|
||||
|
||||
export interface RawJobDataObject {
|
||||
// From DecodedEnv
|
||||
insp_date?: string;
|
||||
loss_date?: string;
|
||||
rf_city?: string;
|
||||
rf_zip?: string;
|
||||
rf_st?: string;
|
||||
rf_ln?: string;
|
||||
rf_fn?: string;
|
||||
rf_ph1?: string;
|
||||
rf_ph2?: string;
|
||||
rf_addr1?: string;
|
||||
rf_ctry?: string;
|
||||
ins_co_nm?: string;
|
||||
clm_no?: string;
|
||||
est_system?: string;
|
||||
|
||||
// From other decoders
|
||||
cat_no?: string;
|
||||
ciecaid?: string;
|
||||
agt_co_id?: string;
|
||||
agt_co_nm?: string;
|
||||
agt_addr1?: string;
|
||||
agt_addr2?: string;
|
||||
agt_city?: string;
|
||||
agt_st?: string;
|
||||
agt_zip?: string;
|
||||
agt_ctry?: string;
|
||||
agt_ph1?: string;
|
||||
agt_ph1x?: string;
|
||||
agt_ph2?: string;
|
||||
agt_ph2x?: string;
|
||||
agt_fax?: string;
|
||||
agt_faxx?: string;
|
||||
agt_ct_ln?: string;
|
||||
agt_ct_fn?: string;
|
||||
agt_ct_ph?: string;
|
||||
agt_ct_phx?: string;
|
||||
agt_ea?: string;
|
||||
agt_lic_no?: string;
|
||||
adj_g_disc?: number;
|
||||
adj_strdis?: number;
|
||||
adj_towdis?: number;
|
||||
asgn_date?: string;
|
||||
asgn_no?: string;
|
||||
asgn_type?: string;
|
||||
clm_addr1?: string;
|
||||
clm_addr2?: string;
|
||||
clm_city?: string;
|
||||
clm_ct_fn?: string;
|
||||
clm_ct_ln?: string;
|
||||
clm_ct_ph?: string;
|
||||
clm_ct_phx?: string;
|
||||
clm_ctry?: string;
|
||||
clm_ea?: string;
|
||||
clm_fax?: string;
|
||||
clm_faxx?: string;
|
||||
clm_ofc_id?: string;
|
||||
clm_ofc_nm?: string;
|
||||
clm_ph1?: string;
|
||||
clm_ph1x?: string;
|
||||
clm_ph2?: string;
|
||||
clm_ph2x?: string;
|
||||
clm_st?: string;
|
||||
clm_title?: string;
|
||||
clm_zip?: string;
|
||||
cust_pr?: string;
|
||||
date_estimated?: string;
|
||||
ded_status?: string;
|
||||
depreciation_taxes?: number;
|
||||
est_addr1?: string;
|
||||
est_addr2?: string;
|
||||
est_city?: string;
|
||||
est_co_nm?: string;
|
||||
est_ct_fn?: string;
|
||||
est_ct_ln?: string;
|
||||
est_ctry?: string;
|
||||
est_ea?: string;
|
||||
est_ph1?: string;
|
||||
est_st?: string;
|
||||
est_zip?: string;
|
||||
federal_tax_rate?: number;
|
||||
ins_addr1?: string;
|
||||
ins_addr2?: string;
|
||||
ins_city?: string;
|
||||
ins_co_id?: string;
|
||||
ins_ct_fn?: string;
|
||||
ins_ct_ln?: string;
|
||||
ins_ct_ph?: string;
|
||||
ins_ct_phx?: string;
|
||||
ins_ctry?: string;
|
||||
ins_ea?: string;
|
||||
ins_fax?: string;
|
||||
ins_faxx?: string;
|
||||
ins_ph1?: string;
|
||||
ins_ph1x?: string;
|
||||
ins_ph2?: string;
|
||||
ins_ph2x?: string;
|
||||
ins_st?: string;
|
||||
ins_title?: string;
|
||||
ins_zip?: string;
|
||||
insd_fax?: string;
|
||||
insd_faxx?: string;
|
||||
kmin?: number;
|
||||
loss_cat?: string;
|
||||
loss_type?: string;
|
||||
ownr_addr1?: string;
|
||||
ownr_addr2?: string;
|
||||
ownr_co_nm?: string;
|
||||
ownr_ctry?: string;
|
||||
ownr_ea?: string;
|
||||
ownr_ph1?: string;
|
||||
ownr_ph2?: string;
|
||||
ownr_st?: string;
|
||||
ownr_title?: string;
|
||||
ownr_zip?: string;
|
||||
ownr_ln?: string;
|
||||
ownr_fn?: string;
|
||||
ownr_city?: string;
|
||||
pay_amt?: number;
|
||||
pay_chknm?: string;
|
||||
pay_date?: string;
|
||||
pay_type?: string;
|
||||
payee_nms?: string;
|
||||
plate_no?: string;
|
||||
plate_st?: string;
|
||||
policy_no?: string;
|
||||
rate_la1?: number;
|
||||
rate_la2?: number;
|
||||
rate_la3?: number;
|
||||
rate_la4?: number;
|
||||
rate_laa?: number;
|
||||
rate_lab?: number;
|
||||
rate_lad?: number;
|
||||
rate_lae?: number;
|
||||
rate_laf?: number;
|
||||
rate_lag?: number;
|
||||
rate_lam?: number;
|
||||
rate_lar?: number;
|
||||
rate_las?: number;
|
||||
rate_lau?: number;
|
||||
rate_ma2s?: number;
|
||||
rate_ma2t?: number;
|
||||
rate_ma3s?: number;
|
||||
rate_mabl?: number;
|
||||
rate_macs?: number;
|
||||
rate_mahw?: number;
|
||||
rate_mapa?: number;
|
||||
rate_mash?: number;
|
||||
tax_lbr_rt?: number;
|
||||
tax_levies_rt?: number;
|
||||
tax_paint_mat_rt?: number;
|
||||
tax_predis?: number;
|
||||
tax_prethr?: number;
|
||||
tax_pstthr?: number;
|
||||
tax_shop_mat_rt?: number;
|
||||
tax_str_rt?: number;
|
||||
tax_sub_rt?: number;
|
||||
tax_thramt?: number;
|
||||
tax_tow_rt?: number;
|
||||
theft_ind?: boolean;
|
||||
v_color?: string;
|
||||
tlos_ind?: boolean;
|
||||
v_make_desc?: string;
|
||||
v_model_desc?: string;
|
||||
v_year?: string;
|
||||
|
||||
// Claimant fields
|
||||
clmt_ln?: string;
|
||||
clmt_fn?: string;
|
||||
clmt_title?: string;
|
||||
clmt_co_nm?: string;
|
||||
clmt_addr1?: string;
|
||||
clmt_addr2?: string;
|
||||
clmt_city?: string;
|
||||
clmt_st?: string;
|
||||
clmt_zip?: string;
|
||||
clmt_ctry?: string;
|
||||
clmt_ph1?: string;
|
||||
clmt_ph2?: string;
|
||||
clmt_ea?: string;
|
||||
|
||||
// Insured fields
|
||||
insd_ln?: string;
|
||||
insd_fn?: string;
|
||||
insd_title?: string;
|
||||
insd_co_nm?: string;
|
||||
insd_addr1?: string;
|
||||
insd_addr2?: string;
|
||||
insd_city?: string;
|
||||
insd_st?: string;
|
||||
insd_zip?: string;
|
||||
insd_ctry?: string;
|
||||
insd_ph1?: string;
|
||||
insd_ph2?: string;
|
||||
insd_ea?: string;
|
||||
|
||||
// Object fields
|
||||
owner?: {
|
||||
data?: Record<string, unknown>;
|
||||
};
|
||||
vehicle?: Record<string, unknown>;
|
||||
bodyshop?: Record<string, unknown>;
|
||||
area_of_damage?: {
|
||||
impact1?: string;
|
||||
impact2?: string;
|
||||
};
|
||||
joblines?: {
|
||||
data?: JobLine[];
|
||||
};
|
||||
clm_total?: number;
|
||||
|
||||
// CIECA fields
|
||||
cieca_pft?: CiecaPft;
|
||||
cieca_pfl?: Record<string, CiecaPfl>;
|
||||
cieca_pfm?: CiecaPfm[];
|
||||
cieca_pfo?: CiecaPfo;
|
||||
cieca_stl?: CiecaStl;
|
||||
cieca_ttl?: CiecaTtl;
|
||||
parts_tax_rates?: Record<string, unknown>;
|
||||
materials?: Record<string, unknown>;
|
||||
|
||||
vehicleid?: UUID;
|
||||
shopid?: UUID;
|
||||
}
|
||||
|
||||
export interface JobLine {
|
||||
line_no?: string;
|
||||
line_ind?: string;
|
||||
line_ref?: string;
|
||||
tran_code?: string;
|
||||
db_ref?: string;
|
||||
unq_seq?: string;
|
||||
line_desc?: string;
|
||||
part_type?: string;
|
||||
glass_flag?: boolean;
|
||||
oem_partno?: string;
|
||||
price_inc?: boolean;
|
||||
alt_part_i?: boolean;
|
||||
tax_part?: boolean;
|
||||
db_price?: number;
|
||||
act_price?: number;
|
||||
price_j?: boolean;
|
||||
cert_part?: boolean;
|
||||
part_qty?: number;
|
||||
alt_co_id?: string;
|
||||
alt_partno?: string;
|
||||
alt_overrd?: boolean;
|
||||
alt_partm?: string;
|
||||
prt_dsmk_p?: string;
|
||||
prt_dsmk_m?: string;
|
||||
mod_lbr_ty?: string;
|
||||
db_hrs?: number;
|
||||
mod_lb_hrs?: number;
|
||||
lbr_inc?: boolean;
|
||||
lbr_op?: string;
|
||||
lbr_hrs_j?: boolean;
|
||||
lbr_typ_j?: boolean;
|
||||
lbr_op_j?: boolean;
|
||||
paint_stg?: string;
|
||||
paint_tone?: string;
|
||||
lbr_tax?: boolean;
|
||||
lbr_amt?: number;
|
||||
misc_amt?: number;
|
||||
misc_sublt?: string;
|
||||
misc_tax?: boolean;
|
||||
bett_type?: string;
|
||||
bett_pctg?: string | number;
|
||||
bett_amt?: number;
|
||||
bett_tax?: boolean;
|
||||
op_code_desc?: string;
|
||||
}
|
||||
|
||||
export interface CiecaPft {
|
||||
data?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export interface CiecaPfl {
|
||||
lbr_desc?: string;
|
||||
lbr_rate?: number;
|
||||
lbr_type?: string;
|
||||
}
|
||||
|
||||
export interface CiecaPfm {
|
||||
cal_prethr?: number;
|
||||
matl_type?: string;
|
||||
}
|
||||
|
||||
export interface CiecaPfo {
|
||||
data?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export interface CiecaStl {
|
||||
data?: Array<{
|
||||
nt_hrs?: number;
|
||||
t_amt?: number;
|
||||
t_hrs?: number;
|
||||
ttl_typecd?: string;
|
||||
}>;
|
||||
}
|
||||
|
||||
export interface CiecaTtl {
|
||||
data?: {
|
||||
supp_amt?: number;
|
||||
};
|
||||
}
|
||||
@@ -6,7 +6,6 @@ import { promises as fsPromises } from "fs";
|
||||
import path from "path";
|
||||
import { RawJobDataObject } from "../decoder/decoder";
|
||||
import store from "../store/store";
|
||||
import TransformJobForEstimateScrubber from "./es-transformer";
|
||||
|
||||
// Function to write job object to logs subfolder
|
||||
async function writeJobToLogsFolder(job, fileName): Promise<string> {
|
||||
@@ -37,13 +36,13 @@ async function writeJobToLogsFolder(job, fileName): Promise<string> {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async function ScrubEstimate({
|
||||
job,
|
||||
}: {
|
||||
job: RawJobDataObject;
|
||||
}): Promise<string | undefined> {
|
||||
const transformedJob = await TransformJobForEstimateScrubber(job); //Job should be transformed server side.
|
||||
|
||||
// No transformation here - send raw job to Lambda
|
||||
const currentChannel = autoUpdater.channel;
|
||||
let estimateScrubberUrl: string;
|
||||
switch (currentChannel) {
|
||||
@@ -67,29 +66,30 @@ async function ScrubEstimate({
|
||||
|
||||
try {
|
||||
const esApiKey = store.get("settings.esApiKey") as string;
|
||||
//Perform data manipulation on the job object
|
||||
if (!transformedJob) {
|
||||
|
||||
if (!job) {
|
||||
console.error("No job provided to ScrubEstimate");
|
||||
return;
|
||||
}
|
||||
|
||||
const fileName = `${esApiKey}-${transformedJob.clm_no}-${Date.now()}`;
|
||||
const fileName = `${esApiKey}-${job.clm_no}-${Date.now()}`;
|
||||
|
||||
// Write job object to logs subfolder
|
||||
try {
|
||||
await writeJobToLogsFolder(transformedJob, fileName);
|
||||
await writeJobToLogsFolder(job, fileName);
|
||||
} catch (error) {
|
||||
log.error("Failed to write job to logs folder:", error);
|
||||
// Continue with the rest of the function even if this fails
|
||||
}
|
||||
|
||||
// Send raw job to Lambda - transformation happens server-side
|
||||
const result = await axios.post(estimateScrubberUrl, {
|
||||
esApiKey,
|
||||
estimate: transformedJob,
|
||||
fileName,
|
||||
rawJob: job, // Changed from 'estimate' to 'rawJob'
|
||||
});
|
||||
|
||||
const { resultPDFUrl, reportIssueUrl } = result?.data ?? {};
|
||||
const { resultPDFUrl, reportIssueUrl, identified_item } =
|
||||
result?.data ?? {};
|
||||
|
||||
// log.log("Estimate Scrubber Result:", result.data, resultPDFUrl);
|
||||
// const b = BrowserWindow.getAllWindows()[0];
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
"src/util/**/*",
|
||||
"src/interfaces/**/*",
|
||||
"tests/index.spec.ts",
|
||||
"/resources/**/*"
|
||||
"/resources/**/*",
|
||||
"shared/**/*"
|
||||
],
|
||||
"compilerOptions": {
|
||||
"resolveJsonModule": true,
|
||||
|
||||
Reference in New Issue
Block a user