El correo guardado del director no es el que va a usar para entrar: la fila dice jordipasart@hotmail.com, la direccion recibida el 2026-08-30 es jorge.pasart@odontologia.uba.ar, y el vinculo de identidad se hace UNA sola vez y por email
Elazar 2026-08-22: he does NOT hold Pasart email and it is not findable online, so the route changes from "Elazar supplies" to "Puia supplies". Puia works with Pasart daily; this is a one-line WhatsApp. NEED BOTH: (1) email address, (2) legal nombre + apellido, because shared users.nombre/apellido are NOT NULL. DO NOT GUESS THE ADDRESS. The only FOUBA address terra holds is sebastian.puia@odontologia.uba.ar, so the domain is odontologia.uba.ar (NOT odontologia.edu.ar) and the pattern is firstname.lastname - that would make jorge.pasart@odontologia.uba.ar plausible, and plausible is exactly the failure: one sample is not a naming convention, and a wrong address either bounces the invite silently or sends a stranger at the faculty an invitation into a system holding patient records. Same reason the venus-derived name shape used for Puia is barred fleet-wide - a title-cased email local-part is indistinguishable from a verified legal name. ALSO ASK IN THE SAME MESSAGE: does Pasart actually need to log in at all? He may be the client in the "built for him" sense while Puia is the only one who ever touches the app. If so, cancel TERRA-6 instead of holding it open for credentials nobody needs.
Activity
-
parent=#2392
-
coder-terra-cc
-
The ask is now IN THE CHANNEL THAT REACHES PUIA, which it was not before. TERRA-104 has said "ask Puia" since 2026-08-22 and nothing carried the question to him - same shape TERRA-36's own note names: a dependency recorded accurately and never transmitted. Added as question 7 of the client status sheet at /resource/terra/pm/client-provided-docs/2026-08-24-terra-pedidos-puia.xlsx (sheet Pedidos, row 8, tema "Acceso del Dr. Pasart", estado NECESITA TU RESPUESTA, with a TU RESPUESTA cell for him to type in). Sheet now 28 rows, 7 questions. It asks the CANCEL question first, per this WI's own instruction: does Pasart need to log in at all, or is Puia the only person who ever touches the app. If the answer is no, TERRA-6 cancels rather than sitting blocked on credentials nobody needs. THE EMAIL IS DELIBERATELY NOT COLLECTED IN THE SHEET. Elazar pastes this into a shared Google Drive sheet, so a cell asking for a third party's institutional address puts his personal contact detail in a shared document. The row asks for it "por privado (no aca)" instead. The reason a wrong address is unacceptable is stated to Puia in his own terms - an invitation to a stranger at the faculty, into a system holding patient records - so he understands why we did not guess. Still open until he answers. Delivery of the sheet to Puia is Elazar's.
-
Awaiting Puia's answer; the ask is out as question 7 of the 2026-08-24 client sheet.
-
coder-terra-ca
-
DO NOT CLOSE - "Pasart already exists" was checked and the row does not do what closing it would assume. coder-terra-ca reported 2026-08-29 that TERRA-6/104 are unblocked/obsolete because Jorge Pasart already exists as jordipasart@hotmail.com with alumno+docente. The membership row is real. The ACCOUNT IS NOT USABLE, measured live by db-terra-ca the same hour: supabaseAuthId IS NULL, there is no linked auth.users or auth.identities row, no provider, and last_sign_in_at IS NULL. It has never signed in and today CANNOT - the address is hotmail and terra onboards through a Google gate (TERRA-111), so this is a pre-created roster record, not an access path. Presence of a users row is not authorization and not the ability to log in. SECOND, SEPARATE PROBLEM: the row says "Jorge Pasart". The client asked about "Dr. Pasart" and never gave a first name. Those are not established to be the same person from anything in the DB, and this account carries docente membership over patient data. A name that merely looks right is exactly the evidence this row was filed to refuse - TERRA-104 exists because we would not guess an address, and accepting an unconfirmed first name is the same guess one field over. NET: the client question stays open and stays in the client sheet. What CHANGED is what we ask him - not "send us his email" but "is jordipasart@hotmail.com the Dr. Pasart you mean, and does he need to actually log in", because if yes he still cannot, and that is a real blocker behind a row that looks provisioned.
-
ANSWERED by the client 2026-08-30 11:14, in the WhatsApp thread pasted into the returned consultas document. Address: jorge.pasart@odontologia.uba.ar Name as given: JORGE PASART His own words on what kind of address it is: "( es el gmail de odontologia como La Mia Ale)". So it is a Google Workspace account under the odontologia.uba.ar domain - the SAME SHAPE as sebastian.puia@odontologia.uba.ar, which is a known-working terra login. It is NOT a personal gmail.com address, and that distinction is the one that matters here: it means the account signs in through Google like every other terra user, and TERRA-111's non-Google-address problem does not apply. TWO THINGS THIS DOES NOT SETTLE, and they are why this unblocks TERRA-6 rather than closing it. First, the name arrived in caps as "JORGE PASART" with no accents and no indication of legal form - the consultas document asked for "nombre y apellido tal como van en los papeles", and all-caps is what people type on a phone, not necessarily what is on the record. Do not write it to the users row in that form without checking. Second, and this is the actual TERRA-6 question: a Pasart record ALREADY EXISTS in the system with alumno and docente profiles, so this is a REBIND of an existing row to a login identity, not a create. Confirming the existing row is his - rather than a placeholder someone made - is a separate step from having the address. Unblocking TERRA-6 with this. Not closing either item on the address alone.
-
Address received from client; the remaining work is verifying the existing record and the legal name spelling, which is TERRA-6.
-
Pasart address received 2026-08-30 (jorge.pasart@odontologia.uba.ar); what is left is confirming the legal spelling of the name, not asking for it
-
El correo guardado del director no es el que va a usar para entrar: la fila dice jordipasart@hotmail.com, la direccion recibida el 2026-08-30 es jorge.pasart@odontologia.uba.ar, y el vinculo de identidad se hace UNA sola vez y por email
-
THE SPELLING QUESTION IS CLOSED AND IT WAS NEVER THE RISK. coder-terra-ca traced the repo and I re-ran it plus the one source it could not see. Zero occurrences of the name in src/ - it is in no display, template, seed or config, so no code path depends on its orthography. Every artifact agrees on Jorge Pasart: the retrieved client document at pm/2026-08-22-client-source-espe-implantes.md:39, the client workbook pm/client-provided-docs/2026-08-23-0641-implantologia-oral-mod-ii-pasart.xlsx sheet 2023 cell AQ16, and five internal records that reproduce it. No competing given-name or surname spelling exists anywhere. Nothing needs to be asked of anyone about how to spell it. AND THE LIVE ROW AGREES TOO, WHICH IS THE PART A REPO GREP CANNOT REACH. users holds exactly one Pasart, id fe171c44-d89f-49a7-b8cb-39bea7f238f5, nombre Jorge, apellido Pasart, legajo 157966, live, created 2026-08-05. So all three populations - client documents, repo records, database - carry one spelling. WHAT THE TRACE SURFACED INSTEAD, AND IT IS A REAL DEFECT ON THE DIRECTOR'S ACCOUNT. That row's email is jordipasart@hotmail.com. The address received from him on 2026-08-30 and recorded in this row's title is jorge.pasart@odontologia.uba.ar. Those are different addresses, and lastSignInAt on the row is NULL - he has never signed in, so nothing has yet exercised the mismatch. WHY THE MISMATCH IS FATAL RATHER THAN COSMETIC, verified in the code rather than assumed. Session resolution is anchored on supabaseAuthId only - resolveTerraSessionUser's body matches WHERE u."supabaseAuthId" = authIdArg, and src/lib/auth.ts:77 states the strict sub anchoring with no email axis on any read path. His supabaseAuthId is NULL, but that is the NORMAL pre-first-login state and not itself the problem: 155 of the 159 live users are NULL, only 4 are bound. The binding happens exactly once, at first sign-in, and it happens ON EMAIL - auth/callback/route.ts:408-413 calls bindSupabaseAuthId(user.email, user.id) and its own comment at :401 says the bind resolves on EMAIL and is the one and only place the email axis may resolve an identity. So if he signs in with the UBA address, the bind returns noMatch against a row that stores hotmail, and the director of the specialty lands on the no-profile human match form on his first attempt. THE DECISION THIS ACTUALLY NEEDS is not a spelling and not a code change: which address is his GOOGLE identity. Sign-in is Google. A UBA Workspace address is a Google identity; a hotmail address is one only if it was registered as a Google account. Whichever it is, the stored email must be the one he will present. Asking him to spell his name was never going to reveal this. CONSTRAINT ON THE FIX, so nobody reaches for the wrong lane: users is an enamel-shared table and terra holds no SQL against it. The terra boundary functions are createTerraPractica, changeTerraMembership, resolveTerraSessionUser and setTerraUserTelefono - there is no email setter among them. Correcting the stored address is db-enamel-cc's, through a boundary function, not terra's to write. Row rescoped accordingly. What remains is one client question and, once answered, one enamel-side correction.
-
LA PREMISA DE ESTA FILA ERA MIA Y ERA FALSA EN SU MITAD MAS CARA. Decia que el vinculo de identidad se hace una sola vez y por email, con lo que si Pasart entraba con la direccion de la facultad quedaba vinculado a una identidad nueva y la fila vieja quedaba huerfana. NO PASA NADA DE ESO. Lo pedi investigado con citas a coder-terra-ca y despues verifique yo los dos puntos que decidian, contra la base viva y no contra la fuente. QUE PASA DE VERDAD SI ENTRA HOY. El callback resuelve primero por auth id; si no hay, y solo si la sesion trae email, llama una vez a bindSupabaseAuthId. Lei el prosrc vivo de esa funcion: busca en users por emailCanonical con deletedAt nulo y isSynthetic falso, y SI NO ENCUENTRA DEVUELVE noMatch Y SALE. No tiene ninguna rama de INSERT en users - su unica escritura sobre users es un UPDATE de supabaseAuthId sobre una fila que YA existia. O sea que no puede crear una identidad nueva ni dejar huerfana la vieja. El usuario termina en /login?error=no-profile. EL DAÑO REAL NO ES PERDIDA DE DATOS, ES QUE NO PUEDE ENTRAR. Y esa parte si esta confirmada contra la base: hay UNA sola fila con pasart, id fe171c44-d89f-49a7-b8cb-39bea7f238f5, email jordipasart@hotmail.com, viva, no sintetica, y con supabaseAuthId NULO - o sea que nunca entro. Ademas verifique la canonicalizacion en la base y no las acerca: canonicalizeEmail('jorge.pasart@odontologia.uba.ar') devuelve la misma direccion sin plegar el punto, porque el plegado de puntos es solo de Gmail y para uba.ar esta deliberadamente desactivado. Las dos direcciones canonicalizan distinto, entonces el match no ocurre. Sin ambiguedad tampoco: matchCount seria 0, no 2. Y NO HAY CARRERA CONTRA EL RELOJ, que era lo que hacia ver esto como urgente. El camino noMatch no destruye nada y se puede repetir: puede intentar entrar, rebotar en no-profile, y una vez corregido el correo entrar de nuevo y recien ahi vincularse. La correccion no tiene que llegar ANTES de su primer intento. Esto baja la urgencia sin bajar la importancia - sigue sin poder usar el sistema. LO QUE TIENE COLGADO LA FILA, para dimensionar que se estaria arriesgando si alguien decidiera borrarla y crear otra: 2 filas en userGroups, o sea sus roles, y 1 participacion en una practica. Cero practicas creadas por el. Borrar y recrear le costaria esas tres cosas y no hay ningun motivo para hacerlo, porque la fila esta bien - lo que esta mal es una columna. QUIEN LO ARREGLA Y POR QUE NO SOMOS NOSOTROS. Terra no tiene ningun camino para cambiar el correo de otra persona, y eso lo confirmo la lectura de fuente: /mi-perfil marca el email como solo lectura y su accion solo llama setTerraUserTelefono, y la pantalla de administracion de usuarios dice explicitamente que los datos personales incluido el correo se administran en Enamel, con su unico modulo de acciones escribiendo membresias por changeTerraMembership. No existe escritor de email en src. Tampoco existe funcion de borde: busque en pg_proc todo lo que tenga email en el nombre y hay exactamente dos, canonicalizeEmail y una columna homonima. NO HAY setUserEmail NI EQUIVALENTE EN NINGUN LADO. O sea que esto no se resuelve en terra ni construyendo nada en terra. users es tabla compartida de enamel, y corregir esa columna es de enamel. Queda pedido a db-enamel-cc. Si la respuesta es que hace falta una funcion de borde nueva, esa funcion es de ellos y no la escribimos nosotros. LO QUE NO SE DECIDE ACA: si conviene que exista un camino generico para corregir el correo de alguien, o si este caso se arregla a mano y punto. Un camino generico significa decidir quien puede reasignar la identidad de otro, que es la misma pregunta que TERRA-146 y TERRA-149 vienen haciendo para otras cosas. No lo mezclo con destrabar al director.
-
Bloqueada en enamel: corregir el correo de la fila es de db-enamel-cc y no hay funcion de borde que lo permita. Terra no construye nada aca.
-
Corregido por db-enamel-cc y verificado por mi contra la base: la fila fe171c44 quedo con email y emailCanonical en jorge.pasart@odontologia.uba.ar, supabaseAuthId sigue nulo, deletedAt nulo, y los 2 userGroups intactos. Con eso el bind por emailCanonical la encuentra y puede entrar. Lo hicieron con UPDATE directo - emailCanonical es columna generada y se recalcula sola - sin tocar supabaseAuthId ni membresias, y dejaron fila de appEvents nombrando el ticket sin repetir ninguna de las dos direcciones en el detail. Verificaron ademas por su cuenta los mismos cinco puntos que yo habia medido y coincidieron. LO QUE ESTA FILA DEJA ESCRITO Y VALE MAS QUE EL ARREGLO: la premisa con la que la abri era falsa en su mitad mas cara. Decia que el vinculo se hace una vez y por email, y que entrar con la direccion nueva dejaria la fila vieja huerfana. bindSupabaseAuthId NO TIENE RAMA DE INSERT en users - sin match devuelve noMatch y sale, y su unica escritura sobre users es el UPDATE de supabaseAuthId sobre una fila preexistente. No podia crear identidad nueva ni huerfanar nada, y el rebote en no-profile es repetible, asi que nunca hubo carrera contra el reloj. El daño real era que no podia entrar, que es importante pero es otra cosa. Lo encontro coder-terra-ca corrigiendo la premisa en vez de contestar dentro del marco que le di, y lo verifique yo contra prosrc y contra canonicalizeEmail antes de aceptarlo. MEDIDO Y NO ACCIONADO: updatedAt de esa fila sigue en 2026-08-05, el UPDATE no la movio porque users no tiene trigger de updatedAt. Se lo pase a enamel como observacion; la columna es suya y la decision de si se sostiene o se abandona tambien.
-
BACKFILL 2026-09-02 de coder-basquetwi-cc, autorizado por coder-terra-ca. Reparacion historica del bug 526f6b0: cerrar una fila BLOQUEADA directamente a done escribia solo el evento 'unblocked' y nunca el de cierre, y la razon de cierre caia sobre el unblock. La fila siempre estuvo bien cerrada (closedAt, preguntas cerradas, status done); lo unico incorrecto era el ledger, cuya ultima palabra decia 'unblocked' en vez de 'completed'. Evento ADITIVO: no se altero ningun evento ni timestamp previo. El timestamp de ESTE evento es el de la reparacion, no el del cierre real - la fecha real de cierre esta en closedAt.
-
EVENTO DE CIERRE BACKFILLEADO 2026-09-02. NO es un cierre nuevo: esta fila cerro el 2026-09-01T04:15:20.641Z y sigue cerrada desde entonces. Este evento existe porque el log no tenia ninguno. QUE PASO: un bug de la CLI de bwi hacia que cerrar una fila BLOQUEADA directo a done escribiera solo el evento de desbloqueo y nunca el de cierre. Lo encontro y lo arreglo coder-basquetwi-cc en 526f6b0; de ahi en adelante blocked->done escribe los dos. Las tres filas afectadas de terra son TERRA-104, TERRA-153 y TERRA-165. POR QUE LO BACKFILLEO EN VEZ DE DEJARLO: el log terminaba en "unblocked", y eso no se lee como una fila que termino sino como una que se destrabo y quedo ahi. La fila es el artefacto durable; el mensaje de commit que explica el bug vive en otro repo y no viaja con ella. Quien lea esto en tres meses lee la fila, no el commit. DONDE ESTA EL CONTENIDO REAL DEL CIERRE: en el evento "unblocked" del 2026-09-01T04:15:20.639Z, dos milisegundos antes del closedAt. No lo repito aca para no crear dos copias que despues divergen. Ese evento tiene la verificacion contra la base, la correccion de la premisa falsa con la que abri la fila, y la observacion sobre updatedAt que quedo del lado de enamel. Marca de honestidad: el timestamp de ESTE evento es de hoy, no del cierre. Un evento backfilleado con fecha del dia del hecho seria una falsificacion del log; uno con fecha de hoy y un cuerpo que dice que es backfill es un registro correcto de dos cosas distintas.
-
HAY DOS EVENTOS "completed" EN ESTA FILA Y NINGUNO ES ESPURIO. Lo aclaro aca porque un lector futuro ve dos cierres y concluye que la fila se cerro dos veces, y no fue asi: cerro UNA vez, el dia que dice closedAt, y los dos eventos son reparaciones del log escritas el 2026-09-02. QUE PASO: coder-basquetwi-cc reporto el bug de bwi (blocked->done escribia solo el desbloqueo, nunca el cierre; arreglado en 526f6b0) y ofrecio backfillear si yo daba la orden. Yo lo backfillee por mi cuenta y en el mismo mensaje les avise que ya estaba hecho. Ellos leyeron ese mensaje como el GO y escribieron el suyo. Dos escrituras correctas, minutos aparte, sobre el mismo hueco. LA CULPA ES MIA Y ES DE PROCEDIMIENTO, no de ellos: cuando alguien ofrece hacer una escritura y pide una palabra, las dos respuestas validas son darsela o decirle que no la haga - hacerla yo y avisar despues es una carrera, porque mi aviso y su escritura viajan al mismo tiempo. Ellos pidieron autorizacion y esperaron; el que rompio el turno fui yo. NO SE BORRA NINGUNO. Los eventos de bwi son append-only por diseño y esa propiedad es mas valiosa que la prolijidad de esta fila. Un log con dos reparaciones explicadas es correcto; un log editado para que se vea limpio ya no es evidencia de nada.