# Upload de Archivos a S3 — Documentación

## Descripción General

Este sistema permite subir archivos directamente a un bucket de almacenamiento (S3 o compatible) utilizando **URLs pre-firmadas** (presigned URLs). El flujo se divide en dos pasos:

1. **Generar la URL pre-firmada** — solicitud al backend.
2. **Subir el archivo** — envío directo al storage usando la URL obtenida.

El archivo se envía en formato **binario crudo** (no Base64), lo cual es más eficiente ya que evita el incremento de ~33% en tamaño que produce la codificación Base64.

---

## Flujo General

```
Cliente                     Backend                      S3 / Storage
  |                            |                              |
  |-- POST /generate-url ----->|                              |
  |<-- { uploadUrl, fileUrl } -|                              |
  |                            |                              |
  |-- PUT uploadUrl (binary) -------------------------------->|
  |<-- 200 OK ------------------------------------------------|
```

---

## Paso 1 — Generar URL Pre-firmada

### Endpoint

```
POST https://www.goappy.net/dev/core/services/public/api/v1/generate-upload-url
```

### Headers

| Header         | Valor              |
|----------------|--------------------|
| Content-Type   | application/json   |

### Body (JSON)

```json
{
    "filename": "foto.jpg",
    "type": "image/jpeg",
    "folder": "casadomenor/photos/"
}
```

### Parámetros

| Campo      | Tipo   | Descripción                                      |
|------------|--------|--------------------------------------------------|
| `filename` | string | Nombre del archivo con extensión                  |
| `type`     | string | Tipo MIME del archivo (ej: `image/jpeg`, `application/pdf`) |
| `folder`   | string | Ruta de destino dentro del bucket                 |

### Respuesta Exitosa

```json
{
    "status": 200,
    "uploadUrl": "https://bucket.s3.amazonaws.com/casadomenor/photos/foto.jpg?X-Amz-...",
    "fileUrl": "https://bucket.s3.amazonaws.com/casadomenor/photos/foto.jpg"
}
```

| Campo       | Descripción                                              |
|-------------|----------------------------------------------------------|
| `status`    | Código de estado (200 = éxito)                           |
| `uploadUrl` | URL pre-firmada para hacer el PUT del archivo            |
| `fileUrl`   | URL pública final del archivo una vez subido             |

### Errores

- `status != 200` — Error del backend al generar la URL.
- `uploadUrl` ausente — La URL no fue generada correctamente.

---

## Paso 2 — Subir el Archivo (PUT)

### Request

```
PUT {uploadUrl obtenida en el paso 1}
```

### Headers

No se requieren headers. La URL pre-firmada contiene los permisos necesarios en sus query params.

> **Nota:** Si el upload falla, intentar agregar el header `Content-Type` con el tipo MIME del archivo (ej: `image/jpeg`).

### Body

- Tipo: **binary**
- Contenido: el archivo crudo (no codificado).

### Respuesta

- `200 OK` — Archivo subido correctamente.
- Cualquier otro código — Error en el upload.

---

## Pruebas con Postman

### Paso 1 — Generar URL

1. Method: **POST**
2. URL: `https://www.goappy.net/dev/core/services/public/api/v1/generate-upload-url`
3. Tab **Headers**: agregar `Content-Type: application/json`
4. Tab **Body**: seleccionar `raw` → `JSON` → pegar:

```json
{
    "filename": "foto.jpg",
    "type": "image/jpeg",
    "folder": "casadomenor/photos/"
}
```

5. Enviar y copiar el valor de `uploadUrl` de la respuesta.

### Paso 2 — Upload del Archivo

1. Method: **PUT**
2. URL: pegar la `uploadUrl` copiada del paso anterior.
3. Tab **Body**: seleccionar **binary** → clic en **Select File** → elegir el archivo.
4. Enviar.

---

## Tipos MIME Comunes

| Extensión | Tipo MIME            |
|-----------|----------------------|
| .jpg      | image/jpeg           |
| .png      | image/png            |
| .gif      | image/gif            |
| .pdf      | application/pdf      |
| .mp4      | video/mp4            |
| .doc      | application/msword   |
| .docx     | application/vnd.openxmlformats-officedocument.wordprocessingml.document |

---

## Ejemplo en JavaScript (Frontend)

```javascript
async function uploadFile(file) {

    // 1. Generar URL pre-firmada
    const response = await fetch(
        'https://www.goappy.net/dev/core/services/public/api/v1/generate-upload-url',
        {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({
                filename: file.name,
                type: file.type,
                folder: 'casadomenor/photos/'
            })
        }
    );

    const data = await response.json();

    if (!response.ok || data.status != 200) {
        throw new Error('Error al generar URL');
    }

    // 2. Upload directo al storage (binario)
    const uploadResponse = await fetch(data.uploadUrl, {
        method: 'PUT',
        body: file  // se envía como binario, NO como Base64
    });

    if (!uploadResponse.ok) {
        throw new Error('Error al subir archivo');
    }

    return data.fileUrl;
}
```
