Files
hotel-hacienda/docs/API.md
Consultoria AS 411d517ba4 docs: documentación extensiva del proyecto
- README.md con guía completa de instalación y arquitectura
- docs/BACKEND.md — guía detallada del API
- docs/FRONTEND.md — guía del SPA React
- docs/DATABASE.md — funciones SQL y patrones de datos
- docs/API.md — referencia completa de endpoints REST
- docs/DEPLOYMENT.md — guía de despliegue en producción
- docs/TROUBLESHOOTING.md — solución de problemas comunes
- CHANGELOG.md — historial de cambios
- CONTRIBUTING.md — guía de contribución
2026-06-09 16:26:09 -07:00

700 lines
12 KiB
Markdown

# 🔌 Referencia Completa de la API REST
**Base URL:** `https://<dominio>/api`
---
## Índice
1. [Convenciones](#convenciones)
2. [Autenticación](#autenticación)
3. [Empleados](#empleados)
4. [Contratos](#contratos)
5. [Productos](#productos)
6. [Gastos](#gastos)
7. [Aprobaciones y Pagos](#aprobaciones-y-pagos)
8. [Pagos Mensuales](#pagos-mensuales)
9. [Configuraciones](#configuraciones)
10. [Emails](#emails)
11. [Ingresos (Little Hotelier)](#ingresos-little-hotelier)
12. [Compras](#compras)
13. [Tipo de Cambio](#tipo-de-cambio)
14. [Hotel P&L](#hotel-pl)
15. [Restaurant P&L](#restaurant-pl)
16. [Ingresos Horux](#ingresos-horux)
---
## Convenciones
- **Formato:** JSON en request body y response.
- **Paginación:** `?page=N&limit=M` (default limit: 500 para empleados, 10 para productos).
- **Errores:** Status `500` con `{ message: "Error descripción" }`.
- **CORS:** Origen controlado por `URL_CORS` en el backend.
---
## Autenticación
> ⚠️ **Nota:** No hay JWT. El login devuelve un rol numérico que el frontend guarda en `localStorage`.
### POST `/api/auth/login`
```json
// Request
{
"name_mail_user": "usuario_o_email",
"user_pass": "contraseña"
}
// Response 200
{
"rol": 1,
"user_id": 5,
"user_name": "Admin",
"message": "Usuario autenticado correctamente"
}
```
**Status codes de la función SQL:**
- `status: 1` = Autenticado
- `status: 2` = Credenciales incorrectas
### POST `/api/auth/createuser`
```json
// Request
{
"name_user": "Nuevo Usuario",
"id_rol": 2,
"email": "user@email.com",
"user_pass": "password123"
}
// Response
{
"message": "Se agrego el usuario correctamente",
"status": 1
}
```
### POST `/api/auth/recoverpass`
Genera una contraseña aleatoria y la envía por correo.
```json
// Request
{ "user_mail": "user@email.com" }
// Response
{
"message": "Correo enviado con nueva contraseña.",
"status": 1
}
```
---
## Empleados
Base: `/api/employees`
### GET `/api/employees/`
Lista paginada de empleados.
**Query params:** `?page=1&limit=500`
```json
// Response
{
"page": 1,
"limit": 500,
"total": 45,
"totalPages": 1,
"data": [
{
"employee_rfc": "RFC123456",
"name_employee": "Juan Pérez",
"nss_employe": "12345678901",
"position_employee": "Recepcionista",
"area_employee": "Front Desk",
"phone_employee": "5551234567",
"end_contract": "2025-12-31",
"daily_pay": 500.00,
"uniforms": 2,
"status": "Activo",
"birthday": "1990-05-15",
"curp": "CURP123456HDF"
}
]
}
```
### GET `/api/employees/activeEmployees`
```json
{ "message": "Total de empleados activos", "data": 42 }
```
### GET `/api/employees/getattendance`
```json
{ "message": "attendance", "data": [...] }
```
### GET `/api/employees/gradeofstudy`
Catálogo de grados de estudio.
### GET `/api/employees/relationship`
Catálogo de parentescos.
### POST `/api/employees/employee`
Obtiene un empleado por RFC.
```json
// Request
{ "rfcEmployee": "RFC123456" }
```
### POST `/api/employees/newemployee`
```json
// Request
{
"name_emp": "Juan Pérez",
"rfc_emp": "RFC123456",
"nss_emp": "12345678901",
"addres_emp": "Calle 123",
"phone_emp": "5551234567",
"email_emp": "juan@email.com",
"birthday_emp": "1990-05-15",
"curp_emp": "CURP123456HDF",
"study_emp": 1,
"emergency_name": "María Pérez",
"emergency_tel": "5559876543",
"relationship_id": 1
}
```
### POST `/api/employees/updateemployee`
Misma firma que `newemployee`. Actualiza por RFC.
---
## Contratos
Base: `/api/contracts`
### GET `/api/contracts/`
### GET `/api/contracts/getinfocontract/:id`
### GET `/api/contracts/neartoend`
### GET `/api/contracts/positions`
### GET `/api/contracts/areas`
### GET `/api/contracts/bosses`
### GET `/api/contracts/reportempcontract`
### GET `/api/contracts/disabledcontract`
### POST `/api/contracts/newcontract`
### PUT `/api/contracts/updatecontract/:id`
---
## Productos
Base: `/api/products`
### GET `/api/products/`
Paginado (default limit: 10).
### GET `/api/products/productcategory`
### GET `/api/products/producttype`
### GET `/api/products/suppliers`
### GET `/api/products/gdiscardproducts`
### GET `/api/products/reportinventory`
### GET `/api/products/stockadjusment`
### GET `/api/products/gethousekeeper`
### GET `/api/products/getproducts`
### GET `/api/products/getconsumptionstockreport`
### POST `/api/products/newsupplier`
```json
{
"new_name_supp": "Proveedor SA",
"new_rfc_supp": "RFC123456",
"new_mail_supp": "prov@email.com",
"new_phone_supp": "5551234567"
}
```
### POST `/api/products/newproduct`
```json
{
"new_name_product": "Toallas",
"new_sku_product": "TOW-001",
"product_type": [{"id": 1, "name": "Textil"}],
"new_category": 1,
"suppliers_id": 1,
"unit": 1,
"new_stock": 100,
"newprice_product": 150.00,
"new_tax": 1,
"currency": 1,
"image_product": "url_o_base64"
}
```
> Nota: `product_type` se serializa a JSONB.
### POST `/api/products/stockadjusmentset`
```json
{
"stockproductadjusment": [
{ "id_product": 1, "new_stock": 50 },
{ "id_product": 2, "new_stock": 30 }
]
}
```
### POST `/api/products/newconsumptionstock`
```json
{
"product_id": 1,
"quantity_consumption": 5,
"date_consumption": "2025-01-15",
"rfc_emp": "RFC123456"
}
```
### POST `/api/products/disableSupplier`
```json
{ "supplier_id": 1 }
```
### PUT `/api/products/update_product/:id`
### PUT `/api/products/discardproduct/:id`
```json
{
"quantity": 5,
"reasons": "Dañado"
}
```
### PUT `/api/products/product/:id`
### PUT `/api/products/updatesupplier/:id`
⚠️ **Bug conocido:** Falta `/` inicial en la ruta del backend.
---
## Gastos
Base: `/api/expenses`
### GET `/api/expenses/pendingapproval`
### GET `/api/expenses/approvedexpenses`
### GET `/api/expenses/rejectedexpenses`
### GET `/api/expenses/mainsupplier`
### PUT `/api/expenses/getexpense/:id`
⚠️ **Nota:** Es `PUT` pero debería ser `GET`. No requiere body.
### GET `/api/expenses/getinfo`
Devuelve catálogos combinados (suppliers, categories, areas, users, currencies, uniforms, taxes).
### GET `/api/expenses/reportexpenses`
### POST `/api/expenses/countpending`
```json
{ "option": 1 } // 1 = aprobaciones, 2 = mensuales
```
### GET `/api/expenses/reportpayments`
### GET `/api/expenses/monthlypayments`
### POST `/api/expenses/newexpense`
```json
{
"new_description": "Compra de amenities",
"suppliers_id": 1,
"new_request_date": "2025-01-01",
"new_payment_deadline": "2025-01-31",
"request_by": 1,
"area": 1,
"expense_cat": 1,
"currency_id": 1,
"products": [
{ "id_product": 1, "quantity": 10 },
{ "id_product": 2, "quantity": 5 }
],
"new_iva": 16.00,
"new_ieps": 0.00,
"new_subtotal": 1000.00,
"new_total": 1160.00,
"needtoapprove": true
}
```
### POST `/api/expenses/totalapproved`
```json
{ "option": 1 } // 1 = aprobado, 2 = rechazado
```
### PUT `/api/expenses/updateexpense/:id`
Misma estructura que `newexpense`, con campos prefijados con `up_`.
### GET `/api/expenses/gettaxes`
---
## Aprobaciones y Pagos
Base: `/api/status`
### PUT `/api/status/approveupdate/:id`
```json
{
"status": 2,
"approved_by": 1
}
```
**Status:**
- `2` = Aprobado
- `3` = Rechazado
### PUT `/api/status/paymentupdate/:id`
```json
{ "status": 2 }
```
### GET `/api/status/penapppayments`
### GET `/api/status/countdelaypay`
### GET `/api/status/totalspent`
---
## Pagos Mensuales
Base: `/api/payment`
### POST `/api/payment/newexpmonthly`
```json
{
"descriptionex": "Renta",
"recurrence_id": 1,
"payment_type": 1,
"currency_id": 1,
"suppliers_id": 1,
"area": 1,
"expense_category": 1,
"day_expense": 15,
"tax_id": 1,
"new_subtotal": 5000.00
}
```
### GET `/api/payment/refreshmonthly`
### PUT `/api/payment/paymentstatusmonthly/:id`
```json
{
"status_payment": 2,
"tax_id": 1,
"subtotal": 5000.00
}
```
Si `subtotal` es null, solo actualiza el estado sin recalcular total.
### PUT `/api/payment/updateexpmonthly/:id`
### GET `/api/payment/onemothlyexpense/:id`
### PUT `/api/payment/needtorefresh/:id`
```json
{ "notrefresh": true }
```
---
## Configuraciones
Base: `/api/settings`
### POST `/api/settings/newroom`
### POST `/api/settings/newproperty`
### GET `/api/settings/reportrooms`
### GET `/api/settings/reportproperties`
### GET `/api/settings/approveby`
### GET `/api/settings/requestby`
### GET `/api/settings/categoryexpense`
### GET `/api/settings/currency`
### GET `/api/settings/units`
### GET `/api/settings/recurrence`
---
## Emails
Base: `/api/emails`
> ⚠️ **Nota:** Todos estos endpoints tienen validación de frecuencia (1 ejecución por mes) mediante la función `validateendpoint()`.
### POST `/api/emails/nearexpiring`
### POST `/api/emails/paymentdelay`
### POST `/api/emails/expensesneartodeadline`
### POST `/api/emails/expensesspecial`
### POST `/api/emails/birthdays`
### POST `/api/emails/contractexpired`
### POST `/api/emails/expiredcontractsmonth`
---
## Ingresos (Little Hotelier)
Base: `/api/incomes`
> **Nota:** La mayoría de estos endpoints reciben filtros de fecha en el body.
### POST `/api/incomes/getincomes`
### POST `/api/incomes/totalincomes`
### POST `/api/incomes/channelscards`
### POST `/api/incomes/loadincomes`
Carga masiva desde CSV/XLSX previamente colocado en `src/resources/littleHotelier/`.
### POST `/api/incomes/loadproductsales`
### POST `/api/incomes/loadchequesdetalle`
### POST `/api/incomes/reportincomes`
### POST `/api/incomes/countticket`
### POST `/api/incomes/efectivo`
### POST `/api/incomes/otros`
### POST `/api/incomes/propinas`
### POST `/api/incomes/tarjeta`
### POST `/api/incomes/vales`
### POST `/api/incomes/sumatotal`
### POST `/api/incomes/ticketpromedio`
### GET `/api/incomes/getproductsales`
### GET `/api/incomes/getdetallecheque`
---
## Compras
Base: `/api/purchases`
### GET `/api/purchases/getpurchases`
Devuelve líneas de compra pendientes de recepción.
```json
// Response
{
"message": "Se obtuvieron todos los Purchases details",
"data": [
{
"id_purchase_dt": 1,
"id_expense": 5,
"id_product": 2,
"product_name": "Toallas",
"quantity": 10,
"delivered": 0,
"id_tax": 1,
"total": 1500.00
}
]
}
```
### PUT `/api/purchases/entry/:id`
Registra la recepción física de una compra.
```json
// Request
{ "checking": 10 }
// Response
{
"message": "Se obtuvo el Purchases details",
"newentry": 1
}
```
---
## Tipo de Cambio
Base: `/api/exchange`
### POST `/api/exchange/consultexchange`
Consulta tipo de cambio actual desde API de Banxico.
### GET `/api/exchange/getexchanges`
Devuelve historial de tipos de cambio guardados.
---
## Hotel P&L
Base: `/api/hotelpl`
### POST `/api/hotelpl/cogs`
### POST `/api/hotelpl/ebitda`
### POST `/api/hotelpl/employeeshare`
### POST `/api/hotelpl/grossprofit`
### POST `/api/hotelpl/tips`
### POST `/api/hotelpl/totalrevenue`
### POST `/api/hotelpl/weightedCategoriesCost`
---
## Restaurant P&L
Base: `/api/restaurantpl`
### POST `/api/restaurantpl/cogs`
### POST `/api/restaurantpl/ebitda`
### POST `/api/restaurantpl/grossprofit`
### POST `/api/restaurantpl/totalrevenue`
### POST `/api/restaurantpl/weightedCategoriesCost`
---
## Ingresos Horux
Base: `/api/incomeshrx`
### GET `/api/incomeshrx/accountincome`
### GET `/api/incomeshrx/categoryincome`
### GET `/api/incomeshrx/invoiceIncome`
### GET `/api/incomeshrx/totalIncome`
### GET `/api/incomeshrx/incomehorux`
### GET `/api/incomeshrx/oneincomehorux/:id`
### GET `/api/incomeshrx/stripedata/`
Obtiene transfers de Stripe y las inserta en PostgreSQL.
### POST `/api/incomeshrx/stripedatademo/`
Crea un transfer de demo en Stripe.
### POST `/api/incomeshrx/insertinvoice`
Descarga facturas de API externa (año actual) y las inserta.
### POST `/api/incomeshrx/newincome`
```json
{
"account_id": 1,
"amount": 5000.00,
"new_date": "2025-01-15",
"newinvoice": "FAC-001",
"area_id": 1,
"categories": [{"id": 1, "amount": 5000}]
}
```
### PUT `/api/incomeshrx/updateincome/:id`
Misma estructura que `newincome`.
---
> **Fin de la referencia API.** Para ver la lógica interna de cada endpoint, revisa los controllers en `backend/hotel_hacienda/src/controllers/`.