retainForTerraformAdoption=true adds the required ManageSiteInfrastructure parameter, conditions the 13 transferred resources and the S3 auto-delete custom resource on it, applies Retain policies, pins the live dev origin ID, attaches the deploy boundary and HcpTerraformWorkspace tag, and narrows the OIDC subject to StringEquals. Normal synthesis is unchanged; template tests cover both modes. |
||
|---|---|---|
| .cursor/rules | ||
| .github | ||
| .husky | ||
| config | ||
| docs | ||
| e2e | ||
| eslint-rules | ||
| infra/cdk | ||
| public | ||
| scripts | ||
| src | ||
| terraform | ||
| tmp/pr-descriptions | ||
| .env | ||
| .env.development | ||
| .env.example | ||
| .env.production | ||
| .gitignore | ||
| .prettierignore | ||
| .prettierrc | ||
| AGENTS.md | ||
| ARCHITECTURE_AND_CODE_QUALITY.md | ||
| commitlint.config.js | ||
| eslint.config.js | ||
| index.html | ||
| package-lock.json | ||
| package.json | ||
| playwright.config.ts | ||
| playwright.visual.config.ts | ||
| QUALITY_GATES.md | ||
| README.md | ||
| REVIEW_AND_PR_FRAMEWORK.md | ||
| tsconfig.json | ||
| tsconfig.node.json | ||
| vite.config.ts | ||
| vitest.config.ts | ||
SHOC Frontend (shoc-frontend-new)
Vite + React SPA for Sea Haven facility management (SHOC): work orders, vendor
portal, uplifts, and related admin features. This is the selective rebuild of
the legacy SHOC frontend — new code follows the IrisLoan.Admin conventions
documented in docs/ARCHITECTURE_PLAN.md.
- GitHub:
Sea-Haven-Industries/shoc-frontend-new - Hosted at: https://dev.seahaven.com (dev environment; the only environment today)
- Backend API:
https://api.dev.seahaven.com/api(called directly, cross-origin) — source:Sea-Haven-Industries/shoc-backend
Architecture
Static SPA hosting on AWS, provisioned by a CDK app local to this repo
(infra/cdk/). CloudFront serves the built dist/
from a private S3 bucket; the SPA calls the backend directly over HTTPS at
VITE_API_URL (no /api proxy at the CDN — the backend allows CORS).
graph LR
U[Browser] -->|HTTPS dev.seahaven.com| CF[CloudFront]
CF -->|OAC| S3[S3 seahaven-shoc-frontend-dev]
CF -.->|viewer-request fn| FN[SPA rewrite → /index.html]
U -->|HTTPS api.dev.seahaven.com/api CORS| API[SHOC backend API]
GH[GitHub Actions push to dev] -->|OIDC| ROLE[githubdeploy-shoc-frontend-new-dev]
ROLE -->|cdk deploy + s3 sync + invalidation| S3
Frontend stack: React 19, TypeScript, Vite, Tailwind CSS 4 + MUI, TanStack
Query, React Router (via @generouted/react-router), React Hook Form + Zod,
Ky HTTP client. Source layout: src/api/, src/domain/, src/app/ (see the
architecture plan for the keep/discard migration matrix).
AWS Resources
Stack shoc-frontend-dev — CDK, account 396287094661, region
us-east-1. Defined in infra/cdk/lib/frontend-stack.ts.
| Resource | Name | Purpose |
|---|---|---|
| S3 bucket | seahaven-shoc-frontend-dev |
Private origin (BLOCK_ALL, SSE, versioned; OAC-only reads) |
| CloudFront distribution | (stack output DistributionId) |
HTTPS static hosting on dev.seahaven.com, ACM *.seahaven.com |
| CloudFront Function | SpaRewrite |
Viewer-request rewrite of extensionless paths to /index.html (deep links) |
| IAM role | githubdeploy-shoc-frontend-new-dev |
GitHub Actions OIDC deploy role, trust scoped to repo:Sea-Haven-Industries/shoc-frontend-new:ref:refs/heads/dev |
| Route 53 records | A/AAAA apex alias in zone dev.seahaven.com (Z07671212N75U4YLPWZR8) |
Points the custom domain at CloudFront |
No Lambdas, queues, or databases — this stack is static hosting only.
Configuration
Secrets
No Secrets Manager or SSM parameters. The one secret is a GitHub Actions repo secret:
| Secret | Purpose |
|---|---|
AWS_DEPLOY_ROLE_ARN |
ARN of githubdeploy-shoc-frontend-new-dev, passed to the org reusable CD workflow |
Environment variables (build-time, VITE_*)
| Variable | Description | Dev value |
|---|---|---|
VITE_API_URL |
Ky API base prefix, baked into the build at vite build |
/api (dev server) / https://api.dev.seahaven.com/api (production build) |
VITE_API_TARGET |
Dev-proxy target for /api (Vite dev server only) |
http://localhost:5141 |
VITE_API_URL supplies the full API prefix — route paths in API_PATHS do
not include /api. Absolute values must end with /api;
vite.config.ts enforces this via config/api-url-contract.ts and fails the
build otherwise. See .env.example,
.env.development, and .env.production.
CDK context (domain, certificate ARN, hosted zone) lives in
infra/cdk/cdk.json so CI runs cdk deploy with no flags.
Local Development
Requirements: Node.js ≥ 22.22.1 (CI/CD run Node 24), npm 11.16.0 (pinned via
packageManager).
npm ci
cp .env.example .env # then set VITE_API_URL=/api for local dev
npm run dev # Vite dev server on port 3000, proxies /api → VITE_API_TARGET
The dev proxy expects the shoc-backend API at http://localhost:5141;
override with VITE_API_TARGET (e.g. https://api.dev.seahaven.com to use
the deployed dev API).
| Command | Description |
|---|---|
npm run dev |
Start Vite dev server on port 3000 |
npm run build |
Type-check (tsc -b) and production build to dist/ |
npm run preview |
Preview the production build locally |
npm test / npm run test:watch |
Vitest unit tests (once / watch) |
npm run test:e2e / npm run test:e2e:ui |
Playwright e2e tests (headless / UI mode) |
npm run lint / npm run lint:fix |
ESLint (check / auto-fix) |
npm run format / npm run format:check |
Prettier (write / check) |
npm run governance |
Frontend governance checks (godfile + maintainability) |
npm run verify |
All gates: format + lint + build + test + governance |
Husky + lint-staged run ESLint and Prettier on staged files at commit;
commitlint enforces conventional commit messages. Run npx tsc --noEmit (or
npm run build) before pushing to catch type errors early.
Contributing
- Branch from
devwith a kebab-case description and a prefix matching the work:feature/,bug/,hotfix/,chore/,docs/, orrefactor/(e.g.feature/vendor-portal-filters,chore/sea-haven-branding). - Commit messages follow Conventional Commits — commitlint rejects anything else at commit time.
- Open PRs against
dev. Bothdevandmainare protected: every PR needs a green CI run and an approving review from a code owner (@Sea-Haven-Industries/internal-dev); new pushes dismiss stale approvals. Merged branches are deleted automatically. - Promotion flow:
feature/* → dev(auto-deployed and verified ondev.seahaven.com)→ main(production promotion — no prod environment exists yet).
Deployment
CI/CD uses the org's reusable workflows (no stored AWS keys — OIDC only):
- CI (
.github/workflows/ci.yaml) — on push and PRs tomain/dev, callsSea-Haven-Industries/.github→ci-typescript-frontend.yaml(Node 24): format check, lint, build, tests; and runs a repo-ownedgovernancejob that callsnpm run verifyso every gate (including the maintainability ratchets inscripts/governance-check.mjs) is guaranteed from this repository. Conventions and gates are documented underAGENTS.md,QUALITY_GATES.md,ARCHITECTURE_AND_CODE_QUALITY.md, andREVIEW_AND_PR_FRAMEWORK.md. - CD (
.github/workflows/deploy.yml) — on push todev, callsSea-Haven-Industries/.github→cd-cdk.yaml, which runscdk deployoninfra/cdk(stackshoc-frontend-dev,us-east-1) and thenscripts/deploy-web.sh:npm run build,aws s3 sync dist/(hashed assets immutable,index.htmlnever cached), CloudFront invalidation. Both run as the OIDC deploy role.
One-time provisioning (OIDC provider, CDK bootstrap, first local deploy,
setting AWS_DEPLOY_ROLE_ARN) is documented in
infra/cdk/README.md.
Manual deploy (emergency/reference only — needs credentials for the
external-dev AWS account; the normal path is push to dev):
(cd infra/cdk && npx cdk deploy)
STACK_NAME=shoc-frontend-dev AWS_REGION=us-east-1 bash scripts/deploy-web.sh
Operations
- Verify: open https://dev.seahaven.com after a green Deploy run in the Actions tab; confirm a deep link (e.g. a work-orders route) loads directly and API calls succeed.
- Logs: deploy logs live in GitHub Actions (CI + Deploy workflows). There are no CloudWatch application logs — the stack is static hosting; runtime errors surface in the browser and on the backend API's side.
- Common failure modes:
- Stale content after deploy — the CloudFront invalidation step failed or
is still propagating; re-run the Deploy workflow or invalidate
/*manually. - OIDC
AssumeRoleerrors — the trust policy is scoped to pushes todevon this repo; deploys from other branches/repos are rejected by design. - Broken API requests after a build —
VITE_API_URLmissing the/apisuffix or carrying the wrong environment's host (it is baked in at build time). - CORS errors — the backend must allow the frontend origin; CloudFront does
not proxy
/api.
- Stale content after deploy — the CloudFront invalidation step failed or
is still propagating; re-run the Deploy workflow or invalidate
- CI and CD both fire on push to
devin parallel — a red-CI commit still deploys (matches the org's push-time-CD model; gating deploy on CI is known follow-up work).
Documentation
- Infra one-time setup and stack details:
infra/cdk/README.md - Rebuild strategy and conventions:
docs/ARCHITECTURE_PLAN.md; design system and UI docs underdocs/