AWS CDK infrastructure code for the OSRS Goals application, which tracks Old School RuneScape player goals.
- Node.js v22 (use nvm to install:
nvm install 22 && nvm use 22) - AWS CLI configured with appropriate credentials
- AWS CDK CLI (
npm install -g aws-cdk) - Python 3.11 (for Lambda tester)
- Install AWS CLI:
# macOS
brew install awscli
# Windows
choco install awscli
# Linux
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install- Configure AWS credentials:
# Configure your AWS credentials
aws configure
# When prompted, enter:
# - AWS Access Key ID
# - AWS Secret Access Key
# - Default region (e.g., us-west-2)
# - Default output format (json)You can get your AWS credentials from:
- AWS Console → IAM → Users → Your User → Security credentials → Create access key
- Save both the Access Key ID and Secret Access Key
- Install dependencies:
npm install- Build the project:
npm run buildDeploy the infrastructure using:
# Deploy all stacks
cdk deploy "*" --context stage=dev --context account=123456789012 [--context region=us-west-2]
# Deploy specific stacks (note: dependencies will be deployed automatically)
cdk deploy GetUserStack --context stage=dev --context account=123456789012 [--context region=us-west-2]
cdk deploy CreateUserStack --context stage=dev --context account=123456789012 [--context region=us-west-2]Required parameters:
stage: Environment name (e.g., dev, prod)account: AWS account ID where you want to deploy
Optional parameters:
region: AWS region (defaults to us-west-2)
Stack Dependencies:
GoalTrackerTableStack- IndependentGetPlayerStatsStack- IndependentGoalEventBusStack- IndependentCreateUserStack- Depends on GoalTrackerTableStackGetUserStack- Depends on GoalTrackerTableStackCreateGoalFromEventStack- Depends on GoalEventBusStack and GoalTrackerTableStackGoalCreationRequestEventProducerStack- Depends on GoalEventBusStackGoalProgressCreatorStack- Depends on GoalTrackerTableStackApiGatewayStack- Depends on all Lambda stacks
The service uses EventBridge for event-driven communication between components. The following events are supported:
Event published when a goal is requested to be created.
Event Detail Type: GoalCreationEvent
Event Detail:
{
"userId": "string",
"characterName": "string",
"targetAttribute": "string",
"targetType": "string",
"targetValue": "number",
"currentValue": "number",
"targetDate": "string (ISO-8601)",
"notificationChannelType": "string",
"frequency": "string"
}Event published when progress is made on a goal.
Event Detail Type: GoalProgressUpdateEvent
Event Detail:
{
"userId": "string",
"characterName": "string",
"goalId": "string",
"progressValue": "number"
}Creates progress entries for user goals in the DynamoDB table.
Input: API Gateway event with goal progress details Output: API Gateway response with 200 status code
Processes GoalCreationEvents from the EventBus and creates goals in the DynamoDB table.
Input: EventBridge event with GoalCreationEvent detail Output: None (writes to DynamoDB)
Processes API requests to create goals and publishes GoalCreationEvents to the EventBus.
Input: API Gateway event with path parameters (userId, name) and request body Output: API Gateway response with 200 status code
The service exposes:
Creates a new user account.
Request Body:
{
"email": "string"
}Response:
{
"userId": "string",
"email": "string"
}Retrieves user information.
Parameters:
userId(path parameter) - The user's unique identifier
Response:
{
"userId": "string",
"email": "string"
}Retrieves player's OSRS stats.
Parameters:
name(path parameter) - RuneScape username
Response:
{
"name": "string",
"stats": {
"overall": {
"rank": number,
"level": number,
"xp": number
}
}
}Adds a player to a user's account.
Parameters:
userId(path parameter) - The user's unique identifiername(path parameter) - RuneScape username to add
Response:
{
"userId": "string",
"name": "string",
"added": true
}Retrieves all players associated with a user's account.
Parameters:
userId(path parameter) - The user's unique identifier
Response:
{
"userId": "string",
"players": [
{
"name": "string",
"addedAt": "timestamp"
}
]
}Creates a notification channel for a user.
Parameters:
userId(path parameter) - The user's unique identifier
Request Body:
{
"type": "EMAIL",
"destination": "string"
}Response:
{
"userId": "string",
"channelId": "string",
"type": "EMAIL",
"destination": "string"
}Retrieves all notification channels for a user.
Parameters:
userId(path parameter) - The user's unique identifier
Response:
{
"userId": "string",
"channels": [
{
"channelId": "string",
"type": "EMAIL",
"destination": "string"
}
]
}Creates a goal for a character.
Parameters:
userId(path parameter) - The user's unique identifiername(path parameter) - RuneScape username
Request Body:
{
"targetAttribute": "string",
"targetType": "string",
"targetValue": number,
"currentValue": number,
"targetDate": "string (ISO-8601)",
"notificationChannelType": "string",
"frequency": "string"
}Response:
{
"success": true,
"message": "Goal creation request submitted"
}npm run build- Compile TypeScriptnpm run watch- Watch for changesnpm run test- Run testscdk list --context stage=dev --context account=<account-id>- List all defined stackscdk diff --context stage=dev --context account=<account-id>- Show deployment changescdk synth --context stage=dev --context account=<account-id>- Emit CloudFormation template./updateDevLambda.sh <FunctionName>- Update Lambda function code in dev environment- Example:
./updateDevLambda.sh CreateUser - Available functions: CreateUser, GetUser, GetPlayerStats, AddCharacterToUser, GetCharactersForUser, CreateNotificationChannelForUser, GetNotificationChannelsForUser, GoalCreationRequestEventProducer
- Automatically uses the correct jar file from ../service/build/libs/
- Example:
./updateAllDevLambdas.sh- Update all Lambda functions at once
- Never commit AWS credentials to the repository
- Use appropriate AWS credentials for each environment
- Ensure you're deploying to the correct AWS account
- Always verify the stage and account before deployment
The infrastructure includes:
- API Gateway for REST endpoints:
- User management endpoints:
- Create user (with DynamoDB write access)
- Get user information (with DynamoDB read access)
- Add player to user (with DynamoDB read/write access)
- Player statistics endpoints
- Notification channel endpoints
- Goal management endpoints:
- Create goal for character (with EventBus write access)
- User management endpoints:
- Lambda functions for business logic:
- CreateUser function for user registration (with DynamoDB write access)
- Name format:
CreateUser-${stage}
- Name format:
- GetUser function for retrieving user information (with DynamoDB read access)
- Name format:
GetUser-${stage}
- Name format:
- GetPlayerStats function for retrieving player statistics
- Name format:
GetPlayerStats-${stage}
- Name format:
- AddPlayerToUser function for adding players to users (with DynamoDB read/write access)
- Name format:
AddPlayerToUser-${stage}
- Name format:
- CreateNotificationChannelForUser function for creating notification channels (with DynamoDB write access)
- Name format:
CreateNotificationChannelForUser-${stage}
- Name format:
- GetNotificationChannelsForUser function for retrieving notification channels (with DynamoDB read access)
- Name format:
GetNotificationChannelsForUser-${stage}
- Name format:
- GoalCreationRequestEventProducer function for creating goal creation requests (with EventBus write access)
- Name format:
GoalCreationRequestEventProducer-${stage}
- Name format:
- CreateGoalFromGoalCreationRequestEvent function for processing goal creation events (with DynamoDB write access)
- Name format:
CreateGoalFromGoalCreationRequestEvent-${stage}
- Name format:
- All functions use simple stage suffix (e.g.,
-devor-prod)
- CreateUser function for user registration (with DynamoDB write access)
- DynamoDB tables:
- GoalTrackerTable (pk/sk) for storing player goals and progress tracking
- Table name format:
goalTracker-${stage} - Partition key (pk): String
- Sort key (sk): String
- Global Secondary Indexes:
- email-id-index:
- Partition key (email): String
- Sort key (id): String
- Projection: ALL
- email-id-index:
- Pay-per-request billing
- Point-in-time recovery enabled
- Used by CreateUser and GetUser functions
- Table name format:
- GoalTrackerTable (pk/sk) for storing player goals and progress tracking
- EventBridge event bus:
- GoalEventBus for event-driven communication
- Bus name format:
goal-event-bus-${stage} - Used for goal creation workflow
- Bus name format:
- GoalEventBus for event-driven communication
- Appropriate IAM roles and permissions
- Create a feature branch
- Make your changes
- Write tests
- Create a pull request
MIT