ó
    > Ìj6  ã                   óÄ  • S r SSKrSSKrSSKJr  SSKJrJr  SSKJ	r	  \R                  " S5      rSS jrSSSSSS	SS
.S\S\\   S\\   S\\   S\\   S\\   S\S\\   SS4S jjrS\4S jrS\\\4   4S jrSSSSSSSSS.S\\   S\\   S\\   S\\   S\\   S\\   S\S\S\\   4S jjrSSSSSSS.S\\   S\\   S\\   S\\   S\\   S\\   S\4S jjrg) uÏ  
audit_service.py â€” Registro de auditorÃ­a de seguridad (MySQL, best-effort).

Fire-and-forget: nunca bloquea ni propaga excepciones â€” un fallo de auditorÃ­a
no debe romper la operaciÃ³n auditada.

ConvenciÃ³n de `action` : "<categorÃ­a>.<evento>", ej. "auth.login",
"photo.rgpd_delete", "consent.given", "family.import", "sale.create".

Niveles de `severity`:
  info     â€” operaciones normales (login correcto, venta, importaciÃ³n)
  warning  â€” intentos fallidos, ediciones, bloqueos temporales
  critical â€” borrado permanente de fotos, fuerza bruta bloqueada

Multi-colegio: cada evento puede llevar `school_id`; el director solo ve los
de su colegio, el operador ve los del colegio seleccionado (o todos).
é    N)ÚOptional)Úget_dbÚTABLE_OPTIONS)Ú
utcnow_isozmeeconic.auditÚreturnc                  óÈ   • [        5        n U R                  S[         S35        U R                  5         S S S 5        [        R                  S5        g ! , (       d  f       N$= f)Na  
            CREATE TABLE IF NOT EXISTS audit_logs (
                id            BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
                created_at    VARCHAR(40)  NOT NULL,
                user_id       VARCHAR(100),
                ip_address    VARCHAR(64),
                action        VARCHAR(80)  NOT NULL,
                resource_type VARCHAR(40),
                resource_id   VARCHAR(100),
                details_json  MEDIUMTEXT,
                severity      VARCHAR(20)  NOT NULL DEFAULT 'info',
                school_id     VARCHAR(64),
                KEY idx_audit_created (created_at),
                KEY idx_audit_action (action),
                KEY idx_audit_severity (severity),
                KEY idx_audit_school (school_id)
            ) z	
        zaudit_logs table ready)r   Úexecuter   ÚcommitÚlogÚinfo)Úconns    ÚYD:\Ingenieria\TRABAJOS ONLINE\Projects\11- Photo School\backend\services\audit_service.pyÚinit_audit_dbr      sR   € Ü	Œ�TØ�‰ð ô  ˆoð 	ð!ô 	ð$ 	�‰Œ÷' 
ô( ‡H�HÐ%Õ&÷) 
�ús   ‹*AÁ
A!r   )Úuser_idÚ
ip_addressÚresource_typeÚresource_idÚdetailsÚseverityÚ	school_idÚactionr   r   r   r   r   r   r   c                ó@  •  [        5        nUR                  S[        5       XXUU(       a  [        R                  " USS9OSXg4	5        UR                  5         SSS5        g! , (       d  f       g= f! [         a   n	[        R                  SX	5         Sn	A	gSn	A	ff = f)u=   Persiste un Ã©vÃ©nement d'audit. Ne lÃ¨ve jamais d'exception.zÀINSERT INTO audit_logs
                   (created_at, user_id, ip_address, action, resource_type, resource_id, details_json, severity, school_id)
                   VALUES (?,?,?,?,?,?,?,?,?)F)Úensure_asciiNzAudit logging failed [%s]: %s)	r   r	   r   ÚjsonÚdumpsr
   Ú	Exceptionr   Úwarning)
r   r   r   r   r   r   r   r   r   Úes
             r   Ú	log_eventr   4   s�   € ð@ÜŒX˜Ø�L‰Lð1ô “L '°vÈkÞ?F”D—J’J˜w°UÒ;ÈDØðô		ð �K‰KŒM÷ �XŽXûô ó @Ü�‰Ð3°V×?Ñ?ûð@ús5   ‚
A3 ŒAA"ÁA3 Á"
A0Á,A3 Á0A3 Á3
BÁ=BÂBc                 ó„   • [        U 5      nUR                  SS 5      nU(       a  [        R                  " U5      OS US'   U$ )NÚdetails_jsonr   )ÚdictÚpopr   Úloads)ÚrÚdr!   s      r   Ú_row_to_dictr'   Q   s6   € ÜˆQ‹€AØ—5‘5˜¨Ó.€LÞ/;”4—:’:˜lÔ+À€A€i�LØ€Hó    c                 ól  • Sn/ nU (       a  US-  ogR                  U  S35        U(       a  US-  ogR                  U5        U(       a  US-  ogR                  U5        U(       a  US-  ogR                  U5        U(       a  US-  ogR                  US-   5        U(       a  US	-  ogR                  U5        Xg4$ )
Nz
 WHERE 1=1z AND action LIKE ?Ú%z AND severity = ?z AND user_id = ?z AND created_at >= ?z AND created_at <= ?z	T23:59:59z AND school_id = ?)Úappend)r   r   r   Ú	date_fromÚdate_tor   ÚqÚparamss           r   Ú_wherer0   X   s©   € Ø€AØ€FÞØ	Ð!Ñ!ˆ§=¡=°F°8¸1°Ô#>ÞØ	Ð Ñ ˆ§-¡-°Ô"9ÞØ	ÐÑˆ§¡¨wÔ!7ÞØ	Ð#Ñ#ˆ§]¡]°9Ô%=ÞØ	Ð#Ñ#ˆ§]¡]°7¸[Ñ3HÔ%IÞØ	Ð!Ñ!ˆ§=¡=°Ô#;Øˆ9Ðr(   éÈ   )r   r   r   r,   r-   r   ÚlimitÚoffsetr,   r-   r2   r3   c                 ó   • [        XX#XE5      u  p‰SU-   S-   n
[        5        nUR                  X©Xg/-   5      R                  5       nS S S 5        W Vs/ s H  n[	        U5      PM     sn$ ! , (       d  f       N*= fs  snf )NzSELECT * FROM audit_logsz3 ORDER BY created_at DESC, id DESC LIMIT ? OFFSET ?)r0   r   r	   Úfetchallr'   )r   r   r   r,   r-   r   r2   r3   Úwherer/   r.   r   Úrowsr%   s                 r   Úlist_eventsr8   j   sq   € ô ˜6¨WÀÓT�M€EØ" UÑ*Ð-bÑb€AÜ	Œ�TØ�|‰|˜A¨¨Ñ7Ó8×AÑAÓCˆ÷ 
á%)Ó*¢T ŒL˜ŽO¡TÑ*Ð*÷ 
�üâ*s   ¢$A*ÁA;Á*
A8)r   r   r   r,   r-   r   c                 ó¶   • [        XX#XE5      u  pg[        5        nUR                  SU-   U5      R                  5       S   sS S S 5        $ ! , (       d  f       g = f)Nz$SELECT COUNT(*) AS n FROM audit_logsÚn)r0   r   r	   Úfetchone)	r   r   r   r,   r-   r   r6   r/   r   s	            r   Úcount_eventsr<   |   sH   € ô ˜6¨WÀÓT�M€EÜ	Œ�TØ�|‰|ÐBÀUÑJÈFÓS×\Ñ\Ó^Ð_bÑc÷ 
��ús   š&A
Á

A)r   N)Ú__doc__r   ÚloggingÚtypingr   Úcore.dbr   r   Úcore.timeutilr   Ú	getLoggerr   r   Ústrr"   r   r'   ÚtupleÚlistr0   Úintr8   r<   © r(   r   Ú<module>rH      sù  ðñó" Û Ý ç )Ý $à×ÒÐ(Ó)€ô'ð6 "Ø $Ø#'Ø!%Ø"ØØ#ò@Øð@ð �c‰]ð@ð ˜‘ð	@ð
 ˜C‘=ð@ð ˜#‘ð@ð �d‰^ð@ð ð@ð ˜‰}ð@ð 
õ@ð:�tô ðÈÈcÐSWÈiÑHXô ð( !Ø"Ø!Ø#Ø!Ø#ØØò+à�S‰Mð+ð �s‰mð+ð �c‰]ð	+ð
 ˜‰}ð+ð �c‰]ð+ð ˜‰}ð+ð ð+ð ð+ð 
ˆ$�Zõ+ð( !Ø"Ø!Ø#Ø!Ø#òdà�S‰Mðdð �s‰mðdð �c‰]ð	dð
 ˜‰}ðdð �c‰]ðdð ˜‰}ðdð 	ödr(   