
    -ǚju                        d Z ddlmZmZmZmZmZmZmZm	Z	m
Z
 ddlmZ ddlmZ ddlmZ ddl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 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 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$ G d+ d,e      Z% G d- d.e      Z&y/)0uN   프로젝트 범위 모델 — PostgreSQL 단일 데이터베이스에 저장.    )	BooleanCheckConstraintColumn
ForeignKeyIndexIntegerStringTextUniqueConstraint)deferred)
expression)Base)ImagePathTypec                   2   e Zd ZdZ eed      Z ee ed      d      Z ee	d      Z
 eed      Z eed      Z eed      Z e ee            Z eed      Z ee	      Z eed	      Z ee      Z ee      Z eed      Z eed      Zy
)EpisodeepisodeTprimary_keyproject_registry.idFnullablekodefaultuploadedN)__name__
__module____qualname____tablename__r   r
   idr   
project_idr   episode_numbertitlesource_filenamesource_pathr   fulltextlanguage
page_countstatusanalysis_errorsummary
created_at
updated_at     H/Users/manta/Documents/Projects/TheRoad-I1/backend/app/models/project.pyr   r   
   s    M	$	'Bj)>?%PJGe4N4%(ETE2O.Kt%HdD)HJ
 D*-FD\NTlGu-Ju-Jr/   r   c                      e Zd ZdZ eed      Z ee ed      d      Z ee      Z	 eed      Z
 eed      Z ee      Z eed      Z eeddd	      Z ee      Z eed
      Z eed      Z eed      Zy)EntityCanonentity_canonTr   r   Fr   {}r   r   server_defaultr   activeN)r   r   r   r   r   r
   r    r   r!   short_identity_typenamedescriptionstable_traitsmetadata_json
t2i_promptr)   r,   r-   r.   r/   r0   r2   r2   !   s    "M	$	'Bj)>?%PJd|H.K$'D,K4.M 4%dSMJD(+Fu-Ju-Jr/   r2   c                      e Zd ZdZdZ eed      Z ee ed      d      Z	 eed      Z
 eed      Z eed      Z eed      Z eed      Z eeddd	      Z eeddd	      Z eed      Z eed      Z eed      Z eed      Z eeddd	      Z eed      Z eedd
d
	      Z eedd
d
	      Z eeddd	      Z eed      Z eed      Z edddddd      fZy)GroundingResearchRevisionu  GROUNDING-V2 §4a — 조사 기록의 **정본**. ★append-only.

    ★**왜 별도 테이블인가.** 계약이 「조사는 별도 durable record」라고 못박았다 —
    canon 평문 칸이나 `review_notes` 에 쓰면 뒤 단계가 그 칸을 덮어 **감사가
    사라진다.** 실제로 그 판이 한 번 있었다.

    ★**신원이 셋이다** (Codex). 하나로 뭉치면 같은 입력의 두 결과를 못 남긴다:

    | 칸 | 무엇의 신원인가 |
    |---|---|
    | `research_input_hash` | **무엇을 조사했는가** — subject+시대+지역+팩+정책 |
    | `revision_content_hash` | **무엇이 나왔는가** — claims/gaps/delta |
    | `attempt_id` | **몇 번째 시도인가** — 같은 입력·같은 결과라도 다른 행 |

    같은 입력인데 결과가 다를 수 있다(`delta=yes` vs `no`). 그건 **다른 시도**이지
    다른 조사가 아니다 — 유일성을 입력에만 걸면 두 번째가 안 들어간다.

    ★체크포인트는 **projection** 이다 — id 와 hash 를 참조만 하고 payload 를
    복사하지 않는다. 복사하면 둘이 갈리고 정본이 사라진다.
    grounding_research_revisionTr   r   Fr    r5   []r4   r!   
episode_idresearch_subject_idresearch_input_hash
attempt_id&uq_grounding_research_revision_attemptr:   N)r   r   r   __doc__r   r   r
   r    r   r!   rD   rE   rF   revision_content_hashrG   eraregionclaims_pack_versionpolicy_versionresearch_input_jsondeltadelta_reasonr)   claims_json	gaps_json
audit_jsonprovenance_jsonr,   r   __table_args__r.   r/   r0   r@   r@   4   sL   * 2M	$	'Bj)>?%PJu-J 6 !6"4%8u-J
b"
ECD5RHF 6D51N
 !64%(E$r2NL D5)FdDQKteD$OIuT4PJ TE2Ou-J
 	|5J.F	HNr/   r@   c                      e Zd ZdZdZ eed      Z ee ed      d      Z	 eed      Z
 eed      Z eeddd	      Z eeddd	      Z eed      Z eed      Z eeddd	      Z eeddd	      Z eed      Z eed      Z eed      Z eeddd	      Z eed      Z eed      Z eed      Z eedd
d
	      Z eed      Z eed      Z eed      Z edddd      fZy) GroundingReferenceFidelityReviewu  사람이 **그 사진이 그 시대·그 지역 것인지** 정한 기록. ★DB 가 정본.

    ★★★왜 별도 테이블인가 (Codex 계약 2026-09-02). coarse 심판은
    「무엇인가 · 보이는가」만 본다 — 시대·나라·정확성은 **안 묻는다**
    (사용자 확정 08-31). 그러니 `selected` 는 「그 종류의 사진을 골랐다」일
    뿐이고, **그 시대·그 지역 것이 맞는지는 사람만** 정한다.
    조사 revision 칸이나 획득 CP 칸을 재사용하지 않는다 — 뒤 단계가 덮으면
    감사가 사라진다.

    ★★**체크포인트는 projection 이다.** 사람이 CP 나 산출 JSON 을 직접
    고치는 길은 만들지 않는다. 결정은 인증된 backend 를 지나 이 표로만
    들어온다.

    ★★★**입력 신원이 정본이다.** 사진이 바뀌거나(SHA) 다른 판으로
    다시 샀거나(acquisition identity) 요구 좌표가 바뀌면, 옛 결정은
    **절대 따라가지 않는다** — 그때 본 것과 지금 것이 다르기 때문이다.

    append-only 다. 정정은 `UPDATE` 가 아니라 `supersedes_id` 를 든 **새 행**.
    #grounding_reference_fidelity_reviewTr   r   Fr   rB   r5   r4   r!   rD   idempotency_key!uq_grounding_fidelity_review_idemrI   N)r   r   r   rJ   r   r   r
   r    r   r!   rD   rE   final_idpurposeacquisition_identityimage_sha256rL   rM   review_input_jsonreview_input_hashverdictreasonreviewer_actorreviewed_atreview_contract_versionobserved_jsonsupersedes_idr[   r,   r   rW   r.   r/   r0   rY   rY   y   s[   ( :M	$	'Bj)>?!&(Ju-J !6dU2rJHTE"bIG!$7$/L
b"
ECD5RHF
 te4te4 TE*GD5RHF D51N.K$TE:4%#')M 4$/MTE2Ou-J 	|5FA	CNr/   rY   c                   0   e Zd ZdZdZ eed      Z ee ed      d      Z	 eed      Z
 eed      Z eed      Z eeddd	      Z eed      Z eed      Z eed      Z eed      Z eed      Z ed
ddd       edd
dd      fZy)GroundingReferenceSelectionuK  사람이 한 대상(research_subject)에 **쓸 사진 한 장**을 고른 기록. ★DB 가 정본 · append-only.

    ★★★왜 판정과 따로인가 (Codex BLOCK 2026-09-02 밤): 판정(`GroundingReferenceFidelityReview`)은
    후보 **한 장마다** 「그 시대·그 곳 것인가」다 — 둘 다 맞으면 둘 다 verified 가 옳다. 어느 장을
    **쓸지**는 다른 물음이라 같은 단추에 합치면 A 를 고른 뒤 B 로 바꾸는 정상 행동이 「두 장 동시
    승인」이 되어 대상 전체가 미확인으로 접힌다. 이 표는 대상당 살아 있는 줄 하나가 선택이고,
    새 선택은 앞 선택을 `supersedes_id` 로 대신한다(UPDATE 없음). 선택만으로는 안 붙는다 —
    그 사진의 판정이 verified 여야 `chosen` 으로 올라간다(`apply_reviews`).
    grounding_reference_selectionTr   r   Fr   rB   r5   r!   rD   r[   %uq_grounding_reference_selection_idemrI   &ix_grounding_reference_selection_scoperE   N)r   r   r   rJ   r   r   r
   r    r   r!   rD   rE   rb   r`   selected_byselected_atri   r[   r,   r   r   rW   r.   r/   r0   rk   rk      s     4M	$	'Bj)>?%PJu-J 6te4$r2NL.K.K4$/MTE2Ou-J 	|5FE	G6L*?	ANr/   rk   c                       e Zd ZdZ eed      Z ee ed      d      Z ee ed      d      Z	 ee ed      d      Z
 eed      Z eed      Zy)	CharacterOutlookcharacter_outlookTr   entity_canon.idFr   r   N)r   r   r   r   r   r
   r    r   character_id
outlook_idr!   rD   r,   r.   r/   r0   rr   rr      si    'M	$	'B$
+< =NLj):;eLJj)>?%PJ
 t,Ju-Jr/   rr   c                   n    e Zd ZdZ eed      Z ee ed      d      Z eed      Z	 e
dd      fZy	)
EntityAliasentity_aliasTr   rt   Fr   canon_idaliasN)r   r   r   r   r   r
   r    r   rz   r{   r   rW   r.   r/   r0   rx   rx      sB    "M	$	'BdJ'89EJH4%(E&z7;=Nr/   rx   c                       e Zd ZdZ eed      Z ee ed      d      Z eed      Z	 eed      Z
 eed      Z eed      Z eed      Z ee      Z eed      Zy)RelationFactrelation_factTr   r   Fr   N)r   r   r   r   r   r
   r    r   r!   relation_familyrelation_typedirectionalitytemporal_scopecontinuity_prioritycontinuity_reasonr,   r.   r/   r0   r}   r}      sz    #M	$	'Bj)>?%PJTE2O4%0MD51ND51N 6tu-Jr/   r}   c                       e Zd ZdZ eed      Z ee ed      d      Z ee ed      d      Z	 eed      Z
 eed	      Zy
)RelationParticipantrelation_participantTr   zrelation_fact.idFr   rt      r   N)r   r   r   r   r   r
   r    r   relation_idrz   participant_roler   participant_orderr.   r/   r0   r   r     sU    *M	$	'Bz*<=NKdJ'89EJHdU3w2r/   r   c                      e Zd ZdZ eed      Z ee ed      d      Z ee ed      d      Z	 ee
d      Z ee      Z ee      Z ee      Z eed	      Z eed	      Z eed
	      Z ee      Z ee      Z ee      Z ee      Z ee
      Z ee
      Z ee      Z ee      Z ee      Z ee      Z ee      Z ee      Z ee      Z ee      Z ee      Z  ee      Z! ee      Z" ee      Z# ee      Z$ ee
      Z% ee
      Z& ee      Z' ee
      Z( eed	      Z) ee      Z* eed
	      Z+ eed
	      Z, ee-d	      Z. ee-d	      Z/ eed	      Z0 eed      Z1y)
SceneStillscene_stillTr   r   Fr   
episode.idr4   r   rC   normalpendingN)2r   r   r   r   r   r
   r    r   r!   rD   r   still_indexscreenplay_scene_heading
beat_titlestill_frame_promptcamera_jsonlighting_jsonvisible_entities_jsont2i_prompt_cinematict2i_prompt_closeupt2i_variations_jsont2i_composer_versionsegment_start_charsegment_end_charvariation_a_typevariation_a_anglevariation_a_colorvariation_a_reasonvariation_b_typevariation_b_anglevariation_b_colorvariation_b_reasonrecommended_variantselected_variantdependent_scene_idshot_type_1shot_type_2scene_index
shot_indexshot_descriptionbased_on_beat
scene_typescene_summaryaudio_entity_idshallucination_entity_idsr   is_selectedimage_generatedr)   r,   r.   r/   r0   r   r     s   !M	$	'Bj)>?%PJj6GJ51K%d|Jt,K4.M"46!$< ,!$<gd|ttd|tt ,d|,K,K/KJd|7OMh/J4LMdD1%dD9$/KWe4OD),Fu-Jr/   r   c                       e Zd ZdZ eed      Z ee ed      d      Z ee ed      d      Z	 ee ed      d      Z
 eed	
      Z eed
      Z eeddd      Z eed      Z edd      fZy)EntityEpisodeLinkentity_episode_linkTr   r   Fr   rt   r   	extractedr   r   r7   r5   rz   rD   N)r   r   r   r   r   r
   r    r   r!   rz   rD   sourcer   t2i_appearance_countpresence_statusepisode_notes_jsonr   rW   r.   r/   r0   r   r   ?  s    )M	$	'Bj)>?%PJdJ'89EJHj6GJD+.F!'15
 TE,4hHO  t4&z<@BNr/   r   c                   b   e Zd ZdZ edd      fZ eed      Z ee e	d      d	      Z
 eed	      Z ee      Z ee      Z ee      Z e e       d	      Z ee      Z ee      Z ee      Z ee      Z eed
      Z eed      Z ee      Z ee      Z ee      Z ee      Z ee      Z ee      Z ee      Z ee      Z ee      Z  eed      Z! ee      Z" ee      Z# ee      Z$ eed      Z% ee e	d            Z& ee      Z' ee      Z( eeddd      Z) e e*d      ddd      Z+ ee      Z, ee      Z- ee      Z. ee      Z/ ee0dd e1jd                               Z3 ee      Z4 ee      Z5 ee      Z6 ee      Z7 ee      Z8 eed	      Z9y)
ImageAssetimage_assetz)file_path = '' OR file_path NOT LIKE '/%'!ck_image_asset_file_path_relativerI   Tr   r   Fr   	generatedr   rB   r   rC   zimage_asset.id0)r   r   r6      v00)r   r   r6   N):r   r   r   r   r   rW   r   r
   r    r   r!   
asset_type	entity_idstill_idrD   r   	file_pathprompt_usedgeneration_modelr   widthheightr)   review_notesvalidation_scorevalidation_resultsanitization_strategyoriginal_promptsanitization_notevariant_typeangle_appliedcolor_appliedsource_image_id
is_primaryprompt_typecode_versionprompt_file_versionreference_image_idsparent_image_idr   theme_labelvariant_indexr	   variant_label	t2i_guideinput_image_idsstagepipeline_roler   r   falseis_intermediategeneration_call_idcandidate_indexpipeline_metadata_jsondispositionattempt_indexr,   r.   r/   r0   r   r   U  s   !M 	74	

N 
$	'Bj)>?%PJu-JtId|HJ}7I,Kd|7OEG_FD+.F$+Lgt"4LTlOt$<L4LM4LMTlO+J,K$<L , !t4T:.>#?@OJ,K7UAcRM6#;V[\MtI TlO4LE4LMWeeTdT^TdTdTfgOWoO#D\,K7OMu-Jr/   r   c                       e Zd ZdZ eed      Z ee ed      dd      Z ee      Z	 ee      Z
 ee      Z ee      Z eed      Z eed	      Z eed
      Zy)ProjectSettingsproject_settingsTr   r   F)r   uniqueX  r   r4   r   N)r   r   r   r   r   r
   r    r   r!   composer_system_promptcomposer_user_promptstyle_rules_jsonworld_summaryr   scene_split_thresholdllm_config_jsonr-   r.   r/   r0   r   r     sv    &M	$	'Bj)>?%X\]J#D\!$<d|4LM"7C8T40Ou-Jr/   r   c                       e Zd ZdZ eed      Z ee ed      d      Z ee ed            Z	 eed      Z
 ee      Z eed      Zy)	
WorldGuideworld_guideTr   r   Fr   r   N)r   r   r   r   r   r
   r    r   r!   rD   
guide_jsonsource_hashr,   r.   r/   r0   r   r     sY    !M	$	'Bj)>?%PJj67Ju-J,Ku-Jr/   r   c                       e Zd ZdZ eed      Z ee ed      d      Z ee ed            Z	 eed      Z
 ee      Z eed      Zy)	WebbookPackagewebbook_packageTr   r   Fr   r   N)r   r   r   r   r   r
   r    r   r!   rD   package_jsonprompt_versionr,   r.   r/   r0   r   r     sY    %M	$	'Bj)>?%PJj67J$/LD\Nu-Jr/   r   c                   V   e Zd ZdZdZ eed      Z ee ed      d      Z	 eed      Z
 ee      Z eed      Z eed      Z ee      Z ee      Z ee      Z ee      Z ee      Z eed      Z ee      Z ee      Z eed	      Z eed	      Z eed      Zy
)OperationLoguO   모든 파이프라인 작업의 프로비저닝 기록 — Opik 호환 구조.operation_logTr   r   Fr   r4   r   N)r   r   r   rJ   r   r   r
   r    r   r!   operation_typerD   module_namemodule_versionprompt_namer   prompt_hashinput_summaryoutput_summaryr)   error_messager   duration_mstoken_usager=   r,   r.   r/   r0   r  r    s    Y#M	$	'Bj)>?%PJD51NJ.KD51N,KD\N,K4LMD\ND5)F4LM/Kt,K4.Mu-Jr/   r  c                   
   e Zd ZdZdZ eed      Z ee ed      d      Z	 eed      Z
 eed      Z eed	      Z eed
	      Z eed	      Z eed	      Z ee      Z eed      Z eed      Z ee      Zy)PipelineProgressuB   파이프라인 진행률 추적 — UI에서 폴링하여 표시.pipeline_progressTr   r   Fr   runningr   rB   r   N)r   r   r   rJ   r   r   r
   r    r   r!   rD   	operationr)   current_stepr   total_stepscompleted_stepsr  
started_atr-   completed_atr.   r/   r0   r  r    s    L'M	$	'Bj)>?%PJu-Jte,ID),F$+L!,KWa0O4LMu-Ju-J$<Lr/   r  c                   <   e Zd ZdZdZ eed      Z ee      Z ee      Z	 ee      Z
 ee      Z eed      Z ee      Z eed      Z ee      Z eed      Z ee      Z ee      Z ee      Z eed      Z ee      Z ee      Z eed      Zy	)

LLMCallLoguC   모든 LLM 호출의 입력/출력 기록 — 추적 및 재활용.llm_call_logTr   Fr   rC   r   N)r   r   r   rJ   r   r   r
   r    r!   rD   r  	step_name
model_namesystem_promptuser_promptoutput_textr   r   r  input_tokensoutput_tokensr)   r  r=   r,   r.   r/   r0   r  r    s    M"M	$	'BJJD\NtIu-J4LM.K,K !t4/K'?L7OMD5)F4LM 4LMu-Jr/   r  c                       e Zd ZdZdZ eed      Z ee ed      d      Z	 ee ed      d      Z
 eed	
      Z eed      Z eed      Z eed
      Z eed      Zy)	ScenePlanu;   씬 분할 계획 — 사용자 승인 전 미리보기용.
scene_planTr   r   Fr   r   r   r   r   N)r   r   r   rJ   r   r   r
   r    r   r!   rD   r   split_thresholdsegments_jsontotal_scenesr)   r,   r.   r/   r0   r#  r#    sy    E M	$	'Bj)>?%PJj6GJWc2O4%0M'E2LD),Fu-Jr/   r#  c                   2   e Zd ZdZ eed      Z ee ed      d      Z ee      Z	 ee      Z
 ee      Z eedd      Z eed      Z eedd	      Z ee      Z eed      Z ee      Z eed
      Z ee      Z ee      Z eed      Zy)GenerationTracegeneration_traceTr   r   Fr   r   )r   r   originalrC   r   N)r   r   r   r   r   r
   r    r   r!   image_asset_idr   r   r   attempt_numberr   r   r  r)   block_reasonblock_categoriesresponse_time_mssanitizer_feedbackr,   r.   r/   r0   r)  r)    s    &M	$	'Bj)>?%PJD\Nd|HtIGeQ?N.KD5*ENJD5)F$<LdD1gu-Jr/   r)  N)'rJ   
sqlalchemyr   r   r   r   r   r   r	   r
   r   sqlalchemy.ormr   sqlalchemy.sqlr   app.core.databaser   app.core.file_pathsr   r   r2   r@   rY   rk   rr   rx   r}   r   r   r   r   r   r   r   r  r  r  r#  r)  r.   r/   r0   <module>r7     s   T s s s # % " -.d ...$ .&B BJDt DN$ @.t .>$ >.4 .3$ 3+. +.\C C,B. B.J.d .. ..T ..4 .. t  $. .:. ..d .r/   