docs: update README for use-case architecture
This commit is contained in:
@@ -1,238 +1,317 @@
|
||||
# Stock Manager Home
|
||||
|
||||
Sistema de gestión de inventario y asignación de activos desarrollado con Next.js 15, Prisma, PostgreSQL y NextAuth.
|
||||
Sistema de gestión de inventario, activos serializados, asignaciones y movimientos construido con Next.js, Prisma, PostgreSQL, NextAuth y Bun.
|
||||
|
||||
## 📋 Descripción
|
||||
|
||||
Stock Manager es una aplicación web completa para la gestión de inventarios, activos y asignaciones de equipamiento. Permite controlar tanto ítems genéricos (gestionados por cantidad) como activos serializados (con número de serie único), registrar movimientos de stock, y gestionar asignaciones a destinatarios por departamentos.
|
||||
|
||||
## ✨ Características principales
|
||||
|
||||
### Gestión de Inventario
|
||||
|
||||
- **Ítems genéricos**: Productos sin número de serie, gestionados por cantidad en stock
|
||||
- **Activos serializados**: Equipos individuales con número de serie único
|
||||
- **Categorías**: Organización jerárquica de productos
|
||||
- **Control de stock**: Niveles mínimos/máximos, alertas de stock bajo (WIP)
|
||||
- **Estados múltiples**: Disponible, Asignado, Reservado, En reparación, Averiado, Robado, Dado de baja
|
||||
|
||||
### Gestión de Destinatarios
|
||||
|
||||
- Registro de empleados/destinatarios por departamento
|
||||
- Información de contacto (email, teléfono)
|
||||
- Historial de asignaciones por destinatario
|
||||
|
||||
### Sistema de Asignaciones
|
||||
|
||||
- Asignación de ítems genéricos (por cantidad)
|
||||
- Asignación de activos individuales (uno a uno)
|
||||
- Seguimiento de fechas de asignación y devolución
|
||||
- Notas y detalles de cada asignación
|
||||
- Registro del usuario que realiza cada asignación
|
||||
|
||||
### Movimientos e Historial
|
||||
|
||||
- Registro completo de todos los movimientos de stock
|
||||
- Tipos de movimiento: IN, OUT, ASSIGNMENT, RETURN, ADJUSTMENT, DELETED
|
||||
- Trazabilidad completa con stock previo y nuevo
|
||||
- Auditoría de todos los cambios con usuario y fecha
|
||||
|
||||
### Importación de Datos
|
||||
|
||||
- Importación masiva vía CSV
|
||||
- Plantilla descargable para importaciones
|
||||
- Validación de datos en el proceso de importación
|
||||
|
||||
### Sistema de Autenticación y Roles
|
||||
|
||||
- Autenticación segura con NextAuth v5
|
||||
- 4 roles de usuario: ADMIN, MANAGER, STAFF, VIEWER
|
||||
- Permisos diferenciados según rol
|
||||
- Contraseñas hasheadas con bcrypt
|
||||
|
||||
## 🚀 Tecnologías
|
||||
|
||||
- **Framework**: Next.js 15 (App Router)
|
||||
- **Base de datos**: PostgreSQL 18
|
||||
- **ORM**: Prisma 6
|
||||
- **Autenticación**: NextAuth v5
|
||||
- **UI**: React 19, Tailwind CSS, Shadcn
|
||||
- **Validación**: Zod
|
||||
- **Formularios**: React Hook Form
|
||||
- **Runtime**: Bun (recomendado)
|
||||
- **Containerización**: Docker + Docker Compose
|
||||
|
||||
## 🔨 Desarrollo en entorno DevContainer
|
||||
|
||||
Este proyecto incluye configuración para desarrollo en contenedor usando [DevContainer](https://containers.dev/).
|
||||
|
||||
1. Abre el proyecto en VS Code y selecciona "Reopen in Container".
|
||||
2. El entorno instalará dependencias automáticamente (bun i) y lanzará el servidor de desarrollo (bun run dev).
|
||||
3. El puerto 3000 estará disponible para acceder a la app desde tu navegador.
|
||||
|
||||
## 🔨 Desarrollo local
|
||||
|
||||
### Prerrequisitos
|
||||
|
||||
- Node.js 18+ o Bun
|
||||
- PostgreSQL 13+ (o usar Docker Compose)
|
||||
- Git
|
||||
|
||||
1. Clonar el repositorio:
|
||||
|
||||
```bash
|
||||
git clone <repo-url>
|
||||
cd stock-manager
|
||||
```
|
||||
|
||||
2. Instalar dependencias:
|
||||
## Quick start
|
||||
|
||||
```bash
|
||||
bun install
|
||||
# o
|
||||
npm install
|
||||
cp .env.example .env
|
||||
bun run db:generate
|
||||
bun run db:migrate
|
||||
bun run db:seed
|
||||
bun run dev
|
||||
```
|
||||
|
||||
3. Configurar variables de entorno:
|
||||
Abrí la aplicación en [http://localhost:3000](http://localhost:3000).
|
||||
|
||||
> `db:seed` crea un administrador inicial cuando no existe ningún admin activo. Configurá las variables `ADMIN_*` en `.env` antes de usarlo en entornos compartidos o productivos.
|
||||
|
||||
## Qué hace la aplicación
|
||||
|
||||
Stock Manager permite gestionar:
|
||||
|
||||
- **Ítems genéricos**: productos gestionados por cantidad de stock.
|
||||
- **Activos serializados**: equipos individuales con número de serie único.
|
||||
- **Categorías**: clasificación de ítems y activos.
|
||||
- **Destinatarios**: personas o departamentos que reciben asignaciones.
|
||||
- **Asignaciones**: entrega y devolución de ítems o activos.
|
||||
- **Movimientos**: historial auditable de entradas, salidas, asignaciones, devoluciones y ajustes.
|
||||
- **Usuarios admin**: gestión de usuarios, roles, estado activo y reseteo de contraseña.
|
||||
- **Importación CSV**: flujo legacy de importación masiva, mantenido estructuralmente pero pendiente de rediseño.
|
||||
|
||||
## Stack técnico
|
||||
|
||||
| Área | Tecnología |
|
||||
|------|------------|
|
||||
| Framework | Next.js 16 App Router |
|
||||
| Runtime/package manager | Bun |
|
||||
| UI | React 19, Tailwind CSS, Radix UI/Shadcn-style components |
|
||||
| Formularios | React Hook Form |
|
||||
| Validación | Zod |
|
||||
| Autenticación | NextAuth v5 |
|
||||
| ORM | Prisma 7 |
|
||||
| Base de datos | PostgreSQL |
|
||||
| Formato/lint | Biome |
|
||||
| Deploy | Docker / Docker Compose |
|
||||
|
||||
## Configuración de entorno
|
||||
|
||||
Copiá el ejemplo y completá los valores reales:
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
Editar `.env` con tus configuraciones:
|
||||
Variables principales:
|
||||
|
||||
```env
|
||||
# Database
|
||||
DATABASE_URL="postgresql://user:password@localhost:5432/stockmanager"
|
||||
POSTGRES_USER=user
|
||||
POSTGRES_PASSWORD=password
|
||||
POSTGRES_DB=stockmanager
|
||||
POSTGRES_HOST=db
|
||||
POSTGRES_PORT=5432
|
||||
| Grupo | Variables |
|
||||
|-------|-----------|
|
||||
| Base de datos | `DATABASE_URL`, `POSTGRES_USER`, `POSTGRES_PASSWORD`, `POSTGRES_DB`, `POSTGRES_HOST`, `POSTGRES_PORT` |
|
||||
| Auth | `AUTH_SECRET`, `AUTH_TRUST_HOST`, `DOMAIN`, `NODE_ENV`, `DEMO_MODE` |
|
||||
| Bootstrap admin | `ADMIN_BOOTSTRAP_ENABLED`, `ADMIN_USERNAME`, `ADMIN_EMAIL`, `ADMIN_NAME`, `ADMIN_PASSWORD` |
|
||||
|
||||
# NextAuth
|
||||
NODE_ENV=development
|
||||
DEMO_MODE=false
|
||||
AUTH_SECRET="your-secret-key-here"
|
||||
AUTH_TRUST_HOST=true
|
||||
DOMAIN=localhost:3000
|
||||
```
|
||||
### Bootstrap admin
|
||||
|
||||
4. Ejecutar migraciones de base de datos:
|
||||
El seed ejecuta `prisma/seed.ts`, que llama a `prisma/bootstrap-admin.ts`.
|
||||
|
||||
```bash
|
||||
bun run db:migrate
|
||||
# o generar el cliente Prisma
|
||||
bun run db:generate
|
||||
```
|
||||
Comportamiento:
|
||||
|
||||
5. (Opcional) Ejecutar seed para datos iniciales:
|
||||
- Si ya existe un usuario `ADMIN` activo, no hace nada.
|
||||
- Si `ADMIN_BOOTSTRAP_ENABLED=false`, no crea administrador.
|
||||
- En producción, `ADMIN_PASSWORD` es obligatorio.
|
||||
- En desarrollo, si no se define contraseña, usa un valor por defecto sólo para facilitar el arranque local.
|
||||
|
||||
Ejecutar manualmente:
|
||||
|
||||
```bash
|
||||
bun run db:seed
|
||||
```
|
||||
|
||||
6. Iniciar el servidor de desarrollo:
|
||||
## Desarrollo local
|
||||
|
||||
### Prerrequisitos
|
||||
|
||||
- Bun 1.3+
|
||||
- PostgreSQL accesible mediante `DATABASE_URL`
|
||||
- Git
|
||||
|
||||
### Pasos
|
||||
|
||||
```bash
|
||||
# 1. Instalar dependencias
|
||||
bun install
|
||||
|
||||
# 2. Configurar entorno
|
||||
cp .env.example .env
|
||||
|
||||
# 3. Generar cliente Prisma
|
||||
bun run db:generate
|
||||
|
||||
# 4. Aplicar migraciones en desarrollo
|
||||
bun run db:migrate
|
||||
|
||||
# 5. Crear admin inicial, si corresponde
|
||||
bun run db:seed
|
||||
|
||||
# 6. Levantar Next
|
||||
bun run dev
|
||||
```
|
||||
|
||||
Abrir [http://localhost:3000](http://localhost:3000) en el navegador.
|
||||
## Desarrollo con DevContainer
|
||||
|
||||
## 🐳 Despliegue con Docker
|
||||
El proyecto incluye configuración para desarrollo en contenedor.
|
||||
|
||||
### Producción
|
||||
1. Abrí el repo en VS Code.
|
||||
2. Elegí **Reopen in Container**.
|
||||
3. El entorno instala dependencias y puede levantar el servidor de desarrollo.
|
||||
4. Accedé a [http://localhost:3000](http://localhost:3000).
|
||||
|
||||
## Docker / despliegue
|
||||
|
||||
Con Docker Compose:
|
||||
|
||||
```bash
|
||||
docker-compose -f compose.yaml up -d
|
||||
docker compose -f compose.yaml up -d
|
||||
```
|
||||
|
||||
Con Traefik (reverse proxy):
|
||||
El `Dockerfile` ejecuta al iniciar:
|
||||
|
||||
```bash
|
||||
docker-compose -f compose.yaml -f compose.traefik.yaml up -d
|
||||
bun run db:deploy && bun run db:seed && bun run start
|
||||
```
|
||||
|
||||
## 📜 Scripts disponibles
|
||||
Esto aplica migraciones pendientes, ejecuta el bootstrap admin si corresponde y luego inicia Next.
|
||||
|
||||
## Scripts disponibles
|
||||
|
||||
| Script | Descripción |
|
||||
|--------|-------------|
|
||||
| `bun run dev` | Inicia Next en desarrollo con Turbopack |
|
||||
| `bun run build` | Construye la aplicación para producción |
|
||||
| `bun run start` | Inicia la build de producción |
|
||||
| `bun run lint` | Ejecuta Biome lint con escritura de fixes |
|
||||
| `bun run format` | Formatea con Biome |
|
||||
| `bun run check` | Ejecuta Biome check con escritura de fixes |
|
||||
| `bun run db:push` | Sincroniza el schema sin crear migraciones |
|
||||
| `bun run db:migrate` | Crea/aplica migraciones en desarrollo |
|
||||
| `bun run db:migrate:reset` | Resetea la base y reaplica migraciones |
|
||||
| `bun run db:deploy` | Aplica migraciones en entornos de deploy |
|
||||
| `bun run db:generate` | Genera el cliente Prisma en `src/generated/prisma` |
|
||||
| `bun run db:seed` | Ejecuta el seed/bootstrap admin |
|
||||
| `bun run db:studio` | Abre Prisma Studio |
|
||||
|
||||
## Prisma
|
||||
|
||||
El proyecto usa Prisma 7 con configuración en:
|
||||
|
||||
```txt
|
||||
prisma.config.ts
|
||||
prisma/schema.prisma
|
||||
prisma/migrations/
|
||||
```
|
||||
|
||||
El cliente Prisma se genera en:
|
||||
|
||||
```txt
|
||||
src/generated/prisma
|
||||
```
|
||||
|
||||
Ese directorio está ignorado por Git. Después de clonar, cambiar schema o instalar dependencias, ejecutá:
|
||||
|
||||
```bash
|
||||
# Desarrollo
|
||||
bun run dev # Inicia servidor de desarrollo con Turbopack
|
||||
bun run build # Construye para producción
|
||||
bun run start # Inicia servidor de producción
|
||||
|
||||
# Linting y formato
|
||||
bun run lint # Ejecuta ESLint
|
||||
bun run lint:fix # Corrige errores de ESLint automáticamente
|
||||
bun run format # Formatea código con Prettier
|
||||
|
||||
# Base de datos
|
||||
bun run db:push # Sincroniza schema sin migraciones
|
||||
bun run db:migrate # Crea y ejecuta migraciones
|
||||
bun run db:migrate:reset # Resetea BD y ejecuta migraciones
|
||||
bun run db:deploy # Ejecuta migraciones en producción
|
||||
bun run db:generate # Genera cliente Prisma
|
||||
bun run db:studio # Abre Prisma Studio (GUI para BD)
|
||||
bun run db:generate
|
||||
```
|
||||
|
||||
## 📁 Estructura del proyecto
|
||||
Validar schema:
|
||||
|
||||
```bash
|
||||
bunx prisma validate
|
||||
```
|
||||
|
||||
## Arquitectura del código
|
||||
|
||||
La aplicación separa responsabilidades por capa:
|
||||
|
||||
| Capa | Ruta | Responsabilidad |
|
||||
|------|------|-----------------|
|
||||
| UI / routes | `src/app` | Páginas, layouts y componentes por ruta |
|
||||
| Server Actions | `src/actions` | Boundary de servidor: auth, Zod, llamada a use-case, revalidación |
|
||||
| Use-cases | `src/use-cases` | Reglas de negocio, coordinación multi-entidad y transacciones |
|
||||
| Services | `src/services` | Acceso a datos/repositories Prisma; muchos aceptan `tx` opcional |
|
||||
| Schemas | `src/schemas` | Validación Zod y tipos de formularios/actions |
|
||||
| Types | `src/types` | Tipos compartidos y aliases de Prisma |
|
||||
| Lib | `src/lib` | Infraestructura común: auth, prisma, paginate, security, constants, utils |
|
||||
|
||||
### Regla práctica
|
||||
|
||||
- Las **Actions** deben ser finas.
|
||||
- Las reglas de negocio viven en **use-cases**.
|
||||
- Los **services** no orquestan flujos: leen/escriben datos y aceptan transacciones cuando participan en una operación mayor.
|
||||
|
||||
## Estructura principal
|
||||
|
||||
```txt
|
||||
src/
|
||||
├── app/ # App Router de Next.js
|
||||
│ ├── (auth)/ # Rutas de autenticación
|
||||
│ │ └── login/
|
||||
│ ├── (dashboard)/ # Rutas del dashboard
|
||||
│ │ ├── (home)/ # Página principal
|
||||
│ │ ├── assignments/ # Gestión de asignaciones
|
||||
│ │ ├── import/ # Importación de datos
|
||||
│ │ ├── inventory/ # Gestión de inventario
|
||||
│ │ │ ├── assets/ # Activos serializados
|
||||
│ │ │ ├── categories/# Categorías
|
||||
│ │ │ └── items/ # Ítems genéricos
|
||||
│ │ ├── movements/ # Historial de movimientos
|
||||
│ │ └── recipients/ # Gestión de destinatarios
|
||||
│ └── api/ # API routes
|
||||
│ ├── auth/ # Endpoints de autenticación
|
||||
│ └── db/ # Endpoints de base de datos
|
||||
├── components/ # Componentes React
|
||||
│ ├── auth/ # Componentes de autenticación
|
||||
│ ├── common/ # Componentes comunes
|
||||
│ ├── forms/ # Componentes de formularios
|
||||
│ ├── layout/ # Componentes de layout
|
||||
│ └── ui/ # Componentes UI (Radix)
|
||||
├── lib/ # Utilidades y configuración
|
||||
│ ├── actions/ # Server Actions
|
||||
│ ├── schemas/ # Schemas de validación Zod
|
||||
│ └── types/ # Tipos TypeScript
|
||||
├── services/ # Servicios de lógica de negocio
|
||||
├── prisma/ # Schema y migraciones Prisma
|
||||
│ ├── schema.prisma # Definición del modelo de datos
|
||||
│ ├── migrations/ # Historial de migraciones
|
||||
│ └── seed.ts # Datos iniciales
|
||||
└── styles/ # Estilos globales
|
||||
├── actions/ # Server Actions finas
|
||||
├── app/ # Next.js App Router
|
||||
│ ├── (auth)/ # Login
|
||||
│ ├── (dashboard)/ # Dashboard, inventario, asignaciones, importación, admin
|
||||
│ ├── api/ # API routes
|
||||
│ └── forbidden/ # Página de acceso denegado
|
||||
├── components/ # Componentes compartidos y UI
|
||||
├── generated/ # Cliente Prisma generado, ignorado por Git
|
||||
├── hooks/ # Hooks React
|
||||
├── lib/ # Infraestructura y utilidades
|
||||
├── schemas/ # Schemas Zod
|
||||
├── services/ # Repositories Prisma / read models
|
||||
├── styles/ # Estilos globales
|
||||
├── types/ # Tipos compartidos
|
||||
└── use-cases/ # Casos de uso transaccionales
|
||||
|
||||
prisma/
|
||||
├── bootstrap-admin.ts # Crea/activa admin inicial si corresponde
|
||||
├── migrations/ # Migraciones Prisma
|
||||
├── schema.prisma # Modelo de datos
|
||||
└── seed.ts # Entry point de seed
|
||||
```
|
||||
|
||||
## 🔐 Seguridad
|
||||
## Autenticación y autorización
|
||||
|
||||
- Autenticación mediante JWT
|
||||
- Contraseñas hasheadas con bcrypt
|
||||
- Validación de datos con Zod en cliente y servidor
|
||||
- Protección de rutas según roles
|
||||
- Variables de entorno para secretos
|
||||
- Sanitización de inputs
|
||||
- Login con NextAuth credentials.
|
||||
- Passwords hasheadas con `bcryptjs`.
|
||||
- Roles soportados: `ADMIN`, `MANAGER`, `STAFF`, `VIEWER`.
|
||||
- `/admin/*` requiere rol `ADMIN`.
|
||||
- Usuarios inactivos no pueden iniciar sesión.
|
||||
|
||||
## 🗃️ Modelo de datos
|
||||
Helpers relevantes:
|
||||
|
||||
El sistema gestiona las siguientes entidades principales:
|
||||
```txt
|
||||
src/services/auth.service.ts
|
||||
src/lib/auth.ts
|
||||
src/proxy.ts
|
||||
```
|
||||
|
||||
- **Users**: Usuarios del sistema con roles y permisos
|
||||
- **Recipients**: Destinatarios/empleados que reciben asignaciones
|
||||
- **Categories**: Categorías de productos
|
||||
- **Items**: Ítems genéricos (sin número de serie)
|
||||
- **Assets**: Activos individuales (con número de serie)
|
||||
- **Assignments**: Asignaciones de ítems/activos a destinatarios
|
||||
- **Movements**: Registro de todos los movimientos de inventario
|
||||
## Modelo de datos
|
||||
|
||||
Ver `src/prisma/schema.prisma` para el esquema completo.
|
||||
Entidades principales:
|
||||
|
||||
| Entidad | Descripción |
|
||||
|---------|-------------|
|
||||
| `User` | Usuarios del sistema y roles |
|
||||
| `Recipient` | Destinatarios de asignaciones |
|
||||
| `Category` | Categorías de inventario |
|
||||
| `Item` | Ítems genéricos con stock |
|
||||
| `Asset` | Activos serializados |
|
||||
| `Assignment` | Asignaciones y devoluciones |
|
||||
| `Movement` | Historial auditable de movimientos |
|
||||
|
||||
Ver el schema completo en:
|
||||
|
||||
```txt
|
||||
prisma/schema.prisma
|
||||
```
|
||||
|
||||
## Flujos importantes
|
||||
|
||||
### Asignaciones
|
||||
|
||||
- Crear asignación decrementa stock de forma transaccional.
|
||||
- Devolver asignación incrementa stock si aplica y libera activo.
|
||||
- Movimientos `ASSIGNMENT` y `RETURN` se crean dentro del use-case.
|
||||
|
||||
### Activos
|
||||
|
||||
- Crear activo disponible incrementa stock.
|
||||
- Crear activo asignado crea asignación y movimiento asociado.
|
||||
- Cambios de estado generan movimientos adecuados (`IN`, `OUT`, `ASSIGNMENT`, `RETURN`, `ADJUSTMENT`).
|
||||
|
||||
### Ítems
|
||||
|
||||
- `Item.name` es único.
|
||||
- Crear item con stock inicial genera movimiento `IN`.
|
||||
- El borrado es soft delete y se bloquea si hay stock o assets asociados.
|
||||
|
||||
### Usuarios
|
||||
|
||||
- Sólo `ADMIN` puede gestionar usuarios.
|
||||
- No se puede quitar el propio acceso admin.
|
||||
- No se puede dejar el sistema sin admin activo.
|
||||
- La protección de último admin usa transacción serializable con retry de conflictos Prisma `P2034`.
|
||||
|
||||
## Validación antes de subir cambios
|
||||
|
||||
Ejecutá al menos:
|
||||
|
||||
```bash
|
||||
bunx tsc --noEmit
|
||||
bunx prisma validate
|
||||
```
|
||||
|
||||
Para cambios de Prisma:
|
||||
|
||||
```bash
|
||||
bun run db:generate
|
||||
bunx prisma validate
|
||||
```
|
||||
|
||||
Para cambios de formato/lint:
|
||||
|
||||
```bash
|
||||
bun run check
|
||||
```
|
||||
|
||||
## Estado conocido
|
||||
|
||||
- La importación CSV actual es legacy y se mantiene por compatibilidad; está previsto rediseñarla.
|
||||
- El cliente Prisma generado no se versiona; debe generarse antes de build/deploy.
|
||||
|
||||
Reference in New Issue
Block a user