Skip to content

Commit d966a3e

Browse files
feat: add finance-tracker migration app with tests
Add the finance-tracker Amplify Gen1 migration test app. Includes auth (Cognito email), GraphQL API with 3 models (Transaction, Budget, FinancialSummary), S3 storage, a Lambda function for financial summaries and SNS notifications, and two CDK custom resources (SNS topics and a custom VTL resolver). Integration tests cover: - Transaction and Budget full CRUD - FinancialSummary model CRUD - Lambda-backed calculateFinancialSummary query - Lambda-backed sendMonthlyReport and sendBudgetAlert mutations (SNS integration) - Custom VTL resolver getTransactionsByCategory - S3 path-based upload and signed URL retrieval --- Prompt: analyze the current tests we have for finance tracker and tell me if theyre accurate or if we need to make changes / yes please fix all
1 parent 34f5189 commit d966a3e

21 files changed

Lines changed: 1705 additions & 7749 deletions

amplify-migration-apps/finance-tracker/README.md

Lines changed: 228 additions & 151 deletions
Large diffs are not rendered by default.
Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,18 @@
11
[
22
{
3-
"Action": [
4-
"sns:Publish",
5-
"sns:ListTopics",
6-
"sns:CreateTopic",
7-
"sns:Subscribe"
8-
],
3+
"Action": ["sns:Publish"],
94
"Resource": ["*"]
105
},
116
{
12-
"Action": [
13-
"dynamodb:Scan",
14-
"dynamodb:Query",
15-
"dynamodb:GetItem"
16-
],
7+
"Action": ["dynamodb:Scan", "dynamodb:Query", "dynamodb:GetItem"],
178
"Resource": [
189
{
19-
"Fn::Sub": [
20-
"arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/Transaction-*",
21-
{}
22-
]
10+
"Fn::Sub": ["arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/Transaction-*", {}]
2311
}
2412
]
2513
},
2614
{
27-
"Action": [
28-
"sts:GetCallerIdentity"
29-
],
15+
"Action": ["sts:GetCallerIdentity"],
3016
"Resource": ["*"]
3117
}
32-
]
18+
]

amplify-migration-apps/finance-tracker/customfinance.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ import * as cdk from 'aws-cdk-lib';
22
import * as AmplifyHelpers from '@aws-amplify/cli-extensibility-helper';
33
import { Construct } from 'constructs';
44
import * as sns from 'aws-cdk-lib/aws-sns';
5+
import * as subscriptions from 'aws-cdk-lib/aws-sns-subscriptions';
56

67
export class cdkStack extends cdk.Stack {
78
constructor(scope: Construct, id: string, props?: cdk.StackProps, amplifyResourceProps?: AmplifyHelpers.AmplifyResourceProps) {
89
super(scope, id, props);
910

10-
/* Do not remove - Amplify CLI automatically injects the current deployment environment in this input parameter */
1111
new cdk.CfnParameter(this, 'env', {
1212
type: 'String',
1313
description: 'Current Amplify CLI env name',
@@ -17,10 +17,13 @@ export class cdkStack extends cdk.Stack {
1717

1818
// 1. SNS Topic for Budget Alerts
1919
const budgetAlertTopic = new sns.Topic(this, 'BudgetAlertTopic', {
20-
topicName: `finance-budget-alerts-${cdk.Fn.ref('env')}`,
2120
displayName: 'Fin Tracker Budget Alerts',
2221
});
2322

23+
budgetAlertTopic.addSubscription(
24+
new subscriptions.EmailSubscription('sanjana.ravikumar.az@gmail.com')
25+
);
26+
2427
new cdk.CfnOutput(this, 'BudgetAlertTopicArn', {
2528
value: budgetAlertTopic.topicArn,
2629
description: 'SNS Topic ARN for budget alerts',
@@ -29,20 +32,19 @@ export class cdkStack extends cdk.Stack {
2932

3033
// 2. SNS Topic for Monthly Reports
3134
const monthlyReportTopic = new sns.Topic(this, 'MonthlyReportTopic', {
32-
topicName: `finance-monthly-reports-${cdk.Fn.ref('env')}`,
3335
displayName: 'Finance Tracker Monthly Reports',
3436
});
3537

36-
// Note: Email subscriptions will be managed dynamically by Lambda
37-
// when users click the email button (allows any user to subscribe)
38+
monthlyReportTopic.addSubscription(
39+
new subscriptions.EmailSubscription('sanjana.ravikumar.az@gmail.com')
40+
);
3841

3942
new cdk.CfnOutput(this, 'MonthlyReportTopicArn', {
4043
value: monthlyReportTopic.topicArn,
4144
description: 'SNS Topic ARN for monthly reports',
4245
exportName: `${amplifyProjectInfo.projectName}-MonthlyReportTopicArn-${cdk.Fn.ref('env')}`,
4346
});
4447

45-
// 3. Add tags for resource organization
4648
cdk.Tags.of(this).add('Project', 'FinanceTracker');
4749
cdk.Tags.of(this).add('Environment', cdk.Fn.ref('env'));
4850
cdk.Tags.of(this).add('ManagedBy', 'Amplify');

amplify-migration-apps/finance-tracker/financetracker.js

Lines changed: 11 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
/* Amplify Params - DO NOT EDIT
2-
API_FINANCETRACKER_GRAPHQLAPIENDPOINTOUTPUT
3-
API_FINANCETRACKER_GRAPHQLAPIIDOUTPUT
4-
API_FINANCETRACKER_GRAPHQLAPIKEYOUTPUT
5-
AUTH_FINANCETRACKERB192A2D4_USERPOOLID
2+
API_FINANCETRACKER2_GRAPHQLAPIIDOUTPUT
3+
API_FINANCETRACKER2_TRANSACTIONTABLE_ARN
4+
API_FINANCETRACKER2_TRANSACTIONTABLE_NAME
65
ENV
76
REGION
87
Amplify Params - DO NOT EDIT */ const { DynamoDBClient, ListTablesCommand } = require('@aws-sdk/client-dynamodb');
98
const { DynamoDBDocumentClient, ScanCommand } = require('@aws-sdk/lib-dynamodb');
10-
const { SNSClient, PublishCommand, SubscribeCommand } = require('@aws-sdk/client-sns');
9+
const { SNSClient, PublishCommand } = require('@aws-sdk/client-sns');
1110

1211
const dynamoClient = new DynamoDBClient({});
1312
const dynamodb = DynamoDBDocumentClient.from(dynamoClient);
@@ -77,7 +76,7 @@ async function calculateSummaryFromDB() {
7776
console.log('calculateSummaryFromDB called');
7877

7978
// Try to get table name from environment variable
80-
let tableName = process.env.API_FINANCETRACKER_TRANSACTIONTABLE_NAME;
79+
let tableName = process.env.API_FINANCETRACKER2_TRANSACTIONTABLE_NAME;
8180
console.log('Table name from env:', tableName);
8281

8382
// If table name has NONE, we need to find the actual API ID
@@ -166,19 +165,15 @@ async function sendMonthlyReport(args) {
166165
}
167166

168167
try {
169-
// Use the SNS topic created by the custom resource
168+
// Use the SNS topic created by the custom resource (subscription managed by CDK)
170169
const topicArn = process.env.MONTHLY_REPORT_TOPIC_ARN;
171170
console.log('Using topic ARN from environment:', topicArn);
172171

173172
if (!topicArn || topicArn === 'NONE') {
174173
throw new Error('Monthly report topic ARN not configured');
175174
}
176175

177-
// Subscribe the user's email to the topic
178-
await subscribeEmailToTopic(topicArn, email);
179-
console.log('Email subscribed to topic');
180-
181-
const tableName = process.env.API_FINANCETRACKER_TRANSACTIONTABLE_NAME;
176+
const tableName = process.env.API_FINANCETRACKER2_TRANSACTIONTABLE_NAME;
182177
console.log('Table name:', tableName);
183178

184179
// Get financial summary from DynamoDB
@@ -272,19 +267,15 @@ async function sendBudgetAlert(args) {
272267
const { email, category, exceeded } = args;
273268

274269
try {
275-
// Use the SNS topic created by the custom resource
270+
// Use the SNS topic created by the custom resource (subscription managed by CDK)
276271
const topicArn = process.env.BUDGET_ALERT_TOPIC_ARN;
277272
console.log('Using topic ARN from environment:', topicArn);
278273

279274
if (!topicArn || topicArn === 'NONE') {
280275
throw new Error('Budget alert topic ARN not configured');
281276
}
282277

283-
// Subscribe the user's email to the topic
284-
await subscribeEmailToTopic(topicArn, email);
285-
console.log('Email subscribed to topic');
286-
287-
const tableName = process.env.API_FINANCETRACKER_TRANSACTIONTABLE_NAME;
278+
const tableName = process.env.API_FINANCETRACKER2_TRANSACTIONTABLE_NAME;
288279

289280
// Get category spending from DynamoDB
290281
const result = await dynamodb.send(
@@ -352,36 +343,5 @@ Finance Tracker Team`,
352343
}
353344
}
354345

355-
// Helper function to subscribe an email to an existing SNS topic
356-
async function subscribeEmailToTopic(topicArn, email) {
357-
console.log('Subscribing email to topic:', topicArn);
358-
console.log('Email for subscription:', email);
359-
360-
try {
361-
// Subscribe the email to the topic
362-
console.log('Attempting to subscribe email to topic...');
363-
const subscribeResult = await sns.send(
364-
new SubscribeCommand({
365-
TopicArn: topicArn,
366-
Protocol: 'email',
367-
Endpoint: email,
368-
}),
369-
);
370-
371-
console.log('Subscription result:', JSON.stringify(subscribeResult, null, 2));
372-
console.log('Subscription ARN:', subscribeResult.SubscriptionArn);
373-
374-
if (subscribeResult.SubscriptionArn === 'pending confirmation') {
375-
console.log('Email subscription pending confirmation - user needs to check email');
376-
}
377-
378-
return subscribeResult.SubscriptionArn;
379-
} catch (error) {
380-
console.error('Error in subscribeEmailToTopic:', error);
381-
console.error('Error name:', error.name);
382-
console.error('Error code:', error.code);
383-
console.error('Error message:', error.message);
384-
console.error('Error stack:', error.stack);
385-
throw new Error(`Failed to subscribe email to SNS topic: ${error.message}`);
386-
}
387-
}
346+
// Email subscriptions are now managed by the CDK custom resource (customfinance)
347+
// The Lambda only publishes messages to the pre-configured SNS topics

amplify-migration-apps/finance-tracker/financetracker.package.json

Lines changed: 0 additions & 16 deletions
This file was deleted.

0 commit comments

Comments
 (0)