Remove serverless, add graphql relationships.
This commit is contained in:
@@ -1,3 +1,14 @@
|
||||
table:
|
||||
name: joblines
|
||||
schema: public
|
||||
object_relationships:
|
||||
- name: job
|
||||
using:
|
||||
manual_configuration:
|
||||
column_mapping:
|
||||
jobid: id
|
||||
version: version
|
||||
insertion_order: null
|
||||
remote_table:
|
||||
name: jobs
|
||||
schema: public
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
table:
|
||||
name: jobs
|
||||
schema: public
|
||||
object_relationships:
|
||||
- name: shop
|
||||
using:
|
||||
foreign_key_constraint_on: shopid
|
||||
array_relationships:
|
||||
- name: joblines
|
||||
using:
|
||||
manual_configuration:
|
||||
column_mapping:
|
||||
id: jobid
|
||||
version: version
|
||||
insertion_order: null
|
||||
remote_table:
|
||||
name: joblines
|
||||
schema: public
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
table:
|
||||
name: shops
|
||||
schema: public
|
||||
array_relationships:
|
||||
- name: jobs
|
||||
using:
|
||||
foreign_key_constraint_on:
|
||||
column: shopid
|
||||
table:
|
||||
name: jobs
|
||||
schema: public
|
||||
|
||||
32
serverless/package-lock.json
generated
32
serverless/package-lock.json
generated
@@ -14,6 +14,8 @@
|
||||
"@aws-sdk/s3-request-presigner": "^3.971.0",
|
||||
"axios": "^1.13.2",
|
||||
"form-data": "^4.0.5",
|
||||
"graphql": "^16.12.0",
|
||||
"graphql-request": "^7.4.0",
|
||||
"lodash": "^4.17.21"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -1720,6 +1722,15 @@
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@graphql-typed-document-node/core": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.2.0.tgz",
|
||||
"integrity": "sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@humanfs/core": {
|
||||
"version": "0.19.1",
|
||||
"resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
|
||||
@@ -4761,6 +4772,27 @@
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/graphql": {
|
||||
"version": "16.12.0",
|
||||
"resolved": "https://registry.npmjs.org/graphql/-/graphql-16.12.0.tgz",
|
||||
"integrity": "sha512-DKKrynuQRne0PNpEbzuEdHlYOMksHSUI8Zc9Unei5gTsMNA2/vMpoMz/yKba50pejK56qj98qM0SjYxAKi13gQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/graphql-request": {
|
||||
"version": "7.4.0",
|
||||
"resolved": "https://registry.npmjs.org/graphql-request/-/graphql-request-7.4.0.tgz",
|
||||
"integrity": "sha512-xfr+zFb/QYbs4l4ty0dltqiXIp07U6sl+tOKAb0t50/EnQek6CVVBLjETXi+FghElytvgaAWtIOt3EV7zLzIAQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@graphql-typed-document-node/core": "^3.2.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"graphql": "14 - 16"
|
||||
}
|
||||
},
|
||||
"node_modules/has-flag": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
"@aws-sdk/s3-request-presigner": "^3.971.0",
|
||||
"axios": "^1.13.2",
|
||||
"form-data": "^4.0.5",
|
||||
"graphql": "^16.12.0",
|
||||
"graphql-request": "^7.4.0",
|
||||
"lodash": "^4.17.21"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -1,397 +0,0 @@
|
||||
service: esdp-infra
|
||||
app: esdp-api-app
|
||||
frameworkVersion: '4'
|
||||
|
||||
stages:
|
||||
shared:
|
||||
observability: false
|
||||
params:
|
||||
# Single shared database name for all app stages (dev/alpha/beta/prod)
|
||||
db_name: esdp
|
||||
# Your public IP in CIDR form for direct DB access (lock this down).
|
||||
admin_cidr: 70.36.57.88/32
|
||||
|
||||
provider:
|
||||
name: aws
|
||||
runtime: nodejs22.x
|
||||
region: ca-central-1
|
||||
|
||||
resources:
|
||||
Resources:
|
||||
EsdpVpc:
|
||||
Type: AWS::EC2::VPC
|
||||
Properties:
|
||||
CidrBlock: 10.0.0.0/16
|
||||
EnableDnsSupport: true
|
||||
EnableDnsHostnames: true
|
||||
Tags:
|
||||
- Key: Name
|
||||
Value: ${self:service}-${sls:stage}-vpc
|
||||
|
||||
InternetGateway:
|
||||
Type: AWS::EC2::InternetGateway
|
||||
Properties:
|
||||
Tags:
|
||||
- Key: Name
|
||||
Value: ${self:service}-${sls:stage}-igw
|
||||
|
||||
VpcGatewayAttachment:
|
||||
Type: AWS::EC2::VPCGatewayAttachment
|
||||
Properties:
|
||||
VpcId:
|
||||
Ref: EsdpVpc
|
||||
InternetGatewayId:
|
||||
Ref: InternetGateway
|
||||
|
||||
PublicSubnetA:
|
||||
Type: AWS::EC2::Subnet
|
||||
Properties:
|
||||
VpcId:
|
||||
Ref: EsdpVpc
|
||||
AvailabilityZone:
|
||||
Fn::Select:
|
||||
- 0
|
||||
- Fn::GetAZs: ''
|
||||
CidrBlock: 10.0.0.0/24
|
||||
MapPublicIpOnLaunch: true
|
||||
Tags:
|
||||
- Key: Name
|
||||
Value: ${self:service}-${sls:stage}-public-a
|
||||
|
||||
PublicSubnetB:
|
||||
Type: AWS::EC2::Subnet
|
||||
Properties:
|
||||
VpcId:
|
||||
Ref: EsdpVpc
|
||||
AvailabilityZone:
|
||||
Fn::Select:
|
||||
- 1
|
||||
- Fn::GetAZs: ''
|
||||
CidrBlock: 10.0.1.0/24
|
||||
MapPublicIpOnLaunch: true
|
||||
Tags:
|
||||
- Key: Name
|
||||
Value: ${self:service}-${sls:stage}-public-b
|
||||
|
||||
PrivateSubnetA:
|
||||
Type: AWS::EC2::Subnet
|
||||
Properties:
|
||||
VpcId:
|
||||
Ref: EsdpVpc
|
||||
AvailabilityZone:
|
||||
Fn::Select:
|
||||
- 0
|
||||
- Fn::GetAZs: ''
|
||||
CidrBlock: 10.0.10.0/24
|
||||
MapPublicIpOnLaunch: false
|
||||
Tags:
|
||||
- Key: Name
|
||||
Value: ${self:service}-${sls:stage}-private-a
|
||||
|
||||
PrivateSubnetB:
|
||||
Type: AWS::EC2::Subnet
|
||||
Properties:
|
||||
VpcId:
|
||||
Ref: EsdpVpc
|
||||
AvailabilityZone:
|
||||
Fn::Select:
|
||||
- 1
|
||||
- Fn::GetAZs: ''
|
||||
CidrBlock: 10.0.11.0/24
|
||||
MapPublicIpOnLaunch: false
|
||||
Tags:
|
||||
- Key: Name
|
||||
Value: ${self:service}-${sls:stage}-private-b
|
||||
|
||||
PublicRouteTable:
|
||||
Type: AWS::EC2::RouteTable
|
||||
Properties:
|
||||
VpcId:
|
||||
Ref: EsdpVpc
|
||||
Tags:
|
||||
- Key: Name
|
||||
Value: ${self:service}-${sls:stage}-public-rt
|
||||
|
||||
PublicRoute:
|
||||
Type: AWS::EC2::Route
|
||||
DependsOn: VpcGatewayAttachment
|
||||
Properties:
|
||||
RouteTableId:
|
||||
Ref: PublicRouteTable
|
||||
DestinationCidrBlock: 0.0.0.0/0
|
||||
GatewayId:
|
||||
Ref: InternetGateway
|
||||
|
||||
PublicSubnetARouteTableAssociation:
|
||||
Type: AWS::EC2::SubnetRouteTableAssociation
|
||||
Properties:
|
||||
SubnetId:
|
||||
Ref: PublicSubnetA
|
||||
RouteTableId:
|
||||
Ref: PublicRouteTable
|
||||
|
||||
PublicSubnetBRouteTableAssociation:
|
||||
Type: AWS::EC2::SubnetRouteTableAssociation
|
||||
Properties:
|
||||
SubnetId:
|
||||
Ref: PublicSubnetB
|
||||
RouteTableId:
|
||||
Ref: PublicRouteTable
|
||||
|
||||
NatEip:
|
||||
Type: AWS::EC2::EIP
|
||||
Properties:
|
||||
Domain: vpc
|
||||
|
||||
NatGateway:
|
||||
Type: AWS::EC2::NatGateway
|
||||
Properties:
|
||||
AllocationId:
|
||||
Fn::GetAtt:
|
||||
- NatEip
|
||||
- AllocationId
|
||||
SubnetId:
|
||||
Ref: PublicSubnetA
|
||||
Tags:
|
||||
- Key: Name
|
||||
Value: ${self:service}-${sls:stage}-nat
|
||||
|
||||
PrivateRouteTable:
|
||||
Type: AWS::EC2::RouteTable
|
||||
Properties:
|
||||
VpcId:
|
||||
Ref: EsdpVpc
|
||||
Tags:
|
||||
- Key: Name
|
||||
Value: ${self:service}-${sls:stage}-private-rt
|
||||
|
||||
PrivateRoute:
|
||||
Type: AWS::EC2::Route
|
||||
Properties:
|
||||
RouteTableId:
|
||||
Ref: PrivateRouteTable
|
||||
DestinationCidrBlock: 0.0.0.0/0
|
||||
NatGatewayId:
|
||||
Ref: NatGateway
|
||||
|
||||
PrivateSubnetARouteTableAssociation:
|
||||
Type: AWS::EC2::SubnetRouteTableAssociation
|
||||
Properties:
|
||||
SubnetId:
|
||||
Ref: PrivateSubnetA
|
||||
RouteTableId:
|
||||
Ref: PrivateRouteTable
|
||||
|
||||
PrivateSubnetBRouteTableAssociation:
|
||||
Type: AWS::EC2::SubnetRouteTableAssociation
|
||||
Properties:
|
||||
SubnetId:
|
||||
Ref: PrivateSubnetB
|
||||
RouteTableId:
|
||||
Ref: PrivateRouteTable
|
||||
|
||||
LambdaSecurityGroup:
|
||||
Type: AWS::EC2::SecurityGroup
|
||||
Properties:
|
||||
GroupDescription: ${self:service}-${sls:stage} Lambda security group
|
||||
VpcId:
|
||||
Ref: EsdpVpc
|
||||
SecurityGroupEgress:
|
||||
- IpProtocol: -1
|
||||
CidrIp: 0.0.0.0/0
|
||||
Tags:
|
||||
- Key: Name
|
||||
Value: ${self:service}-${sls:stage}-lambda-sg
|
||||
|
||||
ProxySecurityGroup:
|
||||
Type: AWS::EC2::SecurityGroup
|
||||
Properties:
|
||||
GroupDescription: ${self:service}-${sls:stage} RDS proxy security group
|
||||
VpcId:
|
||||
Ref: EsdpVpc
|
||||
SecurityGroupIngress:
|
||||
- IpProtocol: tcp
|
||||
FromPort: 5432
|
||||
ToPort: 5432
|
||||
SourceSecurityGroupId:
|
||||
Ref: LambdaSecurityGroup
|
||||
- IpProtocol: tcp
|
||||
FromPort: 5432
|
||||
ToPort: 5432
|
||||
CidrIp: ${param:admin_cidr}
|
||||
SecurityGroupEgress:
|
||||
- IpProtocol: -1
|
||||
CidrIp: 0.0.0.0/0
|
||||
Tags:
|
||||
- Key: Name
|
||||
Value: ${self:service}-${sls:stage}-proxy-sg
|
||||
|
||||
RdsSecurityGroup:
|
||||
Type: AWS::EC2::SecurityGroup
|
||||
Properties:
|
||||
GroupDescription: ${self:service}-${sls:stage} RDS security group
|
||||
VpcId:
|
||||
Ref: EsdpVpc
|
||||
SecurityGroupIngress:
|
||||
- IpProtocol: tcp
|
||||
FromPort: 5432
|
||||
ToPort: 5432
|
||||
SourceSecurityGroupId:
|
||||
Ref: ProxySecurityGroup
|
||||
- IpProtocol: tcp
|
||||
FromPort: 5432
|
||||
ToPort: 5432
|
||||
CidrIp: ${param:admin_cidr}
|
||||
Tags:
|
||||
- Key: Name
|
||||
Value: ${self:service}-${sls:stage}-rds-sg
|
||||
|
||||
DbSubnetGroup:
|
||||
Type: AWS::RDS::DBSubnetGroup
|
||||
Properties:
|
||||
DBSubnetGroupDescription: ${self:service}-${sls:stage} DB subnet group
|
||||
SubnetIds:
|
||||
- Ref: PublicSubnetA
|
||||
- Ref: PublicSubnetB
|
||||
|
||||
DbSecret:
|
||||
Type: AWS::SecretsManager::Secret
|
||||
Properties:
|
||||
Description: ${self:service}-${sls:stage} RDS master credentials
|
||||
GenerateSecretString:
|
||||
SecretStringTemplate: '{"username":"esdp_admin"}'
|
||||
GenerateStringKey: password
|
||||
PasswordLength: 32
|
||||
ExcludeCharacters: '"@/\\'
|
||||
|
||||
DbProxyRole:
|
||||
Type: AWS::IAM::Role
|
||||
Properties:
|
||||
AssumeRolePolicyDocument:
|
||||
Version: '2012-10-17'
|
||||
Statement:
|
||||
- Effect: Allow
|
||||
Principal:
|
||||
Service:
|
||||
- rds.amazonaws.com
|
||||
Action:
|
||||
- sts:AssumeRole
|
||||
Policies:
|
||||
- PolicyName: ${self:service}-${sls:stage}-db-proxy-secrets
|
||||
PolicyDocument:
|
||||
Version: '2012-10-17'
|
||||
Statement:
|
||||
- Effect: Allow
|
||||
Action:
|
||||
- secretsmanager:GetSecretValue
|
||||
Resource:
|
||||
- Ref: DbSecret
|
||||
|
||||
DbProxy:
|
||||
Type: AWS::RDS::DBProxy
|
||||
Properties:
|
||||
DBProxyName: ${self:service}-${sls:stage}-proxy
|
||||
EngineFamily: POSTGRESQL
|
||||
IdleClientTimeout: 1800
|
||||
RequireTLS: true
|
||||
RoleArn:
|
||||
Fn::GetAtt:
|
||||
- DbProxyRole
|
||||
- Arn
|
||||
VpcSubnetIds:
|
||||
- Ref: PrivateSubnetA
|
||||
- Ref: PrivateSubnetB
|
||||
VpcSecurityGroupIds:
|
||||
- Ref: ProxySecurityGroup
|
||||
Auth:
|
||||
- AuthScheme: SECRETS
|
||||
SecretArn:
|
||||
Ref: DbSecret
|
||||
IAMAuth: DISABLED
|
||||
|
||||
DbProxyTargetGroup:
|
||||
Type: AWS::RDS::DBProxyTargetGroup
|
||||
Properties:
|
||||
DBProxyName:
|
||||
Ref: DbProxy
|
||||
TargetGroupName: default
|
||||
DBInstanceIdentifiers:
|
||||
- Ref: PostgresDb
|
||||
ConnectionPoolConfigurationInfo:
|
||||
MaxConnectionsPercent: 75
|
||||
MaxIdleConnectionsPercent: 50
|
||||
ConnectionBorrowTimeout: 120
|
||||
|
||||
PostgresDb:
|
||||
Type: AWS::RDS::DBInstance
|
||||
DeletionPolicy: Snapshot
|
||||
UpdateReplacePolicy: Snapshot
|
||||
Properties:
|
||||
DBInstanceIdentifier: ${self:service}-${sls:stage}-postgres
|
||||
Engine: postgres
|
||||
# EngineVersion intentionally omitted so AWS uses the current default/latest for RDS Postgres.
|
||||
AutoMinorVersionUpgrade: true
|
||||
DBInstanceClass: db.t4g.micro
|
||||
AllocatedStorage: 20
|
||||
StorageType: gp3
|
||||
StorageEncrypted: true
|
||||
PubliclyAccessible: true
|
||||
MultiAZ: false
|
||||
DBName: ${param:db_name}
|
||||
BackupRetentionPeriod: 7
|
||||
CopyTagsToSnapshot: true
|
||||
DeletionProtection: true
|
||||
VPCSecurityGroups:
|
||||
- Ref: RdsSecurityGroup
|
||||
DBSubnetGroupName:
|
||||
Ref: DbSubnetGroup
|
||||
MasterUsername:
|
||||
Fn::Sub: '{{resolve:secretsmanager:${DbSecret}::username}}'
|
||||
MasterUserPassword:
|
||||
Fn::Sub: '{{resolve:secretsmanager:${DbSecret}::password}}'
|
||||
|
||||
Outputs:
|
||||
VpcId:
|
||||
Value:
|
||||
Ref: EsdpVpc
|
||||
PrivateSubnetAId:
|
||||
Value:
|
||||
Ref: PrivateSubnetA
|
||||
PrivateSubnetBId:
|
||||
Value:
|
||||
Ref: PrivateSubnetB
|
||||
|
||||
LambdaSecurityGroupId:
|
||||
Value:
|
||||
Ref: LambdaSecurityGroup
|
||||
ProxySecurityGroupId:
|
||||
Value:
|
||||
Ref: ProxySecurityGroup
|
||||
RdsSecurityGroupId:
|
||||
Value:
|
||||
Ref: RdsSecurityGroup
|
||||
|
||||
DbName:
|
||||
Value: ${param:db_name}
|
||||
DbPort:
|
||||
Value: 5432
|
||||
|
||||
DbEndpointAddress:
|
||||
Value:
|
||||
Fn::GetAtt:
|
||||
- PostgresDb
|
||||
- Endpoint.Address
|
||||
DbEndpointPort:
|
||||
Value:
|
||||
Fn::GetAtt:
|
||||
- PostgresDb
|
||||
- Endpoint.Port
|
||||
DbSecretArn:
|
||||
Value:
|
||||
Ref: DbSecret
|
||||
|
||||
DbProxyEndpoint:
|
||||
Value:
|
||||
Fn::GetAtt:
|
||||
- DbProxy
|
||||
- Endpoint
|
||||
@@ -1,6 +1,5 @@
|
||||
service: esdp-api
|
||||
app: esdp-api-app
|
||||
frameworkVersion: '4'
|
||||
|
||||
stages:
|
||||
prod:
|
||||
|
||||
@@ -1,76 +1,10 @@
|
||||
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 ScrubRequest {
|
||||
esApiKey: string;
|
||||
rawJob: RawJobDataObject;
|
||||
}
|
||||
|
||||
interface ScrubResponse {
|
||||
report_link?: string;
|
||||
identified_item?: unknown;
|
||||
}
|
||||
|
||||
export const handler = async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {
|
||||
try {
|
||||
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.sending_entity_id = '87330f61-412b-4251-baaa-d026565b23c5';
|
||||
|
||||
const fileName = `${esApiKey}-${rawJob.clm_no}-${Date.now()}`;
|
||||
const formData = new FormData();
|
||||
const jsonString = JSON.stringify(estimate);
|
||||
|
||||
formData.append('file', Buffer.from(jsonString), {
|
||||
filename: `${fileName}.json`,
|
||||
contentType: 'application/json',
|
||||
});
|
||||
|
||||
const result = await axios.post<ScrubResponse>(`${ES_ENDPOINT}/api/sendems`, formData, {
|
||||
auth: {
|
||||
username: ES_USER,
|
||||
password: ES_PASSWORD,
|
||||
},
|
||||
headers: {
|
||||
APIkey: esApiKey,
|
||||
},
|
||||
});
|
||||
|
||||
const resultPDFUrl = result?.data?.report_link;
|
||||
const reportIssueUrl = `https://insurtechtoolkit.com/pcontactUs.aspx?apiKey=${esApiKey}&file=${fileName}.json`;
|
||||
|
||||
return {
|
||||
statusCode: 200,
|
||||
body: JSON.stringify({
|
||||
resultPDFUrl,
|
||||
reportIssueUrl,
|
||||
identified_item: result.data?.identified_item,
|
||||
}),
|
||||
};
|
||||
} catch (error) {
|
||||
const axiosError = error as AxiosError;
|
||||
const errorMessage = axiosError.response?.data || axiosError.message || 'Unknown error';
|
||||
|
||||
return {
|
||||
statusCode: 400,
|
||||
body: JSON.stringify({
|
||||
message: 'Error scrubbing estimate.',
|
||||
error: errorMessage,
|
||||
}),
|
||||
};
|
||||
}
|
||||
return {
|
||||
statusCode: 200,
|
||||
body: JSON.stringify({
|
||||
message: 'Scrub handler is under construction',
|
||||
}),
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user