Inicializar rioCata - Sistema de Catación de Café
- Base de datos PostgreSQL 16 con extensiones JSONB y arrays - Docker Compose para containerización - Scripts SQL de inicialización (schema, funciones, índices, datos de prueba) - Suite de tests de validación (18 tests) - Queries de ejemplo (17 queries) - Script helper para gestión (scripts/riocata.sh) - Documentación completa en README.md Estructura: - 4 tablas principales: sesion, auth.users, sesion_participante, muestra, evaluacion - Tipo ENUM para defectos - 2 triggers automáticos (updated_at, puntaje_final) - 19 índices de optimización (GIN, B-tree, funcionales) - Constraints de validación para arrays y JSONB - 2 funciones auxiliares para análisis
This commit is contained in:
347
README.md
Normal file
347
README.md
Normal file
@@ -0,0 +1,347 @@
|
||||
# rioCata - Sistema de Catación de Café
|
||||
|
||||
Sistema digital para realizar sesiones de catación de café de manera ordenada y profesional.
|
||||
|
||||
## Arquitectura
|
||||
|
||||
- **Base de datos**: PostgreSQL 16 con extensiones para JSONB y arrays
|
||||
- **Containerización**: Docker Compose
|
||||
- **Estructura de datos**: Modelo relacional optimizado para catación profesional
|
||||
|
||||
## Estructura del Proyecto
|
||||
|
||||
```
|
||||
rioCata/
|
||||
├── docker-compose.yml # Configuración de servicios
|
||||
├── scripts/ # Scripts de gestión y administración
|
||||
│ ├── riocata.sh # Script helper principal
|
||||
│ └── README.md # Documentación de scripts
|
||||
├── postgres/
|
||||
│ ├── init/ # Scripts de inicialización (ejecutados automáticamente)
|
||||
│ │ ├── 01_schema.sql # Tipos y tablas
|
||||
│ │ ├── 02_functions.sql # Funciones y triggers
|
||||
│ │ ├── 03_indexes.sql # Índices de optimización
|
||||
│ │ └── 04_sample_data.sql # Datos de prueba
|
||||
│ └── tests/ # Scripts de testing
|
||||
│ ├── test_all.sql # Suite completa de tests
|
||||
│ └── example_queries.sql # Queries de ejemplo
|
||||
└── README.md
|
||||
```
|
||||
|
||||
## Inicio Rápido
|
||||
|
||||
### 1. Levantar el entorno
|
||||
|
||||
```bash
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
Esto iniciará PostgreSQL con todos los scripts de inicialización ejecutados automáticamente.
|
||||
|
||||
### 2. Verificar que el servicio está corriendo
|
||||
|
||||
```bash
|
||||
docker-compose ps
|
||||
```
|
||||
|
||||
Deberías ver `riocata_postgres` en estado `Up`.
|
||||
|
||||
### 3. Conectarse a la base de datos
|
||||
|
||||
```bash
|
||||
docker-compose exec postgres psql -U riocata_user -d riocata
|
||||
```
|
||||
|
||||
### 4. Ejecutar los tests
|
||||
|
||||
Una vez dentro de psql:
|
||||
|
||||
```sql
|
||||
\i postgres/tests/test_all.sql
|
||||
```
|
||||
|
||||
Esto ejecutará 18 tests que validan:
|
||||
- Existencia de tablas y tipos
|
||||
- Funcionamiento de triggers
|
||||
- Constraints de validación
|
||||
- Queries típicas
|
||||
- Funciones auxiliares
|
||||
|
||||
### 5. Explorar los datos de ejemplo
|
||||
|
||||
```sql
|
||||
\i postgres/tests/example_queries.sql
|
||||
```
|
||||
|
||||
Esto ejecutará 17 queries de ejemplo que muestran:
|
||||
- Listado de sesiones, muestras y evaluaciones
|
||||
- Top evaluaciones por puntaje
|
||||
- Evaluaciones con defectos
|
||||
- Promedios de parámetros por muestra
|
||||
- Análisis de notas de fragancia y sabor
|
||||
- Estadísticas por catador
|
||||
|
||||
## Scripts Helper
|
||||
|
||||
Para facilitar la gestión del proyecto, hay scripts helper disponibles en la carpeta `scripts/`.
|
||||
|
||||
### Script Principal: riocata.sh
|
||||
|
||||
El script `scripts/riocata.sh` proporciona comandos útiles para gestión:
|
||||
|
||||
```bash
|
||||
# Ver ayuda
|
||||
./scripts/riocata.sh help
|
||||
|
||||
# Iniciar servicios
|
||||
./scripts/riocata.sh start
|
||||
|
||||
# Conectarse a PostgreSQL
|
||||
./scripts/riocata.sh psql
|
||||
|
||||
# Ejecutar tests
|
||||
./scripts/riocata.sh test
|
||||
|
||||
# Ejecutar queries de ejemplo
|
||||
./scripts/riocata.sh queries
|
||||
|
||||
# Ver estado
|
||||
./scripts/riocata.sh status
|
||||
|
||||
# Crear backup
|
||||
./scripts/riocata.sh backup
|
||||
|
||||
# Restaurar backup
|
||||
./scripts/riocata.sh restore backup_20251017_143022.sql
|
||||
|
||||
# Detener servicios
|
||||
./scripts/riocata.sh stop
|
||||
|
||||
# Reiniciar todo (borra datos - ¡CUIDADO!)
|
||||
./scripts/riocata.sh reset
|
||||
```
|
||||
|
||||
**Documentación completa**: Ver `scripts/README.md` para información detallada sobre todos los comandos disponibles.
|
||||
|
||||
## Modelo de Datos
|
||||
|
||||
### Tablas Principales
|
||||
|
||||
#### `sesion`
|
||||
Representa una sesión de catación.
|
||||
- `id`: UUID (PK)
|
||||
- `codigo`: Código único (ej. "S-2025-10-17-01")
|
||||
- `fecha`: Fecha de la catación
|
||||
- `nombre`: Nombre descriptivo (ej. "Mesa Laboratorio #1")
|
||||
|
||||
#### `auth.users`
|
||||
Usuarios/catadores del sistema (simula Supabase auth.users).
|
||||
- `id`: UUID (PK)
|
||||
- `email`: Email único
|
||||
- `nombre`: Nombre del catador
|
||||
|
||||
#### `sesion_participante`
|
||||
Relación de catadores participantes en una sesión.
|
||||
- `id`: UUID (PK)
|
||||
- `sesion_id`: FK a sesion
|
||||
- `catador_id`: FK a auth.users
|
||||
- `rol`: Rol del participante (catador, juez, etc.)
|
||||
|
||||
#### `muestra`
|
||||
Muestras de café evaluadas en una sesión.
|
||||
- `id`: UUID (PK)
|
||||
- `sesion_id`: FK a sesion
|
||||
- `codigo`: Código de la muestra (ej. "Muestra A-101")
|
||||
- `posicion`: Orden físico en la mesa
|
||||
|
||||
#### `evaluacion`
|
||||
Evaluación completa de una muestra por un catador.
|
||||
|
||||
**Campos de intensidades (JSONB)**:
|
||||
- `intensidades`: JSON con 8 parámetros (descriptiva 1-15, afectiva 1-10):
|
||||
- fragancia, aroma, sabor, saborResidual
|
||||
- acidez, dulzor, sensacionBoca, impresionGlobal
|
||||
|
||||
**Campos de notas (JSONB arrays)**:
|
||||
- `fragancia_aroma_notas`: Array de objetos {categoria, subcategoria, notaEspecifica}
|
||||
- `sabor_notas`: Array de objetos {categoria, subcategoria, notaEspecifica}
|
||||
|
||||
**Campos de arrays**:
|
||||
- `tazas_no_uniformes`: smallint[] (valores 1-5)
|
||||
- `tazas_defectuosas`: smallint[] (valores 1-5)
|
||||
- `sensacion_en_boca`: text[] (Áspero, Suave, Aceitoso, Metálico, Astringente)
|
||||
- `gustos_predominantes`: text[] (1-2 elementos: Salado, Amargo, Ácido, Dulce, Umami)
|
||||
|
||||
**Otros campos**:
|
||||
- `defecto`: ENUM (Mohoso, Fenólico, Papa)
|
||||
- `otras_notas`: Texto libre
|
||||
- `puntaje_final`: int (calculado automáticamente por trigger)
|
||||
|
||||
### Triggers Automáticos
|
||||
|
||||
1. **`trg_eval_updated_at`**: Actualiza `updated_at` en cada UPDATE
|
||||
2. **`trg_eval_score_bi`**: Calcula `puntaje_final` como suma de valores afectivos
|
||||
|
||||
### Constraints de Validación
|
||||
|
||||
- Tazas no uniformes/defectuosas: solo valores 1-5
|
||||
- Sensaciones en boca: solo valores permitidos
|
||||
- Gustos predominantes: máximo 2 elementos
|
||||
- Intensidades descriptivas: rango 1-15
|
||||
- Intensidades afectivas: rango 1-10
|
||||
- Una evaluación única por participante/muestra
|
||||
|
||||
## Funciones Auxiliares
|
||||
|
||||
### `get_promedio_parametro_afectivo(sesion_id, parametro)`
|
||||
Obtiene el promedio de un parámetro afectivo para toda una sesión.
|
||||
|
||||
```sql
|
||||
SELECT get_promedio_parametro_afectivo(
|
||||
'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa',
|
||||
'acidez'
|
||||
);
|
||||
```
|
||||
|
||||
### `get_top_muestras(sesion_id, limit)`
|
||||
Obtiene las mejores muestras de una sesión ordenadas por puntaje.
|
||||
|
||||
```sql
|
||||
SELECT * FROM get_top_muestras(
|
||||
'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa',
|
||||
3
|
||||
);
|
||||
```
|
||||
|
||||
## Queries Típicas
|
||||
|
||||
### Promedio de dulzor por sesión
|
||||
```sql
|
||||
SELECT s.id, AVG(((e.intensidades->'dulzor'->>'afectiva')::int))
|
||||
FROM sesion s
|
||||
JOIN muestra m ON m.sesion_id = s.id
|
||||
JOIN evaluacion e ON e.muestra_id = m.id
|
||||
WHERE s.id = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'
|
||||
GROUP BY s.id;
|
||||
```
|
||||
|
||||
### Buscar evaluaciones con defecto específico
|
||||
```sql
|
||||
SELECT e.*
|
||||
FROM evaluacion e
|
||||
WHERE e.defecto = 'Fenólico';
|
||||
```
|
||||
|
||||
### Buscar taza defectuosa específica (usando índice GIN)
|
||||
```sql
|
||||
SELECT e.*
|
||||
FROM evaluacion e
|
||||
WHERE e.tazas_defectuosas @> ARRAY[5]::smallint[];
|
||||
```
|
||||
|
||||
### Top 3 muestras por puntaje
|
||||
```sql
|
||||
SELECT m.codigo, e.puntaje_final, sp.catador_id
|
||||
FROM muestra m
|
||||
JOIN evaluacion e ON e.muestra_id = m.id
|
||||
JOIN sesion_participante sp ON sp.id = e.sesion_participante_id
|
||||
WHERE m.sesion_id = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'
|
||||
ORDER BY e.puntaje_final DESC
|
||||
LIMIT 3;
|
||||
```
|
||||
|
||||
### Filtrar por acidez alta (usa índice funcional)
|
||||
```sql
|
||||
SELECT *
|
||||
FROM evaluacion
|
||||
WHERE ((intensidades->'acidez'->>'afectiva')::int) >= 8;
|
||||
```
|
||||
|
||||
## Datos de Prueba
|
||||
|
||||
El sistema viene con datos de prueba precargados:
|
||||
|
||||
- **3 usuarios**: Dario, Juan Pérez, María González
|
||||
- **1 sesión**: "Mesa Laboratorio #1 - Lotes Lavados"
|
||||
- **3 muestras**: A-101, B-202, C-303
|
||||
- **5 evaluaciones**: Con variedad de puntajes, defectos, y características
|
||||
|
||||
## Configuración
|
||||
|
||||
### Credenciales por defecto (docker-compose.yml)
|
||||
- **Base de datos**: `riocata`
|
||||
- **Usuario**: `riocata_user`
|
||||
- **Contraseña**: `riocata_password`
|
||||
- **Puerto**: `5432`
|
||||
|
||||
### Modificar credenciales
|
||||
|
||||
Edita `docker-compose.yml` y cambia las variables de entorno:
|
||||
|
||||
```yaml
|
||||
environment:
|
||||
POSTGRES_DB: tu_base_de_datos
|
||||
POSTGRES_USER: tu_usuario
|
||||
POSTGRES_PASSWORD: tu_contraseña
|
||||
```
|
||||
|
||||
## Comandos Útiles
|
||||
|
||||
### Ver logs de PostgreSQL
|
||||
```bash
|
||||
docker-compose logs -f postgres
|
||||
```
|
||||
|
||||
### Reiniciar la base de datos (¡CUIDADO! Borra todos los datos)
|
||||
```bash
|
||||
docker-compose down -v
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
### Backup de la base de datos
|
||||
```bash
|
||||
docker-compose exec postgres pg_dump -U riocata_user riocata > backup.sql
|
||||
```
|
||||
|
||||
### Restaurar backup
|
||||
```bash
|
||||
docker-compose exec -T postgres psql -U riocata_user -d riocata < backup.sql
|
||||
```
|
||||
|
||||
### Ejecutar script SQL desde el host
|
||||
```bash
|
||||
docker-compose exec -T postgres psql -U riocata_user -d riocata < mi_script.sql
|
||||
```
|
||||
|
||||
## Optimizaciones
|
||||
|
||||
El esquema incluye múltiples índices para optimizar queries comunes:
|
||||
|
||||
- **Índices B-tree** en claves foráneas y puntaje_final
|
||||
- **Índices GIN** en JSONB y arrays (para operadores @>, &&, etc.)
|
||||
- **Índices funcionales** para valores específicos en JSONB
|
||||
- **Índices de texto** para búsqueda full-text en español
|
||||
|
||||
## Próximos Pasos
|
||||
|
||||
1. **Frontend**: Desarrollar UI en Nuxt 4
|
||||
2. **API**: Crear endpoints REST/GraphQL
|
||||
3. **Autenticación**: Integrar con Supabase Auth
|
||||
4. **Análisis**: Dashboards y reportes estadísticos
|
||||
5. **Export**: Generar PDFs de sesiones de catación
|
||||
|
||||
## Desarrollo
|
||||
|
||||
Para desarrollar sobre este esquema:
|
||||
|
||||
1. Los scripts en `postgres/init/` solo se ejecutan la primera vez
|
||||
2. Para aplicar cambios, usa migrations o reinicia el contenedor con `-v`
|
||||
3. Los tests en `postgres/tests/` son re-ejecutables sin problemas
|
||||
|
||||
## Soporte
|
||||
|
||||
Para reportar problemas o sugerencias, contacta al equipo de Nucleo Rio Frio.
|
||||
|
||||
---
|
||||
|
||||
**Desarrollado por Nucleo Rio Frio** con Claude Code
|
||||
Reference in New Issue
Block a user