Ë
    LµCjø  ã                   óÜ   — d Z ddlZddlmZ ddlmZmZmZmZmZm	Z	m
Z
 ddlmZmZmZmZ  G d„ de«      Z G d„ d	e«      Z G d
„ de«      Z G d„ de«      Z G d„ de«      Z G d„ de«      Zy)u3  
SQLAlchemy ORM models.

Why a database at all, given Redis already caches results: Redis is
ephemeral (TTL-based) and not queryable in any structured way. The
client will want to know things like "how many requests for rice in
Thanjavur did we get last month" or "show me every analysis that hit a
conflict flag" â€” that needs a real relational store with indexes, not
a key-value cache.

AnalysisRecord is the permanent audit trail: every completed analysis,
regardless of whether it was served from cache or freshly computed.

User / CropPlan / Notification support the customer-facing SaaS layer
(see app/api/v1/endpoints/auth.py and docs/architecture.md) â€” these are
separate from the original API-key-based service auth, which remains in
place for any machine-to-machine integrations the client may also want.
é    N)Údatetime)ÚJSONÚBooleanÚDateTimeÚ
ForeignKeyÚIntegerÚStringÚText)ÚDeclarativeBaseÚMappedÚmapped_columnÚrelationshipc                   ó   — e Zd Zy)ÚBaseN)Ú__name__Ú
__module__Ú__qualname__© ó    ú:C:\Crop_Prediction\Backend\crop-ai-system\app\db\models.pyr   r      s   „ Ør   r   c                   óü  — e Zd ZU dZdZ e ed«      dd„ ¬«      Zee	   e
d<    e ed«      dd¬	«      Zee	   e
d
<    e ed«      «      Zee	   e
d<    e ed«      d¬«      Zee	   e
d<    e ed«      d¬«      Zee	   e
d<    eed¬«      Zee   e
d<    eed¬«      Zee   e
d<    eeej*                  ¬«      Zee   e
d<    eed¬«      Zee   e
d<    ed¬«      Zeed      e
d<    ed¬«      Zeed      e
d<   y)ÚUseruû   
    Customer account for the SaaS web application. Distinct from the
    API-key auth used elsewhere in this system â€” API keys identify a
    calling SERVICE/integration, a User identifies an individual
    customer logging into the dashboard.
    Úusersé$   Tc                  ó<   — t        t        j                  «       «      S ©N©ÚstrÚuuidÚuuid4r   r   r   ú<lambda>zUser.<lambda>(   ó   € ÔRUÔVZ×V`ÑV`ÓVbÓRc€ r   ©Úprimary_keyÚdefaultÚidéÿ   )ÚuniqueÚindexÚemailÚhashed_password©ÚnullableÚ	full_nameÚorganization©r%   Ú	is_activeFÚis_verifiedÚ
created_atÚlast_login_atÚuser©Úback_populatesÚCropPlanÚ
crop_plansÚNotificationÚnotificationsN)r   r   r   Ú__doc__Ú__tablename__r   r	   r&   r   r   Ú__annotations__r*   r+   r.   r/   r   r1   Úboolr2   r   r   Úutcnowr3   r4   r   r9   Úlistr;   r   r   r   r   r      s  … ñð €Má#¡F¨2£J¸DÑJcÔd€Bˆˆs‰ÓdÙ&¡v¨c£{¸4ÀtÔL€Eˆ6�#‰;ÓLÙ#0±¸³Ó#=€O�V˜C‘[Ó=Ù*©6°#«;ÀÔF€Iˆv�c‰{ÓFÙ -©f°S«kÀDÔ I€L�&˜‘+ÓIá+¨G¸TÔB€Iˆv�d‰|ÓBÙ -¨g¸uÔ E€K�˜‘ÓEá#0°À8Ç?Á?Ô#S€J��xÑ ÓSÙ&3°HÀtÔ&L€M�6˜(Ñ#ÓLá+7ÀvÔ+N€J��t˜JÑ'Ñ(ÓNÙ2>ÈfÔ2U€M�6˜$˜~Ñ.Ñ/ÔUr   r   c                   ó(  — e Zd ZU dZdZ e ed«      dd„ ¬«      Zee	   e
d<    e ed«       ed«      d¬	«      Zee	   e
d
<    e ed«      «      Zee	   e
d<    e ed«      «      Zee	   e
d<    e ed«      «      Zee	   e
d<    ee«      Zee   e
d<    e ed«      d¬«      Zee	   e
d<    eed¬«      Zee   e
d<    eeej2                  ¬«      Zee   e
d<    eeej2                  ej2                  ¬«      Zee   e
d<    ed¬«      Zed   e
d<   y)r8   uL  
    A saved crop planning scenario a customer created via the dashboard
    (module 1.1.3 / 1.1.8 in the SaaS spec). Each plan can have multiple
    linked AnalysisRecord rows over time â€” e.g. the customer re-runs the
    analysis after climate data updates, or compares scenarios with
    different risk tolerance settings.
    r9   r   Tc                  ó<   — t        t        j                  «       «      S r   r   r   r   r   r!   zCropPlan.<lambda>B   r"   r   r#   r&   úusers.id©r)   Úuser_idr'   Únameé2   Úcropéd   ÚlocationÚplanting_monthé   Úmoderater0   Úrisk_toleranceFÚis_archivedr3   )r%   ÚonupdateÚ
updated_atr6   r   r5   N)r   r   r   r<   r=   r   r	   r&   r   r   r>   r   rF   rG   rI   rK   r   rL   ÚintrO   r   rP   r?   r   r   r@   r3   rR   r   r5   r   r   r   r8   r8   8   s!  … ñð !€Má#¡F¨2£J¸DÑJcÔd€Bˆˆs‰ÓdÙ(©°«±ZÀ
Ó5KÐSWÔX€GˆV�C‰[ÓXá%¡f¨S£kÓ2€Dˆ&�‰+Ó2Ù%¡f¨R£jÓ1€Dˆ&�‰+Ó1Ù)©&°«+Ó6€Hˆf�S‰kÓ6Ù"/°Ó"8€N�F˜3‘KÓ8Ù"/±°r³
ÀJÔ"O€N�F˜3‘KÓOá -¨g¸uÔ E€K�˜‘ÓEá#0°À8Ç?Á?Ô#S€J��xÑ ÓSÙ#0°À8Ç?Á?Ð]e×]lÑ]lÔ#m€J��xÑ Ómá'°|ÔD€Dˆ&�‰.ÔDr   r8   c                   óæ  — e Zd ZU dZdZ e ed«      dd„ ¬«      Zee	   e
d<    e ed«       ed«      d¬	«      Zee	   e
d
<    e ed«      «      Zee	   e
d<    ee«      Zee	   e
d<    e ed«      d¬«      Zee	   e
d<    e ed«       ed«      d¬«      Zee	   e
d<    eed¬«      Zee   e
d<    eed¬«      Zee   e
d<    eeej0                  d¬«      Zee   e
d<    ed¬«      Zed   e
d<   y)r:   uR  
    In-app / email alert record (module 1.1.11). Generated either by a
    completed analysis (e.g. "your rice plan is now classified as
    risky") or by a scheduled job (e.g. seasonal reminders) â€” the
    generation logic lives in app/services/, this table is just storage
    plus read/unread state for the dashboard bell icon.
    r;   r   Tc                  ó<   — t        t        j                  «       «      S r   r   r   r   r   r!   zNotification.<lambda>]   r"   r   r#   r&   rD   rE   rF   r'   ÚtitleÚmessagerM   Úinfor0   Úseverityúcrop_plans.idr,   Úrelated_crop_plan_idFÚis_readÚ
email_sent©r%   r)   r3   r6   r   r5   N)r   r   r   r<   r=   r   r	   r&   r   r   r>   r   rF   rV   r
   rW   rY   r[   r   r\   r?   r]   r   r   r@   r3   r   r5   r   r   r   r:   r:   S   s
  … ñð $€Má#¡F¨2£J¸DÑJcÔd€Bˆˆs‰ÓdÙ(©°«±ZÀ
Ó5KÐSWÔX€GˆV�C‰[ÓXá&¡v¨c£{Ó3€Eˆ6�#‰;Ó3Ù(¨Ó.€GˆV�C‰[Ó.Ù)©&°«*¸fÔE€Hˆf�S‰kÓEÙ(5±f¸R³jÁ*È_ÓB]ÐhlÔ(mÐ˜& ™+Ómá)¨'¸5ÔA€GˆV�D‰\ÓAÙ,¨W¸eÔD€J��t‘ÓDá#0°À8Ç?Á?ÐZ^Ô#_€J��xÑ Ó_á'°ÔG€Dˆ&�‰.ÔGr   r:   c                   ó:  — e Zd ZU dZ e ed«      dd„ ¬«      Zee   e	d<    e ed«      d¬«      Z
ee   e	d	<    e ed«       ed
«      dd¬«      Zee   e	d<    e ed«       ed«      dd¬«      Zee   e	d<    e ed«      d¬«      Zee   e	d<    e ed«      d¬«      Zee   e	d<    ee«      Zee   e	d<    e ed«      d¬«      Zee   e	d<    ed¬«      Zee   e	d<    eed¬«      Zee   e	d<    eed¬«      Zee   e	d<    ee«      Zee   e	d<    e ed«      «      Zee   e	d<    eed¬«      Zee   e	d<    ee«      Z ee   e	d<    e ed«      d¬«      Z!ee   e	d <    e ed«      d¬«      Z"ee   e	d!<    ee#e$jJ                  d¬"«      Z&ee$   e	d#<   y$)%ÚAnalysisRecordÚanalysis_recordsr   Tc                  ó<   — t        t        j                  «       «      S r   r   r   r   r   r!   zAnalysisRecord.<lambda>p   r"   r   r#   r&   é@   rE   Ú
request_idrD   )r-   r)   rF   rZ   Úcrop_plan_idrH   rI   rJ   ÚdistrictÚmonthrM   r,   Úfeasibility_labelÚexpected_yield_ton_haFr0   Úhad_conflictsÚdegraded_modelsÚfull_resultÚmodel_versionÚserved_from_cacheÚprocessing_msÚapi_key_prefixÚ	client_ipr^   r3   N)'r   r   r   r=   r   r	   r&   r   r   r>   rd   r   rF   re   rI   rf   r   rg   rS   rh   ri   Úfloatr   rj   r?   r
   rk   r   rl   Údictrm   rn   ro   rp   rq   r   r   r@   r3   r   r   r   r`   r`   m   sÅ  … Ø&€Má#¡F¨2£J¸DÑJcÔd€Bˆˆs‰ÓdÙ+©F°2«J¸dÔC€J��s‘ÓCñ
 )©°«±ZÀ
Ó5KÐVZÐbfÔg€GˆV�C‰[ÓgÙ -©f°R«j¹*À_Ó:UÐ`dÐlpÔ q€L�&˜‘+Óqá%¡f¨R£j¸Ô=€Dˆ&�‰+Ó=Ù)©&°«+¸TÔB€Hˆf�S‰kÓBÙ& wÓ/€Eˆ6�#‰;Ó/á%2±6¸"³:ÈÔ%MÐ�v˜c‘{ÓMÙ+8À$Ô+GÐ˜6 %™=ÓGÙ"/°ÀÔ"G€M�6˜$‘<ÓGÙ#0°ÀÔ#E€O�V˜C‘[ÓEá -¨dÓ 3€K�˜‘Ó3Ù!.©v°b«zÓ!:€M�6˜#‘;Ó:á&3°GÀUÔ&KÐ�v˜d‘|ÓKÙ!.¨wÓ!7€M�6˜#‘;Ó7á"/±°r³
ÀTÔ"J€N�F˜3‘KÓJÙ*©6°"«:ÀÔE€Iˆv�c‰{ÓEá#0°À8Ç?Á?ÐZ^Ô#_€J��xÑ Ô_r   r`   c                   ó(  — e Zd ZU dZdZ e ed«      dd„ ¬«      Zee	   e
d<    e ed«      d¬	«      Zee	   e
d
<    e ed«      d¬	«      Zee	   e
d<    ee«      Zee	   e
d<    eed¬«      Zee   e
d<    eeej(                  d¬«      Zee   e
d<   y)ÚFailedRequestLoguÖ   
    Separate table for failed requests â€” deliberately kept apart from
    AnalysisRecord so a flood of failures (e.g. during an LLM outage)
    doesn't pollute the table used for legitimate usage analytics.
    Úfailed_request_logsr   Tc                  ó<   — t        t        j                  «       «      S r   r   r   r   r   r!   zFailedRequestLog.<lambda>–   r"   r   r#   r&   rc   rE   rd   rH   Ú
error_codeÚerror_messager,   Úinput_payloadr^   r3   N)r   r   r   r<   r=   r   r	   r&   r   r   r>   rd   rx   r
   ry   r   rz   rs   r   r   r@   r3   r   r   r   ru   ru   Ž   s¡   … ñð
 *€Má#¡F¨2£J¸DÑJcÔd€Bˆˆs‰ÓdÙ+©F°2«J¸dÔC€J��s‘ÓCÙ+©F°2«J¸dÔC€J��s‘ÓCÙ!.¨tÓ!4€M�6˜#‘;Ó4Ù"/°¸tÔ"D€M�6˜$‘<ÓDÙ#0°À8Ç?Á?ÐZ^Ô#_€J��xÑ Ô_r   ru   )r<   r   r   Ú
sqlalchemyr   r   r   r   r   r	   r
   Úsqlalchemy.ormr   r   r   r   r   r   r8   r:   r`   ru   r   r   r   ú<module>r}      st   ðñó& Ý ç Q× QÑ Qß OÓ Oô	ˆ?ô 	ôVˆ4ô Vô2Eˆtô Eô6H�4ô Hô4`�Tô `ôB`�tõ `r   