Soporte ZH Consultores 012c4e1c66 fix(horas): normalizar nombres legacy de abogado en hours/obs/escrituras
Antes de la migración 007 los dropdowns guardaban variantes parciales
(ej. "Altafulla" en vez de "Julio Altafulla"). El filtro del Reporte
de Horas no encontraba esos registros viejos porque users.name ahora
es el nombre completo.

Migración 013 hace un UPDATE con JOIN a users donde haya match único
LIKE %legacy%. Aplicó a 4 filas: 2 en tramites_hours, 1 en
tramites_obs, 1 en escrituras_tramites.
2026-06-04 22:14:53 -05:00
2026-05-11 19:10:36 +00:00
2026-05-11 19:10:36 +00:00
2026-05-11 19:10:36 +00:00

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

# 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:

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.

S
Description
No description provided
Readme
908 KiB
Languages
HTML 63.8%
PHP 32.3%
JavaScript 2.4%
Shell 1%
CSS 0.5%