docs(readme): patrón de sesiones PHP con read_and_close

Documenta el fix de 1bfb3fb en la sección "Patrones de código" para
que futuros contribuyentes no escriban a $_SESSION sin llamar
startSession(true), lo cual perdería el write en silencio.
This commit is contained in:
Soporte ZH Consultores
2026-07-17 11:06:24 -05:00
parent 1bfb3fba1f
commit 1097b2df00
+7
View File
@@ -308,6 +308,13 @@ Resto → creador, o abogado solicitante (match por users.name = t.abogado
### FK `user_id` en hours/obs
Tanto `tramites_hours` como `tramites_obs` tienen `abogado VARCHAR(100)` (display) **y** `user_id INT NULL` (FK canónica `ON DELETE SET NULL`). Esto evita que renombrar un usuario en el Panel de Control desconecte sus entradas históricas de los filtros. Si lo borras, `user_id` queda NULL y el string `abogado` permanece como historia.
### Sesiones PHP: `Auth::startSession($forWrite = false)`
`session_start()` por defecto toma un `flock()` exclusivo sobre el archivo de sesión que dura **todo el request**. Con polling en `/escrituras/` cada 15 s + varias pestañas abiertas del mismo usuario, los requests se serializan esperando el lock y agotan el pool de php-fpm.
Por eso `Auth::startSession()` usa `session_start(['read_and_close' => true])` por defecto: carga `$_SESSION` en memoria y libera el lock de inmediato. Todos los `Auth::requireAuth()` / `isAuthenticated()` / `user()` funcionan con esta snapshot.
**Regla al agregar código nuevo:** si vas a escribir a `$_SESSION[...] = ...` o `unset($_SESSION[...])`, debes hacerlo dentro de un método que llame `self::startSession(true)` para tomar el lock exclusivo real. Si no, el write ocurre en memoria pero **no se persiste al archivo** al final del request. Los 5 flujos que ya lo hacen: `buildLoginUrl`, `completeLogin`, `logout`, `popReturnTo`, `checkState`.
---
## Identidad visual