Ë
    Ì
âi™1  ã                   ó,  — d Z ddlZddlZddlmZ ddlmZmZmZ ddl	m
Z
 e
 G d„ d«      «       Z G d„ d	«      Zed
k(  rV ee«      j                  j                  j                  Z e ee«      «      Zej'                  «       Zej+                  e«       yy)zT
Migration Checker - Validates Alembic migration consistency with SQLAlchemy models
é    N)ÚPath)ÚDictÚListÚOptional)Ú	dataclassc                   ó:   — e Zd ZU dZeed<   eed<   eed<   eed<   y)ÚMigrationInfoz(Represents information about a migrationÚfilenameÚrevisionÚdescriptionÚ	timestampN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__ÚstrÚ__annotations__© ó    ú</home/factor_ks/STREAMA2026/tests/utils/migration_checker.pyr	   r	      s   … á2ØƒMØƒMØÓØ„Nr   r	   c                   ó‚   — e Zd ZdZdefd„Zdee   fd„Zdee   fd„Z	de
e   fd„Zdefd„Zdefd	„Zdefd
„Zdefd„Zy)ÚMigrationCheckerzBChecks migration consistency between models and Alembic migrationsÚproject_dirc                 óŒ   — t        |«      | _        | j                  dz  dz  dz  | _        | j                  dz  dz  dz  | _        y )NÚbackendÚalembicÚversionsÚappÚmodels)r   r   Úversions_dirÚ
models_dir)Úselfr   s     r   Ú__init__zMigrationChecker.__init__   sH   € Ü Ó,ˆÔØ ×,Ñ,¨yÑ8¸9ÑDÀzÑQˆÔØ×*Ñ*¨YÑ6¸Ñ>ÀÑIˆ�r   Úreturnc                 ó:  — 	 t        j                  g d¢ddd¬«      }|j                  dk(  rL|j                  j	                  «       j                  d«      }t        |«      dk\  r|d   j	                  «       }|S y	# t        $ r}t        d
|› �«       Y d	}~y	d	}~ww xY w)z3Get the current migration version from the database)ÚdockerÚcomposeÚexecz-TÚpostgresÚpsqlz-UÚstreamaz-dÚstreama2026z-cz(SELECT version_num FROM alembic_version;Té
   )Úcapture_outputÚtextÚtimeoutr   ú
é   é   Nz)Error getting current migration version: )	Ú
subprocessÚrunÚ
returncodeÚstdoutÚstripÚsplitÚlenÚ	ExceptionÚprint)r"   ÚresultÚlinesÚversionÚes        r   Úget_current_migration_versionz.MigrationChecker.get_current_migration_version   s™   € ð	ä—^‘^òCð  $ØØôˆFð × Ñ  AÒ%àŸ™×+Ñ+Ó-×3Ñ3°DÓ9�Ü�u“: ’?Ø# A™hŸn™nÓ.�GØ"�NàøÜò 	ÜÐ=¸a¸SÐAÔBÜûð	ús   ‚A5A9 Á9	BÂBÂBc                 óœ  — | j                   j                  «       sy	 t        | j                   j                  d«      d¬«      }|D �]"  }|j                  j                  d«      rŒ d}d}d}	 t        |dd¬«      5 }|j                  «       }t        j                  d	|«      }|r|j                  d
«      }t        j                  d|t        j                  «      }	|	r1|	j                  d
«      j                  «       j                  d«      d   }t        j                  d|j                  «      }
|
r|
j                  d
«      }ddd«       |s�Œ|s�Œ
t#        |j                  |||¬«      c S  y# 1 sw Y   Œ.xY w# t        $ r&}t!        d|j                  › d|› �«       Y d}~�Œ]d}~ww xY w# t        $ r}t!        d|› �«       Y d}~yd}~ww xY w)z)Get the latest migration file informationNú*.pyT)ÚreverseÚ__Úrúutf-8©Úencodingúrevision\s*=\s*['\"](\w+)['\"]é   ú"""(.+?)"""r1   r   ú(\d+)(?:_\d+)?_úError reading migration file ú: ©r
   r   r   r   z%Error getting latest migration file: )r    ÚexistsÚsortedÚglobÚnameÚ
startswithÚopenÚreadÚreÚsearchÚgroupÚDOTALLr8   r9   Úmatchr;   r<   r	   )r"   Úmigration_filesÚmigration_filer   r   r   ÚfÚcontentÚrevision_matchÚ
desc_matchÚtimestamp_matchr@   s               r   Úget_latest_migration_filez*MigrationChecker.get_latest_migration_file5   sÁ  € à× Ñ ×'Ñ'Ô)Øð-	Ü$ T×%6Ñ%6×%;Ñ%;¸FÓ%CÈTÔRˆOà"1ó %�à!×&Ñ&×1Ñ1°$Ô7Øð  �Ø"�Ø �	ðÜ˜n¨c¸GÔDð AÈØ"#§&¡&£(˜ä)+¯©Ð3TÐV]Ó)^˜Ù)Ø'5×';Ñ';¸AÓ'>˜Hô &(§Y¡Y¨~¸wÌÏ	É	Ó%R˜
Ù%Ø*4×*:Ñ*:¸1Ó*=×*CÑ*CÓ*E×*KÑ*KÈDÓ*QÐRSÑ*T˜Kô +-¯(©(Ð3EÀ~×GZÑGZÓ*[˜Ù*Ø(7×(=Ñ(=¸aÓ(@˜I÷Aó( £Ü(Ø!/×!4Ñ!4Ø!)Ø$/Ø"+ô	ò ðA%ðN ÷9Að Aûô  !ò ÜÐ9¸.×:MÑ:MÐ9NÈbÐQRÐPSÐTÔUÝûðûô ò 	ÜÐ9¸!¸Ð=Ô>Üûð	úsm   �AF* Á,E8Á:CE,Ä?E8ÅF* ÅF* ÅF* Å*F* Å,E5	Å1E8Å8	F'ÆF"ÆF* Æ"F'Æ'F* Æ*	GÆ3GÇGc           	      óÂ  — | j                   j                  «       sg S g }	 t        | j                   j                  d«      «      }|D �]1  }|j                  j                  d«      rŒ d}d}d}	 t        |dd¬«      5 }|j                  «       }t        j                  d|«      }	|	r|	j                  d«      }t        j                  d	|t        j                  «      }
|
r1|
j                  d«      j                  «       j                  d
«      d   }t        j                  d|j                  «      }|r|j                  d«      }ddd«       |s�Œ|s�Œ
|j#                  t%        |j                  |||¬«      «       �Œ4 |S # 1 sw Y   Œ>xY w# t        $ r&}t!        d|j                  › d|› �«       Y d}~�Œmd}~ww xY w# t        $ r}t!        d|› �«       g cY d}~S d}~ww xY w)z+Get all migration files sorted by timestamprC   rE   NrF   rG   rH   rJ   rK   rL   r1   r   rM   rN   rO   rP   zError getting all migrations: )r    rQ   rR   rS   rT   rU   rV   rW   rX   rY   rZ   r[   r8   r9   r\   r;   r<   Úappendr	   )r"   Ú
migrationsr]   r^   r   r   r   r_   r`   ra   rb   rc   r@   s                r   Úget_all_migrationsz#MigrationChecker.get_all_migrationsi   sÒ  € à× Ñ ×'Ñ'Ô)ØˆIàˆ
ð,	Ü$ T×%6Ñ%6×%;Ñ%;¸FÓ%CÓDˆOà"1ó $�Ø!×&Ñ&×1Ñ1°$Ô7Øð  �Ø"�Ø �	ðÜ˜n¨c¸GÔDð AÈØ"#§&¡&£(˜ä)+¯©Ð3TÐV]Ó)^˜Ù)Ø'5×';Ñ';¸AÓ'>˜Hô &(§Y¡Y¨~¸wÌÏ	É	Ó%R˜
Ù%Ø*4×*:Ñ*:¸1Ó*=×*CÑ*CÓ*E×*KÑ*KÈDÓ*QÐRSÑ*T˜Kô +-¯(©(Ð3EÀ~×GZÑGZÓ*[˜Ù*Ø(7×(=Ñ(=¸aÓ(@˜I÷Aó( £Ø×%Ñ%¤mØ!/×!4Ñ!4Ø!)Ø$/Ø"+ô	'ö ð?$ðL Ð÷9Að Aûô  !ò ÜÐ9¸.×:MÑ:MÐ9NÈbÐQRÐPSÐTÔUÝûðûô ò 	ÜÐ2°1°#Ð6Ô7Ø�Iûð	úsm    AF; Á-F	Á;CE=Å F	ÅF; ÅF; Å,F; Å=F	ÆF	Æ		F8ÆF3Æ-F; Æ3F8Æ8F; Æ;	GÇGÇGÇGc                 ó  — | j                  «       }|sdddœS 	 | j                  |j                  z  }|j                  «       j                  }g }| j
                  j                  d«      D ]M  }|j                  dk(  rŒ|j                  «       j                  }||kD  sŒ3|j                  |j                  «       ŒO |rdd||j                  dœS dd	|j                  d
œS # t        $ r }t        d|› �«       dd|› �dœcY d}~S d}~ww xY w)z5Detect if there are model changes that need migrationFzNo migrations found)Úneeds_migrationÚreasonrC   z__init__.pyTz+Model files modified after latest migration)rj   rk   Úmodified_modelsÚlatest_migrationz*Models not modified since latest migration)rj   rk   rm   zError detecting model changes: zError checking model changes: N)rd   r    r
   ÚstatÚst_mtimer!   rS   rT   rf   r;   r<   )r"   rm   Úmigration_pathÚmigration_mtimeÚmodels_modifiedÚ
model_fileÚmodel_mtimer@   s           r   Údetect_model_changesz%MigrationChecker.detect_model_changes�   s)  € ð  ×9Ñ9Ó;ÐÙà#(Ø/ñð ð
	Ø!×.Ñ.Ð1A×1JÑ1JÑJˆNØ,×1Ñ1Ó3×<Ñ<ˆOà ˆOØ"Ÿo™o×2Ñ2°6Ó:ò <�
Ø—?‘? mÒ3Øà(Ÿo™oÓ/×8Ñ8�Ø Ó0Ø#×*Ñ*¨:¯?©?Õ;ð<ñ à'+ØKØ'6Ø(8×(AÑ(Añ	ð ð (-ØJØ(8×(AÑ(Añð øô
 ò 	ÜÐ3°A°3Ð7Ô8à#(Ø:¸1¸#Ð>ñõ ûð	ús*   ™BC Â/C ÃC Ã	DÃ%D Ã:DÄ Dc                 óà  — | j                  «       }| j                  «       }| j                  «       }| j                  «       }||r|j                  nd|r|j
                  ndt        |«      dddd||D �cg c]&  }|j                  |j
                  |j                  dœ‘Œ( c}dœ
}|r"|r ||j
                  k(  rd|d<   nd|d<   d|d<   n|s
d|d<   d|d	<   |j                  d«      rd|d<   |S c c}w )
z6Check migration consistency between database and filesNF)r
   r   r   )
Úcurrent_versionrm   Úlatest_revisionÚtotal_migrationsÚis_up_to_daterj   Úneeds_upgradeÚdrift_detectedÚmodel_changesÚmigrations_listTrz   r{   rj   r|   )	rA   rd   rh   ru   r
   r   r:   r   Úget)r"   rw   rm   Úall_migrationsr}   ÚmÚconsistency_reports          r   Úcheck_migration_consistencyz,MigrationChecker.check_migration_consistencyÍ   s*  € à×<Ñ<Ó>ˆØ×9Ñ9Ó;ÐØ×0Ñ0Ó2ˆØ×1Ñ1Ó3ˆð  /Ù=MÐ 0× 9Ò 9ÐSWÙ<LÐ/×8Ò8ÐRVÜ # NÓ 3Ø"Ø$Ø"Ø#Ø*ð (ö ð ð	 !"§
¡
Ø !§
¡
Ø#$§=¡=óò ñ
Ðñ* Ñ/ØÐ"2×";Ñ";Ò;Ø6:Ð" ?Ò3à6:Ð" ?Ñ3Ø8<Ð"Ð#4Ò5Ù Ø48ÐÐ0Ñ1Ø37ÐÐ/Ñ0ð ×ÑÐ.Ô/Ø48ÐÐ0Ñ1à!Ð!ùò3 s   Á3+C+c                 óZ   — | j                  «       }|d   ry|d   ry|d   d   ry|d   ry	y
)z/Generate a recommendation for migration actionsr|   zPWARNING: Database migration drift detected. Manual intervention may be required.r{   z5Run: docker compose exec backend alembic upgrade headr}   rj   zQRun: docker compose exec backend alembic revision --autogenerate -m "description"rz   zMigrations are up to date.z%Unable to determine migration status.)rƒ   )r"   Úconsistencys     r   Ú!generate_migration_recommendationz2MigrationChecker.generate_migration_recommendationù   sF   € à×6Ñ6Ó8ˆàÐ'Ò(ØeØ˜Ò)ØKØ˜Ñ)Ð*;Ò<ØiØ˜Ò)Ø/à:r   r‚   c                 óÒ  — t        d«       t        d«       t        d«       t        d|d   xs d› �«       t        d|d   xs d› �«       t        d|d	   xs d› �«       t        d
|d   › �«       |d   rt        d«       nt        d«       |d   rt        d«       |d   rt        d«       t        d«       |d   }|d   r6t        d|d   › �«       d|v r2t        ddj                  |d   «      › �«       nt        d|d   › �«       t        d«       t        d| j                  «       › �«       t        d«       |d   D ]  }t        d|d    › d!|d"   › �«       Œ t        d«       y#)$z6Print a human-readable report of migration consistencyz<============================================================zMigration Consistency Reportz
Current Version: rw   z	Not foundzLatest Migration: rm   zLatest Revision: rx   zTotal Migrations: ry   rz   u1   
âœ“ Database is up to date with latest migrationu   
âœ— Database is not up to dater{   u#     â†’ Database needs to be upgradedr|   uB     âš  Migration drift detected - manual intervention may be neededz
Model Changes:r}   rj   z
  Reason: rk   rl   z  Modified models: z, z  z
Recommendation:z
Migrations:r~   z  - r
   rO   r   N)r<   Újoinr†   )r"   r‚   r}   Úmigs       r   Úprint_reportzMigrationChecker.print_report  s�  € äˆhŒÜÐ,Ô-ÜˆhŒäÐ#Ð$6Ð7HÑ$IÒ$XÈ[Ð#YÐZÔ[ÜÐ"Ð#5Ð6HÑ#IÒ#XÈ[Ð"YÐZÔ[ÜÐ!Ð"4Ð5FÑ"GÒ"VÈ;Ð!WÐXÔYÜÐ"Ð#5Ð6HÑ#IÐ"JÐKÔLà˜oÒ.ÜÐFÕGäÐ4Ô5à˜oÒ.ÜÐ7Ô8àÐ.Ò/ÜÐVÔWäÐ Ô!Ø*¨?Ñ;ˆØÐ*Ò+Ü�J˜}¨XÑ6Ð7Ð8Ô9Ø  MÑ1ÜÐ+¨D¯I©I°mÐDUÑ6VÓ,WÐ+XÐYÕZä�B�} XÑ.Ð/Ð0Ô1äÐ!Ô"Ü��4×9Ñ9Ó;Ð<Ð=Ô>äˆoÔØ%Ð&7Ñ8ò 	BˆCÜ�D˜˜Z™Ð)¨¨C°Ñ,>Ð+?Ð@ÕAð	Bô 	ˆh�r   N)r   r   r   r   r   r#   r   rA   r	   rd   r   rh   r   ru   rƒ   r†   rŠ   r   r   r   r   r      sy   „ ÙLðJ Có Jð
¨x¸©}ó ð22¨8°MÑ+Bó 2ðh2 D¨Ñ$7ó 2ðh. dó .ð`*"¨Tó *"ðX;°3ó ;ð&¨tô &r   r   Ú__main__)r   rX   r4   Úpathlibr   Útypingr   r   r   Údataclassesr   r	   r   r   Ú__file__Úparentr   r   Úcheckerrƒ   r‚   rŠ   r   r   r   ú<module>r’      s›   ðñó 
Û Ý ß 'Ñ 'Ý !ð ÷ð ó ð÷Zñ Zðz ˆzÒá�x“.×'Ñ'×.Ñ.×5Ñ5€KÙ™s ;Ó/Ó0€Gà ×<Ñ<Ó>ÐØ×ÑÐ+Õ,ð r   