-- Session history table for tracking all RADIUS connections -- This table persists session data that was previously only in memory CREATE TABLE IF NOT EXISTS sesiones ( id SERIAL PRIMARY KEY, -- RADIUS session identifiers session_id VARCHAR(64) UNIQUE NOT NULL, -- Acct-Session-Id from FreeRADIUS username VARCHAR(64) NOT NULL, -- User-Name dispositivo_id INTEGER REFERENCES dispositivos(id) ON DELETE SET NULL, -- NAS (Network Access Server) information nas_ip VARCHAR(45), -- NAS-IP-Address nas_id VARCHAR(64), -- NAS-Identifier calling_station_id VARCHAR(32), -- MAC address of client device called_station_id VARCHAR(64), -- SSID or AP identifier -- Session timestamps started_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), ended_at TIMESTAMPTZ, -- NULL if session is active last_update TIMESTAMPTZ NOT NULL DEFAULT NOW(), -- Session state: active, stopped, stale status VARCHAR(16) NOT NULL DEFAULT 'active', stop_reason VARCHAR(64), -- Acct-Terminate-Cause -- Traffic statistics (from Interim-Updates and Stop) bytes_in BIGINT DEFAULT 0, -- Acct-Input-Octets bytes_out BIGINT DEFAULT 0, -- Acct-Output-Octets packets_in BIGINT DEFAULT 0, -- Acct-Input-Packets packets_out BIGINT DEFAULT 0, -- Acct-Output-Packets session_time INTEGER DEFAULT 0, -- Acct-Session-Time (seconds) -- For stale detection interim_interval INTEGER -- Expected Acct-Interim-Interval ); -- Indexes for efficient queries CREATE INDEX IF NOT EXISTS idx_sesiones_username ON sesiones(username); CREATE INDEX IF NOT EXISTS idx_sesiones_dispositivo ON sesiones(dispositivo_id); CREATE INDEX IF NOT EXISTS idx_sesiones_status ON sesiones(status); CREATE INDEX IF NOT EXISTS idx_sesiones_started ON sesiones(started_at DESC); CREATE INDEX IF NOT EXISTS idx_sesiones_last_update ON sesiones(last_update); CREATE INDEX IF NOT EXISTS idx_sesiones_calling_station ON sesiones(calling_station_id); -- Partial index for active sessions (frequently queried) CREATE INDEX IF NOT EXISTS idx_sesiones_active ON sesiones(username, dispositivo_id) WHERE status = 'active';