|
|
@@ -0,0 +1,424 @@
|
|
|
+# API Documentation - Web Pedidos Klein
|
|
|
+
|
|
|
+## Información General
|
|
|
+
|
|
|
+**Título:** Web Pedidos Klein - FastAPI Backend
|
|
|
+**Descripción:** Backend para la aplicación Web Pedidos Klein utilizando FastAPI
|
|
|
+**URL Base:** `http://localhost:8000` (o su dominio de producción)
|
|
|
+
|
|
|
+## Autenticación
|
|
|
+
|
|
|
+La API utiliza autenticación basada en tokens JWT. La mayoría de endpoints requieren autenticación a través del header:
|
|
|
+```
|
|
|
+Authorization: Bearer <token>
|
|
|
+```
|
|
|
+
|
|
|
+## Endpoints
|
|
|
+
|
|
|
+### 🔐 Autenticación y Usuarios (`/api/users`)
|
|
|
+
|
|
|
+#### Verificar existencia de usuario
|
|
|
+- **POST** `/api/users/exists`
|
|
|
+- **Descripción:** Verifica si un usuario existe por ID
|
|
|
+- **Cuerpo de solicitud:**
|
|
|
+ ```json
|
|
|
+ {
|
|
|
+ "id": 123
|
|
|
+ }
|
|
|
+ ```
|
|
|
+- **Respuestas:**
|
|
|
+ - `200`: Usuario existe
|
|
|
+ - `404`: Usuario no encontrado
|
|
|
+
|
|
|
+#### Registrar usuario
|
|
|
+- **POST** `/api/users/register`
|
|
|
+- **Descripción:** Registra un nuevo usuario y envía código de verificación por email
|
|
|
+- **Cuerpo de solicitud:**
|
|
|
+ ```json
|
|
|
+ {
|
|
|
+ "name": "Juan Pérez",
|
|
|
+ "email": "juan@ejemplo.com",
|
|
|
+ "rut": "12345678-9"
|
|
|
+ }
|
|
|
+ ```
|
|
|
+- **Respuestas:**
|
|
|
+ - `201`: Usuario registrado exitosamente
|
|
|
+ - `400`: Usuario ya existe
|
|
|
+
|
|
|
+#### Crear usuario con PIN
|
|
|
+- **POST** `/api/users/create-user?q={verification_code}`
|
|
|
+- **Descripción:** Completa el registro del usuario estableciendo un PIN de 4 dígitos
|
|
|
+- **Parámetros de consulta:**
|
|
|
+ - `q`: Código de verificación recibido por email
|
|
|
+- **Cuerpo de solicitud:**
|
|
|
+ ```json
|
|
|
+ {
|
|
|
+ "pin": "1234"
|
|
|
+ }
|
|
|
+ ```
|
|
|
+- **Respuestas:**
|
|
|
+ - `201`: Usuario creado exitosamente con token
|
|
|
+ - `400`: PIN inválido o código de verificación expirado
|
|
|
+
|
|
|
+#### Iniciar sesión
|
|
|
+- **POST** `/api/users/login`
|
|
|
+- **Descripción:** Autentica un usuario con email y PIN
|
|
|
+- **Cuerpo de solicitud:**
|
|
|
+ ```json
|
|
|
+ {
|
|
|
+ "email": "juan@ejemplo.com",
|
|
|
+ "pin": "1234"
|
|
|
+ }
|
|
|
+ ```
|
|
|
+- **Respuestas:**
|
|
|
+ - `200`: Login exitoso con datos de usuario y token
|
|
|
+ - `401`: Credenciales inválidas
|
|
|
+ - `403`: Usuario bloqueado por intentos fallidos
|
|
|
+ - `429`: Demasiados intentos de login
|
|
|
+
|
|
|
+#### Eliminar usuario
|
|
|
+- **DELETE** `/api/users/delete`
|
|
|
+- **Descripción:** Elimina un usuario por ID
|
|
|
+- **Cuerpo de solicitud:**
|
|
|
+ ```json
|
|
|
+ {
|
|
|
+ "id": 123
|
|
|
+ }
|
|
|
+ ```
|
|
|
+- **Respuestas:**
|
|
|
+ - `200`: Usuario eliminado
|
|
|
+ - `404`: Usuario no encontrado
|
|
|
+
|
|
|
+#### Obtener todos los usuarios
|
|
|
+- **GET** `/api/users/all`
|
|
|
+- **Descripción:** Obtiene lista de todos los usuarios registrados
|
|
|
+- **Respuestas:**
|
|
|
+ - `200`: Lista de usuarios
|
|
|
+
|
|
|
+### 📧 Verificación (`/verify`)
|
|
|
+
|
|
|
+#### Verificar usuario
|
|
|
+- **GET** `/verify/?q={verification_code}`
|
|
|
+- **Descripción:** Página de verificación de usuario
|
|
|
+- **Parámetros de consulta:**
|
|
|
+ - `q`: Código de verificación
|
|
|
+- **Respuestas:**
|
|
|
+ - `200`: Página de verificación HTML
|
|
|
+ - `400`: Código de verificación inválido
|
|
|
+
|
|
|
+### 🛍️ Productos (`/api/products`)
|
|
|
+*Requiere autenticación*
|
|
|
+
|
|
|
+#### Obtener productos
|
|
|
+- **GET** `/api/products/`
|
|
|
+- **Descripción:** Obtiene lista de todos los productos disponibles
|
|
|
+- **Headers requeridos:** `Authorization: Bearer <token>`
|
|
|
+- **Respuestas:**
|
|
|
+ - `200`: Lista de productos
|
|
|
+ ```json
|
|
|
+ {
|
|
|
+ "products": [
|
|
|
+ {
|
|
|
+ "id": 1,
|
|
|
+ "name": "Producto 1",
|
|
|
+ "price": 1500.0,
|
|
|
+ "description": "Descripción del producto"
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ "message": "Productos obtenidos exitosamente"
|
|
|
+ }
|
|
|
+ ```
|
|
|
+
|
|
|
+### 🛒 Pedidos (`/api/orders`)
|
|
|
+*Requiere autenticación*
|
|
|
+
|
|
|
+#### Enviar pedido
|
|
|
+- **POST** `/api/orders/send`
|
|
|
+- **Descripción:** Procesa un pedido, lo envía al sistema Fudo y a la impresora
|
|
|
+- **Headers requeridos:** `Authorization: Bearer <token>`
|
|
|
+- **Cuerpo de solicitud:**
|
|
|
+ ```json
|
|
|
+ {
|
|
|
+ "customerId": 123,
|
|
|
+ "items": [
|
|
|
+ {
|
|
|
+ "id": 1,
|
|
|
+ "quantity": 2
|
|
|
+ },
|
|
|
+ {
|
|
|
+ "id": 2,
|
|
|
+ "quantity": 1
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ "totalAmount": 4500.0,
|
|
|
+ "orderDate": "2025-07-31T10:30:00",
|
|
|
+ "table": 5
|
|
|
+ }
|
|
|
+ ```
|
|
|
+- **Respuestas:**
|
|
|
+ - `200`: Pedido procesado exitosamente
|
|
|
+ - `400`: Campos faltantes o tipo de mesa inválido
|
|
|
+ - `404`: Usuario no encontrado o venta activa no encontrada
|
|
|
+ - `424`: Impresora desconectada o error agregando productos
|
|
|
+
|
|
|
+### 💰 Ventas (`/api/sales`)
|
|
|
+*Requiere autenticación*
|
|
|
+
|
|
|
+#### Obtener ventas por usuario
|
|
|
+- **GET** `/api/sales/user/{user_id}`
|
|
|
+- **Descripción:** Obtiene el historial de ventas de un usuario específico
|
|
|
+- **Headers requeridos:** `Authorization: Bearer <token>`
|
|
|
+- **Parámetros de ruta:**
|
|
|
+ - `user_id`: ID del usuario
|
|
|
+- **Respuestas:**
|
|
|
+ - `200`: Lista de ventas del usuario
|
|
|
+ ```json
|
|
|
+ {
|
|
|
+ "sales": [
|
|
|
+ {
|
|
|
+ "id": 1,
|
|
|
+ "user_id": 123,
|
|
|
+ "total": 4500.0,
|
|
|
+ "fudo_id": "abc123",
|
|
|
+ "date": "2025-07-31T10:30:00",
|
|
|
+ "table": 5,
|
|
|
+ "username": "Juan Pérez",
|
|
|
+ "user_email": "juan@ejemplo.com",
|
|
|
+ "products": [...]
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ "message": "Ventas obtenidas correctamente"
|
|
|
+ }
|
|
|
+ ```
|
|
|
+ - `404`: No se encontraron ventas
|
|
|
+
|
|
|
+### 💬 Chat (`/api/chat`)
|
|
|
+*Requiere autenticación*
|
|
|
+
|
|
|
+#### Completar chat
|
|
|
+- **POST** `/api/chat/completions`
|
|
|
+- **Descripción:** Obtiene respuestas de chat utilizando OpenAI
|
|
|
+- **Headers requeridos:** `Authorization: Bearer <token>`
|
|
|
+- **Cuerpo de solicitud:**
|
|
|
+ ```json
|
|
|
+ {
|
|
|
+ "messages": [
|
|
|
+ {
|
|
|
+ "role": "user",
|
|
|
+ "content": "Hola, ¿qué productos tienen disponibles?"
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ "user": "juan@ejemplo.com"
|
|
|
+ }
|
|
|
+ ```
|
|
|
+- **Respuestas:**
|
|
|
+ - `200`: Respuesta del chat
|
|
|
+ ```json
|
|
|
+ {
|
|
|
+ "response": "Respuesta generada por IA",
|
|
|
+ "message": "Respuesta de chat generada exitosamente"
|
|
|
+ }
|
|
|
+ ```
|
|
|
+ - `500`: Error interno del servidor
|
|
|
+
|
|
|
+### 🌐 Rutas Estáticas
|
|
|
+
|
|
|
+#### Página principal
|
|
|
+- **GET** `/`
|
|
|
+- **Descripción:** Sirve la página principal de la aplicación
|
|
|
+- **Respuestas:**
|
|
|
+ - `200`: Página HTML principal
|
|
|
+ - `404`: Archivo no encontrado
|
|
|
+
|
|
|
+#### Página de registro
|
|
|
+- **GET** `/register`
|
|
|
+- **Descripción:** Sirve la página de registro
|
|
|
+- **Respuestas:**
|
|
|
+ - `200`: Página HTML de registro
|
|
|
+ - `404`: Archivo no encontrado
|
|
|
+
|
|
|
+## Modelos de Datos
|
|
|
+
|
|
|
+### Usuario (User)
|
|
|
+```json
|
|
|
+{
|
|
|
+ "id": 123,
|
|
|
+ "email": "usuario@ejemplo.com",
|
|
|
+ "name": "Nombre Usuario",
|
|
|
+ "rut": "12345678-9",
|
|
|
+ "pin_hash": "hashed_pin_value",
|
|
|
+ "kleincoins": "100.00",
|
|
|
+ "created_at": "2025-07-31T10:30:00"
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+### Producto (Product)
|
|
|
+```json
|
|
|
+{
|
|
|
+ "id": 1,
|
|
|
+ "name": "Nombre del Producto",
|
|
|
+ "type": "bebida",
|
|
|
+ "description": "Descripción del producto",
|
|
|
+ "price": 1500.0,
|
|
|
+ "image": "url_imagen.jpg",
|
|
|
+ "status": 1,
|
|
|
+ "quantity": 1
|
|
|
+}
|
|
|
+```
|
|
|
+**Campos:**
|
|
|
+- `id`: Identificador único
|
|
|
+- `name`: Nombre del producto
|
|
|
+- `type`: Tipo/categoría del producto (opcional)
|
|
|
+- `description`: Descripción del producto (opcional)
|
|
|
+- `price`: Precio del producto
|
|
|
+- `image`: URL de la imagen (opcional)
|
|
|
+- `status`: Estado del producto (0: Inactivo, 1: Activo)
|
|
|
+- `quantity`: Cantidad disponible (opcional, por defecto 1)
|
|
|
+
|
|
|
+### Pedido (OrderWeb)
|
|
|
+```json
|
|
|
+{
|
|
|
+ "customerId": 123,
|
|
|
+ "items": [
|
|
|
+ {
|
|
|
+ "id": 1,
|
|
|
+ "quantity": 2
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ "totalAmount": 3000.0,
|
|
|
+ "orderDate": "2025-07-31T10:30:00",
|
|
|
+ "table": 5
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+### Item del Pedido (ItemWeb)
|
|
|
+```json
|
|
|
+{
|
|
|
+ "id": 1,
|
|
|
+ "quantity": 2
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+### Venta (Sale)
|
|
|
+```json
|
|
|
+{
|
|
|
+ "id": 1,
|
|
|
+ "user_id": 123,
|
|
|
+ "total": 3000.0,
|
|
|
+ "fudo_id": "abc123",
|
|
|
+ "date": "2025-07-31T10:30:00",
|
|
|
+ "table": 5,
|
|
|
+ "username": "Juan Pérez",
|
|
|
+ "user_email": "juan@ejemplo.com",
|
|
|
+ "products": [
|
|
|
+ {
|
|
|
+ "id": 1,
|
|
|
+ "name": "Producto 1",
|
|
|
+ "price": 1500.0,
|
|
|
+ "quantity": 2
|
|
|
+ }
|
|
|
+ ]
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+### Mensaje de Chat (Message)
|
|
|
+```json
|
|
|
+{
|
|
|
+ "role": "user",
|
|
|
+ "content": "¿Qué productos tienen disponibles?"
|
|
|
+}
|
|
|
+```
|
|
|
+**Roles disponibles:** `user`, `assistant`, `system`
|
|
|
+
|
|
|
+### Solicitud de Chat (ChatCompletionRequest)
|
|
|
+```json
|
|
|
+{
|
|
|
+ "messages": [
|
|
|
+ {
|
|
|
+ "role": "user",
|
|
|
+ "content": "Hola, necesito ayuda"
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ "user": "usuario@ejemplo.com"
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+### Lista Negra (Blacklist)
|
|
|
+```json
|
|
|
+{
|
|
|
+ "id": 1,
|
|
|
+ "user_id": 123,
|
|
|
+ "email": "usuario@ejemplo.com",
|
|
|
+ "name": "Juan Pérez",
|
|
|
+ "rut": "12345678-9"
|
|
|
+}
|
|
|
+```
|
|
|
+**Campos:**
|
|
|
+- `id`: Identificador único
|
|
|
+- `user_id`: ID del usuario en lista negra
|
|
|
+- `email`: Email del usuario (opcional)
|
|
|
+- `name`: Nombre del usuario (opcional)
|
|
|
+- `rut`: RUT del usuario (opcional)
|
|
|
+
|
|
|
+### Modelos de Solicitud
|
|
|
+
|
|
|
+#### Registro de Usuario (RegisterUserRequest)
|
|
|
+```json
|
|
|
+{
|
|
|
+ "name": "Juan Pérez",
|
|
|
+ "email": "juan@ejemplo.com",
|
|
|
+ "rut": "12345678-9"
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+#### Login de Usuario (LoginRequest)
|
|
|
+```json
|
|
|
+{
|
|
|
+ "email": "juan@ejemplo.com",
|
|
|
+ "pin": "1234"
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+#### PIN de Usuario (PinUserRequest)
|
|
|
+```json
|
|
|
+{
|
|
|
+ "pin": "1234"
|
|
|
+}
|
|
|
+```
|
|
|
+**Validación:** PIN debe ser exactamente 4 dígitos
|
|
|
+
|
|
|
+#### ID de Usuario (UserIDRequest)
|
|
|
+```json
|
|
|
+{
|
|
|
+ "id": 123
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+## Códigos de Error Comunes
|
|
|
+
|
|
|
+- **400**: Solicitud incorrecta (datos faltantes o inválidos)
|
|
|
+- **401**: No autorizado (token inválido o credenciales incorrectas)
|
|
|
+- **403**: Prohibido (usuario bloqueado)
|
|
|
+- **404**: No encontrado (recurso no existe)
|
|
|
+- **424**: Dependencia fallida (problemas con servicios externos como impresora)
|
|
|
+- **429**: Demasiadas solicitudes (límite de intentos alcanzado)
|
|
|
+- **500**: Error interno del servidor
|
|
|
+
|
|
|
+## Notas Importantes
|
|
|
+
|
|
|
+1. **Autenticación**: La mayoría de endpoints requieren un token JWT válido
|
|
|
+2. **Límites de intentos**: El sistema bloquea usuarios después de 5 intentos fallidos de login
|
|
|
+3. **Verificación por email**: El registro requiere verificación por email antes de completarse
|
|
|
+4. **Integración con Fudo**: Los pedidos se sincronizan automáticamente con el sistema Fudo
|
|
|
+5. **Impresión automática**: Los pedidos se envían automáticamente a la impresora USB configurada
|
|
|
+6. **Logs**: Todas las interacciones importantes se registran para auditoría
|
|
|
+
|
|
|
+## Middleware
|
|
|
+
|
|
|
+- **SessionMiddleware**: Manejo de sesiones con tiempo de expiración de 60 minutos
|
|
|
+- **CORS**: Configurado para permitir solicitudes cross-origin según necesidades
|
|
|
+
|
|
|
+## Archivos Estáticos
|
|
|
+
|
|
|
+- **Principales**: `/express/` - Archivos de la aplicación principal
|
|
|
+- **Registro**: `/register/` - Archivos de la página de registro
|