# Almacenamiento S3 por app (API central)

Guía para **apps creadas con bootstrap** (Vite, Next, Streamlit) que necesitan subir, listar o descargar archivos en su bucket dedicado.

## Resumen

| Capa | Responsabilidad |
|------|-----------------|
| **Terraform (bootstrap)** | Crea bucket `boogiepop-{slug}-{accountId}` + task role de la **app** (uso server-side opcional) |
| **Terraform (global, una vez)** | IAM del **API** (`ecs_task_app_storage`): presign/list/get en `uploads/*` de todos los buckets app |
| **boogiepop-backend** | Módulo `storage`: presign PUT/GET, listado por usuario |
| **Remote / seed** | Cliente HTTP con `applicationSlug`; **sin** `VITE_AWS_*` ni `@aws-sdk` en browser |

Infra global ya aplicada en `boogiepop-infra/terraform/iam_hub_manifest.tf` (política `ecs_task_app_storage`) y env del API: `AWS_ACCOUNT_ID`, `BOOGIEPOP_PROJECT_NAME`.

## Endpoints (`/api/storage/...`)

Documentación completa: **`boogiepop-backend/AGENTS.md`**.

| Método | Ruta | Uso |
|--------|------|-----|
| POST | `uploads/presign` | Body: `applicationSlug`, `fileName`, `contentType` → PUT a `uploadUrl` |
| GET | `uploads?applicationSlug=` | Lista `uploads/<userId>/` del usuario autenticado |
| POST | `downloads/presign` | Body: `applicationSlug`, `objectKey` → abrir `downloadUrl` |

**Prod:** JWT + acceso a la app. **Dev API** (`NODE_ENV=development`): sin JWT; basta `applicationSlug` válido.

## Por tipo de seed

### Vite (remote estático / MF)

- Env build: **`VITE_API_BASE_URL`** (ej. `https://boogiepop.cloud`, sin `/api`).
- Constante **`applicationSlug`** = `HTTP_PATH` del bootstrap (ej. `sql-validator`).
- Patrón: `src/lib/storageApi.ts` — ver repo **boogiepop-sql-validator**.
- AGENTS: **boogiepop-react-seed/AGENTS.md**.

### Next.js (App Router)

- Mismo contrato HTTP desde **Client Components** (`fetch` + JWT del auth-sdk).
- Env: **`NEXT_PUBLIC_API_BASE_URL`** (añadir al Dockerfile/CI si hace falta).
- **No** duplicar S3 en Route Handlers salvo casos excepcionales; preferir API central.
- AGENTS: **boogiepop-next-seed/AGENTS.md**.

### Streamlit (Python)

- Bucket existe; **`APP_S3_BUCKET`** en el contenedor es para boto3 **server-side** (opcional).
- Para alinear con el resto de la plataforma: **`requests`** al API (`/api/storage/...`) con token de sesión si lo tenés, o dev bypass local.
- En Streamlit no hay presign en browser; el servidor Python llama al backend y luego PUT/GET a la URL firmada, o listá vía GET `/api/storage/uploads`.
- AGENTS: **boogiepop-streamlit-seed/AGENTS.md**.

## Checklist nueva app con archivos

1. **`boogiepop new`** con infra → bucket creado automáticamente.
2. App registrada en backend con `route: /{slug}` (bootstrap lo hace).
3. Remote/UI: implementar cliente storage con tu **`applicationSlug`**.
4. CI: incluir **`VITE_API_BASE_URL`** o **`NEXT_PUBLIC_API_BASE_URL`** apuntando al API prod.
5. **No** agregar keys AWS al frontend ni a Secrets de la app para upload browser.
6. Deploy **backend** (código `storage` module) + **app** cuando cambies UI.

## Visibilidad en el hub

`boogiepop new` y `boogiepop register-app` registran la app con **`hubVisible=false`**. La app responde en `https://boogiepop.cloud/<slug>/` pero **no aparece en el catálogo del hub** hasta publicarla:

```bash
boogiepop platform config   # una vez: credenciales admin
boogiepop publish -y <slug>  # ej. sql-validator
```

Para ocultarla de nuevo: `boogiepop hide -y <slug>`. Ver [CLI-BOOTSTRAP-INFRA.md](./CLI-BOOTSTRAP-INFRA.md#boogiepop-register-app--publish--hide).

## Apply infra global (solo si cambia IAM/env del API)

```bash
cd boogiepop-infra/terraform
terraform apply -target='aws_iam_role_policy.ecs_task_app_storage[0]' -target='aws_ecs_task_definition.api'
aws ecs update-service --cluster boogiepop-api-cluster --service boogiepop-api-svc --force-new-deployment --region us-east-1
```

Las apps nuevas **no** requieren apply extra para storage: el bucket viene en su `-target` de bootstrap; el API ya tiene permiso wildcard `boogiepop-*-{account}/uploads/*`.

## Referencia sql-validator

Implementación de referencia: repo **boogiepop-sql-validator** — `SqlValidatorPanel`, `S3UploadPanel`, `S3FilesPanel`, `src/lib/storageApi.ts`.
