Small full-stack app for a cabin trip: Cognito Hosted UI sign-in, exclusive guest roster claims, DynamoDB preference catalog + per-user answers, and two 5×5 bingo cards (fixed center square + 24 generated challenges) from a .NET 10 Lambda HTTP API. Static SPA is built with Vite + React and served from S3 + CloudFront. Infrastructure is AWS SAM (CloudFormation) in us-east-2.
| Path | Purpose |
|---|---|
| src/CabinBingo.Api | ASP.NET Core minimal API (Handler: CabinBingo.Api, runtime dotnet10) |
| CabinBingo.slnx | .NET solution (Visual Studio / dotnet build CabinBingo.slnx) |
| infrastructure/template.yaml | SAM template: Cognito, DynamoDB (3 tables), HTTP API → Lambda, S3, CloudFront |
| web | React SPA (Hosted UI + PKCE via oidc-client-ts) |
| tools/Seed.ps1 | Seeds sample CabinGuests + PreferenceCatalog rows via AWS CLI |
- .NET 10 SDK
- AWS SAM CLI
- AWS CLI configured with credentials that can deploy the stack (
us-east-2) - Node.js 20+ for the SPA
-
Copy SAM config and adjust if needed:
copy infrastructure\samconfig.toml.example infrastructure\samconfig.toml
Pick a globally unique
CognitoDomainPrefixinparameter_overrides(Cognito hosted domains are shared across accounts). -
From the infrastructure directory:
cd infrastructure sam build sam deploy
-
Note stack Outputs:
HttpApiUrl,UserPoolId,UserPoolClientId,CognitoIssuer,CognitoHostedUiBaseUrl,CloudFrontDomainName,WebsiteBucketName. -
Seed DynamoDB (replace table names with your stack’s physical names from the console or
aws cloudformation describe-stack-resources):./tools/Seed.ps1 -GuestsTable YOUR_GUESTS_TABLE -PreferencesTable YOUR_PREFS_TABLE -Region us-east-2
-
Cognito app client callbacks: ensure
SpaCallbackUrl/SpaLogoutUrlmatch what you use in the SPA. After you know the CloudFront URL, update the user pool client (redeploy withCorsOrigin1=https://YOUR.cloudfront.netand Hosted UI callbackhttps://YOUR.cloudfront.net/callback, or edit the client in the console). -
Configure the SPA — copy web/.env.example to
web/.envand set:VITE_COGNITO_AUTHORITY=CognitoIssueroutputVITE_COGNITO_CLIENT_ID=UserPoolClientIdVITE_REDIRECT_URI/VITE_POST_LOGOUT_REDIRECT_URI= your SPA origin (localhost or CloudFront)VITE_API_BASE_URL=HttpApiUrloutput (no trailing slash)
-
Build and upload the SPA:
cd web npm ci npm run build aws s3 sync ./dist s3://YOUR_WEBSITE_BUCKET_NAME/ --delete
-
Open
https://YOUR_CLOUDFRONT_DOMAIN(ornpm run devfor local UI against deployed API).
Set CabinBingo__* environment variables or edit appsettings.Development.json with real table names and Cognito settings, then:
dotnet run --project src/CabinBingo.ApiThe project is configured for Lambda (AWSProjectType); local Kestrel still runs for smoke tests.
GET /healthGET /guests— selectable guests (others’ claims hidden)GET /profile,PUT /profile{ "guestId": "..." }GET /preferences/catalog,GET /preferences/me,PUT /preferences/me{ "answers": { "drink": ["Yes"], ... } }POST /bingo/cards{ "seed": "optional" }
Private / use for your cabin trip.