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
180 lines
6.4 KiB
PHP
180 lines
6.4 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
require_once __DIR__ . '/../../src/Auth.php';
|
|
require_once __DIR__ . '/../../src/Db.php';
|
|
|
|
if (($_GET['action'] ?? '') === 'logout') {
|
|
header('Location: /auth/logout.php');
|
|
exit;
|
|
}
|
|
|
|
Auth::requireAuth();
|
|
header('Content-Type: application/json; charset=utf-8');
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { http_response_code(204); exit; }
|
|
|
|
function ok($data = null): void {
|
|
echo json_encode(['ok' => true, 'data' => $data, 'user' => Auth::user()], JSON_UNESCAPED_UNICODE);
|
|
exit;
|
|
}
|
|
|
|
function err(string $msg, int $code = 400): void {
|
|
http_response_code($code);
|
|
echo json_encode(['ok' => false, 'error' => $msg], JSON_UNESCAPED_UNICODE);
|
|
exit;
|
|
}
|
|
|
|
function body(): array {
|
|
return json_decode((string) file_get_contents('php://input'), true) ?? [];
|
|
}
|
|
|
|
$method = $_SERVER['REQUEST_METHOD'];
|
|
$action = $_GET['action'] ?? '';
|
|
$user = Auth::user();
|
|
$pdo = Db::pdo();
|
|
|
|
try {
|
|
if ($method === 'GET' && $action === 'list') {
|
|
$rows = $pdo->query('SELECT * FROM escrituras_tramites ORDER BY id DESC')->fetchAll();
|
|
ok($rows);
|
|
}
|
|
|
|
if ($method === 'POST' && $action === 'create') {
|
|
$b = body();
|
|
$stmt = $pdo->prepare(
|
|
'INSERT INTO escrituras_tramites
|
|
(tramite, cliente, abogado, notaria, inscribe, altera_turno, instrucciones,
|
|
fecha_solicitud, estatus, observaciones, creado_por)
|
|
VALUES
|
|
(:tramite, :cliente, :abogado, :notaria, :inscribe, :altera, :instrucciones,
|
|
NOW(), :estatus, :obs, :user)'
|
|
);
|
|
$stmt->execute([
|
|
':tramite' => $b['tramite'] ?? '',
|
|
':cliente' => $b['cliente'] ?? '',
|
|
':abogado' => $b['abogado'] ?? '',
|
|
':notaria' => $b['notaria'] ?? '',
|
|
':inscribe' => $b['inscribe'] ?? 'Sí',
|
|
':altera' => $b['altera_turno'] ?? 'No',
|
|
':instrucciones' => $b['instrucciones'] ?? '',
|
|
':estatus' => $b['estatus'] ?? 'Solicitado',
|
|
':obs' => $b['observaciones'] ?? '',
|
|
':user' => $user['email'],
|
|
]);
|
|
$id = (int) $pdo->lastInsertId();
|
|
|
|
$pdo->prepare(
|
|
"INSERT INTO escrituras_historial
|
|
(tramite_id, modificado_por, campo, valor_anterior, valor_nuevo)
|
|
VALUES (?, ?, 'Trámite', '', 'Creado')"
|
|
)->execute([$id, $user['email']]);
|
|
|
|
$row = $pdo->prepare('SELECT * FROM escrituras_tramites WHERE id = :id');
|
|
$row->execute([':id' => $id]);
|
|
ok($row->fetch());
|
|
}
|
|
|
|
if ($method === 'PUT' && $action === 'update') {
|
|
$b = body();
|
|
$id = (int) ($b['id'] ?? 0);
|
|
if (!$id) err('ID requerido');
|
|
|
|
$beforeStmt = $pdo->prepare('SELECT * FROM escrituras_tramites WHERE id = :id');
|
|
$beforeStmt->execute([':id' => $id]);
|
|
$before = $beforeStmt->fetch();
|
|
if (!$before) err('Trámite no encontrado', 404);
|
|
|
|
$fields = [
|
|
'tramite' => $b['tramite'] ?? '',
|
|
'cliente' => $b['cliente'] ?? '',
|
|
'abogado' => $b['abogado'] ?? '',
|
|
'notaria' => $b['notaria'] ?? '',
|
|
'inscribe' => $b['inscribe'] ?? 'Sí',
|
|
'altera_turno' => $b['altera_turno'] ?? 'No',
|
|
'instrucciones' => $b['instrucciones'] ?? '',
|
|
'estatus' => $b['estatus'] ?? 'Solicitado',
|
|
'observaciones' => $b['observaciones'] ?? '',
|
|
];
|
|
|
|
$stmt = $pdo->prepare(
|
|
'UPDATE escrituras_tramites SET
|
|
tramite=:tramite, cliente=:cliente, abogado=:abogado, notaria=:notaria,
|
|
inscribe=:inscribe, altera_turno=:altera_turno, instrucciones=:instrucciones,
|
|
estatus=:estatus, observaciones=:observaciones,
|
|
actualizado_por=:actualizado_por
|
|
WHERE id=:id'
|
|
);
|
|
$stmt->execute(array_merge(
|
|
array_combine(
|
|
array_map(fn($k) => ':' . $k, array_keys($fields)),
|
|
array_values($fields)
|
|
),
|
|
[':actualizado_por' => $user['email'], ':id' => $id]
|
|
));
|
|
|
|
$labels = [
|
|
'tramite' => 'Nombre del Trámite',
|
|
'cliente' => 'Cliente',
|
|
'abogado' => 'Abogado Solicitante',
|
|
'notaria' => 'Notaría',
|
|
'inscribe' => 'Se Inscribe',
|
|
'altera_turno' => 'Alt. de Turno',
|
|
'instrucciones' => 'Instrucciones Especiales',
|
|
'estatus' => 'Estatus',
|
|
'observaciones' => 'Observaciones',
|
|
];
|
|
|
|
$hist = $pdo->prepare(
|
|
'INSERT INTO escrituras_historial
|
|
(tramite_id, modificado_por, campo, valor_anterior, valor_nuevo)
|
|
VALUES (:tid, :por, :campo, :ant, :nvo)'
|
|
);
|
|
foreach ($fields as $campo => $nuevo) {
|
|
$anterior = $before[$campo] ?? '';
|
|
if ((string) $anterior !== (string) $nuevo) {
|
|
$hist->execute([
|
|
':tid' => $id,
|
|
':por' => $user['email'],
|
|
':campo' => $labels[$campo] ?? $campo,
|
|
':ant' => $anterior,
|
|
':nvo' => $nuevo,
|
|
]);
|
|
}
|
|
}
|
|
|
|
$row = $pdo->prepare('SELECT * FROM escrituras_tramites WHERE id = :id');
|
|
$row->execute([':id' => $id]);
|
|
ok($row->fetch());
|
|
}
|
|
|
|
if ($method === 'DELETE' && $action === 'delete') {
|
|
$id = (int) ($_GET['id'] ?? 0);
|
|
if (!$id) err('ID requerido');
|
|
$pdo->prepare('DELETE FROM escrituras_tramites WHERE id = :id')->execute([':id' => $id]);
|
|
ok(['deleted' => $id]);
|
|
}
|
|
|
|
if ($method === 'GET' && $action === 'historial') {
|
|
$tid = (int) ($_GET['id'] ?? 0);
|
|
if (!$tid) err('ID requerido');
|
|
$stmt = $pdo->prepare(
|
|
'SELECT * FROM escrituras_historial
|
|
WHERE tramite_id = :tid
|
|
ORDER BY modificado_en DESC
|
|
LIMIT 200'
|
|
);
|
|
$stmt->execute([':tid' => $tid]);
|
|
ok($stmt->fetchAll());
|
|
}
|
|
|
|
err('Acción no reconocida', 404);
|
|
|
|
} catch (PDOException $e) {
|
|
error_log('escrituras db error: ' . $e->getMessage());
|
|
err('Error de base de datos', 500);
|
|
} catch (Throwable $e) {
|
|
error_log('escrituras error: ' . $e->getMessage());
|
|
err('Error interno', 500);
|
|
}
|