Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add seed and clean stacks #177

Merged
merged 1 commit into from
Jun 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ X Deploy to AWS Amplify
X Update to codegen 5
X Build accounts page
X Add environment variables to AppSync JS Resolvers/DynamoDB table - https://docs.aws.amazon.com/appsync/latest/devguide/environment-variables.html
X Fix DynamoDB seeding

- Add DynamoDB seeding - https://blog.serverlessadvocate.com/auto-populate-dynamodb-table-with-data-06856d8ff5e9
- Fix bugs with adding account after validation error
- Fix bugs with edit account not prepopulating type
- Fix bugs no validation to edit account
Expand Down
36 changes: 10 additions & 26 deletions infrastructure/bin/pecuniary.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
#!/usr/bin/env node
import 'source-map-support/register';
import { App } from 'aws-cdk-lib';
import { AuthStack } from '../lib/auth-stack';
import { ApiStack } from '../lib/api-stack';
import { DatabaseStack } from '../lib/database-stack';
import { MessagingStack } from '../lib/messaging-stack';
import { DataStack } from '../lib/data-stack';
import { PecuniaryBaseStackProps } from '../lib/types/PecuniaryStackProps';
import { APP_NAME, DEFAULT_VALUES } from '../lib/constants';
import { FrontendStack } from '../lib/frontend-stack';

const APP_NAME = 'pecuniary';

const app = new App();

Expand All @@ -29,38 +27,24 @@ const baseProps: PecuniaryBaseStackProps = {

switch (stage) {
case 'backend': {
const auth = new AuthStack(app, `${APP_NAME}-auth-${envName}`, baseProps);

const database = new DatabaseStack(app, `${APP_NAME}-database-${envName}`, baseProps);

const messaging = new MessagingStack(app, `${APP_NAME}-messaging-${envName}`, {
...baseProps,
params: {
dlqNotifications: process.env.DLQ_NOTIFICATIONS ?? DEFAULT_VALUES.EMAIL,
},
});
// Stateful resources
const data = new DataStack(app, `${APP_NAME}-data-${envName}`, baseProps);

// Stateless resources
new ApiStack(app, `${APP_NAME}-api-${envName}`, {
...baseProps,
params: {
userPoolId: auth.userPoolId,
dataTableArn: database.dataTableArn,
eventHandlerQueueArn: messaging.eventHandlerQueueArn,
eventBusArn: messaging.eventBusArn,
dlqNotifications: process.env.DLQ_NOTIFICATIONS ?? '',
userPoolId: data.userPoolId,
dataTableArn: data.dataTableArn,
},
});

break;
}

case 'frontend': {
// new FrontendStack(app, `${APP_NAME}-frontend-${envName}`, {
// ...baseProps,
// params: {
// certificateArn: process.env.CERTIFICATE_ARN ?? 'not_an_arn',
// },
// });

// Next.js frontend deployed by Amplify Console
break;
}
}
178 changes: 5 additions & 173 deletions infrastructure/data/seeds.json
Original file line number Diff line number Diff line change
@@ -1,178 +1,10 @@
[
{
"userId": "eric",
"aggregateId": "70d2626a-2d28-439f-802a-76be94af0b55",
"sk": "ACC#",
"description": "Test TFSA Account #1",
"entity": "account",
"pk": "acc#70d2626a-2d28-439f-802a-76be94af0b55",
"createdAt": "2023-08-15T14:00:00.000Z",
"accountId": "70d2626a-2d28-439f-802a-76be94af0b55",
"name": "TFSA #1",
"type": "TFSA"
},
{
"userId": "eric",
"sk": "TRANS#",
"aggregateId": "70d2626a-2d28-439f-802a-76be94af0b55",
"commission": 9.99,
"entity": "transaction",
"price": 125.23,
"shares": 100,
"symbol": "AAPL",
"transactionDate": "2022-04-11Z",
"type": "Buy"
},
{
"userId": "eric",
"sk": "TRANS#",
"aggregateId": "70d2626a-2d28-439f-802a-76be94af0b55",
"commission": 2.5,
"entity": "transaction",
"price": 135.23,
"shares": 25,
"symbol": "AAPL",
"transactionDate": "2022-05-03Z",
"type": "Buy"
},
{
"userId": "eric",
"sk": "TRANS#",
"aggregateId": "70d2626a-2d28-439f-802a-76be94af0b55",
"commission": 2,
"entity": "transaction",
"price": 105,
"shares": 25,
"symbol": "AAPL",
"transactionDate": "2022-04-20Z",
"type": "Buy"
},
{
"userId": "eric",
"sk": "ACCPOS#",
"acb": 15916.24,
"aggregateId": "70d2626a-2d28-439f-802a-76be94af0b55",
"bookValue": 15891.26,
"currency": "USD",
"description": "Apple Inc.",
"entity": "position",
"exchange": "NasdaqGS",
"marketValue": 19660,
"shares": 125,
"symbol": "AAPL"
},
{
"userId": "eric",
"sk": "TRANS#",
"aggregateId": "70d2626a-2d28-439f-802a-76be94af0b55",
"commission": 5,
"entity": "transaction",
"price": 110,
"shares": 100,
"symbol": "DDOG",
"transactionDate": "2022-03-03Z",
"type": "Buy"
},
{
"userId": "eric",
"sk": "TRANS#",
"aggregateId": "70d2626a-2d28-439f-802a-76be94af0b55",
"commission": 5,
"entity": "transaction",
"price": 125,
"shares": 50,
"symbol": "DDOG",
"transactionDate": "2022-04-14Z",
"type": "Sell"
},
{
"userId": "eric",
"sk": "ACCPOS#",
"acb": 11005,
"aggregateId": "70d2626a-2d28-439f-802a-76be94af0b55",
"bookValue": 10995,
"currency": "USD",
"description": "Datadog, Inc.",
"entity": "position",
"exchange": "NasdaqGS",
"marketValue": 11000,
"shares": 100,
"symbol": "DDOG"
},
{
"userId": "eric",
"sk": "TRANS#",
"aggregateId": "70d2626a-2d28-439f-802a-76be94af0b55",
"commission": 5,
"entity": "transaction",
"price": 76.23,
"shares": 100,
"symbol": "TD.TO",
"transactionDate": "2022-05-04Z",
"type": "Buy"
},
{
"userId": "eric",
"sk": "ACCPOS#",
"acb": 7628,
"aggregateId": "70d2626a-2d28-439f-802a-76be94af0b55",
"bookValue": 7618,
"currency": "CAD",
"description": "The Toronto-Dominion Bank",
"entity": "position",
"exchange": "Toronto",
"marketValue": 9297,
"shares": 100,
"symbol": "TD.TO"
},
{
"userId": "eric",
"sk": "ACC#",
"aggregateId": "d10b3f6f-5e8d-4863-bbf8-25b64d651206m",
"description": "Test RRSP Account #1",
"entity": "account",
"name": "RRSP #1",
"type": "RRSP"
},
{
"userId": "eric",
"sk": "TRANS#",
"aggregateId": "d10b3f6f-5e8d-4863-bbf8-25b64d651206m",
"commission": 4.95,
"entity": "transaction",
"price": 104.23,
"shares": 150,
"symbol": "BMO.TO",
"transactionDate": "2022-04-18Z",
"type": "Buy"
},
{
"userId": "eric",
"sk": "ACCPOS#",
"acb": 15639.45,
"aggregateId": "d10b3f6f-5e8d-4863-bbf8-25b64d651206m",
"bookValue": 15629.55,
"currency": "CAD",
"description": "Bank of Montreal",
"entity": "position",
"exchange": "Toronto",
"marketValue": 20221.5,
"shares": 150,
"symbol": "BMO.TO"
},
{
"userId": "eric",
"sk": "ACC#",
"aggregateId": "8004d652-f461-4db4-9536-aa6cc0c338b1",
"description": "TFSA #2",
"entity": "account",
"name": "TFSA #2",
"type": "TFSA"
},
{
"userId": "eric",
"sk": "ACC#",
"aggregateId": "3fa14896-8ae7-4e59-845b-d6c09044cc58",
"description": "RRSP #2",
"entity": "account",
"name": "RRSP #2",
"type": "RRSP"
"type": "TFSA",
"entity": "account"
}
]
29 changes: 16 additions & 13 deletions infrastructure/helpers/seed.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
import { DynamoDBClient, PutItemCommand, PutItemCommandInput } from '@aws-sdk/client-dynamodb';
import { ConditionalCheckFailedException, DynamoDBClient, PutItemCommand, PutItemCommandInput } from '@aws-sdk/client-dynamodb';
import { CloudFormationClient, DescribeStacksCommand } from '@aws-sdk/client-cloudformation';
import { marshall } from '@aws-sdk/util-dynamodb';
import * as fs from 'fs';

const STACK_NAME = 'pecuniary-data-dev';

async function seed() {
try {
// Get DynamoDB table name
const tableName = await getTableName('pecuniary-dev');
console.log('✅ Seed table: ', tableName);
const tableName = await getTableName(STACK_NAME);
console.log(' ✅ Verify table exists:', tableName);

// Read items to see from data/seeds.json
const data = getSeedData('./data/seeds.json');
console.log('✅ Seed data: ', data);

console.log('\n🚀 Starting to seed table...');
console.log(` ✅ Parsed seed data: ${data.length} objects`);

console.log('\n🚀 Seeding table...\n');
// Seed each item in table
data.map(async (item: any) => {
await seedItem(tableName, item);
Expand All @@ -27,14 +28,12 @@ async function seed() {

async function seedItem(tableName: string, item: any) {
item.sk = item.sk + new Date().toISOString();
item.createdAt = new Date().toISOString();
item.updatedAt = new Date().toISOString();

const putItemCommandInput: PutItemCommandInput = {
TableName: tableName,
// TODO Fix this error
//@ts-ignore
Item: marshall(item),
ConditionExpression: 'attribute_not_exists(pk)',
};

await dynamoDbCommand(new PutItemCommand(putItemCommandInput));
Expand All @@ -53,7 +52,7 @@ function getSeedData(file: string) {
}

async function getTableName(stackName: string): Promise<string> {
var tableName: string = 'pecuniary-dev-Data';
var tableName: string = 'pecuniary-data-dev';

const client = new CloudFormationClient({});
const command = new DescribeStacksCommand({ StackName: stackName });
Expand All @@ -74,12 +73,16 @@ async function dynamoDbCommand(command: any) {
try {
var client = new DynamoDBClient({});

console.debug(`🔔 Seeding item: ${JSON.stringify(command)}`);
console.debug(` 🔔 Seeding item: ${JSON.stringify(command.input.Item)}`);
result = await client.send(command);

console.log(`🔔 DynamoDB result:${JSON.stringify(result)}`);
console.log(` ✔️ DynamoDB result:${JSON.stringify(result.$metadata)}`);
} catch (error) {
console.error(`🛑 Error with DynamoDB command:\n`, error);
if (error instanceof ConditionalCheckFailedException) {
console.warn(` ✔️ Item already exists, skipping`);
} else {
console.error(`🛑 Error with DynamoDB command:\n`, error);
}
}

return result;
Expand Down
Loading
Loading