# Invernada Web — Multiusuario + Multi-establecimiento (Etapa 1)

Base del sistema en **PHP + MySQL + arquitectura MVC**, con **partials** en las vistas y el **JavaScript dentro de las vistas**, como se pidió.

Esta Etapa 1 entrega la **columna vertebral**: login, usuarios, establecimientos, roles y **aislamiento** (nadie entra a un establecimiento que no es suyo). La lógica de la invernada (animales, tropas, rodeos, sanidad, pesajes, etc.) se integra encima de esta base.

---

## Estructura (MVC)

```
invernada-web/
├─ config/
│  └─ config.php            # datos de conexión y ajustes
├─ sql/
│  └─ schema.sql            # crea la base y las tablas
├─ app/
│  ├─ core/                 # núcleo del framework casero
│  │  ├─ Database.php       # conexión PDO (singleton)
│  │  ├─ Auth.php           # sesión, login y AISLAMIENTO por establecimiento
│  │  └─ Controller.php     # controlador base (render, CSRF, escape)
│  ├─ models/
│  │  ├─ Usuario.php
│  │  └─ Establecimiento.php
│  ├─ controllers/
│  │  ├─ AuthController.php
│  │  ├─ EstablecimientosController.php
│  │  ├─ UsuariosController.php
│  │  └─ DashboardController.php
│  └─ views/
│     ├─ partials/          # header, footer (reutilizables)
│     ├─ auth/login.php
│     ├─ establecimientos/  # elegir, crear, usuarios
│     └─ dashboard/index.php
└─ public/                  # <-- RAÍZ WEB (apuntá el dominio acá)
   ├─ index.php             # Front Controller (router)
   ├─ install.php           # instalador (correr 1 vez y BORRAR)
   └─ css/estilos.css
```

> **Importante:** el `DocumentRoot` del servidor debe apuntar a la carpeta **`public/`**. Así `config/` y `app/` quedan fuera del alcance web (más seguro).

---

## Instalación (local o servidor)

1. **Crear la base de datos**: importá `sql/schema.sql` en tu MySQL/MariaDB (phpMyAdmin o consola):
   ```
   mysql -u root -p < sql/schema.sql
   ```
2. **Configurar conexión**: editá `config/config.php` (DB_HOST, DB_NAME, DB_USER, DB_PASS). Si la app queda en una subcarpeta, poné `BASE_URL`.
3. **Crear el admin**: abrí en el navegador `.../install.php`. Crea el usuario:
   - **Email:** `admin@invernada.local`
   - **Contraseña:** `admin123`
4. **Borrá `install.php`** (seguridad).
5. Entrá a `.../index.php?c=auth&a=login`.

### Probar rápido en tu máquina (PHP incorporado)
```
cd invernada-web
php -S localhost:8000 -t public
```
Luego: `http://localhost:8000/install.php` y después `http://localhost:8000/index.php`.

---

## Cómo funciona el aislamiento (lo clave)

- Un **usuario** entra con email + contraseña (hasheada con `password_hash`).
- Pertenece a uno o varios **establecimientos** (tabla `usuario_establecimiento`) con un **rol**: `admin`, `encargado`, `operario`.
- Al entrar elige el establecimiento. Ese "establecimiento activo" queda en sesión y **se re-valida contra la base en cada request** (`Auth::requiereEstablecimiento()`): si el usuario no pertenece, no entra.
- Todos los datos se leen/guardan **filtrados por `establecimiento_id`** → nadie ve los de otro.

### Roles (ajustables)
| Rol | Qué hace |
|-----|----------|
| **admin** | Ve y edita todo. Gestiona usuarios del establecimiento. |
| **encargado** | Carga y ve producción. |
| **operario** | Carga pesajes y movimientos. |

Se refinan con `Auth::requiereRol([...])` en cada controlador/acción.

---

## El "enchufe" para la app de invernada

Para no reescribir toda la lógica ya hecha en el HTML, la tabla `datos_establecimiento` guarda el **estado (JSON)** de cada establecimiento. La app (HTML/JS) lee y guarda vía:

- **Leer:** `index.php?c=dashboard&a=datosLeer` → `{ ok, datos }`
- **Guardar:** `POST index.php?c=dashboard&a=datosGuardar` (JSON en el cuerpo + token CSRF)

Así el sistema **ya funciona multiusuario**. Más adelante, tu programador puede **normalizar** ese JSON en tablas (animales, tropas, rodeos, pastoreos…) sin tocar el login ni el aislamiento.

---

## Seguridad incluida

- Contraseñas **hasheadas** (`password_hash` / `password_verify`).
- **CSRF** en los formularios (token por sesión).
- **Escape anti-XSS** en las vistas (`Controller::e()`).
- **Sentencias preparadas** (PDO) → sin inyección SQL.
- `session_regenerate_id` al loguear (anti fijación de sesión).
- Re-validación del establecimiento activo en cada request.

> En producción: `MODO_DEBUG = 0`, servir por **HTTPS**, y cookies de sesión seguras.

---

## Próximas etapas sugeridas

2. Gestión de usuarios más completa (editar rol, resetear contraseña, invitaciones por link).
3. Normalizar el modelo de datos en tablas (portar la lógica del HTML módulo por módulo).
4. API para que la app sincronice animales/tropas/rodeos directamente (no solo el JSON).
5. Auditoría (quién cambió qué y cuándo).
