Repr data is stored in AWS (DynamoDB) through an authenticated API.
- Web client:
apps/client-web(Next.js) - Mobile client:
apps/client-mobile(Expo / React Native — starter template) - Backend app:
apps/server(TypeScript Lambda handlers + CDK stacks)
The mobile app lives in apps/client-mobile with its own package.json / node_modules (npm). From the repo root:
yarn start:mobile
# or
yarn start:androidOr cd apps/client-mobile && npm start. First-time setup after clone: cd apps/client-mobile && npm install.
Auth uses the same Cognito pool/API as web. Repo-root .env NEXT_PUBLIC_* values are loaded via app.config.js and mapped to EXPO_PUBLIC_* (see .env.example).
After npm install, a local apps/client-mobile/libs junction/symlink is created so Metro can resolve shared @reprman/* packages (run npm run link:libs if needed).
Note: Amplify Auth needs a development build (npx expo run:android / run:ios), not Expo Go.
Next.js reads NEXT_PUBLIC_* variables from the repository root .env (see apps/client-web/next.config.ts). Copy .env.example to .env or .env.local and fill in values.
For local UI against the Dev API, use the CloudFormation outputs from stack ReprServerStack-Dev (UserPoolId, UserPoolClientId, ApiBaseUrl) after a deploy:
aws cloudformation describe-stacks \
--stack-name ReprServerStack-Dev \
--query "Stacks[0].Outputs" \
--output tableSet NEXT_PUBLIC_COGNITO_USER_POOL_ID, NEXT_PUBLIC_COGNITO_USER_POOL_CLIENT_ID, and NEXT_PUBLIC_REPRS_API_BASE_URL accordingly.
yarn build:serveryarn lint:serveryarn test:server
Browser tests live in apps/client-web/e2e/specs (*.spec.ts). They need Dev Cognito/API in repo root .env plus test credentials in .env.e2e (see apps/client-web/e2e/README.md).
yarn test:e2e:install— install Chromium for Playwrightyarn test:e2e— run the suite (starts the Next.js dev server unless one is already running)yarn test:e2e:ui— debug in UI mode
The app defines two stacks in the same AWS account:
| Stack id | Purpose |
|---|---|
ReprServerStack-Dev |
Dev API, Cognito user pool + client, DynamoDB (isolated from prod) |
ReprServerStack-Prod |
Production API + Cognito + DynamoDB |
Each stack creates its own Cognito User Pool and app client (no --context userPoolId anymore).
Deploy from your machine (after yarn build:server, from repo root):
- Dev API only:
yarn deploy:serverornx run server:cdk:deploy:dev - Prod API only (no frontend, no git promotion):
nx run server:cdk:deploy:prod
| Branch | Role |
|---|---|
main |
Day-to-day integration. Pushing here deploys the Dev API only (see Actions). Run the app locally against Dev using .env / .env.local from ReprServerStack-Dev outputs. |
production |
What ships to customers. Pushing here runs validate → build → CDK Prod → S3 → CloudFront (see .github/workflows/deploy-prod.yml). |
Promote main → production (recommended release command):
yarn deploy:prodThis runs scripts/promote-production.mjs: fast-forward main from origin, merge origin/main into production with a merge commit, and git push origin production. That push triggers the Deploy Production workflow — no AWS steps run on your laptop.
- First run: if
origin/productiondoes not exist yet, the script createsproductionfrom the currentmaintip and pushes it (then CI deploys). - On success, the script checks out
mainagain and deletes your localproductionbranch for safety. - Optional env:
REPRMAN_MAIN_BRANCH(defaultmain),REPRMAN_PRODUCTION_BRANCH(defaultproduction).
If production is already up to date with main, the merge is a no-op and the push may not create a new commit — GitHub Actions might not run again. To redeploy the same commit, use Actions → Deploy Production → Run workflow (workflow_dispatch).
Local commit guard on production
- The pre-commit hook now blocks commits when your current branch is
production. yarn deploy:prodstill works because it sets an internal one-command bypass (ALLOW_PRODUCTION_COMMIT=1) for the release merge commit only.- If a promotion merge conflicts, the script leaves you on
productionso you can resolve/abort manually.
Protecting production from casual pushes
GitHub → Settings → Branches → Add branch protection rule for production:
- Turn on Restrict who can push to matching branches and allow only you (or a release role), or require pull request reviews and disallow direct pushes for everyone.
- If no one may push directly (strict PR-only),
yarn deploy:prodfrom your laptop will be rejected unless you use a bypass or a personal access token with admin rights. In that case, promote by opening a PR frommain→productionand merging on GitHub instead; the same Deploy Production workflow still runs on merge.
Keep the repository default branch as main for normal development and PRs.
Optional environment variables for cdk synth / cdk deploy (same shell as the CDK process on CI or locally):
| Variable | Effect |
|---|---|
CDK_DEV_CORS_ORIGINS |
Comma-separated browser origins for Dev API CORS (default: http://localhost:3000) |
CDK_PROD_CORS_ORIGINS |
Comma-separated origins for Prod API CORS (default includes localhost + reprman.com) |
CDK_BILLING_ALERT_EMAIL |
If set on Prod deploy, enables the monthly estimated charges alarm + SNS email subscription |
CDK context keys devCorsOrigins and prodCorsOrigins still work if you prefer --context instead of env vars.
Optional monitoring context (unchanged):
--context monthlyBudgetUsd=<number>(default:25) when billing email is enabled
- Push to
main:.github/workflows/deploy-dev-api.ymlruns checks and deploysReprServerStack-Devonly (no frontend upload). - Push to
production:.github/workflows/deploy-prod.ymlruns the same checks, then deploysReprServerStack-Prod, builds the SPA from stack outputs, uploads to S3, and optionally invalidates CloudFront. - Deploy Production (manual): Actions → Deploy Production → Run workflow — same job as above, but without a new commit on
production(useful to redeploy the currentproductiontip).
Repository secrets / variables (non-exhaustive):
- AWS:
AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY,AWS_REGION - Optional variable:
CDK_DEV_CORS_ORIGINS(e.g. extra dev origins beyond localhost) - Prod workflow:
AWS_PROD_BUCKET_NAME(or legacyAWS_TEST_BUCKET_NAME), optionalAWS_PROD_CLOUDFRONT_DISTRIBUTION_ID(or legacyAWS_CLOUDFRONT_DISTRIBUTION_ID), optional variableCDK_PROD_CORS_ORIGINS, optional secretCDK_BILLING_ALERT_EMAIL - Optional
VITE_*for the prod client build:VITE_REQUIRE_HOME_SIGN_IN,VITE_ALLOW_ANONYMOUS_HOME,VITE_COGNITO_IDENTITY_POOL_ID(see workflow file)
If you previously deployed a single stack named ReprServerStack, it is separate from ReprServerStack-Dev / ReprServerStack-Prod. Plan migration or delete the old stack after cutover.