| .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 and https://staging.seahaven.com
- Backend APIs: matching
api.<environment>.seahaven.com/apiendpoints, called directly from the browser
Architecture
Static SPA hosting on AWS. CloudFront serves the built dist/ from a private,
versioned S3 bucket; the SPA calls the backend directly over HTTPS at
VITE_API_URL. The live stacks remain CDK/CloudFormation-owned while the
import-first Terraform transfer is rehearsed and reviewed. See
terraform/README.md.
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[Manual GitHub deployment] -->|OIDC| ROLE[Environment deploy role]
ROLE -->|content publish + 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
Stacks shoc-frontend-dev and shoc-frontend-staging are currently
CDK-owned in account 396287094661, region us-east-1. They are defined in
infra/cdk/lib/frontend-stack.ts.
| Resource | Name | Purpose |
|---|---|---|
| S3 bucket | seahaven-shoc-frontend-{dev,staging} |
Private origin (BLOCK_ALL, SSE, versioned; OAC-only reads) |
| CloudFront distribution | E2CWLM1AFB964P / E2JDVEZ6EGD49J |
HTTPS static hosting on the matching environment domain |
| CloudFront Function | SpaRewrite |
Viewer-request rewrite of extensionless paths to /index.html (deep links) |
| IAM role | githubdeploy-shoc-frontend-new-{dev,staging} |
Environment-scoped GitHub OIDC content deploy role |
| Route 53 records | A/AAAA aliases in the dev and staging hosted zones | Point each custom domain at its CloudFront distribution |
No Lambdas, queues, or databases — this stack is static hosting only.
Configuration
Secrets
No Secrets Manager, SSM parameters, AWS access keys, or deploy-role repo secret are used. Content workflows assume their pinned environment role through GitHub OIDC.
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 for normal dev synthesis lives in
infra/cdk/cdk.json. CDK deployment is no longer part of
recurring content releases during the ownership transfer.
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/,fix/,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 during migration:
feature/* → dev, then an explicitly approved manual dev deployment and verification ondev.seahaven.com. Staging promotion and deployment are separate approvals. No production environment exists yet.
Deployment
CI/CD uses OIDC and stores no AWS access keys:
- 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,.github/workflows/deploy-staging.yml, and.github/workflows/deploy-tf-poc.yml) is manual-only during migration.scripts/deploy-web.shpublishes to pinned targets, verifies cache/API/routing behavior, retains two release manifests, and restores the prior versioned index on verification failure.
The isolated rehearsal, retention mechanism, and deployment prerequisites are
documented in infra/cdk/README.md. Terraform ownership,
HCP configuration, import gates, evidence, and rollback are documented in
terraform/README.md.
Infrastructure changes and ownership transfer remain separate reviewed
administrator actions. Content workflows never run cdk deploy or Terraform
apply.
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
- Deploy workflow is unavailable on an arbitrary ref — each manual workflow checks its exact branch or protected GitHub environment before assuming AWS credentials.
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/