basquetWi + New ticket
terra TERRA-235

Cuanto tiempo se guardan los datos personales de un pedido de registro de paciente RECHAZADO - hoy para siempre, y nadie lo decidio

Backlog normal ctcoder-terra-cc

Un pedido de registro RECHAZADO guarda el documento, el nombre, el email y la fecha de nacimiento de una persona real que nunca entro al registro de pacientes y que nunca consintio una ficha clinica. Hoy esa fila se guarda para siempre - borrado fisico prohibido, borrado logico nada mas - y eso no es una decision que alguien haya tomado: es lo que pasa por defecto porque forbidHardDelete es la regla de la casa en toda tabla de terra que tenga triggers. DE DONDE SALE. TERRA-150 mitad 2 narrowea la creacion de pacientes a docente/bedel/admin. Un alumno o un jtp que carga una practica para un paciente que todavia no existe recibe "registrar y pedir": la practica no se pierde y el pedido queda anotado en public."terraPacienteRegistrationRequests" para que alguien con permiso lo complete. Los pedidos CUMPLIDOS se resuelven solos - la persona pasa a estar en el registro y la fila del pedido es redundante con el paciente. Los RECHAZADOS son el caso abierto: la persona no entro, y sus datos personales quedan igual. LA PREGUNTA, en la forma en que hay que contestarla: un pedido rechazado, .se conserva indefinidamente, se purga a los N dias, o se anonimiza dejando solo que hubo un pedido y quien lo hizo? Y si se purga, .quien decide el N? POR QUE NO LA CONTESTA NINGUN CARRIL TECNICO. db-terra-cc se nego explicitamente a resolverla en el encabezado de la migracion y tiene razon: es una regla de retencion sobre datos personales de salud de alguien que no es paciente, no una decision de esquema. Yo tampoco puedo tomarla - no es una eleccion de implementacion con una respuesta correcta, es una politica sobre datos de terceros. Es de Elazar, y probablemente del cliente despues de el. POR QUE AHORA Y NO DESPUES. Se archiva antes de que la tabla tenga una sola fila. Una regla de retencion decidida cuando ya hay datos adentro se decide con el costo de borrarlos encima, que es exactamente como se contesta que si por omision. TERRA-146 es el ejemplo vivo de lo que pasa cuando este tipo de pregunta se responde callandose: la columna existio meses antes de que nadie decidiera quien podia corregirla. LO QUE SE VA A IMPLEMENTAR MIENTRAS TANTO, para que no quede como bloqueante: conservar, borrado fisico prohibido. Es el default de la casa y es la opcion reversible - purgar despues siempre se puede, recuperar lo purgado no. Si la respuesta es purgar, es una migracion chica y un cron. CONDICION DE CIERRE: una respuesta de Elazar o del cliente, anotada en esta fila, y si difiere de "conservar" la migracion que la implementa.

Sub-tickets

No sub-tickets.
+ Add sub-ticket

Activity

  • wi-cli-venus created · 5w ago
  • wi-cli-venus spec · 5w ago
    T235-spec-mtx6v - THE DESIGN HALF, so this becomes a yes/no rather than a question to think about. WHAT IS AFFECTED TODAY: ZERO ROWS. terraPacienteRegistrationRequests was created 2026-09-11 16:03:03 UTC and verified at 0 rows post-apply. Nothing has to be migrated, nothing has to be destroyed, and no one is harmed by either answer yet. That is the argument for deciding NOW rather than when the table has a year of rejected people in it. THE FINDING THAT CHANGES THE QUESTION: THE LOOKUP KEY IS ITSELF THE PII. The refusal path in createPractica reads the last request for a documento - WHERE documentoType = $1 AND normalizeDocumentoNumber(documentoNumber) = normalizeDocumentoNumber($2) - and if that row says 'rejected' it renders the reviewer's note back to the asker instead of filing a duplicate request. Null the documento and that lookup finds nothing: the alumno re-submits, a fresh request is filed, and the rejection they were supposed to read is silently unreachable. So this is NOT 'how long do we keep the PII'. It is: AFTER N DAYS, IS A REJECTED REQUEST STILL ALLOWED TO ANSWER A RE-SUBMIT, OR DOES IT BECOME AN UNLINKABLE RECORD? THE MINIMUM RETAINED SET FOR EACH ANSWER, which is what Elazar is really choosing between: A) STILL ANSWERS. Keep id, status, requestedBy, resolvedBy, resolvedAt, resolutionNote, createdAt AND documentoType + documentoNumber. Drop nombre, apellido, fechaNacimiento, email, telefono. The documento stays because it is the key; the rest is contact and identity data with no bearing on either the audit or the lookup. This keeps a rejected person's national ID number indefinitely and is the cost of the feature working as designed. B) BECOMES UNLINKABLE. Also null documentoType/documentoNumber. The row survives as an audit record of a decision - who asked, who refused, when, why - about a person it can no longer name. A re-submit after that point files fresh and the asker never sees the old note. Nothing breaks; the feature degrades exactly as if the request had never been made. NOT AN OPTION: deleting the row. forbidHardDelete is ENABLE ALWAYS on this table and, more to the point, the asker's right to read the note is why the row exists. WHAT MAKES B CHEAPER THAN IT LOOKS: a re-submit for a person who was genuinely rejected is answered anyway - by a human, in the queue, again. The gate does not depend on the lookup; the lookup only saves the reviewer from answering twice. WHAT IS NOT DECIDED HERE AND MUST NOT BE DEFAULTED: N. Today N is infinity by accident, because the house forbidHardDelete default is what happens when nobody names a retention period. That accident is the whole row. MIGRATION: not written. It is db-terra-cc's lane and it is one scheduled UPDATE nulling a named column set WHERE status = 'rejected' AND resolvedAt < now() - interval 'N', which cannot be written before N and the A/B choice exist. Asking them to hold rather than draft against a guess.
  • coder-terra-cc assigned · 2w ago
    coder-terra-cc
task
5w ago by wi-cli-venus
2w ago