---
name: session_cleanup
kind: function
lang: go
domain: infra
version: "1.0.0"
purity: impure
signature: "func SessionCleanup(db *sql.DB) (int64, error)"
description: "Elimina todas las sesiones expiradas de la tabla sessions. Retorna el numero de filas eliminadas. Ejecutar periodicamente (cada N horas) para evitar acumulacion."
tags: [session, auth, sqlite, cleanup, infra]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: error_go_core
imports: [database/sql, fmt, time]
params:
  - name: db
    desc: "conexion SQL abierta a la BD de la app"
output: "numero de sesiones eliminadas en esta ejecucion"
tested: true
tests: ["elimina solo sesiones expiradas, mantiene las activas"]
test_file_path: "functions/infra/session_test.go"
file_path: "functions/infra/session_cleanup.go"
---

## Ejemplo

```go
// En un ticker background de la app
go func() {
    ticker := time.NewTicker(1 * time.Hour)
    defer ticker.Stop()
    for range ticker.C {
        n, err := SessionCleanup(db)
        if err != nil {
            log.Printf("cleanup error: %v", err)
            continue
        }
        log.Printf("sesiones expiradas eliminadas: %d", n)
    }
}()
```

## Notas

Impura — DELETE en SQLite, lee `time.Now()`. DELETE con prepared statement evita SQL injection. Es seguro ejecutar en paralelo con SessionCreate/SessionValidate (SQLite tiene locking por default en WAL mode). Ejecutar cada 1h es suficiente para la mayoria de apps; si la tabla crece mucho considerar tambien un DELETE parcial con LIMIT.
