Sitelet https://github.com/plazasgiovanny/PoliMarket-Backend/tree/master
Skip to content

Latest commit

 

History

32 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PoliMarket Backend

Sistema de gestión empresarial para PoliMarket desarrollado con .NET 9 y Clean Architecture. Implementa módulos de Ventas, Inventario, Seguridad y Logística con integración completa entre módulos.

🎯 Descripción General

PoliMarket-Backend es una API RESTful robusta que proporciona:

  • Gestión de Ventas: CRUD de clientes, facturación con validación de stock en tiempo real
  • Gestión de Inventario: Consulta de productos, verificación de stock, trazabilidad de movimientos
  • Seguridad: Autenticación de usuarios, gestión de roles y permisos
  • Integración de Módulos: Validación cross-module (ventas valida stock, registra movimientos)

Requisitos Funcionales Implementados

RF Descripción Estado Módulo
RF01 Gestión Centralizada de Autorizaciones de Usuario ✅ Security
RF02 Inicio de Sesión de Usuarios ✅ Security
RF03 Consulta en Tiempo Real de Disponibilidad de Productos ✅ Inventory + Sales
RF04 Registro Automatizado de Salida de Stock por Venta ✅ Sales + Inventory
RF05 Generación Automática de Órdenes de Entrega ✅ Logistics

🏗️ Arquitectura

Clean Architecture

El proyecto sigue los principios de Clean Architecture con separación clara de responsabilidades:

┌──────────────────────────────────────────────────────┐
│                  Presentation Layer                   │
│              (Controllers - API REST)                 │
│                                                       │
│  SecurityController | InventoryController |          │
│  SalesController | LogisticsController              │
└──────────────────────────────────────────────────────┘
                        ↓ depende de
┌──────────────────────────────────────────────────────┐
│                  Application Layer                    │
│          (Services - Lógica de Negocio)              │
│                                                       │
│  ISecurityService ← SecurityService                  │
│  IInventoryService ← InventoryService                │
│  ICustomerService ← CustomerService                  │
│  IInvoiceService ← InvoiceService                    │
│                                                       │
│  + DTOs (Request/Response)                           │
└──────────────────────────────────────────────────────┘
                        ↓ depende de
┌──────────────────────────────────────────────────────┐
│                    Domain Layer                       │
│            (Entidades - Reglas de Negocio)           │
│                                                       │
│  Entities: User, Role, Product, Customer, Invoice    │
│  Interfaces: IUserRepository, IProductRepository     │
└──────────────────────────────────────────────────────┘
                        ↓ implementado por
┌──────────────────────────────────────────────────────┐
│                Infrastructure Layer                   │
│          (Implementaciones - EF Core + SQL)          │
│                                                       │
│  Repositories: UserRepository, ProductRepository     │
│  DbContext: ApplicationDbContext                     │
│  Configurations: Fluent API mappings                 │
└──────────────────────────────────────────────────────┘

Flujo de una Request

1. HTTP Request (ej: POST /api/Sales/invoices)
2. SalesController recibe el request
3. Controller llama a IInvoiceService
4. InvoiceService (implementación) ejecuta lógica de negocio
5. Service usa IRepository para acceso a datos
6. Repository usa EF Core para consultar SQL Server
7. Response regresa por el mismo camino (inverso)

Principios SOLID Aplicados

✅ Single Responsibility Principle (SRP)

  • Cada servicio tiene una única responsabilidad (CustomerService, InvoiceService, etc.)
  • Cada repositorio maneja una sola entidad

✅ Open/Closed Principle (OCP)

  • Extensible mediante nuevas implementaciones de servicios
  • Cerrado a modificación en componentes existentes

✅ Liskov Substitution Principle (LSP)

  • Cualquier implementación de IService puede sustituir a otra
  • Todos los repositorios implementan IRepository<T>

✅ Interface Segregation Principle (ISP)

  • Interfaces pequeñas y específicas por dominio
  • ICustomerService, IInvoiceService separados (no una interfaz gorda)

✅ Dependency Inversion Principle (DIP)

  • Controllers dependen de abstracciones (IService)
  • Services dependen de abstracciones (IRepository)
  • No hay dependencias directas de implementaciones concretas

📁 Estructura del Proyecto

PoliMarket-Backend/
│
├── Application/                    # Capa de Aplicación
│   ├── Common/
│   │   ├── DependencyInjection.cs # Registro de servicios
│   │   └── Interfaces/
│   │       └── IApplicationDbContext.cs
│   │
│   ├── Inventory/                 # Módulo Inventario
│   │   ├── DTOs/
│   │   │   ├── ProductResponse.cs
│   │   │   ├── CheckStockRequest.cs
│   │   │   └── CheckStockResponse.cs
│   │   └── Services/
│   │       ├── IInventoryService.cs
│   │       └── InventoryService.cs
│   │
│   ├── Sales/                     # Módulo Ventas
│   │   ├── DTOs/
│   │   │   ├── CustomerResponse.cs
│   │   │   ├── InvoiceResponse.cs
│   │   │   └── CreateInvoiceRequest.cs
│   │   └── Services/
│   │       ├── ICustomerService.cs
│   │       ├── CustomerService.cs
│   │       ├── IInvoiceService.cs
│   │       └── InvoiceService.cs
│   │
│   └── Security/                  # Módulo Seguridad
│       ├── DTOs/
│       │   ├── LoginRequest.cs
│       │   ├── LoginResponse.cs
│       │   └── UserResponse.cs
│       └── Services/
│           ├── ISecurityService.cs
│           ├── SecurityService.cs
│           └── IPasswordHasher.cs
│
├── Domain/                        # Capa de Dominio
│   ├── Entities/
│   │   ├── BaseEntity.cs         # Entidad base (Id, CreatedAt, UpdatedAt)
│   │   ├── Inventory/
│   │   │   ├── Product.cs
│   │   │   ├── Supplier.cs
│   │   │   ├── InventoryMovement.cs
│   │   │   └── StockAlert.cs
│   │   ├── Sales/
│   │   │   ├── Customer.cs
│   │   │   ├── Invoice.cs
│   │   │   └── InvoiceDetail.cs
│   │   ├── Security/
│   │   │   ├── User.cs
│   │   │   └── Rol.cs
│   │   └── Logistics/
│   │       └── DeliveryOrder.cs
│   │
│   └── Repositories/              # Interfaces de repositorios
│       ├── IRepository.cs         # Repositorio genérico
│       ├── IUserRepository.cs
│       ├── IProductRepository.cs
│       ├── ICustomerRepository.cs
│       └── IInvoiceRepository.cs
│
├── Infrastructure/                # Capa de Infraestructura
│   ├── Persistence/
│   │   ├── ApplicationDbContext.cs
│   │   ├── Configurations/       # Fluent API
│   │   │   ├── Inventory/
│   │   │   ├── Sales/
│   │   │   ├── Security/
│   │   │   └── Logistics/
│   │   └── Migrations/           # EF Core Migrations
│   │
│   ├── Repositories/              # Implementaciones
│   │   ├── BaseRepository.cs
│   │   ├── Inventory/
│   │   │   ├── ProductRepository.cs
│   │   │   └── InventoryMovementRepository.cs
│   │   ├── Sales/
│   │   │   ├── CustomerRepository.cs
│   │   │   └── InvoiceRepository.cs
│   │   └── Security/
│   │       ├── UserRepository.cs
│   │       └── RolRepository.cs
│   │
│   ├── Security/
│   │   └── PasswordHasher.cs     # Hashing con SHA256
│   │
│   └── Common/
│       └── DependencyInjection.cs # Registro de infraestructura
│
├── Presentation/                  # Capa de Presentación
│   └── Controllers/
│       ├── BaseApiController.cs   # Controlador base
│       ├── SecurityController.cs  # Endpoints de autenticación
│       ├── InventoryController.cs # Endpoints de inventario
│       ├── SalesController.cs     # Endpoints de ventas
│       └── LogisticsController.cs # Endpoints de logística
│
├── Database/                      # Scripts SQL
│   ├── SeedData.sql              # Roles y usuarios iniciales
│   ├── SeedData_Inventory.sql    # Productos y proveedores
│   └── SeedData_Sales.sql        # Clientes de prueba
│
├── docs/                          # Documentación
│   ├── Architecture/
│   │   └── MEDIATR_REMOVAL_SUMMARY.md
│   ├── Security/
│   │   └── README.md
│   ├── Inventory/
│   │   └── README.md
│   └── Sales/
│       └── README.md
│
├── Program.cs                     # Punto de entrada
├── appsettings.json              # Configuración
└── PoliMarket-Backend.csproj     # Proyecto .NET

🛠️ Tecnologías Utilizadas

Backend

  • .NET 9 (Framework principal)
  • ASP.NET Core Web API (REST API)
  • Entity Framework Core 9.0 (ORM)
  • SQL Server (Base de datos)

Patrones y Principios

  • Clean Architecture (separación de capas)
  • SOLID Principles (diseño orientado a objetos)
  • Service Layer Pattern (lógica de negocio)
  • Repository Pattern (abstracción de datos)
  • Dependency Injection (IoC Container)
  • Unit of Work (transacciones)

Herramientas

  • EF Core Migrations (gestión de esquema de BD)
  • Fluent API (configuración de entidades)
  • SHA256 (hashing de contraseñas)

🚀 Cómo Empezar

Prerequisitos

  • .NET 9 SDK o superior
  • SQL Server (Express o superior)
  • Visual Studio 2022 / VS Code / Rider
  • SQL Server Management Studio (opcional)

1. Clonar el Repositorio

git clone https://github.com/tu-usuario/PoliMarket-Backend.git
cd PoliMarket-Backend

2. Configurar Connection String

Edita appsettings.json:

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=.\\SQLEXPRESS;Database=PoliMarketDb;Integrated Security=true;TrustServerCertificate=true;MultipleActiveResultSets=true;"
  }
}

3. Crear Base de Datos

dotnet ef database update

Esto ejecutará las migraciones y creará la base de datos PoliMarketDb con todas las tablas.

4. Poblar con Datos de Prueba

# Usuarios y roles
sqlcmd -S .\SQLEXPRESS -d PoliMarketDb -i Database\SeedData.sql

# Productos y proveedores
sqlcmd -S .\SQLEXPRESS -d PoliMarketDb -i Database\SeedData_Inventory.sql

# Clientes
sqlcmd -S .\SQLEXPRESS -d PoliMarketDb -i Database\SeedData_Sales.sql

5. Ejecutar la Aplicación

dotnet run

La API estará disponible en:

  • HTTP: http://localhost:5289
  • HTTPS: https://localhost:7057

Ejecutar con Docker

Si prefieres levantar la API y SQL Server en contenedores:

# Construir y levantar los servicios
docker compose up -d

# Ver logs
docker compose logs -f api
  • API: http://localhost:8080
  • Swagger: http://localhost:8080/swagger
  • SQL Server: localhost:1433 (usuario sa, contraseña por defecto YourStrong@Passw0rd)

Las migraciones EF se ejecutan automáticamente al arrancar la API. Para usar otra contraseña de SQL Server, define la variable de entorno MSSQL_SA_PASSWORD antes de docker compose up.

Para cargar datos de prueba en la base de datos del contenedor, ejecuta los scripts en Database/ conectándote a localhost,1433 (por ejemplo con Azure Data Studio o sqlcmd).

6. Probar la API

Usando cURL:

# Login
curl -X POST http://localhost:5289/api/Security/login \
  -H "Content-Type: application/json" \
  -d '{"username": "jperez", "password": "password123"}'

# Listar productos
curl http://localhost:5289/api/Inventory/products

# Crear factura (con validación de stock)
curl -X POST http://localhost:5289/api/Sales/invoices \
  -H "Content-Type: application/json" \
  -d '{
    "salesPersonId": 2,
    "customerId": 1,
    "details": [
      {"productId": 1, "quantitySold": 2}
    ]
  }'

Usando Swagger/OpenAPI:

Navega a: http://localhost:5289/openapi (si está habilitado en desarrollo)


📦 Módulos Implementados

1. Módulo Security 🔐

Responsabilidad: Autenticación y gestión de usuarios

Endpoints:

  • POST /api/Security/login - Iniciar sesión
  • GET /api/Security/users - Listar usuarios
  • POST /api/Security/users - Crear usuario
  • PUT /api/Security/users/{id} - Actualizar usuario
  • POST /api/Security/users/{id}/revoke-access - Revocar acceso
  • GET /api/Security/roles - Listar roles

Entidades:

  • User (usuarios/empleados)
  • Rol (roles del sistema)

Características:

  • ✅ Autenticación con usuario/contraseña
  • ✅ Hashing de contraseñas (SHA256)
  • ✅ Validación de usuarios activos
  • ✅ Gestión de roles (Vendedor Activo, Administrador, etc.)

📚 Documentación completa


2. Módulo Inventory 📦

Responsabilidad: Gestión de productos y stock

Endpoints:

  • GET /api/Inventory/products - Listar productos
  • GET /api/Inventory/products/{id} - Obtener producto
  • GET /api/Inventory/products/{id}/stock - Consultar stock (RF03)
  • POST /api/Inventory/products/check-stock - Validar disponibilidad (RF03)
  • GET /api/Inventory/products/{id}/suppliers - Producto con proveedores

Entidades:

  • Product (productos del inventario)
  • Supplier (proveedores)
  • ProductSupplier (relación productos-proveedores)
  • InventoryMovement (movimientos de stock)
  • StockAlert (alertas de stock bajo)

Características:

  • ✅ RF03: Consulta en tiempo real de disponibilidad
    • CA 3.1: Visualización de stock exacto
    • CA 3.2: Validación positiva (stock suficiente)
    • CA 3.3: Validación negativa con mensaje claro
    • CA 3.4: Latencia < 1 segundo
  • ✅ Trazabilidad de movimientos de inventario
  • ✅ Gestión de proveedores por producto

📚 Documentación completa


3. Módulo Sales 💰

Responsabilidad: Gestión de clientes y facturación

Endpoints Clientes:

  • GET /api/Sales/customers - Listar clientes
  • GET /api/Sales/customers/{id} - Obtener cliente
  • POST /api/Sales/customers - Crear cliente
  • PUT /api/Sales/customers/{id} - Actualizar cliente
  • DELETE /api/Sales/customers/{id} - Eliminar cliente

Endpoints Facturas:

  • GET /api/Sales/invoices - Listar facturas
  • GET /api/Sales/invoices/{id} - Obtener factura
  • POST /api/Sales/invoices - ⭐ Crear factura (RF03 + RF04)

Entidades:

  • Customer (clientes)
  • Invoice (facturas)
  • InvoiceDetail (detalles de factura)

Características:

  • ✅ CRUD completo de clientes
  • ✅ Validación de emails únicos
  • ✅ RF03 + RF04: Facturación con validación e integración de stock
    • Valida stock en tiempo real antes de venta
    • Descuenta stock automáticamente
    • Transaccionalidad completa (rollback si falla)
    • Registra movimientos de inventario
  • ✅ Validación de vendedor activo (RF01)
  • ✅ Protección de integridad referencial

📚 Documentación completa


4. Módulo Logistics 🚚

Responsabilidad: Gestión de órdenes de entrega

Endpoints:

  • GET /api/Logistics/delivery-orders - Listar órdenes de entrega
  • GET /api/Logistics/delivery-orders/{id} - Obtener orden por ID
  • GET /api/Logistics/delivery-orders/pending - Órdenes pendientes (RF05 CA 5.3)
  • POST /api/Logistics/delivery-orders/generate/{invoiceId} - Generar orden manual

Entidades:

  • DeliveryOrder (órdenes de entrega)

Características:

  • ✅ RF05: Generación Automática de Órdenes de Entrega
    • CA 5.1: Creación automática con estado "Pending"
    • CA 5.2: Incluye datos del cliente, dirección y productos
    • CA 5.3: Panel de control dedicado sin intervención manual
  • ✅ Integración automática con módulo Sales
  • ✅ Consulta de órdenes pendientes

📚 Documentación completa


🔗 Integración entre Módulos

Sales → Security (RF01)

Cuando se crea una factura:

// 1. Sales valida que el vendedor esté activo
var salesPerson = await _userRepository.GetByIdAsync(request.SalesPersonId);
if (!salesPerson.IsActive)
    throw new InvalidOperationException("Vendedor no activo");

Sales → Inventory (RF03 + RF04)

Al crear una factura:

// 2. Sales consulta stock disponible (RF03)
foreach (var detail in request.Details)
{
    var product = await _productRepository.GetByIdAsync(detail.ProductId);
    if (detail.QuantitySold > product.QuantityAvailable)
        throw new InvalidOperationException("Stock insuficiente");
}

// 3. Sales reduce stock automáticamente (RF04)
using var transaction = await _context.Database.BeginTransactionAsync();
product.QuantityAvailable -= detail.QuantitySold;
await _productRepository.UpdateAsync(product);

// 4. Sales registra movimiento de inventario (RF04)
var movement = new InventoryMovement
{
    ProductId = detail.ProductId,
    MovementType = 'O', // Output
    Quantity = detail.QuantitySold,
    EntityName = "Invoice",
    EntityId = invoice.Id
};
await _inventoryMovementRepository.AddAsync(movement);
await transaction.CommitAsync();

Sales → Logistics (RF05)

Una vez completada la venta:

// 5. Sales genera automáticamente orden de entrega (RF05)
await transaction.CommitAsync(); // Confirmar venta primero

// RF05 CA 5.1, 5.2, 5.3: Generar orden con datos completos
await _deliveryOrderService.GenerateDeliveryOrderAsync(invoiceId);

// La orden se crea con:
// - Estado: "Pending" (CA 5.1)
// - Datos: Cliente, Dirección, Productos, ID de Venta (CA 5.2)
// - Visible en panel de Entregas sin intervención manual (CA 5.3)

🗄️ Base de Datos

Esquemas

El sistema utiliza 4 esquemas para separación lógica:

Esquema Descripción Tablas
Security Usuarios y roles Users, Roles
Inventory Productos y stock Products, Suppliers, ProductSuppliers, InventoryMovements, StockAlerts
Sales Ventas y clientes Customers, Invoices, InvoiceDetails
Logistics Logística DeliveryOrders

Diagrama de Entidades Principales

Security.Users (Vendedores)
    ↓ 1:N
Sales.Invoices ← N:1 → Sales.Customers
    ↓ 1:N
Sales.InvoiceDetails → N:1 → Inventory.Products
                                    ↓ 1:N
                            Inventory.InventoryMovements

Migraciones

# Ver migraciones aplicadas
dotnet ef migrations list

# Crear nueva migración
dotnet ef migrations add NombreMigracion

# Aplicar migraciones
dotnet ef database update

# Revertir a migración específica
dotnet ef database update MigracionAnterior

🧪 Testing

Tests Manuales con cURL

Ver guías de testing en cada módulo:

Suite de Pruebas Recomendada

  1. Login y Autenticación

    curl -X POST http://localhost:5289/api/Security/login \
      -H "Content-Type: application/json" \
      -d '{"username": "jperez", "password": "password123"}'
  2. Consultar Productos

    curl http://localhost:5289/api/Inventory/products
  3. Validar Stock

    curl -X POST http://localhost:5289/api/Inventory/products/check-stock \
      -H "Content-Type: application/json" \
      -d '{"productId": 1, "quantityRequested": 5}'
  4. Crear Factura (Integración RF03 + RF04)

    curl -X POST http://localhost:5289/api/Sales/invoices \
      -H "Content-Type: application/json" \
      -d '{
        "salesPersonId": 2,
        "customerId": 1,
        "details": [
          {"productId": 1, "quantitySold": 2},
          {"productId": 3, "quantitySold": 5}
        ]
      }'
  5. Verificar Movimientos de Inventario

    SELECT * FROM Inventory.InventoryMovements 
    WHERE EntityName = 'Invoice' 
    ORDER BY MovementDate DESC;
  6. Verificar Orden de Entrega Generada (RF05)

    curl http://localhost:5289/api/Logistics/delivery-orders/pending

📊 Estado del Proyecto

Requisitos Funcionales

RF Descripción Estado Módulo Criterios
RF01 Gestión Centralizada de Autorizaciones ✅ 100% Security 2/2 CA
RF02 Inicio de Sesión de Usuarios ✅ 100% Security 4/4 CA
RF03 Consulta en Tiempo Real de Disponibilidad ✅ 100% Inventory + Sales 4/4 CA
RF04 Registro Automatizado de Salida de Stock ✅ 100% Sales + Inventory 3/3 CA
RF05 Generación Automática de Órdenes ✅ 100% Logistics 3/3 CA

Módulos

Módulo Estado Endpoints Tests Documentación
Security ✅ Completo 6 ✅ ✅
Inventory ✅ Completo 5 ✅ ✅
Sales ✅ Completo 8 ✅ ✅
Logistics ✅ Completo 4 ✅ ✅

Métricas de Código

  • Líneas de código: ~7,200
  • Archivos C#: ~88
  • Controladores: 4
  • Servicios: 5
  • Repositorios: 9
  • Entidades: 11
  • Compilación: ✅ 0 errores, 0 warnings
  • Cobertura SOLID: ✅ 100%

🔧 Configuración

appsettings.json

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=.\\SQLEXPRESS;Database=PoliMarketDb;Integrated Security=true;TrustServerCertificate=true;"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning",
      "Microsoft.EntityFrameworkCore": "Information"
    }
  },
  "AllowedHosts": "*"
}

Configuraciones Importantes

  • Connection String: Ajustar según tu instancia de SQL Server
  • Entity Framework Logging: Nivel Information para ver queries SQL
  • HTTPS: Puerto 7057 (desarrollo)
  • HTTP: Puerto 5289 (desarrollo)

🔮 Roadmap

Completado ✅

Q4 2024

  • [✅] RF05: Generación Automática de Órdenes de Entrega
  • [✅] Módulo Logistics completo
  • [✅] Integración automática Sales → Logistics

Próximas Implementaciones

Q1 2025

  • Implementar JWT para autenticación stateless
  • Agregar middleware de manejo de excepciones global
  • Implementar logging con Serilog
  • Actualización de estados de órdenes de entrega

Q2 2025

  • Tests unitarios (xUnit)
  • Tests de integración
  • Documentación OpenAPI/Swagger mejorada
  • CI/CD con GitHub Actions

Q3 2025

  • Implementar cache con Redis
  • Agregar rate limiting
  • Implementar CORS configurado
  • Dashboard de métricas

Backlog

  • Migrar a BCrypt para hashing de contraseñas
  • Implementar refresh tokens
  • Agregar versionado de API
  • Implementar pagination en endpoints de listado
  • Agregar filtros y búsqueda avanzada

📚 Documentación Adicional


🤝 Contribución

Guía de Estilo

  • Seguir convenciones de C# y .NET
  • Aplicar principios SOLID
  • Documentar métodos públicos con <summary>
  • Usar nombres descriptivos en español para entidades de negocio
  • Mantener arquitectura Clean Architecture

Proceso de Contribución

  1. Fork el repositorio
  2. Crear una rama feature (git checkout -b feature/NuevaFuncionalidad)
  3. Commit cambios (git commit -m 'Add: Nueva funcionalidad')
  4. Push a la rama (git push origin feature/NuevaFuncionalidad)
  5. Abrir un Pull Request

👥 Equipo

  • Backend Lead: [Tu Nombre]
  • Arquitectura: [Nombre]
  • Database: [Nombre]

📄 Licencia

Este proyecto es privado y propiedad de PoliMarket.


📞 Soporte

Para preguntas o issues:


🎉 Agradecimientos

  • Equipo de desarrollo PoliMarket
  • Comunidad .NET
  • Microsoft por las herramientas y frameworks

Última actualización: Noviembre 2024
Versión: 1.1.0
Estado: ✅ Producción-Ready para RF01-RF05 (Todos los requisitos funcionales completados)

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages