--- name: session_create kind: function lang: go domain: infra version: "1.0.0" purity: impure signature: "func SessionCreate(db *sql.DB, userID string, ttl time.Duration, metadata map[string]any) (Session, error)" description: "Crea una sesion SQLite con token aleatorio de 32 bytes hex (256 bits de entropia). Crea la tabla sessions si no existe. Retorna la Session lista para devolver al cliente." tags: [session, auth, sqlite, token, infra] uses_functions: [] uses_types: [Session_go_infra] returns: [Session_go_infra] returns_optional: false error_type: error_go_core imports: [crypto/rand, database/sql, encoding/hex, encoding/json, fmt, time] params: - name: db desc: "conexion SQL abierta a la BD de la app. No debe ser nil" - name: userID desc: "identificador del usuario al que pertenece la sesion. No vacio" - name: ttl desc: "tiempo de vida de la sesion (time.Duration). Debe ser positivo" - name: metadata desc: "datos libres a persistir junto a la sesion (role, email, ip, etc.). Puede ser nil" output: "Session con token opaco listo para devolver al cliente via header o cookie" tested: true tests: ["crea sesion y persiste en BD", "genera tokens distintos", "rechaza db nil", "rechaza user_id vacio"] test_file_path: "functions/infra/session_test.go" file_path: "functions/infra/session_create.go" --- ## Ejemplo ```go db, _ := sql.Open("sqlite3", "app.db") session, err := SessionCreate(db, user.ID, 24*time.Hour, map[string]any{ "email": user.Email, "role": "admin", "ip": r.RemoteAddr, }) if err != nil { HTTPErrorResponse(w, HTTPError{Status: 500, Code: "session_error", Message: err.Error()}) return } HTTPJSONResponse(w, 200, map[string]string{"token": session.Token}) ``` ## Notas Impura — hace I/O en SQLite, usa entropia del OS con `crypto/rand`, y lee el tiempo con `time.Now()`. La tabla `sessions` se crea con `CREATE TABLE IF NOT EXISTS` (PK token, indices en user_id y expires_at) para que la primera llamada deje todo listo sin setup manual. Token es 32 bytes aleatorios codificados en hex = 64 chars, 256 bits de entropia. Session fixation mitigada: el token lo genera el servidor, no se acepta del cliente. Para invalidar una sesion: `DELETE FROM sessions WHERE token = ?`. Limpieza periodica de expiradas: SessionCleanup.