Remove drizzle and serverless infra. Add terraform deployment.
This commit is contained in:
@@ -1,10 +0,0 @@
|
||||
import { defineConfig } from 'drizzle-kit';
|
||||
|
||||
export default defineConfig({
|
||||
schema: './src/db/schema/**/*.ts',
|
||||
out: './drizzle',
|
||||
dialect: 'postgresql',
|
||||
dbCredentials: {
|
||||
url: process.env.DATABASE_URL ?? '',
|
||||
},
|
||||
});
|
||||
@@ -1,42 +0,0 @@
|
||||
CREATE TABLE
|
||||
"joblines" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid () NOT NULL,
|
||||
"created_at" timestamp
|
||||
with
|
||||
time zone DEFAULT now () NOT NULL,
|
||||
"jobId" uuid NOT NULL,
|
||||
"line_desc" text
|
||||
);
|
||||
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE
|
||||
"jobs" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid () NOT NULL,
|
||||
"shopId" uuid NOT NULL,
|
||||
"created_at" timestamp
|
||||
with
|
||||
time zone DEFAULT now () NOT NULL,
|
||||
"clm_no" text,
|
||||
"ciecaid" text
|
||||
);
|
||||
|
||||
--> statement-breakpoint
|
||||
CREATE TABLE
|
||||
"shops" (
|
||||
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid () NOT NULL,
|
||||
"created_at" timestamp
|
||||
with
|
||||
time zone DEFAULT now () NOT NULL,
|
||||
"es_api_key" text NOT NULL,
|
||||
"active" boolean DEFAULT true NOT NULL,
|
||||
CONSTRAINT "shops_es_api_key_unique" UNIQUE ("es_api_key")
|
||||
);
|
||||
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "joblines" ADD CONSTRAINT "joblines_jobId_jobs_id_fk" FOREIGN KEY ("jobId") REFERENCES "public"."jobs" ("id") ON DELETE no action ON UPDATE no action;
|
||||
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "jobs" ADD CONSTRAINT "jobs_shopId_shops_id_fk" FOREIGN KEY ("shopId") REFERENCES "public"."shops" ("id") ON DELETE no action ON UPDATE no action;
|
||||
|
||||
--> statement-breakpoint
|
||||
CREATE INDEX "clm_no_idx" ON "jobs" USING btree ("clm_no");
|
||||
@@ -1,195 +0,0 @@
|
||||
{
|
||||
"id": "e789ff38-2370-43ff-825a-fde4c3efca40",
|
||||
"prevId": "00000000-0000-0000-0000-000000000000",
|
||||
"version": "7",
|
||||
"dialect": "postgresql",
|
||||
"tables": {
|
||||
"public.joblines": {
|
||||
"name": "joblines",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp with time zone",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
},
|
||||
"jobId": {
|
||||
"name": "jobId",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"line_desc": {
|
||||
"name": "line_desc",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {
|
||||
"joblines_jobId_jobs_id_fk": {
|
||||
"name": "joblines_jobId_jobs_id_fk",
|
||||
"tableFrom": "joblines",
|
||||
"tableTo": "jobs",
|
||||
"columnsFrom": [
|
||||
"jobId"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"policies": {},
|
||||
"checkConstraints": {},
|
||||
"isRLSEnabled": false
|
||||
},
|
||||
"public.jobs": {
|
||||
"name": "jobs",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"shopId": {
|
||||
"name": "shopId",
|
||||
"type": "uuid",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp with time zone",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
},
|
||||
"clm_no": {
|
||||
"name": "clm_no",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
},
|
||||
"ciecaid": {
|
||||
"name": "ciecaid",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": false
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
"clm_no_idx": {
|
||||
"name": "clm_no_idx",
|
||||
"columns": [
|
||||
{
|
||||
"expression": "clm_no",
|
||||
"isExpression": false,
|
||||
"asc": true,
|
||||
"nulls": "last"
|
||||
}
|
||||
],
|
||||
"isUnique": false,
|
||||
"concurrently": false,
|
||||
"method": "btree",
|
||||
"with": {}
|
||||
}
|
||||
},
|
||||
"foreignKeys": {
|
||||
"jobs_shopId_shops_id_fk": {
|
||||
"name": "jobs_shopId_shops_id_fk",
|
||||
"tableFrom": "jobs",
|
||||
"tableTo": "shops",
|
||||
"columnsFrom": [
|
||||
"shopId"
|
||||
],
|
||||
"columnsTo": [
|
||||
"id"
|
||||
],
|
||||
"onDelete": "no action",
|
||||
"onUpdate": "no action"
|
||||
}
|
||||
},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {},
|
||||
"policies": {},
|
||||
"checkConstraints": {},
|
||||
"isRLSEnabled": false
|
||||
},
|
||||
"public.shops": {
|
||||
"name": "shops",
|
||||
"schema": "",
|
||||
"columns": {
|
||||
"id": {
|
||||
"name": "id",
|
||||
"type": "uuid",
|
||||
"primaryKey": true,
|
||||
"notNull": true,
|
||||
"default": "gen_random_uuid()"
|
||||
},
|
||||
"created_at": {
|
||||
"name": "created_at",
|
||||
"type": "timestamp with time zone",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": "now()"
|
||||
},
|
||||
"es_api_key": {
|
||||
"name": "es_api_key",
|
||||
"type": "text",
|
||||
"primaryKey": false,
|
||||
"notNull": true
|
||||
},
|
||||
"active": {
|
||||
"name": "active",
|
||||
"type": "boolean",
|
||||
"primaryKey": false,
|
||||
"notNull": true,
|
||||
"default": true
|
||||
}
|
||||
},
|
||||
"indexes": {},
|
||||
"foreignKeys": {},
|
||||
"compositePrimaryKeys": {},
|
||||
"uniqueConstraints": {
|
||||
"shops_es_api_key_unique": {
|
||||
"name": "shops_es_api_key_unique",
|
||||
"nullsNotDistinct": false,
|
||||
"columns": [
|
||||
"es_api_key"
|
||||
]
|
||||
}
|
||||
},
|
||||
"policies": {},
|
||||
"checkConstraints": {},
|
||||
"isRLSEnabled": false
|
||||
}
|
||||
},
|
||||
"enums": {},
|
||||
"schemas": {},
|
||||
"sequences": {},
|
||||
"roles": {},
|
||||
"policies": {},
|
||||
"views": {},
|
||||
"_meta": {
|
||||
"columns": {},
|
||||
"schemas": {},
|
||||
"tables": {}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
{
|
||||
"version": "7",
|
||||
"dialect": "postgresql",
|
||||
"entries": [
|
||||
{
|
||||
"idx": 0,
|
||||
"version": "7",
|
||||
"when": 1768419700617,
|
||||
"tag": "0000_fearless_vector",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -2,10 +2,6 @@ service: esdp-api
|
||||
app: esdp-api-app
|
||||
frameworkVersion: '4'
|
||||
|
||||
package:
|
||||
patterns:
|
||||
- drizzle/**
|
||||
|
||||
stages:
|
||||
prod:
|
||||
# Enables observability in the prod stage
|
||||
@@ -17,8 +13,6 @@ stages:
|
||||
domain: es.imex.online
|
||||
es_user: Imex2
|
||||
es_password: Patrick
|
||||
infra_service: esdp-infra
|
||||
infra_stage: shared
|
||||
beta:
|
||||
# Enables observability in the prod stage
|
||||
observability: false
|
||||
@@ -29,8 +23,6 @@ stages:
|
||||
domain: beta.es.imex.online
|
||||
es_user: Imex2
|
||||
es_password: Patrick
|
||||
infra_service: esdp-infra
|
||||
infra_stage: shared
|
||||
alpha:
|
||||
# Enables observability in the prod stage
|
||||
observability: false
|
||||
@@ -40,8 +32,6 @@ stages:
|
||||
domain: alpha.es.imex.online
|
||||
es_user: Imex2
|
||||
es_password: Patrick
|
||||
infra_service: esdp-infra
|
||||
infra_stage: shared
|
||||
dev:
|
||||
# Enables observability in the prod stage
|
||||
observability: false
|
||||
@@ -51,17 +41,6 @@ stages:
|
||||
domain: dev.es.imex.online
|
||||
es_user: Imex2
|
||||
es_password: Patrick
|
||||
infra_service: esdp-infra
|
||||
infra_stage: shared
|
||||
|
||||
custom:
|
||||
infra_stack: ${param:infra_service}-${param:infra_stage}
|
||||
|
||||
db:
|
||||
host: ${cf:${self:custom.infra_stack}.DbProxyEndpoint}
|
||||
port: ${cf:${self:custom.infra_stack}.DbPort}
|
||||
name: ${cf:${self:custom.infra_stack}.DbName}
|
||||
secretArn: ${cf:${self:custom.infra_stack}.DbSecretArn}
|
||||
|
||||
# params:
|
||||
# dev:
|
||||
@@ -81,31 +60,6 @@ provider:
|
||||
httpApi: # This creates a cheaper, faster "HTTP API" Gateway
|
||||
cors: true # Automatically configures CORS
|
||||
|
||||
# Ensure all Lambdas can reach the shared RDS Proxy in the infra VPC
|
||||
vpc:
|
||||
securityGroupIds:
|
||||
- ${cf:${self:custom.infra_stack}.LambdaSecurityGroupId}
|
||||
subnetIds:
|
||||
- ${cf:${self:custom.infra_stack}.PrivateSubnetAId}
|
||||
- ${cf:${self:custom.infra_stack}.PrivateSubnetBId}
|
||||
|
||||
# Default DB connection settings for all Lambdas (used by src/lib/db.ts)
|
||||
environment:
|
||||
DB_HOST: ${self:custom.db.host}
|
||||
DB_PORT: ${self:custom.db.port}
|
||||
DB_NAME: ${self:custom.db.name}
|
||||
DB_SECRET_ARN: ${self:custom.db.secretArn}
|
||||
|
||||
# Allow Lambdas to fetch the DB credentials from Secrets Manager
|
||||
iam:
|
||||
role:
|
||||
statements:
|
||||
- Effect: Allow
|
||||
Action:
|
||||
- secretsmanager:GetSecretValue
|
||||
Resource:
|
||||
- ${self:custom.db.secretArn}
|
||||
|
||||
build:
|
||||
esbuild:
|
||||
bundle: true
|
||||
@@ -151,28 +105,6 @@ functions:
|
||||
path: /emsupload
|
||||
method: post
|
||||
|
||||
dbMigrate:
|
||||
handler: src/handlers/dbMigrate.handler
|
||||
timeout: 30
|
||||
memorySize: 512
|
||||
iamRoleStatements:
|
||||
- Effect: Allow
|
||||
Action:
|
||||
- secretsmanager:GetSecretValue
|
||||
Resource:
|
||||
- ${cf:${self:custom.infra_stack}.DbSecretArn}
|
||||
|
||||
dbPing:
|
||||
handler: src/handlers/dbPing.handler
|
||||
timeout: 15
|
||||
memorySize: 256
|
||||
iamRoleStatements:
|
||||
- Effect: Allow
|
||||
Action:
|
||||
- secretsmanager:GetSecretValue
|
||||
Resource:
|
||||
- ${cf:${self:custom.infra_stack}.DbSecretArn}
|
||||
|
||||
resources:
|
||||
Resources:
|
||||
UploadBucket:
|
||||
|
||||
55
serverless/src/lib/hasura.ts
Normal file
55
serverless/src/lib/hasura.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
import { SecretsManagerClient, GetSecretValueCommand } from '@aws-sdk/client-secrets-manager';
|
||||
|
||||
const client = new SecretsManagerClient({ region: 'ca-central-1' });
|
||||
|
||||
interface HasuraCredentials {
|
||||
database_url: string;
|
||||
admin_secret: string;
|
||||
}
|
||||
|
||||
let cachedCredentials: HasuraCredentials | null = null;
|
||||
|
||||
/**
|
||||
* Fetches Hasura credentials from AWS Secrets Manager
|
||||
* Caches the result for subsequent invocations within the same Lambda container
|
||||
*/
|
||||
export async function getHasuraCredentials(): Promise<HasuraCredentials> {
|
||||
if (cachedCredentials) {
|
||||
return cachedCredentials;
|
||||
}
|
||||
|
||||
const secretArn = process.env.HASURA_SECRET_ARN;
|
||||
if (!secretArn) {
|
||||
throw new Error('HASURA_SECRET_ARN environment variable not set');
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await client.send(new GetSecretValueCommand({ SecretId: secretArn }));
|
||||
|
||||
if (!response.SecretString) {
|
||||
throw new Error('Secret value is empty');
|
||||
}
|
||||
|
||||
cachedCredentials = JSON.parse(response.SecretString);
|
||||
return cachedCredentials!;
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch Hasura credentials:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Get just the admin secret
|
||||
*/
|
||||
export async function getHasuraAdminSecret(): Promise<string> {
|
||||
const creds = await getHasuraCredentials();
|
||||
return creds.admin_secret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: Get just the database URL
|
||||
*/
|
||||
export async function getHasuraDatabaseUrl(): Promise<string> {
|
||||
const creds = await getHasuraCredentials();
|
||||
return creds.database_url;
|
||||
}
|
||||
Reference in New Issue
Block a user