This guide covers development setup for the three main components of the project:
- Web Frontend - React application with Vite and Tailwind CSS
- AWS Infrastructure & Backend - CloudFormation templates and Lambda functions
- LED Display Visualizer - Python application for Raspberry Pi or emulator mode
- Node.js v18+
The frontend uses a runtime configuration approach:
- Deployed environments: The stack automatically creates a
config.jsfile in the Amazon S3 bucket with all necessary settings (API endpoints, Amazon Cognito configuration, etc.) - Local development: Download this
config.jsfile from Amazon S3 to your localpublic/directory
-
Install dependencies:
npm install
-
Download configuration from your deployed stack:
BUCKET_NAME=$(aws cloudformation describe-stacks --stack-name visualise-saas --query 'Stacks[0].Outputs[?OutputKey==`FrontendBucket`].OutputValue' --output text) aws s3 cp s3://$BUCKET_NAME/config.js public/config.js
npm run devThe development server will start and you can access the application at http://localhost:5173 (or the port shown in your terminal).
npm run lintnpm run build- AWS SAM CLI
- AWS CLI with configured credentials
- Python 3.x (for Lambda functions)
After making changes to backend or infrastructure code:
sam build
sam deployFor more efficient iteration during development, you can use:
sam syncFor additional debugging, deploy with development settings:
sam deploy --parameter-overrides IsDevDeployment=TrueThis enables additional logging and debugging features in the backend.
For more troubleshooting help, see the Troubleshooting Guide.
- CloudFormation templates:
cfn/ - API Lambda functions:
src/backend/ - Load generator Lambda:
src/load-generator/ - Database cleanup Lambda:
src/mysql-record-reaper/
The load generator is an optional Lambda function that automatically generates simulated traffic to demonstrate the SaaS architecture under load.
Load generator settings are configured in samconfig.toml before deployment:
parameter_overrides=[
"EnableLoadGenerator=False", # Set to True to enable
"LoadGeneratorMinRequests=1", # Min requests per invocation
"LoadGeneratorMaxRequests=5", # Max requests per invocation
"LoadGeneratorFrequency=5", # Run every N minutes
]When enabled, the load generator:
- Runs on a schedule - Invokes every N minutes (default: 5 minutes)
- Authenticates as demo users - Uses tenants 21-24 for generated traffic
- Places random orders - Generates 1-5 orders per invocation with random products
- Uses both queue types - Randomly selects shared or siloed queue paths
- Provides continuous visualization - Keeps the LED display active even when idle
To enable after initial deployment:
- Edit
samconfig.tomland setEnableLoadGenerator=True - Optionally adjust frequency and request counts
- Redeploy:
sam build sam deploy
The load generator will start running on the configured schedule. You can monitor its activity by:
- Watching the LED display for automated transactions
- Logging in as tenants 21-24 to see generated orders
- Checking CloudWatch Logs for the LoadGenerator Lambda function
To stop automated traffic generation:
- Edit
samconfig.tomland setEnableLoadGenerator=False - Redeploy:
sam build sam deploy
The EventBridge schedule will be disabled, stopping all automated invocations.
The load generator adds minimal cost:
- Lambda invocations: ~8,640/month at 5-minute intervals (within free tier: 1M requests/month)
- Lambda duration: ~1-2 seconds per invocation (within free tier: 400,000 GB-seconds/month)
- Database writes: Additional Aurora write operations (~10K-40K/month depending on configuration)
For cost optimization during extended testing, consider:
- Increasing
LoadGeneratorFrequencyto 15 or 30 minutes - Reducing
LoadGeneratorMaxRequeststo 1-2 - Disabling when not actively demonstrating the system
- Python 3.13+
- uv package manager
The LED display code can run in emulator mode, allowing development and testing without Raspberry Pi hardware. The emulator runs a web server that displays the LED matrix in your browser.
Navigate to the visualizer-display directory:
cd src/visualizer-displayInstall uv if needed (see https://docs.astral.sh/uv/getting-started/installation/)
Install all dependencies (uv automatically creates and manages virtualenv):
uv sync --group devCopy environment configuration:
cp .env.example .envEdit .env and set LED_EMULATOR_MODE=true
The display requires a font file from the rpi-rgb-led-matrix project. Clone it as a sibling directory:
# From project root (visualise-saas directory), clone as sibling
cd ..
git clone https://github.com/hzeller/rpi-rgb-led-matrix.git
cd rpi-rgb-led-matrix
git checkout ef43b877570b727d771e13f287546f12fcf2217b
cd ../visualise-saasThe font will be automatically discovered at ../rpi-rgb-led-matrix/fonts/4x6.bdf.
Alternatively, set LED_FONT_PATH in .env to point to an existing font file.
Generate the IoT certificates required for device authentication.
From the root of the saas-visualiser repository:
cd ../..
uv run scripts/setup_iot_certificates.py createThis creates an iot-certificates/ directory containing:
certificate.pem.crt- Device certificateprivate.pem.key- Private keyrootCA.pem- Amazon Root CAdevice-config.json- Configuration file with IoT endpoint and topic
After deploying your CloudFormation stack and setting up IoT certificates.
Navigate back to the visualizer-display directory:
cd src/visualizer-displayUse the convenience script:
./scripts/run_emulator.shOr run directly (uv handles virtualenv automatically):
uv run visualizer-display --config /path/to/device-config.jsonThe emulator will start a web server at http://localhost:8888/ where you can view the LED matrix in your browser. It connects to AWS IoT Core and visualizes transactions in real-time, just like the physical hardware.
Once the emulator is running and connected to AWS IoT Core, you can start using the application! See the Usage Guide for:
- How to log in and test the application
- Watching transactions flow through the architecture visualization
- Understanding what each component represents on the LED display
Make sure you're in the visualizer-display directory:
cd src/visualizer-displayInstall all dependencies (same as emulator setup):
uv syncCopy environment configuration:
cp .env.example .envEdit .env and set LED_EMULATOR_MODE=false:
nano .envRun:
./scripts/run_hardware.shNote: The hardware library (rgbmatrix) requires Raspberry Pi with GPIO access. See Hardware Setup for detailed instructions.
For detailed LED display debugging, set LOG_LEVEL=DEBUG in the .env file:
In src/visualizer-display/.env:
LOG_LEVEL=DEBUG
This will output detailed transaction processing, MQTT messages, and rendering statistics.
The emulator provides an identical software interface to the hardware. The only differences are:
- Emulator renders to a web browser instead of GPIO pins
- Emulator may run at different framerates depending on system performance
- Hardware requires sudo for GPIO access, emulator does not
All configuration, MQTT integration, state management, and rendering logic are identical.