diff --git a/public/tramites/api.php b/public/tramites/api.php
index 8e0f3e5..9037a4c 100644
--- a/public/tramites/api.php
+++ b/public/tramites/api.php
@@ -91,7 +91,7 @@ function hydrate(PDO $pdo, array $row): array {
}, $hrs->fetchAll());
$inv = $pdo->prepare(
- 'SELECT u.id, u.email, u.name, u.apellido
+ 'SELECT u.id, u.email, u.name
FROM tramites_involucrados ti
JOIN users u ON u.id = ti.user_id
WHERE ti.tramite_id = :t
@@ -109,7 +109,7 @@ function hydrate(PDO $pdo, array $row): array {
/**
* ¿El usuario actual puede ver/editar este trámite?
* Socio → siempre
- * Resto → si es creador, o abogado solicitante (apellido), o involucrado
+ * Resto → si es creador, o abogado solicitante (name), o involucrado
*/
function canView(PDO $pdo, int $tid): bool {
if (Auth::isSocio()) return true;
@@ -117,7 +117,7 @@ function canView(PDO $pdo, int $tid): bool {
$uid = Auth::userId();
$stmt = $pdo->prepare(
"SELECT 1 FROM tramites_legales t
- LEFT JOIN users ua ON ua.apellido = t.abogado AND ua.activo = 1
+ LEFT JOIN users ua ON ua.name = t.abogado AND ua.activo = 1
LEFT JOIN tramites_involucrados ti ON ti.tramite_id = t.id AND ti.user_id = :uid
WHERE t.id = :tid
AND (t.creado_por = :email OR ua.id = :uid2 OR ti.user_id IS NOT NULL)
@@ -153,7 +153,7 @@ try {
} else {
$stmt = $pdo->prepare(
"SELECT DISTINCT t.* FROM tramites_legales t
- LEFT JOIN users ua ON ua.apellido = t.abogado AND ua.activo = 1
+ LEFT JOIN users ua ON ua.name = t.abogado AND ua.activo = 1
LEFT JOIN tramites_involucrados ti ON ti.tramite_id = t.id AND ti.user_id = :uid
WHERE t.creado_por = :email
OR ua.id = :uid2
diff --git a/sql/007_drop_apellido.sql b/sql/007_drop_apellido.sql
new file mode 100644
index 0000000..a6c31b5
--- /dev/null
+++ b/sql/007_drop_apellido.sql
@@ -0,0 +1,26 @@
+-- ============================================================
+-- Donna — Schema 007: Eliminar apellido, usar Nombre Completo
+-- ============================================================
+-- Decisión: simplificar el modelo trabajando solo con `name` en lugar de
+-- mantener apellido + name. El dropdown "Abogado Solicitante" muestra el
+-- nombre completo en lugar del apellido suelto.
+
+-- 1) Migrar nombres de placeholders desde apellido
+UPDATE users
+ SET name = apellido
+ WHERE (name = '' OR name = '(Asignar email real)')
+ AND apellido != '';
+
+-- 2) Migrar tramites a usar el name en lugar del apellido
+UPDATE escrituras_tramites t
+ JOIN users u ON u.apellido = t.abogado AND u.apellido != '' AND u.name != ''
+ SET t.abogado = u.name;
+
+UPDATE tramites_legales t
+ JOIN users u ON u.apellido = t.abogado AND u.apellido != '' AND u.name != ''
+ SET t.abogado = u.name;
+
+-- 3) Drop columna apellido + su índice
+ALTER TABLE users
+ DROP INDEX idx_apellido,
+ DROP COLUMN apellido;
diff --git a/src/Auth.php b/src/Auth.php
index b1406f8..75048c4 100644
--- a/src/Auth.php
+++ b/src/Auth.php
@@ -47,7 +47,7 @@ final class Auth {
if (!$email) return self::$userRowCache = self::defaultRow();
try {
$stmt = Db::pdo()->prepare(
- 'SELECT id, email, name, role, apellido, activo
+ 'SELECT id, email, name, role, activo
FROM users WHERE email = :e LIMIT 1'
);
$stmt->execute([':e' => $email]);
@@ -61,12 +61,12 @@ final class Auth {
}
private static function defaultRow(): array {
- return ['id' => 0, 'email' => '', 'name' => '', 'role' => 'usuario', 'apellido' => '', 'activo' => 1];
+ return ['id' => 0, 'email' => '', 'name' => '', 'role' => 'usuario', 'activo' => 1];
}
public static function userId(): int { return (int)(self::userRow()['id'] ?? 0); }
public static function role(): string { return (string)(self::userRow()['role'] ?? 'usuario'); }
- public static function apellido(): string { return (string)(self::userRow()['apellido'] ?? ''); }
+ public static function userName(): string { return (string)(self::userRow()['name'] ?? ''); }
public static function isSocio(): bool { return self::role() === 'socio'; }
public static function isAbogado(): bool { return in_array(self::role(), ['socio','abogado'], true); }
diff --git a/src/Bootstrap.php b/src/Bootstrap.php
index 272994b..8a146b1 100644
--- a/src/Bootstrap.php
+++ b/src/Bootstrap.php
@@ -20,7 +20,7 @@ final class Bootstrap {
'isAbogado' => Auth::isAbogado(),
'canCreate' => Auth::canCreate(),
'canDelete' => Auth::canDelete(),
- 'abogados' => Lookups::abogadoApellidos(),
+ 'abogados' => Lookups::abogadoNames(),
'users' => Lookups::involucrablesUsers(),
];
$json = json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_HEX_TAG | JSON_HEX_AMP);
diff --git a/src/Lookups.php b/src/Lookups.php
index 6763410..11c7f6a 100644
--- a/src/Lookups.php
+++ b/src/Lookups.php
@@ -5,25 +5,25 @@ require_once __DIR__ . '/Db.php';
/**
* Lookups — vistas de solo lectura sobre la tabla users para poblar
- * dropdowns y resolver mapeo email ↔ apellido.
+ * dropdowns y resolver visibilidad.
*/
final class Lookups {
- /** Apellidos para el dropdown "Abogado Solicitante" (socios + abogados activos). */
- public static function abogadoApellidos(): array {
+ /** Nombres completos para el dropdown "Abogado Solicitante" (socios + abogados activos). */
+ public static function abogadoNames(): array {
$rows = Db::pdo()->query(
- "SELECT DISTINCT apellido FROM users
+ "SELECT DISTINCT name FROM users
WHERE activo = 1
AND role IN ('socio','abogado')
- AND apellido != ''
- ORDER BY orden ASC, apellido ASC"
+ AND name != ''
+ ORDER BY orden ASC, name ASC"
)->fetchAll();
- return array_map(fn($r) => $r['apellido'], $rows);
+ return array_map(fn($r) => $r['name'], $rows);
}
/** Todos los usuarios activos para el picker de Involucrados. */
public static function involucrablesUsers(): array {
$rows = Db::pdo()->query(
- "SELECT id, email, name, role, apellido
+ "SELECT id, email, name, role
FROM users
WHERE activo = 1
AND email NOT LIKE 'placeholder-%'
@@ -36,10 +36,10 @@ final class Lookups {
/** Todos los users (incluye inactivos y placeholders) para el Panel de Control. */
public static function allUsers(): array {
$rows = Db::pdo()->query(
- "SELECT id, email, name, role, apellido, activo, orden,
+ "SELECT id, email, name, role, activo, orden,
first_seen_at, last_login_at
FROM users
- ORDER BY role DESC, apellido ASC, name ASC, email ASC"
+ ORDER BY role DESC, name ASC, email ASC"
)->fetchAll();
foreach ($rows as &$r) {
$r['id'] = (int)$r['id'];
diff --git a/views/admin.html b/views/admin.html
index 516058e..7cb81a3 100644
--- a/views/admin.html
+++ b/views/admin.html
@@ -157,18 +157,18 @@ tr.is-me td { background:#FFFBEB; font-weight:500; }
Usuarios y permisos
-
Administra la lista unificada de usuarios del sistema. El campo Apellido es lo que aparece en el dropdown "Abogado Solicitante" (solo si el rol es Socio o Abogado). Los emails que empiezan con placeholder- son los apellidos sembrados al inicio para que los dropdowns no salieran vacíos; reemplázalos con los emails reales conforme los abogados se logueen.
+
Administra la lista unificada de usuarios del sistema. El campo Nombre completo es lo que aparece en el dropdown "Abogado Solicitante" (solo si el rol es Socio o Abogado). Los emails que empiezan con placeholder- son los nombres sembrados al inicio para que los dropdowns no salieran vacíos; reemplázalos con los emails reales conforme los abogados se logueen.