# API de Menús y Carrito - Documentación Completa

## Base URL
- Desarrollo local: `http://127.0.0.1:8000`
- Android Emulator: `http://10.0.2.2:8000`

---

## Autenticación

### Registro de usuario
**POST** `/api/register`

**Body:**
```json
{
  "name": "Juan Pérez",
  "email": "juan@example.com",
  "password": "123456",
  "password_confirmation": "123456"
}
```

**Respuesta (201):**
```json
{
  "message": "Usuario registrado correctamente",
  "data": {
    "id": 1,
    "name": "Juan Pérez",
    "email": "juan@example.com"
  }
}
```

### Login
**POST** `/api/login`

**Body:**
```json
{
  "email": "juan@example.com",
  "password": "123456"
}
```

**Respuesta (200):**
```json
{
  "access_token": "abc123...",
  "token_type": "Bearer",
  "user": {
    "id": 1,
    "name": "Juan Pérez",
    "email": "juan@example.com"
  }
}
```

---

## Menús

### Obtener menú por fecha
**GET** `/api/menus?date=YYYY-MM-DD&user_id=ID`

**Query Params:**
- `date` (opcional): Fecha del menú en formato YYYY-MM-DD
- `user_id` (opcional): ID del usuario

**Respuesta (200):**
```json
{
  "id": 1,
  "user_id": 1,
  "date": "2025-10-08",
  "name": "Menú del día",
  "is_default": false,
  "sections": [
    {
      "id": 1,
      "title": "Entradas",
      "items": [
        {
          "id": 1,
          "name": "Ensalada",
          "price_per_gram": 0.02,
          "observations": "sin cebolla"
        }
      ]
    }
  ]
}
```

### Crear menú
**POST** `/api/menus`

**Body:**
```json
{
  "user_id": 1,
  "date": "2025-10-08",
  "name": "Menú del día 2025-10-08",
  "is_default": false,
  "sections": [
    {
      "title": "Entradas",
      "items": [
        {
          "name": "Ensalada",
          "price_per_gram": 0.02,
          "observations": "sin cebolla"
        },
        {
          "name": "Ceviche",
          "price_per_gram": 0.04,
          "observations": ["sin limón", "con cilantro"]
        }
      ]
    },
    {
      "title": "Platos fuertes",
      "items": [
        {
          "name": "Pollo asado",
          "price_per_gram": 0.05,
          "observations": "con papas"
        }
      ]
    }
  ]
}
```

**Respuesta (201):** Menú creado con todas sus secciones e items.

---

## Carrito

### Obtener carrito
**GET** `/api/cart?user_id=ID&date=YYYY-MM-DD`

**Query Params:**
- `user_id` (requerido): ID del usuario
- `date` (opcional): Fecha del carrito

**Notas de seguridad:** Solo devuelve el carrito del usuario especificado.

**Respuesta (200):**
```json
{
  "id": 1,
  "user_id": 1,
  "date": "2025-10-08",
  "items": [
    {
      "id": 1,
      "cart_id": 1,
      "menu_item_id": 1,
      "name": "Ensalada",
      "grams": 150,
      "price_per_gram": 0.02,
      "note": "sin sal",
      "menu_item": {
        "id": 1,
        "name": "Ensalada",
        "price_per_gram": 0.02
      }
    }
  ]
}
```

### Agregar ítem al carrito
**POST** `/api/cart/add`

**Opción 1 - Con menu_item_id:**
```json
{
  "user_id": 1,
  "date": "2025-10-08",
  "item": {
    "menu_item_id": 1,
    "grams": 150,
    "note": "sin sal"
  }
}
```

**Opción 2 - Ítem personalizado:**
```json
{
  "user_id": 1,
  "date": "2025-10-08",
  "item": {
    "name": "Tallarines",
    "grams": 200,
    "price_per_gram": 0.03,
    "note": "extra queso"
  }
}
```

**Respuesta (201):** Item agregado al carrito.

### Eliminar un ítem del carrito
**DELETE** `/api/cart/item/{id}?user_id=ID`

**Path Params:**
- `id`: ID del cart_item a eliminar

**Query Params:**
- `user_id` (requerido): ID del usuario

**Notas de seguridad:** Solo puede eliminar ítems de su propio carrito.

**Respuesta (200):**
```json
{
  "message": "Item removed successfully"
}
```

**Respuesta (404):**
```json
{
  "error": "Item not found or not owned by user"
}
```

### Vaciar carrito completo
**DELETE** `/api/cart?user_id=ID&date=YYYY-MM-DD`

**Query Params:**
- `user_id` (requerido): ID del usuario
- `date` (requerido): Fecha del carrito a vaciar

**Notas de seguridad:** Solo puede vaciar su propio carrito.

**Respuesta (200):**
```json
{
  "message": "Cart cleared successfully"
}
```

**Respuesta (404):**
```json
{
  "error": "Cart not found"
}
```

---

## Códigos de Estado HTTP

- `200 OK`: Operación exitosa
- `201 Created`: Recurso creado exitosamente
- `400 Bad Request`: Faltan parámetros requeridos o datos inválidos
- `401 Unauthorized`: Credenciales inválidas
- `404 Not Found`: Recurso no encontrado o no pertenece al usuario
- `422 Unprocessable Entity`: Error de validación

---

## Seguridad y Mejores Prácticas

### Filtrado por usuario
Todos los endpoints de carrito filtran por `user_id` para garantizar que:
- Un usuario solo puede ver sus propios carritos
- Un usuario solo puede modificar/eliminar sus propios ítems
- Un usuario solo puede vaciar sus propios carritos

### Autenticación (para futuras mejoras)
Actualmente los endpoints aceptan `user_id` como parámetro. Para producción se recomienda:
1. Proteger rutas con middleware de autenticación
2. Extraer el `user_id` del token en lugar de recibirlo como parámetro
3. Usar el header: `Authorization: Bearer {access_token}`

---

## Ejemplos de Integración Flutter

### Servicio de Carrito (cart_service.dart)

```dart
import 'dart:convert';
import 'package:http/http.dart' as http;

class CartService {
  final String baseUrl;
  CartService(this.baseUrl);

  // Obtener carrito
  Future<Map<String, dynamic>> getCart(String userId, String date, String token) async {
    final uri = Uri.parse('$baseUrl/api/cart?user_id=$userId&date=$date');
    final res = await http.get(uri, headers: {
      'Content-Type': 'application/json',
      'Authorization': 'Bearer $token'
    });
    return {'statusCode': res.statusCode, 'body': jsonDecode(res.body)};
  }

  // Agregar ítem al carrito
  Future<Map<String, dynamic>> addItem(Map<String, dynamic> payload, String token) async {
    final uri = Uri.parse('$baseUrl/api/cart/add');
    final res = await http.post(uri,
      headers: {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer $token'
      },
      body: jsonEncode(payload),
    );
    return {'statusCode': res.statusCode, 'body': jsonDecode(res.body)};
  }

  // Eliminar ítem del carrito
  Future<Map<String, dynamic>> removeItem(String itemId, String userId, String token) async {
    final uri = Uri.parse('$baseUrl/api/cart/item/$itemId?user_id=$userId');
    final res = await http.delete(uri, headers: {
      'Content-Type': 'application/json',
      'Authorization': 'Bearer $token'
    });
    return {'statusCode': res.statusCode, 'body': jsonDecode(res.body)};
  }

  // Vaciar carrito completo
  Future<Map<String, dynamic>> clearCart(String userId, String date, String token) async {
    final uri = Uri.parse('$baseUrl/api/cart?user_id=$userId&date=$date');
    final res = await http.delete(uri, headers: {
      'Content-Type': 'application/json',
      'Authorization': 'Bearer $token'
    });
    return {'statusCode': res.statusCode, 'body': jsonDecode(res.body)};
  }
}
```

### Ejemplo de uso en Flutter

```dart
// Agregar al carrito
final payload = {
  'user_id': userId,
  'date': '2025-10-08',
  'item': {
    'menu_item_id': 1,
    'grams': 150,
    'note': 'sin sal'
  }
};
final result = await cartService.addItem(payload, token);

// Eliminar un ítem
final result = await cartService.removeItem('1', userId, token);

// Vaciar carrito
final result = await cartService.clearCart(userId, '2025-10-08', token);
```

---

## Testing con Postman

1. Importar colección: `postman_collection_menus_cart.json`
2. Configurar variables:
   - `base_url`: http://127.0.0.1:8000
   - `user_id`: 1
   - `menu_date`: 2025-10-08

3. Orden de prueba recomendado:
   - POST /api/register
   - POST /api/login
   - POST /api/menus (crear menú)
   - GET /api/menus (verificar menú)
   - POST /api/cart/add (agregar items)
   - GET /api/cart (ver carrito)
   - DELETE /api/cart/item/{id} (eliminar un item)
   - DELETE /api/cart (vaciar carrito completo)
