
    xyMjH                     ,   d Z ddlZddlZddlmZ ddlmZ ddlmZmZm	Z	m
Z
 ddlZ ej                         Zed        ZdZd Zd	ed
ee   dee   dee   dededee   fdZdedee	ee
f      fdZdee	ee
f      fdZdededefdZdededefdZy)uB   
Camada de persistência SQLite para o serviço PX3Lab Follow-up.
    N)contextmanager)datetime)OptionalListDictAnyc               #     K   t         5  t        j                  t        j                  d      } t        j
                  | _        | j                  d       | j                  d       	 |  | j                          	 | j                          	 ddd       y# t        $ r | j                           w xY w# | j                          w xY w# 1 sw Y   yxY ww)uH   Contexto seguro para uso em multi-thread (SQLite requer serialização).g      >@)timeoutzPRAGMA journal_mode=WAL;zPRAGMA foreign_keys=ON;N)_locksqlite3connectconfigDB_PATHRowrow_factoryexecutecommit	Exceptionrollbackcloseconns    7/opt/mia/workspace/clientes/px3lab/followup_notif/db.pyget_connr      s      
 v~~t<";;/0./	JKKM
 JJL   	MMO	 JJL sA   CAC	'B<C		CB11B44CC		CCa  
CREATE TABLE IF NOT EXISTS events (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    contact_id TEXT NOT NULL,
    contact_name TEXT,
    contact_phone TEXT,
    assigned_user_id TEXT,
    tag TEXT NOT NULL,
    tag_added_at TIMESTAMP NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    UNIQUE(contact_id, tag)
);

CREATE INDEX IF NOT EXISTS idx_events_tag_added_at
    ON events(tag_added_at);

CREATE TABLE IF NOT EXISTS notifications_sent (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    event_id INTEGER REFERENCES events(id) ON DELETE CASCADE,
    delay_hours INTEGER NOT NULL,
    sent_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    UNIQUE(event_id, delay_hours)
);
c                  l    t               5 } | j                  t               d d d        y # 1 sw Y   y xY w)N)r   executescriptSCHEMAr   s    r   init_dbr   A   s,    	 #t6"# # #s   *3
contact_idcontact_namecontact_phoneassigned_user_idtagtag_added_atreturnc                     t               5 }|j                  d| |||||j                         f      }|j                  r|j                  ndcddd       S # 1 sw Y   yxY w)u   
    Insere um novo evento (tag adicionada). Se já existe (contact_id + tag),
    retorna None e ignora - isso evita reiniciar a contagem de follow-up caso
    o Linkia emita eventos repetidos.
    z
            INSERT OR IGNORE INTO events
                (contact_id, contact_name, contact_phone, assigned_user_id, tag, tag_added_at)
            VALUES (?, ?, ?, ?, ?, ?)
            N)r   r   	isoformatrowcount	lastrowid)r   r    r!   r"   r#   r$   r   curs           r   insert_eventr+   I   sf     
 7tll  &&(
 !$s}}$!7 7 7s   A AAc                     t               5 }|j                  d| f      j                         }|D cg c]  }t        |       c}cd d d        S c c}w # 1 sw Y   y xY w)Nz"SELECT * FROM events WHERE tag = ?r   r   fetchalldict)r#   r   rowsrs       r   list_events_for_tagr2   i   s^    	 't||0F
 (* 	 "&&AQ&' '
 '' 's   &AAAAAc                      t               5 } | j                  d      j                         }|D cg c]  }t        |       c}cd d d        S c c}w # 1 sw Y   y xY w)NzSELECT * FROM eventsr-   )r   r0   r1   s      r   list_all_eventsr4   r   sP    	 't||23<<>!%&AQ&' '&' 's   $AAAAAevent_iddelay_hoursc                     t               5 }|j                  d| |f      j                         }|d ucd d d        S # 1 sw Y   y xY w)NzCSELECT 1 FROM notifications_sent WHERE event_id=? AND delay_hours=?)r   r   fetchone)r5   r6   r   rows       r   notification_already_sentr:   x   sL    	 tllQ{#
 (* 	 $  s	   &;Ac                     t               5 }|j                  d| |f      }|j                  dkD  cddd       S # 1 sw Y   yxY w)uJ   Retorna True se marcou (não existia). False se já existia (idempotente).zt
            INSERT OR IGNORE INTO notifications_sent (event_id, delay_hours)
            VALUES (?, ?)
            r   N)r   r   r(   )r5   r6   r   r*   s       r   mark_notification_sentr<      sI    	  tll {#
 ||a     s	   #8A)__doc__r   	threading
contextlibr   r   typingr   r   r   r   r   Lockr   r   r   r   strintr+   r2   r4   boolr:   r<        r   <module>rG      s     %  , , 	  (
4#773-7 C=7 sm	7
 
7 7 c]7@'S 'T$sCx.%9 ''d38n- ' # $ 
 S 
 s 
 t 
 rF   