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
This commit is contained in:
@@ -0,0 +1,179 @@
|
||||
<?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);
|
||||
}
|
||||
Reference in New Issue
Block a user