Files
donna/README.md
T
Soporte ZH Consultores 4ee32aec6d Initial commit — Donna portal v1
Setup completo del portal interno donna.aal-law.com:

* Landing público con OAuth login + grid de apps autenticado
* Flujo OAuth2 contra Mailcow (mail.aal-law.com)
* Sesiones SSO compartidas en el dominio (cookie donna_session, 8h)
* Whitelist de dominios aal-law.com / aalnlaw.com
* App "Control de Escrituras" migrada desde ZH-Consultores/control-escrituras
  (mismo schema, mismo frontend, ahora con shared Auth/Db/Config libs)
* Migraciones SQL para users, escrituras_tramites, escrituras_historial
* Caddy on :80 con rewrite extless → .php
* Backup diario MariaDB (systemd timer + script) con retención 14d
* Documentación de arquitectura en README + infra files en docs/infra
2026-05-11 19:10:36 +00:00

207 lines
7.0 KiB
Markdown

# Donna — Portal interno AALN Law
Portal interno de la firma **Arias, Abrego, López & Noriega** (aalnlaw.com) que aloja herramientas internas para el equipo. Primer app embarcada: **Control de Escrituras Públicas**.
> Producción: <https://donna.aal-law.com>
---
## Arquitectura
```
Navegador
│ HTTPS
▼
Cloudflare → Caddy infra (SSL termination)
│ HTTP :80
▼
┌──────────────────────┐
│ Caddy (este server) │ /opt/donna/public
│ rewrite *.php │
└──────┬───────────────┘
│ unix socket
▼
┌──────────────────────┐
│ PHP-FPM 8.4 │
└──────┬───────────────┘
▼
┌──────────────────────┐
│ MariaDB 11.8 │ DB: donna
└──────────────────────┘
```
**Stack:**
- PHP 8.4-fpm (`/run/php/php8.4-fpm.sock`)
- Caddy 2.6 en `:80`
- MariaDB 11.8 (`127.0.0.1:3306`)
- Autenticación OAuth2 contra Mailcow (`mail.aal-law.com`)
- Backups diarios automáticos vía systemd timer
---
## Estructura del repo
```
donna/
├── public/ ← DocumentRoot
│ ├── index.php ← Landing + grid de apps
│ ├── auth/
│ │ ├── login.php ← Inicia OAuth flow
│ │ ├── callback.php ← Recibe code de Mailcow
│ │ └── logout.php
│ └── escrituras/
│ ├── index.php ← Auth-guard + sirve view
│ └── api.php ← CRUD trámites + historial
├── src/ ← Librerías PHP compartidas (fuera de DocumentRoot)
│ ├── Config.php ← Lee /etc/donna/donna.env
│ ├── Db.php ← PDO singleton
│ ├── Auth.php ← Sesión + OAuth guard + whitelist
│ ├── Oauth.php ← Cliente HTTP a Mailcow
│ └── Apps.php ← Catálogo de apps del menú
├── views/ ← Templates HTML servidos por PHP tras auth
│ └── escrituras.html
├── sql/ ← Migraciones (aplicar manualmente)
│ ├── 001_core.sql ← users
│ └── 002_escrituras.sql ← escrituras_tramites + escrituras_historial
├── bin/
│ └── donna-backup.sh ← mysqldump diario, retención 14 días
├── docs/ ← Diseños y archivos de infra de referencia
├── donna.env.example ← Plantilla del archivo de secrets
└── README.md
```
**Fuera del repo (en el servidor):**
- `/etc/donna/donna.env` — secrets reales (`640 root:www-data`)
- `/etc/caddy/Caddyfile` — config del Caddy local
- `/etc/systemd/system/donna-backup.{service,timer}` — backups
- `/var/log/donna/` — access logs
- `/var/backups/donna/` — dumps SQL
---
## Setup en un servidor nuevo
```bash
# 1. Paquetes del SO (Debian 13)
apt install -y caddy php8.4-fpm php8.4-mysql php8.4-curl \
php8.4-mbstring php8.4-intl php8.4-zip mariadb-server
# 2. Base de datos
mariadb -e "CREATE DATABASE donna CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
mariadb -e "CREATE USER 'donna_app'@'localhost' IDENTIFIED BY 'XXX';
GRANT ALL ON donna.* TO 'donna_app'@'localhost';"
# 3. Código
git clone https://git.zhconsultores.com/ZH-Consultores/donna.git /opt/donna
chown -R www-data:www-data /opt/donna
# 4. Migraciones
mariadb donna < /opt/donna/sql/001_core.sql
mariadb donna < /opt/donna/sql/002_escrituras.sql
# 5. Secrets
mkdir -p /etc/donna
cp /opt/donna/donna.env.example /etc/donna/donna.env
# Editar /etc/donna/donna.env con valores reales (OAuth, DB_PASS, APP_SECRET)
chown root:www-data /etc/donna/donna.env
chmod 640 /etc/donna/donna.env
# 6. Caddy y backups: ver docs/infra/ para Caddyfile y systemd units
systemctl reload caddy
systemctl enable --now donna-backup.timer
```
---
## OAuth2 con Mailcow
1. En `https://mail.aal-law.com/admin` → **Access → OAuth2 Apps**
2. Crear app con `Redirect URI = https://donna.aal-law.com/auth/callback`
3. Copiar `Client ID` y `Client Secret` a `/etc/donna/donna.env`
El flujo:
```
/ ──login──▶ /auth/login.php ──redirect──▶ mail.aal-law.com/oauth/authorize
│
▼ ?code=...&state=...
/auth/callback.php ◀── redirect ◀── usuario autorizado
│
├── valida state (anti-CSRF)
├── intercambia code → token
├── lee profile (email, nombre)
├── valida dominio @aal-law.com o @aalnlaw.com
├── inserta/actualiza fila en `users`
└── redirige a /
```
Sesión: cookie `donna_session`, `path=/`, `Secure`, `HttpOnly`, `SameSite=Lax`, lifetime 8h. SSO automático entre todas las apps del portal.
---
## Apps
Las apps se registran en `src/Apps.php::catalog()`. El landing las renderiza automáticamente como cards.
| Slug | Estado | Ruta | Tablas DB |
|---|---|---|---|
| `escrituras` | Live | `/escrituras/` | `escrituras_tramites`, `escrituras_historial` |
| `casos` | Coming soon | — | — |
| `agenda` | Coming soon | — | — |
| `clientes` | Coming soon | — | — |
**Para agregar una app nueva:**
1. Crear `/opt/donna/public/<slug>/index.php` con `Auth::requireAuth()` arriba.
2. Crear `/opt/donna/public/<slug>/api.php` si necesita backend.
3. Prefijar todas las tablas DB con `<slug>_`.
4. Crear migración en `sql/00N_<slug>.sql`.
5. Registrar en `src/Apps.php::catalog()`.
6. Commit + push.
---
## Identidad visual
| Token | Valor |
|---|---|
| `--navy` | `#1B3A6B` |
| `--navy-d` | `#112446` |
| `--navy-l` | `#2D5090` |
| `--gold` | `#C9A84C` |
| `--gold-l` | `#E8C96A` |
| `--gold-d` | `#9E7C2E` |
| `--off` | `#F7F6F3` |
| Fuente headlines | DM Serif Display |
| Fuente UI | DM Sans |
Gradient hero del landing: `#0E1F3F → #1B3A6B → #2D5090`.
---
## Backups
`donna-backup.timer` ejecuta diariamente a las 03:00 (con jitter de ±5min) y vuelca `donna` comprimido a `/var/backups/donna/donna-YYYY-MM-DD_HHMMSS.sql.gz`. Retención 14 días.
Restaurar:
```bash
gunzip -c /var/backups/donna/donna-2026-MM-DD_HHMMSS.sql.gz | mariadb donna
```
---
## Operación
| Acción | Comando |
|---|---|
| Reload Caddy | `systemctl reload caddy` |
| Reload PHP-FPM | `systemctl reload php8.4-fpm` |
| Ver logs Caddy | `tail -f /var/log/donna/access.log` |
| Ver errores PHP | `journalctl -u php8.4-fpm -f` |
| Backup manual | `/opt/donna/bin/donna-backup.sh` |
| Próximo backup | `systemctl list-timers donna-backup.timer` |
---
## Licencia
Software interno — sin licencia pública. Propiedad de **Arias, Abrego, López & Noriega**.