--- name: session_validate kind: function lang: go domain: infra version: "1.0.0" purity: impure signature: "func SessionValidate(db *sql.DB, token string) (Session, error)" description: "Busca un token en la tabla sessions, verifica que no este expirado y retorna la Session con metadata deserializada. Error si no existe o expirado." tags: [session, auth, sqlite, validate, infra] uses_functions: [] uses_types: [Session_go_infra] returns: [Session_go_infra] returns_optional: false error_type: error_go_core imports: [database/sql, encoding/json, errors, fmt, time] params: - name: db desc: "conexion SQL abierta a la BD de la app" - name: token desc: "token opaco recibido del cliente (ej: header X-Session-Token o cookie)" output: "Session valida con user_id, metadata y timestamps. Error si token invalido o expirado" tested: true tests: ["valida token existente no expirado", "rechaza token inexistente", "rechaza token expirado"] test_file_path: "functions/infra/session_test.go" file_path: "functions/infra/session_validate.go" --- ## Ejemplo ```go token := r.Header.Get("X-Session-Token") session, err := SessionValidate(db, token) if err != nil { HTTPErrorResponse(w, HTTPError{Status: 401, Code: "invalid_session", Message: "sesion invalida o expirada"}) return } role, _ := session.Metadata["role"].(string) ``` ## Notas Impura — I/O en SQLite, lee `time.Now()` para validar expiracion. Query con prepared statement (`?` placeholder) para evitar SQL injection. En respuestas HTTP al cliente no distinguir entre "token no existe" y "expirado" para no filtrar informacion. Si necesitas invalidar la sesion tras validar (ej: renovar token): `DELETE FROM sessions WHERE token = ?` en el mismo handler.