feat: agregar endpoints atómicos, auth de descuentos y limpiar deuda técnica #28

Open
Jose wants to merge 1 commits from refactor/tech-debt-cleanup into main
pull from: refactor/tech-debt-cleanup
Member

📌 Descripción General

Este PR consolida mejoras críticas de integridad transaccional, reglas de negocio en el POS y saneamiento de deuda técnica en el monorepo (apps/api y apps/web):

  1. Endpoints atómicos en productos: Reemplazo de flujos secuenciales y llamadas en ráfaga por operaciones atómicas en backend para precios y categorías.
  2. Control y autorización de descuentos en POS: Reglas de tope al subtotal, umbral del 15% para cajeros con modal de autorización de administrador y validaciones defensivas en API.
  3. Limpieza de deuda técnica e higiene de código: Eliminación de APIs deprecadas de React, unificación de modelos de usuario, centralización de configuración de temas, validación de rutas dinámicas y remoción de código/dependencias huérfanas.

🛠️ Cambios Detallados

1. Operaciones Atómicas de Productos (Backend & Frontend)

  • Actualización de precios (POST /api/products/:id/price):
    • Backend (ProductController, ProductService, ProductRepository): Recibe { unitPrice, costUnit }. Archiva en una sola transacción los registros de precio con estado active previos y crea el nuevo con active: true.
    • Frontend (apps/web/.../productos/page.tsx): handlePriceSubmit ahora ejecuta un único apiClient.post(...), eliminando la secuencia de requests fragmentados que arriesgaba dejar al producto sin precio activo ante fallos de red.
  • Sincronización de categorías (PATCH /api/products/:id/categories):
    • Backend: Recibe { categoryIds: number[] }. Limpia las relaciones anteriores e inserta el nuevo conjunto en una única operación atómica.
    • Frontend (apps/web/.../productos/page.tsx): syncCategories sustituye la ráfaga de Promise.all (POST/DELETE múltiples) por una sola llamada apiClient.patch(...).

2. Límite de Descuentos y Flujo de Autorización (POS & API)

  • Reglas en POS (apps/web/src/app/pos/page.tsx):
    • Tope al subtotal: Se configuró max={subtotal} en el input y se calculó effectiveDiscount = Math.min(discount, subtotal) para imposibilitar totales negativos o descuentos inflados.
    • Límite del 15% sin autorización: Cálculo en tiempo real de maxUnauthDiscount visible como referencia en la cabecera del campo.
    • Modal de autorización para cajeros: Al intentar aplicar un descuento superior al 15% (si el usuario no es admin ni fue previamente autorizado en ese carrito), se despliega un diálogo (Dialog) para validar credenciales de un administrador contra /api/auth/login.
    • Checkout: Envío y guardado estricto de effectiveDiscount.
  • Validaciones en API (apps/api/src/modules/shop-cart/shop-cart.service.ts):
    • Validación defensiva en métodos create y update: rechazo si discount < 0 o totalPrice < 0.

3. Deuda Técnica e Higiene de Código

  • Migración de APIs deprecadas: Reemplazo de React.FormEvent por React.SubmitEvent<HTMLFormElement> en 14 ocurrencias sobre 11 archivos:
    • admin/clientes/page.tsx
    • admin/inventario/page.tsx
    • admin/inventario/[id]/page.tsx (2 handlers)
    • admin/inventario/categorias/page.tsx
    • admin/inventario/productos/page.tsx (2 handlers)
    • admin/proveedores/page.tsx
    • admin/usuarios/page.tsx
    • login/_components/password-form.tsx
    • pos/page.tsx
    • pos/_components/cash-register-control.tsx (3 handlers)
  • Depuración de dependencias y código muerto:
    • Eliminado el componente en desuso SectionPlaceholder (apps/web/src/app/_core/components/section-placeholder.tsx).
    • Removido @prisma/client innecesario de apps/api/package.json (manejado vía @prisma/orm-postgres).
  • Unificación de tipos y estados compartidos:
    • auth-user.ts: se unificó AuthUser como alias directo de AppUser (entities.ts), eliminando la redundancia de contratos.
    • use-theme.tsx: se centralizaron THEME_MODES, THEME_ICONS, THEME_LABELS y el tipo ThemeMode, consumidos homogéneamente por theme-toggle.tsx y user-menu.tsx.
  • Seguridad en rutas dinámicas:
    • Validación con Number.isNaN(...) e invocación a notFound() de next/navigation en admin/inventario/[id]/page.tsx y admin/proveedores/[id]/page.tsx para evitar solicitudes a /api/.../NaN.

✅ Verificación y Calidad

  • Linting: npm run lint validado con 0 errores y 0 warnings en todo el workspace.
  • Build: npm run build completado exitosamente tanto para @pdv/web (Next.js) como para @pdv/api (NestJS).
  • Flujo transaccional probado: Verificado el archivado y alta atómica de precios y categorías sin inconsistencias en BD.
  • Flujo POS probado: Verificada la apertura del diálogo de autorización al superar el 15% de descuento con credenciales de cajero.
## 📌 Descripción General Este PR consolida mejoras críticas de integridad transaccional, reglas de negocio en el POS y saneamiento de deuda técnica en el monorepo (`apps/api` y `apps/web`): 1. **Endpoints atómicos en productos:** Reemplazo de flujos secuenciales y llamadas en ráfaga por operaciones atómicas en backend para precios y categorías. 2. **Control y autorización de descuentos en POS:** Reglas de tope al subtotal, umbral del 15% para cajeros con modal de autorización de administrador y validaciones defensivas en API. 3. **Limpieza de deuda técnica e higiene de código:** Eliminación de APIs deprecadas de React, unificación de modelos de usuario, centralización de configuración de temas, validación de rutas dinámicas y remoción de código/dependencias huérfanas. --- ## 🛠️ Cambios Detallados ### 1. Operaciones Atómicas de Productos (Backend & Frontend) - **Actualización de precios (`POST /api/products/:id/price`):** - **Backend (`ProductController`, `ProductService`, `ProductRepository`):** Recibe `{ unitPrice, costUnit }`. Archiva en una sola transacción los registros de precio con estado `active` previos y crea el nuevo con `active: true`. - **Frontend (`apps/web/.../productos/page.tsx`):** `handlePriceSubmit` ahora ejecuta un único `apiClient.post(...)`, eliminando la secuencia de requests fragmentados que arriesgaba dejar al producto sin precio activo ante fallos de red. - **Sincronización de categorías (`PATCH /api/products/:id/categories`):** - **Backend:** Recibe `{ categoryIds: number[] }`. Limpia las relaciones anteriores e inserta el nuevo conjunto en una única operación atómica. - **Frontend (`apps/web/.../productos/page.tsx`):** `syncCategories` sustituye la ráfaga de `Promise.all` (`POST`/`DELETE` múltiples) por una sola llamada `apiClient.patch(...)`. --- ### 2. Límite de Descuentos y Flujo de Autorización (POS & API) - **Reglas en POS (`apps/web/src/app/pos/page.tsx`):** - **Tope al subtotal:** Se configuró `max={subtotal}` en el input y se calculó `effectiveDiscount = Math.min(discount, subtotal)` para imposibilitar totales negativos o descuentos inflados. - **Límite del 15% sin autorización:** Cálculo en tiempo real de `maxUnauthDiscount` visible como referencia en la cabecera del campo. - **Modal de autorización para cajeros:** Al intentar aplicar un descuento superior al 15% (si el usuario no es admin ni fue previamente autorizado en ese carrito), se despliega un diálogo (`Dialog`) para validar credenciales de un administrador contra `/api/auth/login`. - **Checkout:** Envío y guardado estricto de `effectiveDiscount`. - **Validaciones en API (`apps/api/src/modules/shop-cart/shop-cart.service.ts`):** - Validación defensiva en métodos `create` y `update`: rechazo si `discount < 0` o `totalPrice < 0`. --- ### 3. Deuda Técnica e Higiene de Código - **Migración de APIs deprecadas:** Reemplazo de `React.FormEvent` por `React.SubmitEvent<HTMLFormElement>` en 14 ocurrencias sobre 11 archivos: - `admin/clientes/page.tsx` - `admin/inventario/page.tsx` - `admin/inventario/[id]/page.tsx` (2 handlers) - `admin/inventario/categorias/page.tsx` - `admin/inventario/productos/page.tsx` (2 handlers) - `admin/proveedores/page.tsx` - `admin/usuarios/page.tsx` - `login/_components/password-form.tsx` - `pos/page.tsx` - `pos/_components/cash-register-control.tsx` (3 handlers) - **Depuración de dependencias y código muerto:** - Eliminado el componente en desuso `SectionPlaceholder` (`apps/web/src/app/_core/components/section-placeholder.tsx`). - Removido `@prisma/client` innecesario de `apps/api/package.json` (manejado vía `@prisma/orm-postgres`). - **Unificación de tipos y estados compartidos:** - `auth-user.ts`: se unificó `AuthUser` como alias directo de `AppUser` (`entities.ts`), eliminando la redundancia de contratos. - `use-theme.tsx`: se centralizaron `THEME_MODES`, `THEME_ICONS`, `THEME_LABELS` y el tipo `ThemeMode`, consumidos homogéneamente por `theme-toggle.tsx` y `user-menu.tsx`. - **Seguridad en rutas dinámicas:** - Validación con `Number.isNaN(...)` e invocación a `notFound()` de `next/navigation` en `admin/inventario/[id]/page.tsx` y `admin/proveedores/[id]/page.tsx` para evitar solicitudes a `/api/.../NaN`. --- ## ✅ Verificación y Calidad - [x] **Linting:** `npm run lint` validado con 0 errores y 0 warnings en todo el workspace. - [x] **Build:** `npm run build` completado exitosamente tanto para `@pdv/web` (Next.js) como para `@pdv/api` (NestJS). - [x] **Flujo transaccional probado:** Verificado el archivado y alta atómica de precios y categorías sin inconsistencias en BD. - [x] **Flujo POS probado:** Verificada la apertura del diálogo de autorización al superar el 15% de descuento con credenciales de cajero.
Jose added 1 commit 2026-10-05 19:14:19 +00:00
Emmanuel was assigned by Jose 2026-10-05 19:16:47 +00:00
You are not authorized to merge this pull request.
This pull request can be merged automatically.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin refactor/tech-debt-cleanup:refactor/tech-debt-cleanup
git checkout refactor/tech-debt-cleanup
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: RynextTechnologies/PDV#28