# dev.theorchard.io internal SPA deployment reference

## Terraform pattern

Use `terraform-internal-spa` from `terraform-infra/dev/<service-name>` for dev-hosted internal SPAs.

Identity-analysis uses:

```hcl
module "internal_spa" {
  source = "git@github.com:theorchard/terraform-internal-spa.git?ref=1.1.0"

  providers = {
    aws.dns = aws
  }

  environment                 = var.environment
  service_name                = var.service_name
  application_family          = var.application_family
  vpc_id                      = data.aws_vpc.dev.id
  load_balancer_subnet_ids    = slice(data.aws_subnets.private.ids, 0, 2)
  fully_qualified_domain_name = "${var.service_name}.${var.dns_zone_name}"
  certificate_domain          = "*.${var.dns_zone_name}"
  ingress_prefix_list_names   = ["vpn-ny-users"]
  route53_record_enabled      = true
  route53_zone_name           = var.dns_zone_name
}
```

Default variables:

- `aws_region`: `us-east-1`
- `environment`: `dev`
- `dns_zone_name`: `dev.theorchard.io`
- `application_family`: commonly `devops`
- `team`: Datadog team slug, identity-analysis uses `accounts-platform`

The state backend for identity-analysis is:

```hcl
backend "s3" {
  bucket  = "dev-orcd-terraform-state"
  key     = "dev/identity-analysis/terraform.tfstate"
  region  = "us-east-1"
  encrypt = "true"
}
```

## Frontend build and upload pattern

Identity-analysis deploys a Suite/Vite app from `frontend/`:

```sh
export GRAPHQL_URL=https://qa-ows-grass.theorchard.io/graphql-router/graphql
export VITE_API_BASE_URL=https://identity-analysis.dev.theorchard.io
export CDN_URL=https://identity-analysis.dev.theorchard.io
npm run build
```

Its `frontend.json` uses:

- `appName`: `frontend-identity-analysis`
- `cdnUrl`: `${env.CDN_URL}`
- `graphqlUrl`: `${env.GRAPHQL_URL}`

Upload shape:

```sh
aws s3 cp build/index.html s3://identity-analysis.dev.theorchard.io/index.html
aws s3 cp build/<asset> s3://identity-analysis.dev.theorchard.io/frontend-identity-analysis/<asset>
```

Identity-analysis patches generated asset paths because the build emits absolute paths. When adapting this pattern, inspect generated `build/index.html` and JS worker URLs before copying the sed commands directly.

## Data-backed static app pattern

`ratoui/identity-analysis/scripts/publish-data.sh` does this:

1. Selects `backend/data/output/combined_users_*.json.gz`.
2. Uploads it to `s3://identity-analysis.dev.theorchard.io/data/<filename>` with `--content-type application/x-gzip`.
3. Updates `frontend/.env` with `VITE_DATA_FILE=<filename>`.
4. Exports `VITE_DATA_FILE` and runs `frontend/scripts/deploy.sh`.

Use versioned data filenames rather than overwriting a generic data blob when freshness and rollback matter.

## Review checklist

- Terraform domain: `<service_name>.dev.theorchard.io`
- S3 bucket target matches the FQDN
- Route53 is enabled for the dev zone
- Ingress is restricted to expected internal prefix lists
- CORS only allows required local/dev origins
- Build env vars match the target domain
- `index.html` upload path and asset prefix match generated references
- Worker/chunk paths resolve under the same asset prefix
- Data files, if any, are uploaded before the build that references them

