@startuml uml-sequence-break-glass-pin !include _style.iuml title 6. Break-glass: acceso a perfil de cliente con PIN ' Fuente: migrations/003_pins_soporte_cliente.sql (pins_soporte_cliente, casos_soporte_abiertos) ' Fuente: 00.sql:1023-1094 (función abrir_acceso_perfil) ' Fuente: 00.sql:592-606 (logs_auditoria) ' Fuente: 00.sql:624-638 (accesos_perfil_usuario, expira_en NOW + 15 min) autoactivate on actor "Cliente" as Cli actor "Agente Soporte" as Ag box "Mobile Client" #F0F0F0 participant "App\n(menú PIN)" as AppCli end box box "Web Admin" #F0F0F0 participant "Workspace\nSoporte" as UI end box box "Server actions / SQL functions" #F5F5F5 control "abrir_acceso_perfil()\n(SECURITY DEFINER)" as Fn end box box "Persistencia Postgres" #EAEAEA database "pins_soporte_cliente" as DBPin database "casos_soporte_abiertos" as DBCaso database "accesos_perfil_usuario\n(expira_en = NOW + 15m)" as DBAcc database "logs_auditoria" as DBLog end box == Solicitud de PIN == Ag -> Cli : Llamada/chat: "Genera PIN en tu app" Cli -> AppCli ++ : Tap "PIN soporte" AppCli -> DBPin ++ : INSERT pins_soporte_cliente\n(pin_hash, expira_en NOW+15m) DBPin --> AppCli -- : pin de 6 dígitos AppCli --> Cli -- : muestra PIN Cli -> Ag : Comparte PIN verbalmente == Apertura de caso == Ag -> UI ++ : Ingresa cliente_id + PIN + motivo (>=10 chars) UI -> Fn ++ : abrir_acceso_perfil(cid, pin, challenge, motivo, ip, ua) note right of Fn 00.sql:1023-1094 - tiene_permiso('usuarios.acceder_perfil') - length(motivo) >= 10 - crypt(pin) match - challenge: fecha_nac o telefono end note alt PIN válido y motivo suficiente Fn -> DBPin ++ : UPDATE pins_soporte_cliente\nusado_por, usado_en DBPin --> Fn -- Fn -> DBAcc ++ : revoca accesos previos\n+ INSERT accesos_perfil_usuario\nexpira_en = NOW + 15m DBAcc --> Fn -- : acceso_id Fn -> DBCaso ++ : (opcional) INSERT casos_soporte_abiertos\npin_id, expira_en NOW+4h DBCaso --> Fn -- Fn -> DBLog ++ : INSERT logs_auditoria\naccion='acceso_perfil.abrir' DBLog --> Fn -- Fn --> UI -- : acceso_id UI --> Ag -- : Sesión break-glass activa (15 min) loop Cada lectura del perfil dentro de la ventana Ag -> UI ++ : Ver datos del cliente UI -> DBLog ++ : INSERT logs_auditoria\naccion='acceso_perfil.lectura'\ncaso_id=acceso_id DBLog --> UI -- UI --> Ag -- : datos enmascarados / completos end == Expiración == ... 15 minutos transcurren ... UI -> DBAcc ++ : SELECT expira_en > NOW() DBAcc --> UI -- : expirado UI --> Ag : Acceso revocado automáticamente else PIN incorrecto Fn -> DBPin : intentos_fallidos += 1\nbloqueado_hasta NOW+10m si >=3 Fn --> UI : RAISE pin_incorrecto UI --> Ag : "PIN inválido, reintenta" end footer Fuente: migrations/003_pins_soporte_cliente.sql | 00.sql L1023-L1094 (abrir_acceso_perfil) | 00.sql L592-L638 @enduml