Owner UI
The owner UI lives under upstream web/. Cognito sign-in → run history + Try it. Self-sign-up is disabled; only the invited owner email can sign in.
| Client | Credential | Routes |
|---|---|---|
| Amplify SPA (browser) | Cognito email/password → JWT Authorization: Bearer | GET /runs, GET /runs/{runId}, POST /ui/analyze |
| GitHub Actions / CLI | API key (x-api-key) | POST /analyze |
Invite the owner
Section titled “Invite the owner”Pass the owner email on CDK deploy. For GitHub Deploy, set Actions secret PR_READY_OWNER_EMAIL (preferred); Deploy reads the secret first, then falls back to an Actions variable of the same name.
export PR_READY_OWNER_EMAIL=you@example.comnpx cdk deploy --require-approval never -c enableDynamo=true -c ownerEmail="$PR_READY_OWNER_EMAIL"If the user was not created by CDK, create once:
POOL_ID="$(aws cloudformation describe-stacks --stack-name PrReadinessCoachStack \ --query "Stacks[0].Outputs[?OutputKey=='CognitoUserPoolId'].OutputValue" --output text)"aws cognito-idp admin-create-user \ --user-pool-id "$POOL_ID" \ --username "$PR_READY_OWNER_EMAIL" \ --user-attributes Name=email,Value="$PR_READY_OWNER_EMAIL" Name=email_verified,Value=true \ --desired-delivery-mediums EMAILInvited users start in FORCE_CHANGE_PASSWORD. Prefer signing in on the SPA (it prompts for a permanent password), or set one via console / admin-set-user-password --permanent.
Amplify Hosting (zip path)
Section titled “Amplify Hosting (zip path)”Hosting uses Amplify zip deploy
SPA hosting path: CDK creates Amplify app/branch with auto-build off; a separate job zip-uploads the Vite build — no GitHub↔Amplify Git connection. — not a GitHub↔Amplify console connection.
- CDK creates an Amplify app +
mainbranch (enableAutoBuild: false, no repository) - Separate job
deploy-amplify(after CDK) runsscripts/deploy-amplify.sh:- Reads
ApiUrl+ Cognito outputs from the stack - Builds
web/withVITE_*baked in - Zip-uploads (
create-deployment→ upload →start-deployment)
- Reads
# After CDK deploynpm run deploy:amplify# App URL:aws cloudformation describe-stacks --stack-name PrReadinessCoachStack \ --query "Stacks[0].Outputs[?OutputKey=='AppUrl'].OutputValue" --output textCaveats
Section titled “Caveats”- Vite bake-time env:
VITE_API_URL/ Cognito IDs are compiled into the JS bundle. The Amplify job must run after CDK so those outputs exist. Re-rundeploy-amplifywhenever API/Cognito outputs change. - Separate jobs on purpose: CDK failures stay in
deploy; SPA/build/Amplify failures stay indeploy-amplify. - No
VITE_API_KEY: browser auth is Cognito JWT only — never put the API key in Amplify / Vite env. - Root
amplify.ymlis unused for this zip path (buildSpec on the Amplify app is console-compat only). - After the first
AppUrlis known, you may tighten API Gateway CORS from*to that origin in a follow-up.
Local UI without Amplify
Section titled “Local UI without Amplify”cd webcp .env.example .env.local # fill Cognito + ApiUrlnpm run devDemo evidence
Section titled “Demo evidence”Runs list (NOT READY / READY / READY WITH WARNINGS):

Try it — POST /ui/analyze with Cognito JWT:

Cost notes
Section titled “Cost notes”DynamoDB on-demand + ~30-day TTL; Cognito free tier covers a single user; Amplify Hosting free tier is usually enough for a private demo. Bedrock invoke cost dominates real usage.