o
    |oj[                     @  s`   d Z ddlmZ ddlZddlZddlmZ ddlmZ e	e
ZdZdZdZG d	d
 d
ZdS )z>Persistencia MySQL: una sola INSERT al finalizar cada llamada.    )annotationsN)Any)CallSessiona  
CREATE TABLE IF NOT EXISTS call_sessions (
  id BIGINT AUTO_INCREMENT PRIMARY KEY,
  call_id VARCHAR(64) NOT NULL,
  document_id VARCHAR(64) NULL,
  number VARCHAR(64) NULL,
  direction VARCHAR(16) NULL,
  start_time DATETIME(3) NULL,
  answer_time DATETIME(3) NULL,
  first_bot_audio_time DATETIME(3) NULL,
  end_time DATETIME(3) NULL,
  duration_seconds DOUBLE NULL,
  time_to_first_audio_ms INT NULL,
  user_turns INT NOT NULL DEFAULT 0,
  bot_turns INT NOT NULL DEFAULT 0,
  stt_requests INT NOT NULL DEFAULT 0,
  llm_requests INT NOT NULL DEFAULT 0,
  tts_requests INT NOT NULL DEFAULT 0,
  total_prompt_tokens INT NOT NULL DEFAULT 0,
  total_completion_tokens INT NOT NULL DEFAULT 0,
  stt_audio_seconds DOUBLE NOT NULL DEFAULT 0,
  tts_characters INT NOT NULL DEFAULT 0,
  estimated_cost DECIMAL(12,6) NOT NULL DEFAULT 0,
  avg_llm_latency_ms DOUBLE NULL,
  avg_tts_latency_ms DOUBLE NULL,
  avg_stt_latency_ms DOUBLE NULL,
  avg_response_latency_ms DOUBLE NULL,
  interruptions INT NOT NULL DEFAULT 0,
  silence_seconds DOUBLE NOT NULL DEFAULT 0,
  silence_percent DOUBLE NULL,
  disconnect_reason VARCHAR(255) NULL,
  turn_timings_json JSON NULL,
  providers_json JSON NULL,
  created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
  KEY idx_call_sessions_call_id (call_id),
  KEY idx_call_sessions_start_time (start_time),
  KEY idx_call_sessions_document (document_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
z=ALTER TABLE call_sessions DROP INDEX uq_call_sessions_call_ida  
INSERT INTO call_sessions (
  call_id, document_id, number, direction,
  start_time, answer_time, first_bot_audio_time, end_time,
  duration_seconds, time_to_first_audio_ms,
  user_turns, bot_turns,
  stt_requests, llm_requests, tts_requests,
  total_prompt_tokens, total_completion_tokens,
  stt_audio_seconds, tts_characters, estimated_cost,
  avg_llm_latency_ms, avg_tts_latency_ms, avg_stt_latency_ms,
  avg_response_latency_ms,
  interruptions, silence_seconds, silence_percent,
  disconnect_reason, turn_timings_json, providers_json
) VALUES (
  %(call_id)s, %(document_id)s, %(number)s, %(direction)s,
  %(start_time)s, %(answer_time)s, %(first_bot_audio_time)s, %(end_time)s,
  %(duration_seconds)s, %(time_to_first_audio_ms)s,
  %(user_turns)s, %(bot_turns)s,
  %(stt_requests)s, %(llm_requests)s, %(tts_requests)s,
  %(total_prompt_tokens)s, %(total_completion_tokens)s,
  %(stt_audio_seconds)s, %(tts_characters)s, %(estimated_cost)s,
  %(avg_llm_latency_ms)s, %(avg_tts_latency_ms)s, %(avg_stt_latency_ms)s,
  %(avg_response_latency_ms)s,
  %(interruptions)s, %(silence_seconds)s, %(silence_percent)s,
  %(disconnect_reason)s, %(turn_timings_json)s, %(providers_json)s
)
c                   @  s`   e Zd ZdZddd$ddZed%ddZd&ddZd&ddZd'ddZ	d(dd Z
d&d!d"Zd#S ))CallMetricsMySqlStoreu<   Pool aiomysql + ensure schema + insert atómico por call_id.T)
autocommithoststrportintuserpassworddatabaser   boolreturnNonec                C  s4   || _ || _|| _|| _|| _|| _d | _d| _d S NF)_host_port_user	_password	_database_autocommit_pool_schema_ready)selfr   r	   r   r   r   r    r   >/var/www/html/bot-asterisk-ari/backend/call_metrics/persist.py__init__[   s   

zCallMetricsMySqlStore.__init__c                 C  s
   | j d uS N)r   r   r   r   r   readyn   s   
zCallMetricsMySqlStore.readyc                   s   | j d urd S zdd l}W n ty } ztd|d }~ww |j| j| j| j| j| j	| j
dddd	I d H | _ |  I d H  td| j| j| j	 d S )Nr   uS   CALL_METRICS_ENABLED=true requiere aiomysql. Instalá: pip install aiomysql PyMySQL      utf8mb4)	r   r	   r   r   dbr   minsizemaxsizecharsetz%Call metrics MySQL conectado %s:%s/%s)r   aiomysqlImportErrorRuntimeErrorcreate_poolr   r   r   r   r   r   ensure_schemaloggerinfo)r   r(   excr   r   r   connectr   s>   
zCallMetricsMySqlStore.connectc                   s  | j s	| jd u rd S | j 4 I d H f}| 4 I d H H}|tI d H  z|tI d H  td W n% t	yZ } zt
|dd gd }|dvrPtd| W Y d }~nd }~ww W d   I d H  n1 I d H skw   Y  W d   I d H  n1 I d H sw   Y  d| _ d S )NzZCall metrics: removido UNIQUE(call_id) legacy (cada llamada queda como fila independiente)argsr   )iC  u0   Call metrics: no se eliminó UNIQUE(call_id): %sT)r   r   acquirecursorexecute_CREATE_TABLE_SQL_DROP_LEGACY_UNIQUE_SQLr-   r.   	Exceptiongetattrdebug)r   conncurr/   errnor   r   r   r,      s0   *(
z#CallMetricsMySqlStore.ensure_schemarowdict[str, Any]c                   s2  | j du r
tdt|}tj|dpg dtd|d< tj|dp%i dtd|d< | j  4 I dH 5}| 4 I dH }|	t
|I dH  |j}W d  I dH  n1 I dH s[w   Y  W d  I dH  n1 I dH spw   Y  td||dt|d	pd
t|dpd
t|dpd
 dS )z:Siempre INSERT (append). Nunca UPDATE de filas anteriores.NzCall metrics MySQL no conectadoturn_timings_jsonF)ensure_asciidefaultproviders_jsonu>   Call metrics persistido id=%s call=%s cost≈$%.6f turns=%d/%dcall_idestimated_costr   
user_turns	bot_turns)r   r*   dictjsondumpsgetr   r2   r3   r4   _INSERT_SQL	lastrowidr-   r.   floatr
   )r   r=   payloadr:   r;   inserted_idr   r   r   insert_session   s8   


*(z$CallMetricsMySqlStore.insert_sessionsessionr   rD   rM   c                   s   |  ||I d H  d S r   )rP   to_row)r   rQ   rD   r   r   r   persist   s   zCallMetricsMySqlStore.persistc                   s:   | j d u rd S | j   | j  I d H  d | _ d| _d S r   )r   closewait_closedr   r   r   r   r   rT      s   


zCallMetricsMySqlStore.closeN)r   r   r	   r
   r   r   r   r   r   r   r   r   r   r   )r   r   )r   r   )r=   r>   r   r   )rQ   r   rD   rM   r   r   )__name__
__module____qualname____doc__r   propertyr    r0   r,   rP   rS   rT   r   r   r   r   r   X   s    




r   )rY   
__future__r   rH   loggingtypingr   call_metrics.sessionr   	getLoggerrV   r-   r5   r6   rK   r   r   r   r   r   <module>   s    
*