ESQUEMA (migraciones 005 + 006)
* users: agrega role ENUM('socio','abogado','usuario'), apellido, activo, orden
* Seed: cabrego@aal-law.com como socio + 15 placeholders por apellido para
poblar el dropdown "Abogado Solicitante" hasta que los reales se logueen.
* tramites_involucrados: tabla N:M (tramite_id, user_id) con CASCADE delete.
AUTH (src/Auth.php)
* userRow() cachea el row del usuario actual por request.
* role(), isSocio(), isAbogado(), canCreate(), canDelete(), requireSocio().
* completeLogin() retorna bool: false si user.activo=0 → callback muestra
pantalla "cuenta deshabilitada" en lugar de loguear.
BOOTSTRAP (src/Bootstrap.php + src/Lookups.php)
* Bootstrap::inject(view) reemplaza readfile en los wrappers; inyecta
<script>window.DONNA={me,name,role,isSocio,isAbogado,canCreate,canDelete,
abogados,users}</script> antes de </head> para que el frontend tenga
contexto sin requests extra.
TRAMITES — visibilidad + involucrados
* api.php: list filtra por (socio | creador | abogado solicitante mapped via
users.apellido | involucrado) excepto socios que ven todo. Todas las
mutaciones validan canView(). create/delete validan rol. Persiste
involucrados vía syncInvolucrados().
* tramites.html: nueva columna "Involucrados" después de "Abogado", chip
picker multi-select en el modal, gear icon (oculto a non-socios), oculta
botones "+ Nuevo" y ✕ para usuarios sin permisos. Auto-incluye al
creador como involucrado por defecto.
* Calendario y demás apps consumen el API filtrado → heredan la
visibilidad sin código nuevo.
PANEL DE CONTROL (/admin/)
* index.php: requireSocio() + Bootstrap injection.
* api.php: list_users, create_user, update_user. Salvaguardas: el socio
no puede demoverse ni desactivarse a sí mismo.
* admin.html: tabla unificada de usuarios con filtros, modal CRUD,
resaltado de fila propia, placeholders identificados visualmente.
GEAR ICON
* Agregado en escrituras.html, tramites.html, calendario.html con
display:none por defecto; JS lo revela si window.DONNA.isSocio.
* Link a /admin/.
53 lines
3.5 KiB
SQL
53 lines
3.5 KiB
SQL
-- ============================================================
|
|
-- Donna — Schema 005: Roles + apellido en tabla users
|
|
-- ============================================================
|
|
-- Modelo de permisos:
|
|
-- socio = modo Dios, ve y edita todo, acceso al Panel de Control
|
|
-- abogado = crea casos. Ve/edita los que creó, los donde es abogado
|
|
-- solicitante (matching users.apellido = tramite.abogado),
|
|
-- y los donde fue involucrado. Puede eliminar lo suyo.
|
|
-- usuario = pasante/asistente. No crea ni elimina. Solo ve/edita
|
|
-- donde fue marcado como involucrado.
|
|
|
|
ALTER TABLE users
|
|
ADD COLUMN IF NOT EXISTS role ENUM('socio','abogado','usuario')
|
|
NOT NULL DEFAULT 'usuario' AFTER name,
|
|
ADD COLUMN IF NOT EXISTS apellido VARCHAR(100) NOT NULL DEFAULT '' AFTER role,
|
|
ADD COLUMN IF NOT EXISTS activo TINYINT(1) NOT NULL DEFAULT 1 AFTER apellido,
|
|
ADD COLUMN IF NOT EXISTS orden INT NOT NULL DEFAULT 0 AFTER activo,
|
|
ADD INDEX IF NOT EXISTS idx_role (role),
|
|
ADD INDEX IF NOT EXISTS idx_apellido (apellido),
|
|
ADD INDEX IF NOT EXISTS idx_activo (activo);
|
|
|
|
-- Bootstrap: el admin (cabrego@aal-law.com) queda como Socio con apellido Abrego
|
|
INSERT INTO users (email, name, role, apellido, activo, first_seen_at, last_login_at)
|
|
VALUES ('cabrego@aal-law.com', 'Carlos Abrego', 'socio', 'Abrego', 1, NOW(), NOW())
|
|
ON DUPLICATE KEY UPDATE role='socio', activo=1, apellido='Abrego';
|
|
|
|
-- Seed: 15 apellidos placeholder para que los dropdowns no salgan vacíos.
|
|
-- Los emails son sintéticos (placeholder-*); el Socio los reemplaza desde el
|
|
-- Panel de Control conforme los abogados reales se vayan logueando.
|
|
INSERT IGNORE INTO users (email, name, role, apellido, activo, orden) VALUES
|
|
('placeholder-arias@aal-law.com', '(Asignar email real)', 'abogado', 'Arias', 1, 1),
|
|
('placeholder-abrego@aal-law.com', '(Asignar email real)', 'abogado', 'Abrego', 1, 2),
|
|
('placeholder-lopez@aal-law.com', '(Asignar email real)', 'abogado', 'Lopez', 1, 3),
|
|
('placeholder-altafulla@aal-law.com', '(Asignar email real)', 'abogado', 'Altafulla', 1, 4),
|
|
('placeholder-alvarez@aal-law.com', '(Asignar email real)', 'abogado', 'Álvarez', 1, 5),
|
|
('placeholder-gutierrez@aal-law.com', '(Asignar email real)', 'abogado', 'Gutiérrez', 1, 6),
|
|
('placeholder-cedeno@aal-law.com', '(Asignar email real)', 'abogado', 'Cedeño', 1, 7),
|
|
('placeholder-mariscal@aal-law.com', '(Asignar email real)', 'abogado', 'Mariscal', 1, 8),
|
|
('placeholder-avila@aal-law.com', '(Asignar email real)', 'abogado', 'Ávila', 1, 9),
|
|
('placeholder-agudo@aal-law.com', '(Asignar email real)', 'abogado', 'Agudo', 1, 10),
|
|
('placeholder-martinez@aal-law.com', '(Asignar email real)', 'abogado', 'Martínez', 1, 11),
|
|
('placeholder-degracia@aal-law.com', '(Asignar email real)', 'abogado', 'De Gracia', 1, 12),
|
|
('placeholder-gondola@aal-law.com', '(Asignar email real)', 'abogado', 'Góndola', 1, 13),
|
|
('placeholder-gonzalez@aal-law.com', '(Asignar email real)', 'abogado', 'González', 1, 14),
|
|
('placeholder-valdes@aal-law.com', '(Asignar email real)', 'abogado', 'Valdés', 1, 15);
|
|
|
|
-- Si el placeholder de Abrego ya existe y hay un usuario real Abrego con apellido asignado,
|
|
-- desactivar el placeholder para evitar duplicados visibles en dropdowns.
|
|
UPDATE users p
|
|
JOIN users r ON r.apellido = p.apellido AND r.id != p.id AND r.email NOT LIKE 'placeholder-%'
|
|
SET p.activo = 0
|
|
WHERE p.email LIKE 'placeholder-%' AND p.activo = 1;
|