Serverless backend for the FreestyleFiend app, built with AWS CDK (TypeScript), DynamoDB (single-table), S3, Cognito, and API Gateway. Includes robust OpenAPI documentation, full Jest test coverage, and CI/CD via GitHub Actions.
- Domain-Driven, Serverless Architecture: Follows DDD, Twelve-Factor, and AWS best practices.
- DynamoDB Single-Table Design: Efficient, scalable, and extensible entity modeling (docs/dynamodb-design.md).
- API Gateway (REST, Cognito Auth): Secure endpoints for recordings, voting, leaderboard, and beats.
- OpenAPI Spec: api/openapi.yaml β always up-to-date.
- Comprehensive Testing: Jest unit tests for all Lambda logic.
- CI/CD: Automated with GitHub Actions (.github/workflows/ci.yml).
# Install dependencies
npm install
# Synthesize CDK (see CloudFormation output)
npx cdk synth
# Run all unit tests
npm test
# Deploy to your AWS account (requires credentials)
npm run deployYou can run real HTTP integration tests against your deployed API using Jest and axios.
- Your backend must be deployed and accessible via API Gateway.
- You need a valid Cognito JWT for an authenticated user.
- Find your Cognito User Pool App Client ID (see AWS Console or CDK output).
- Register a user (if needed):
aws cognito-idp sign-up \ --client-id <YOUR_APP_CLIENT_ID> \ --username <YOUR_EMAIL> \ --password <YOUR_PASSWORD>
- You may need to confirm the user (via email or admin action).
- Authenticate and get your JWT:
aws cognito-idp initiate-auth \ --auth-flow USER_PASSWORD_AUTH \ --client-id <YOUR_APP_CLIENT_ID> \ --auth-parameters USERNAME=<YOUR_EMAIL>,PASSWORD=<YOUR_PASSWORD>
- The output will include
IdToken,AccessToken, andRefreshToken. - Use the
IdTokenorAccessTokenas your JWT for Authorization.
- The output will include
-
Set environment variables:
API_BASE_URL: Your API Gateway base URL (e.g.,https://abc123.execute-api.us-east-1.amazonaws.com/prod)COGNITO_JWT: The JWT you obtained above (for endpoints that require auth)
-
Run integration tests:
API_BASE_URL=https://your-api-url COGNITO_JWT=your-jwt npm run test:integration
- This runs
/tests/integration/api.integration.test.tsand exercises all major API flows. - Output will show which endpoints succeeded or failed.
- This runs
-
Test file location:
- See
/tests/integration/api.integration.test.tsfor test source and scenarios.
- See
- Run all unit tests (Lambdas, models, etc):
npm run test:unit
- Requires environment variables:
API_BASE_URL(your deployed API Gateway URL)COGNITO_JWT(see JWT automation section below)
- Run all integration tests:
npm run test:integration
- Integration tests will fail if required env vars are not set.
- Note: Integration tests are designed to work with any user account that already exists and is confirmed in Cognito. You do not need to register a new user for each run, but the user must be in the Cognito User Pool and able to sign in.
- To run all tests (unit + integration):
npm test - Note: Integration tests require env vars as described above.
To run integration tests that require Cognito authentication, use the provided script to fetch a JWT token for your test user.
- Node.js 18+
- ts-node installed (
npm install -D ts-node) - Your Cognito User Pool ID, App Client ID, and a test user with a confirmed email in the pool
npm run get-jwtYou will be prompted for your Cognito username/email, password, App Client ID, and User Pool ID. Optionally, you can provide these as environment variables:
COGNITO_USER(username/email)COGNITO_PASSWORDCOGNITO_CLIENT_IDCOGNITO_USER_POOL_IDAWS_REGION(default: us-east-1)
Example:
COGNITO_USER=your@email.com COGNITO_PASSWORD=yourpassword COGNITO_CLIENT_ID=xxxx COGNITO_USER_POOL_ID=us-east-1_xxxxx npm run get-jwtThis will print your JWT token to stdout.
Set the JWT as an environment variable and run the tests:
export COGNITO_JWT=$(npm run get-jwt --silent)
export API_BASE_URL=https://<your-api-id>.execute-api.<region>.amazonaws.com/prod
npm run test:integrationYou can also combine these steps:
COGNITO_USER=your@email.com COGNITO_PASSWORD=yourpassword COGNITO_CLIENT_ID=xxxx COGNITO_USER_POOL_ID=us-east-1_xxxxx \
API_BASE_URL=https://<your-api-id>.execute-api.<region>.amazonaws.com/prod \
COGNITO_JWT=$(npm run get-jwt --silent) npm run test:integration- Works with any existing Cognito user: As long as the user is confirmed in the User Pool, you can use their credentials for integration testing. No special test user is required.
- No manual JWT copy-paste needed: The script automates JWT retrieval for both local and CI/CD workflows.
- No more manual JWT copy-paste for integration tests.
- Script works locally and in CI/CD (set secrets as env vars).
- Follows Twelve-Factor App and security best practices.
To enable frontend engineers to build against the FreestyleFiend backend, provide them with the following resources:
- See
openapi.yamlfor a machine-readable API spec (importable into Swagger UI, Postman, etc.)
- See
api/integration-examples.httpfor real-world request/response samples
- AWS Cognito User Pool ID: (ask backend engineer or see deployment output)
- AWS Cognito App Client ID: (ask backend engineer or see deployment output)
- All endpoints except
GET /recordings/{id}require a valid JWT (see below)
- Use the script
scripts/get-jwt.tsornpm run get-jwtfor easy JWT token retrieval - See Automated JWT Retrieval for Integration Tests above for workflow
- See the API Overview section above for a summary of endpoints, methods, and authentication requirements
- For backend support or questions, contact the backend engineering team or refer to this README
- POST /recordings (auth): Create new recording, receive S3 presigned upload URL
- GET /recordings: List all recordings
- GET /recordings/{id}: Fetch single recording
- POST /votes (auth): Upvote/downvote a recording
- GET /votes: List votes for a recording
- GET /leaderboard: Top recordings for a date
- GET /beats: List available beats
See api/openapi.yaml for full details and schemas.
- Returns a list of all available beats with metadata and presigned S3 URLs for audio and image.
- Authentication: None (public endpoint)
- Response Example:
[
{
"beatId": "celestial",
"title": "Celestial",
"producer": "FreeBeats.io",
"genre": "Hip-Hop",
"bpm": 163,
"duration": "3:24",
"tags": ["Atmospheric", "Chill", "Vibe"],
"description": "Chill, atmospheric hip-hop beat.",
"audioUrl": "https://your-s3-bucket.s3.amazonaws.com/beats/celestial.mp3?...",
"imageUrl": "https://your-s3-bucket.s3.amazonaws.com/beats/images/celestial.png?..."
}
]- See also:
/data/beats-with-urls.jsonfor a local dump of all beats with public S3 URLs (useful for frontend prototyping).
- Run all tests:
npm test - Test files: See tests/lambda/
- CI: All pushes/PRs are checked by GitHub Actions.
/lambdaβ Lambda function handlers/libβ CDK stack definitions/apiβ OpenAPI spec and TypeScript types/docsβ Architecture and DynamoDB design docs/testsβ Jest unit tests.github/workflowsβ CI/CD pipelines
- Fork and clone the repo
- Create a feature branch
- Commit and push your changes
- Open a pull request
MIT