Actualización de función /planes en base de datos + primera versión del README
This commit is contained in:
parent
5342fb489d
commit
f7962f894d
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,7 +1,7 @@
|
|||||||
# Ignorar los directorios de dependencias
|
# Ignorar los directorios de dependencias
|
||||||
node_modules/
|
node_modules/
|
||||||
|
|
||||||
# Ignorar los volumenes respaldados
|
# Ignorar los volumenes respaldados de docker compose
|
||||||
docker-volumes*
|
docker-volumes*
|
||||||
|
|
||||||
# Ignorar las carpetas de bases de datos
|
# Ignorar las carpetas de bases de datos
|
||||||
|
|||||||
303
README.md
Normal file
303
README.md
Normal file
@ -0,0 +1,303 @@
|
|||||||
|
# SuiteCoffee — Sistema de gestión para cafeterías (Dockerizado y multi‑servicio)
|
||||||
|
|
||||||
|
SuiteCoffee es un sistema modular pensado para la **gestión de cafeterías** (y negocios afines), con servicios Node.js para **aplicación** y **autenticación**, bases de datos **PostgreSQL** separadas para negocio y multi‑tenencia, y un **stack Docker Compose** que facilita levantar entornos de **desarrollo** y **producción**. Incluye herramientas auxiliares como **Nginx Proxy Manager (NPM)** y **CloudBeaver** para administrar bases de datos desde el navegador.
|
||||||
|
|
||||||
|
> Repositorio: https://gitea.mateosaldain.uy/msaldain/SuiteCoffee.git
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Tabla de contenidos
|
||||||
|
|
||||||
|
- [Arquitectura](#arquitectura)
|
||||||
|
- [Características principales](#características-principales)
|
||||||
|
- [Requisitos](#requisitos)
|
||||||
|
- [Inicio rápido](#inicio-rápido)
|
||||||
|
- [Variables de entorno](#variables-de-entorno)
|
||||||
|
- [Endpoints](#endpoints)
|
||||||
|
- [Estructura del proyecto](#estructura-del-proyecto)
|
||||||
|
- [Herramientas auxiliares (NPM y CloudBeaver)](#herramientas-auxiliares-npm-y-cloudbeaver)
|
||||||
|
- [Backups y restauración de volúmenes](#backups-y-restauración-de-volúmenes)
|
||||||
|
- [Comandos útiles](#comandos-útiles)
|
||||||
|
- [Licencia](#licencia)
|
||||||
|
- [Sugerencias de mejora](#sugerencias-de-mejora)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Arquitectura
|
||||||
|
|
||||||
|
**Servicios principales**
|
||||||
|
|
||||||
|
- **app** (Node.js / Express): API de negocio y páginas simples para cargar y listar *roles, usuarios, categorías y productos*.
|
||||||
|
- **auth** (Node.js / Express + bcrypt): endpoints de **registro** e **inicio de sesión**.
|
||||||
|
- **db** (PostgreSQL 16): base de datos de la aplicación.
|
||||||
|
- **tenants** (PostgreSQL 16): base de datos separada para **multi-tenencia** (aislar clientes/tiendas).
|
||||||
|
|
||||||
|
**Herramientas**
|
||||||
|
|
||||||
|
- **Nginx Proxy Manager (NPM)**: reverse proxy y certificados (Let’s Encrypt) para exponer servicios.
|
||||||
|
- **CloudBeaver (DBeaver)**: administración de PostgreSQL vía web.
|
||||||
|
|
||||||
|
**Redes & Volúmenes**
|
||||||
|
|
||||||
|
- Redes independientes por entorno (`suitecoffee_dev_net` / `suitecoffee_prod_net`).
|
||||||
|
- Volúmenes gestionados por Compose para persistencia: `suitecoffee-db`, `tenants-db`, etc.
|
||||||
|
|
||||||
|
### Diagrama (alto nivel)
|
||||||
|
|
||||||
|
```plantuml
|
||||||
|
@startuml
|
||||||
|
skinparam componentStyle rectangle
|
||||||
|
skinparam rectangle {
|
||||||
|
BorderColor #555
|
||||||
|
RoundCorner 10
|
||||||
|
}
|
||||||
|
actor Usuario
|
||||||
|
|
||||||
|
package "Entorno DEV/PROD" {
|
||||||
|
[app (Express)] as APP
|
||||||
|
[auth (Express + bcrypt)] as AUTH
|
||||||
|
database "db (PostgreSQL)" as DB
|
||||||
|
database "tenants (PostgreSQL)" as TENANTS
|
||||||
|
APP -down-> DB : Pool PG
|
||||||
|
APP -down-> TENANTS : Pool PG
|
||||||
|
AUTH -down-> DB : Pool PG (usuarios)
|
||||||
|
Usuario --> APP : UI / API
|
||||||
|
Usuario --> AUTH : Login/Registro
|
||||||
|
}
|
||||||
|
|
||||||
|
package "Herramientas" {
|
||||||
|
[Nginx Proxy Manager] as NPM
|
||||||
|
[CloudBeaver] as DBVR
|
||||||
|
NPM ..> APP : proxy
|
||||||
|
NPM ..> AUTH : proxy
|
||||||
|
DBVR ..> DB : admin
|
||||||
|
DBVR ..> TENANTS : admin
|
||||||
|
}
|
||||||
|
@enduml
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Características principales
|
||||||
|
|
||||||
|
- **API REST** para entidades clave (roles, usuarios, categorías y productos).
|
||||||
|
- **Autenticación básica** (registro y login) con **hash de contraseñas** (bcrypt).
|
||||||
|
- **Multi‑tenencia** con base `tenants` separada para aislar clientes/tiendas.
|
||||||
|
- **Docker Compose v2** con entornos de **desarrollo** y **producción**.
|
||||||
|
- **Herramientas integradas** (NPM + CloudBeaver) en un `compose.tools.yaml` aparte.
|
||||||
|
- **Scripts** de **backup/restauración de volúmenes** y **gestión de entornos**.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Requisitos
|
||||||
|
|
||||||
|
- **Docker** y **Docker Compose v2** (recomendado).
|
||||||
|
- **Python 3.9+** (para scripts `suitecoffee.py`, backups y utilidades).
|
||||||
|
- **Node.js 20+** (sólo si vas a ejecutar servicios Node fuera de Docker).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Inicio rápido
|
||||||
|
|
||||||
|
### Opción A — Gestor interactivo (recomendado)
|
||||||
|
|
||||||
|
1. Clona el repo y entra al directorio:
|
||||||
|
```bash
|
||||||
|
git clone https://gitea.mateosaldain.uy/msaldain/SuiteCoffee.git
|
||||||
|
cd SuiteCoffee
|
||||||
|
```
|
||||||
|
2. (Opcional) Crea/copía tus archivos `.env` para **app** y **auth** en `./services/<service>/.env.development` (ver sección de variables).
|
||||||
|
3. Ejecuta el gestor:
|
||||||
|
```bash
|
||||||
|
python3 suitecoffee.py
|
||||||
|
```
|
||||||
|
- Verás un **menú** para levantar **DESARROLLO** o **PRODUCCIÓN**.
|
||||||
|
- Desde ahí también puedes **levantar/apagar** las herramientas **NPM** y **CloudBeaver**.
|
||||||
|
4. Accede:
|
||||||
|
- App (dev): suele estar disponible via NPM o directamente dentro de la red, según tu configuración.
|
||||||
|
- Páginas simples: `/roles`, `/usuarios`, `/categorias`, `/productos` (servidas por `app`).
|
||||||
|
- Salud: `/health` en `app` y `auth`.
|
||||||
|
|
||||||
|
> Consejo: primero levanta **desarrollo/producción** y luego las **herramientas** para que existan las redes externas `suitecoffee_dev_net`/`suitecoffee_prod_net` que usa `compose.tools.yaml`.
|
||||||
|
|
||||||
|
### Opción B — Comandos Docker Compose (avanzado)
|
||||||
|
|
||||||
|
- **Desarrollo**:
|
||||||
|
```bash
|
||||||
|
docker compose -f compose.yaml -f compose.dev.yaml --env-file ./services/app/.env.development --env-file ./services/auth/.env.development -p suitecoffee_dev up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
- **Producción**:
|
||||||
|
```bash
|
||||||
|
docker compose -f compose.yaml -f compose.prod.yaml --env-file ./services/app/.env.production --env-file ./services/auth/.env.production -p suitecoffee_prod up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
> Los puertos se **exponen** para herramientas (NPM UI `:81`, CloudBeaver `:8978`); los servicios `app` y `auth` se **exponen dentro de la red** y se publican externamente a través de NPM.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Variables de entorno
|
||||||
|
|
||||||
|
Crea un archivo `.env.development` (y uno `.env.production`) en **cada servicio** (`./services/app` y `./services/auth`). Variables comunes:
|
||||||
|
|
||||||
|
```dotenv
|
||||||
|
# Servidor
|
||||||
|
PORT=4000 # puerto HTTP del servicio
|
||||||
|
NODE_ENV=development # development | production
|
||||||
|
|
||||||
|
# Base de datos
|
||||||
|
DB_HOST=db # nombre del servicio postgres (o host)
|
||||||
|
DB_LOCAL_PORT=5432 # puerto de PG al que conectarse
|
||||||
|
DB_USER=postgres
|
||||||
|
DB_PASS=postgres
|
||||||
|
DB_NAME=suitecoffee_db # para 'db' (aplicación)
|
||||||
|
TENANTS_DB_NAME=tenants_db # si el servicio necesita apuntar a 'tenants'
|
||||||
|
```
|
||||||
|
|
||||||
|
> Ajusta `DB_HOST` a `db` o `tenants` según corresponda. En desarrollo, los alias útiles son `dev-db` y `dev-tenants`; en producción: `prod-db` y `prod-tenants`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Endpoints
|
||||||
|
|
||||||
|
### Servicio **app** (negocio)
|
||||||
|
|
||||||
|
- `GET /health`
|
||||||
|
- `GET /api/roles` — lista roles
|
||||||
|
- `POST /api/roles` — crea un rol
|
||||||
|
- `GET /api/usuarios` — lista usuarios
|
||||||
|
- `POST /api/usuarios` — crea un usuario
|
||||||
|
- `GET /api/categorias` — lista categorías
|
||||||
|
- `POST /api/categorias` — crea una categoría
|
||||||
|
- `GET /api/productos` — lista productos
|
||||||
|
- `POST /api/productos` — crea un producto
|
||||||
|
- Páginas estáticas simples para probar: `/roles`, `/usuarios`, `/categorias`, `/productos`
|
||||||
|
|
||||||
|
### Servicio **auth** (autenticación)
|
||||||
|
|
||||||
|
- `GET /health`
|
||||||
|
- `POST /register` — registro de usuario (password con **bcrypt**)
|
||||||
|
- `POST /auth/login` — inicio de sesión
|
||||||
|
|
||||||
|
> **Nota**: En esta etapa los endpoints son **básicos** y pensados para desarrollo/PoC. Ver la sección *Sugerencias de mejora* para próximos pasos (JWT, autorización, etc.).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Estructura del proyecto
|
||||||
|
|
||||||
|
```
|
||||||
|
SuiteCoffee/
|
||||||
|
├─ services/
|
||||||
|
│ ├─ app/
|
||||||
|
│ │ ├─ src/
|
||||||
|
│ │ │ ├─ index.js # API y páginas simples
|
||||||
|
│ │ │ └─ pages/ # roles.html, usuarios.html, categorias.html, productos.html
|
||||||
|
│ │ ├─ .env.development # variables (ejemplo)
|
||||||
|
│ │ └─ .env.production
|
||||||
|
│ └─ auth/
|
||||||
|
│ ├─ src/
|
||||||
|
│ │ └─ index.js # /register y /auth/login
|
||||||
|
│ ├─ .env.development
|
||||||
|
│ └─ .env.production
|
||||||
|
├─ compose.yaml # base (db, tenants)
|
||||||
|
├─ compose.dev.yaml # entorno desarrollo (app, auth, db, tenants)
|
||||||
|
├─ compose.prod.yaml # entorno producción (app, auth, db, tenants)
|
||||||
|
├─ compose.tools.yaml # herramientas (NPM, CloudBeaver) con redes externas
|
||||||
|
├─ suitecoffee.py # gestor interactivo (Docker Compose)
|
||||||
|
├─ backup_compose_volumes.py # backups de volúmenes Compose
|
||||||
|
└─ restore_compose_volumes.py# restauración de volúmenes Compose
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Herramientas auxiliares (NPM y CloudBeaver)
|
||||||
|
|
||||||
|
Los servicios de **herramientas** están separados para poder usarlos con **ambos entornos** (dev y prod) a la vez. Se levantan con `compose.tools.yaml` y se conectan a las **redes externas** `suitecoffee_dev_net` y `suitecoffee_prod_net`.
|
||||||
|
|
||||||
|
- **Nginx Proxy Manager (NPM)**
|
||||||
|
Puertos: `80` (HTTP), `81` (UI). Volúmenes: `npm_data`, `npm_letsencrypt`.
|
||||||
|
- **CloudBeaver**
|
||||||
|
Puerto: `8978`. Volúmenes: `dbeaver_logs`, `dbeaver_workspace`.
|
||||||
|
|
||||||
|
> Si es la primera vez, arranca un entorno (dev/prod) para que Compose cree las redes; luego levanta las herramientas:
|
||||||
|
>
|
||||||
|
> ```bash
|
||||||
|
> docker compose -f compose.tools.yaml --profile npm -p suitecoffee up -d
|
||||||
|
> docker compose -f compose.tools.yaml --profile dbeaver -p suitecoffee up -d
|
||||||
|
> ```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Backups y restauración de volúmenes
|
||||||
|
|
||||||
|
Este repo incluye dos utilidades:
|
||||||
|
|
||||||
|
- `backup_compose_volumes.py` — detecta volúmenes de un proyecto de Compose (por **labels** y nombres) y los exporta a `tar.gz` usando un contenedor `alpine` temporal.
|
||||||
|
- `restore_compose_volumes.py` — permite restaurar esos `tar.gz` en volúmenes (útil para migraciones y pruebas).
|
||||||
|
|
||||||
|
**Ejemplos básicos**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Listar ayuda
|
||||||
|
python3 backup_compose_volumes.py --help
|
||||||
|
|
||||||
|
# Respaldar volúmenes asociados a "suitecoffee_dev" en ./backups
|
||||||
|
python3 backup_compose_volumes.py --project suitecoffee_dev --output ./backups
|
||||||
|
|
||||||
|
# Restaurar un archivo a un volumen
|
||||||
|
python3 restore_compose_volumes.py --archive ./backups/suitecoffee_dev_suitecoffee-db-YYYYmmddHHMMSS.tar.gz --volume suitecoffee_dev_suitecoffee-db
|
||||||
|
```
|
||||||
|
|
||||||
|
> Consejo: si migraste manualmente y ves advertencias tipo “volume ... already exists but was not created by Docker Compose”, considera marcar el volumen como `external: true` en el YAML o recrearlo para que Compose lo etiquete correctamente.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Comandos útiles
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Ver estado (menú interactivo)
|
||||||
|
python3 suitecoffee.py
|
||||||
|
|
||||||
|
# Levantar DEV/PROD por menú (con o sin --force-recreate)
|
||||||
|
python3 suitecoffee.py
|
||||||
|
|
||||||
|
# Levantar herramientas (también desde menú)
|
||||||
|
docker compose -f compose.tools.yaml --profile npm -p suitecoffee up -d
|
||||||
|
docker compose -f compose.tools.yaml --profile dbeaver -p suitecoffee up -d
|
||||||
|
|
||||||
|
# Inspeccionar servicios/volúmenes que Compose detecta desde los YAML
|
||||||
|
docker compose -f compose.yaml -f compose.dev.yaml config --services
|
||||||
|
docker compose -f compose.yaml -f compose.dev.yaml config --format json | jq .volumes
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Licencia
|
||||||
|
|
||||||
|
- **ISC** (ver `package.json`).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Sugerencias de mejora
|
||||||
|
|
||||||
|
- **Autenticación y seguridad**
|
||||||
|
- Emitir **JWT** en el login y proteger rutas (roles/autorización por perfil).
|
||||||
|
- Configurar **CORS** por orígenes (en dev está abierto; en prod restringir).
|
||||||
|
- Añadir **rate‑limit** y **helmet** en Express.
|
||||||
|
- **Esquema de datos y migraciones**
|
||||||
|
- Añadir migraciones automatizadas (p.ej. **Prisma**, **Knex**, **Sequelize** o SQL versionado) y seeds iniciales.
|
||||||
|
- Clarificar el **modelo multi‑tenant**: por **BD por tenant** o **schema por tenant**; documentar estrategia.
|
||||||
|
- **Calidad & DX**
|
||||||
|
- Tests (unitarios e integración) y **CI** básico.
|
||||||
|
- Validación de entrada (**zod / joi**), manejo de errores consistente y logs estructurados.
|
||||||
|
- **Docker/DevOps**
|
||||||
|
- Documentar variables `.env` completas por servicio.
|
||||||
|
- Publicar imágenes de producción y usar `IMAGE:TAG` en `compose.prod.yaml` (evitar build en servidor).
|
||||||
|
- Añadir **healthchecks** a `app`/`auth` (ya hay ejemplos comentados).
|
||||||
|
- **Frontend**
|
||||||
|
- Reemplazar páginas HTML de prueba por un **frontend** (React/Vite) o una UI admin mínima.
|
||||||
|
- **Pequeños fixes**
|
||||||
|
- En los HTML de ejemplo corregir las referencias a campos `id_rol`, `id_categoria`, etc.
|
||||||
|
- Centralizar constantes (nombres de tablas/campos) y normalizar respuestas API.
|
||||||
|
|
||||||
|
---
|
||||||
@ -72,19 +72,18 @@ app.get('/',(req, res) => res.sendFile(path.join(__dirname, 'pages', 'index.html
|
|||||||
|
|
||||||
app.get('/planes', async (req, res) => {
|
app.get('/planes', async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const result = await pool.query(`
|
const { rows: [row] } = await pool.query(
|
||||||
SELECT id, nombre, descripcion, precio
|
'SELECT api.get_planes_json($1) AS data;',
|
||||||
FROM plan
|
[true]
|
||||||
WHERE activo = true
|
);
|
||||||
ORDER BY id
|
res.type('application/json').send(row.data);
|
||||||
`);
|
|
||||||
res.json(result.rows);
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
res.status(500).json({ error: 'Error al cargar planes' });
|
res.status(500).json({ error: 'Error al cargar planes' });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
app.post('/api/registro', async (req, res) => {
|
app.post('/api/registro', async (req, res) => {
|
||||||
const {
|
const {
|
||||||
nombre_empresa,
|
nombre_empresa,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user