# Manual de instalación

Este manual describe cómo instalar el Sistema Integral de Proveeduría Municipal en un servidor
con Apache o Nginx, PHP 8.2+ y MySQL 8 / MariaDB 10.4+. Está pensado para personal de sistemas
con conocimiento básico de hosting y bases de datos.

---

## 1. Requisitos previos

### 1.1 Software del servidor

| Componente | Mínimo | Recomendado | Cómo verificarlo |
|---|---|---|---|
| PHP | 8.2.0 | 8.3 o superior | `php -v` |
| Extensión `pdo_mysql` | Sí | — | `php -m \| grep pdo_mysql` |
| Extensión `mbstring` | Sí | — | `php -m \| grep mbstring` |
| Extensión `dom` | Sí | — | `php -m \| grep dom` |
| Extensión `fileinfo` | Sí | — | `php -m \| grep fileinfo` |
| Extensión `openssl` | Sí | — | `php -m \| grep openssl` |
| Extensión `gd` | — | Sí (logotipos) | `php -m \| grep gd` |
| Extensión `zip` | — | Sí (respaldos) | `php -m \| grep zip` |
| MySQL / MariaDB | 8.0 / 10.4 | 8.0 / 10.6 | `mysql --version` |
| Apache | 2.4 con `mod_rewrite` | — | `apache2ctl -M \| grep rewrite` |
| Espacio en disco | 100 MB | 500 MB | `df -h` |

El asistente web comprueba estos puntos en su paso 1 y le dice exactamente qué corregir.

### 1.2 Permisos de carpetas

El sistema necesita escribir en dos rutas, **fuera** del directorio público:

```bash
chown -R usuario:www-data config storage
chmod -R 775 config storage
chmod 640 config/app.php        # después de instalar
```

Si el servidor usa PHP-FPM con un usuario distinto, ajuste el grupo: en Debian/Ubuntu suele ser
`www-data`; en CentOS/CPanel suele ser `nobody` o el usuario del FTP.

### 1.3 Creación de la base de datos

```sql
CREATE DATABASE proveeduria CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'proveeduria'@'localhost' IDENTIFIED BY 'una-clave-segura';
GRANT ALL PRIVILEGES ON proveeduria.* TO 'proveeduria'@'localhost';
FLUSH PRIVILEGES;
```

El usuario necesita todos los privilegios sobre **esa** base de datos para poder crear las tablas.

---

## 2. Instalación mediante el asistente web

### 2.1 Publicación de los archivos

1. Descargue el paquete y descomprímalo.

2. **Instale las dependencias de PHP** en la carpeta donde se descomprimió el paquete:

   ```bash
   cd /home/usuario/proveeduria
   composer install --no-dev --optimize-autoloader
   ```

   El paquete **no incluye `vendor/`** a propósito: las dependencias se instalan en el servidor,
   donde se ejecuta el sistema. Si se omite este paso, el sitio no arranca y muestra un aviso
   en pantalla indicando que faltan las dependencias (no un error de PHP).

   > Sin acceso por SSH: ejecute `composer install --no-dev` en su equipo y suba la carpeta
   > `vendor/` resultante al servidor, dentro de la carpeta del sistema.

3. Suba el contenido a `/home/usuario/proveeduria` (o a la carpeta del dominio).
4. Configure el **document root** apuntando a la carpeta `public/`:

   ```apache
   <VirtualHost *:80>
       ServerName proveeduria.ejemplo.gob.mx
       DocumentRoot /home/usuario/proveeduria/public

       <Directory /home/usuario/proveeduria/public>
           AllowOverride All
           Require all granted
           Options -Indexes
       </Directory>

       ErrorLog  logs/proveeduria-error.log
       CustomLog logs/proveeduria-access.log combined
   </VirtualHost>
   ```

   En cPanel, use el campo «Document Root» del dominio o un subdominio dedicado.

5. Verifique que `public/.htaccess` está presente: contiene la reescritura a `index.php`
   y las cabeceras de seguridad.

### 2.2 Ejecución del asistente

Abra en el navegador `https://proveeduria.ejemplo.gob.mx/install`.

> **El asistente es esa dirección, no una carpeta del paquete.** No existe una carpeta `install/`
> dentro del ZIP: el asistente es una ruta de la propia aplicación (su código está en
> `app/Views/install`), y por eso funciona con cualquier dominio, puerto o subcarpeta sin
> editar nada a mano. Si el ZIP se descomprimió completo y el sitio responde, `/install` existe.

**Paso 1 — Verificación del servidor.** Se comprueban PHP, extensiones, permisos de escritura,
sesiones, compatibilidad con MySQL, requisitos de PDF y HTTPS. Si algo obligatorio falla,
el botón «Continuar» permanece deshabilitado y el detalle indica cómo corregirlo.

**Paso 2 — Configuración de MySQL.** Indique host, puerto, base de datos, usuario, contraseña y
prefijo de tablas. El botón «Probar la conexión» valida los datos sin tocar el esquema.
Si la base de datos no existe, el sistema lo indica con claridad: créela en cPanel o phpMyAdmin.

**Paso 3 — Configuración institucional.** Nombre del sistema, institución, departamento
responsable, logotipos, favicon, colores, zona horaria, moneda, IVA, ejercicio fiscal y
la política de folios. La vista previa muestra el resultado con los colores elegidos.

**Paso 4 — Cuenta del administrador.** Nombre, usuario, correo y contraseña. Esta cuenta recibe
el rol de Superadministrador.

**Paso 5 — Finalización.** Revise el resumen y pulse «Activar el sistema». El proceso:

1. escribe `config/app.php` con la configuración y las credenciales;
2. ejecuta las migraciones (crea las tablas);
3. carga la configuración institucional, los roles y los permisos;
4. crea los catálogos iniciales (unidades de medida y ejercicio fiscal);
5. registra la cuenta del administrador;
6. escribe `storage/install.lock`, que bloquea el asistente.

Si algo falla, el sistema lo indica y **no** deja el sistema a medio instalar: revise el mensaje,
corrija y repita. Puede volver al paso 2 con el enlace «Volver».

### 2.3 Después de instalar

- Inicie sesión en `/login`.
- En **Configuración → Sistema**, cambie el nombre del logotipo por el escudo oficial definitivo.
- Verifique el flujo completo: cree un departamento, una partida con presupuesto, un proveedor
  y una orden de compra; emítala y compruebe que se generó el vale y que el presupuesto se descontó.

---

## 3. Instalación por línea de comandos

Útil en servidores con SSH o para preparar un entorno de pruebas.

```bash
cd /home/usuario/proveeduria

# Dependencias
composer install --no-dev --optimize-autoloader

# Permisos
chmod -R 775 config storage

# Instalación
php tools/instalar-cli.php \
  --host=127.0.0.1 --port=3306 --db=proveeduria \
  --user=proveeduria --pass='clave' --prefix=pv_ \
  --admin-user=admin --admin-pass='ClaveSegura2026' \
  --admin-email=admin@ejemplo.gob.mx --admin-name="Nombre Apellido" \
  --institution="H. Ayuntamiento Municipal" \
  --procurement-name="Departamento de Proveeduría" \
  --fiscal-year=2026
```

Si la aplicación **no** se sirve en la raíz del dominio (por ejemplo, vive en
`https://ejemplo.gob.mx/proveeduria/`), añade la ruta:

```bash
php tools/instalar-cli.php ... --base-url="/proveeduria"
```

Sin ese parámetro el sistema asume la raíz del dominio, que es el caso más
habitual en hosting compartido.

El instalador imprime el resultado de cada paso. Si la instalación falla, muestra el paso exacto
y el mensaje del error.

---

## 4. Configuración con Nginx

```nginx
server {
    listen 80;
    server_name proveeduria.ejemplo.gob.mx;
    root /home/usuario/proveeduria/public;
    index index.php;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_pass unix:/run/php/php8.3-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param HTTP_PROXY "";
    }

    location ~* ^/(app|config|database|resources|storage|tests|tools|vendor)/ {
        deny all;
        return 404;
    }

    location ~ /\. {
        deny all;
    }
}
```

Con Nginx **no** se usa `.htaccess`: las reglas de seguridad deben declararse en el bloque
`server`, como en el ejemplo.

---

## 5. Problemas frecuentes

| Síntoma | Causa probable | Solución |
|---|---|---|
| «La conexión no es válida» en el paso 2 | La base de datos no existe o el usuario no tiene permisos | Créela en phpMyAdmin/cPanel y otorgue privilegios |
| «No fue posible escribir la configuración» | `config/` sin permiso de escritura | `chmod 775 config` y verifique el propietario |
| Pantalla en blanco | `display_errors` activo o error fatal | Revise `storage/logs/app-AAAA-MM-DD.log` |
| «La sesión expiró» al guardar | El navegador bloqueó cookies | Verifique que PHP no tiene `session.cookie_secure` activo sin HTTPS |
| «No se encontró la plantilla del documento» | Falta `resources/document-templates/` | Revise que el paquete se descomprimió completo |
| El PDF sale sin imágenes | `ext-gd` deshabilitada | Habilite `extension=gd` en `php.ini` y reinicie PHP-FPM |
| 404 en todas las rutas | `mod_rewrite` desactivado o `AllowOverride None` | Habilite `mod_rewrite` y use `AllowOverride All` |
| «El asistente de instalación ya fue utilizado» | El sistema está instalado | Es el comportamiento correcto; use `/login` |

---

## 6. Actualizaciones

1. Respaldar la base de datos: **Configuración → Sistema → Descargar respaldo**.
2. Copiar los archivos nuevos del paquete sobre el servidor, **sin** sobrescribir `config/app.php`
   ni la carpeta `storage/`.
3. Ejecutar las migraciones:

   ```bash
   php tools/migrar.php
   ```

4. Verificar la integridad en **Configuración → Verificación de integridad**.

---

## 7. Restablecer el asistente de instalación

Solo en una instalación de prueba o cuando el sistema se haya bloqueado por un error:

```bash
rm storage/install.lock
```

El asistente volverá a estar disponible. Tenga en cuenta que reinstalar sobre una base de datos
con datos puede duplicar catálogos: en producción, restablezca primero el respaldo.
