# Infrastructure & hosting

This page is the **current-truth topology** for Drape production hosting,
reconciled against a live read of AWS account `230790682930` (**us-east-1**) on
2026-09-17. Resource IDs, RDS classifications, and the evidence legend live on
the [AWS system map](./aws-system-map.md).

**AWS is not Amplify-only.** Amplify hosts the four web surfaces. Route 53,
Amplify-managed CloudFront hostnames, an ALB, ECS Fargate, ECR, RDS PostgreSQL,
ACM, and Secrets Manager run the Postgres web API. The MongoDB mobile backend
remains on **Render** (non-AWS). Object storage is still **Supabase** (this
account has **zero** S3 buckets — that empty result is live, not a claim that
“nothing else is on AWS”).

:::warning[Superseded claims — do not revive]
These used to appear here as current truth and are **wrong**:

- **“No Route 53”** — hosted zone `drape.to` / `Z00780563EFBECXPWSBK4` is live.
- **Amplify Git on `KCB1099/*` only** — live Amplify repositories are
  `https://github.com/drape-ai-llc/...` (org).
- **ECS cluster named `drape-prod`** — the cluster is **`drape`**; `drape-prod`
  and `drape-dev` are **services**.
- **Docs site amplifyapp-only** — `docs.drape.to` is a live Amplify custom
  domain.
- **API / Postgres only on Render or off-AWS** — `api.drape.to` is ALB → ECS;
  Postgres is RDS in this account. Render is the **Mongo mobile** path only.
- **“No RDS” / “no ACM”** — three RDS instances and an ALB ACM cert exist in
  us-east-1.
- **Lightsail still serving `api.drape.to`** — decommissioned; see
  [prod cutover](../shipping/prod-cutover.md).
:::

## The real topology

```mermaid
graph TB
    subgraph aws [AWS account 230790682930 us-east-1]
        R53["Route 53 zone drape.to"]
        AM["AWS Amplify"]
        AM --> A1["Marketing - drape.to + www"]
        AM --> A2["Brand - brand + wildcard"]
        AM --> A3["Admin - admin.drape.to"]
        AM --> A4["Docs - docs.drape.to"]
        ALB["ALB drape-alb"]
        ECS["ECS cluster drape"]
        ALB -->|"host api.drape.to"| P["service drape-prod"]
        ALB -->|"default / dev-api"| D["service drape-dev"]
        P -.->|"docs-supported"| RDSp[("RDS prod-live docs-supported")]
        D -.->|"docs-supported"| RDSd[("RDS drape-postgres probable DEV")]
        ECS --> P
        ECS --> D
    end

    subgraph off [Off-AWS]
        Render["Render - Mongo FastAPI + worker + cron"]
        Mongo[("MongoDB Atlas")]
        Redis[("Upstash Redis")]
        Supa[("Supabase storage")]
        EAS["EAS / TestFlight - mobile"]
    end

    R53 --> AM
    R53 --> ALB
    A1 --> ALB
    A2 --> ALB
    A3 --> ALB
    Render --> Mongo
    Render --> Redis
    Render --> Supa
```

*ECS → RDS edges are **docs-supported**, not proven by reading secret contents.
`drape-postgres` is **probable** DEV, not API-verified. See the
[AWS system map](./aws-system-map.md).*

Web apps call the Postgres API at `api.drape.to` (prod) / `dev-api.drape.to`
(dev). The mobile app still talks to the Mongo backend on Render.

## AWS Amplify apps (verified)

All four are in **us-east-1**. The three Next.js apps are **`WEB_COMPUTE`**
(Amplify's Next.js server runtime, not a pure static bucket), git-connected,
with `main` = production. This docs site is platform **`WEB`** (static) and is
git-connected to the org — it is **not** amplifyapp-only.

| App | App ID | Custom domain | Platform | Repo on Amplify | Branches |
|---|---|---|---|---|---|
| Drape-Marketing | `d25a3s1rbghls0` | `drape.to` + `www` | WEB_COMPUTE | `drape-ai-llc/drape-marketing` | `main` (prod), `develop` |
| Drape-brand | `du0asj4lh5zwr` | `brand.drape.to` + `*.drape.to` | WEB_COMPUTE | `drape-ai-llc/drape-brand` | `main` (prod) |
| Drape-admin-v1 | `d2pa8ox8j0q7ch` | `admin.drape.to` | WEB_COMPUTE | `drape-ai-llc/drape-admin-v1` | `main` (prod) |
| Drape-Docs | `d2ip1x1ygwzne5` | **`docs.drape.to`** | WEB (static) | `drape-ai-llc/drape-docs` | `main` |

Two corrections versus older READMEs and this page's prior revision:

- **Not static exports in practice** for marketing / brand / admin. Repos may
  still say `output: "export"`, but Amplify runs them as **`WEB_COMPUTE`**.
- **Repos on Amplify are the org**, `github.com/drape-ai-llc/*`, not the
  founder's personal `KCB1099/*` copies.

:::note[Brand wildcard DNS is live; Amplify verified=false is a quirk]
Route 53 has `brand` and `*.drape.to` CNAMEs to the brand CloudFront hostname,
and the Amplify domain association includes both. Amplify still reports
**`verified=false`** on those two names while `domainStatus` is **AVAILABLE**.
That is a console/metadata issue — not “the wildcard is unwired.” See the
[AWS system map](./aws-system-map.md).
:::

## DNS is Route 53

The `drape.to` hosted zone is **`Z00780563EFBECXPWSBK4`**. Apex/www, brand,
wildcard, admin, and docs point at Amplify-managed CloudFront hostnames. `api`
and `dev-api` are alias A records to `drape-alb`.

`ListDistributions` in-account is empty (not AccessDenied). CloudFront IDs are
abstracted by Amplify; the hostnames in Route 53 are the live proof.

Dev API hostname is **`dev-api.drape.to`**. `staging.drape.to` is not in this
zone map.

## Postgres API — ECS Fargate + RDS

Per [ADR-0002](../decisions/0002-lightsail-to-ecs-rds-migration.md) and the
[2026-08-31 cutover](../shipping/prod-cutover.md):

- Cluster **`drape`** (Fargate). Services **`drape-prod`** and **`drape-dev`**.
- Both services assign a **public IP** (no NAT). Ingress is from the ALB
  security group only.
- ALB **`drape-alb`**: host `api.drape.to` → prod target group; default and
  `dev-api.drape.to` → dev target group.
- Images from ECR **`drape-backend-postgres`**.
- Code: `Drape-AI-LLC/Drape-` **`backend-postgres/`**. `develop` auto-deploys
  ECS **dev**; **prod is `workflow_dispatch`**.

### RDS — classify, do not delete

`DATABASE_URL` host mapping is **docs-supported** (cutover + README). Stage 2A
did **not** read secret values to re-prove which task definition points at which
instance.

| Instance | Role | Notes |
|---|---|---|
| `drape-postgres-prod-live` | **ACTIVE PROD** | Private `db.t4g.small`. Cutover restored live data here. |
| `drape-postgres` | **probable ACTIVE DEV** | Public `db.t4g.micro` — README-documented shortcut, not secret-read proven. |
| `drape-postgres-prod` | **LEGACY CANDIDATE** | Rollback leftover. **Not approved for deletion.** |

## What is empty on AWS vs what is not

Live-empty in us-east-1 (this is *not* “AWS hosts nothing but Amplify”):

- **No S3 buckets** — object storage is Supabase.
- **No Lambda, API Gateway, ElastiCache, or EC2 instances.**
- **No SSM parameters** listed.

Present and live:

- Route 53, Amplify, ALB, ECS, ECR, RDS, ACM (ALB cert), Secrets Manager
  (names only: `drape/backend/prod-keys`, `drape/backend/shared-keys`).

## Where the rest runs

| Concern | Runs on |
|---|---|
| Postgres web API | **ECS Fargate** on cluster `drape` — `api.drape.to` (prod), `dev-api.drape.to` (dev) |
| PostgreSQL | **RDS** in this account (see table above) |
| Mongo FastAPI + worker + cron | **Render** (`drape-backend-avjg.onrender.com`) — mobile path only |
| MongoDB (generation 1) | MongoDB Atlas |
| Cache / rate limits / try-on jobs | Upstash Redis |
| Object storage (body photos, garments) | Supabase Storage |
| DNS for `drape.to` | **Route 53** zone `Z00780563EFBECXPWSBK4` |
| Web apps + this docs site | AWS Amplify (us-east-1) |
| Mobile builds / distribution | EAS → TestFlight |

Mental model: **Amplify + Route 53 = web CDN/DNS; ECS + RDS = Postgres API;
Render = Mongo mobile backend; Supabase / Upstash / Stripe stay managed
off-AWS.** Deploy mechanics:
[Web deploys](../shipping/web-deploys.md) ·
[Backend deploys](../shipping/backend-deploys.md) ·
[AWS system map](./aws-system-map.md).
