o
    լi                     @   s
  d Z ddlZddlmZmZ ddlmZ g dZg dZde	deed	 e
e
f fd
dZg dZg dZg dZg dZg dZg dZi ddddddddddddddddddddddd dd!dd"dd#dd$dd%di d&dd'dd(d)d*d)d+dd,dd-dd.dd/dd0dd1d)d2d)d3d4d5d6d7d6d8d4d9d4i d:d6d;d<d=d4d>d6d?d4d@d4dAd4dBd<dCd4dDd4dEd4dFd4dGd4dHd4dId4dJd6dKd4i dLd4dMd4dNd6dOd4dPd4dQd6dRd4dSd4dTd4dUd4dVd4dWd6dXd<dYd4dZd4d[d4d\d4d4d<d4d6d4d4d<d4d6d<d4d4d6d4d]Zi d^d_d`d_dadbdcd_ddd_dedfdgd_dhd_did_djdkdldkdmdndodndpdkdqdkdrd_dsd_d_d_d_dfdkdkdndkd_dfd_d_dkdkdndtZg duZde	deedv eeef fdwdxZg dyZg dzZg d{Zg d|Zeeeed}Zd~Zde	defddZded ded de	defddZde	de
dB fddZ ddl!m"Z"m#Z#m$Z$ dde	de	de	de
fddZ%	dde	ded ded de	de	defddZ&ded ded de	defddZ'dS )u'  
==============================================================================
Goalskill 데이터 분류 알고리즘 (전역 유틸리티)
==============================================================================
INPUT 데이터를 분석하여 Goalskill_DB의 48개 테이블 중 하나로 매칭·저장.

테이블명 패턴: {H|S}{A|B|C|D}_{T|P|R}{I|M}
  - H/S  : 큰 목표(H) vs 작은 목표(S)  ← 알고리즘이 판단
  - A~D   : 파트                         ← 호출 시 전달
  - T/P/R : 대화/조언/방향성              ← 알고리즘이 판단
  - I/M   : AI/User                       ← 호출 시 전달

사용법 (각 파트 라우터에서):
    from app.services.goalskill_classifier import classify_and_save

    await classify_and_save(
        session_id="sess_xxx",
        sender="M",        # "M" = User, "I" = AI
        part="A",           # "A" / "B" / "C" / "D"
        text="오늘 컨디션이 안 좋아서 쉬고 싶어"
    )
==============================================================================
    N)LiteralTuple)logger)3u   오늘u   내일u   모레u   어제u   그제u
   이번 주u	   이번주u   며칠u   하루	   컨디션   기분   의지	   진행도   진척u
   몇 시간u   오전u   오후u   저녁u   아침u   今日u   明日u	   明後日u   昨日u	   一昨日u   今週u   数日u   1日   コンディション   気分	   やる気   進捗u	   何時間u   午前u   午後u   夕方u   朝   体調u   調子u   今回u   次回u   直近u   最近u	   この前todaytomorrow	yesterdayz	this week	conditionmoodprogressfeeling)6   목표   장기u   전체   커리큘럼	   로드맵   계획   최종   취업	   자격증u   경력u   개월u   년	   앞으로u   미래u   전략   방향u   비전u   포부u   6개월u   1년u   반년u   한달u
   다음 달u   目標   長期u   全体   カリキュラム   ロードマップ   計画   最終   就職   資格u   キャリアu   ヶ月u   年   将来u   未来u   戦略   方向u   ビジョンu   抱負u   半年u   1年u   来月u	   再来月goal	long-termcareer
curriculumroadmapcertificatefuturestrategyvisiontextreturn)HSc                 C   sh   |   }d}d}tD ]}|  |v r|d7 }q
tD ]}|  |v r%|d7 }q||kr/d||fS d||fS )u}  
    텍스트를 분석하여 H(큰 목표) 또는 S(작은 목표) 분류.

    판단 기준:
    - S: 어제~7일 이내 시간 범위, 컨디션, 진행도 관련
    - H: 장기적 시간 범위, 큰 목표, 방향성, 커리어 관련

    동일한 점수일 경우 S를 기본값으로 (일상적 대화가 더 빈번)

    Returns:
        (result, h_score, s_score)
    r      r4   r5   )lower
S_KEYWORDS
H_KEYWORDS)r2   
text_lowers_scoreh_scorekw r>   ?/home/air/goalskill_t/back/app/services/goalskill_classifier.pyclassify_goal_scopeC   s   

r@   )u   안녕하세요u   오늘 기분이 좋아요u   잘 모르겠어요u   네 알겠습니다u   좀 더 설명해주세요u
   그래요?u   어떻게 하면 돼요?u   오늘 뭐 했어요?u   고마워요u   재밌었어요   こんにちはu   今日は気分がいいですu   よくわかりませんu   はい、わかりましたu$   もう少し説明してくださいu   そうですか？u!   どうすればいいですか？u!   今日は何をしましたか？u   ありがとうございますu   楽しかったですHellozI'm feeling good todayzI don't understandzYes, I got itzCan you explain more?zReally?zHow do I do this?zWhat did you do today?z	Thank youzThat was fun)u%   이렇게 하면 좋을 것 같아요u.   먼저 기초부터 배우는 걸 추천해요u   파이썬부터 시작하세요u1   매일 1시간씩 공부하면 효과적이에요u$   이 부분은 다시 복습하세요u#   유튜브 강의를 참고하세요u   실습을 많이 해보세요u#   에러가 나면 구글링하세요u+   이 자료를 읽어보면 도움이 돼요u*   코드를 직접 쳐보면서 배우세요u$   こうするといいと思いますu3   まず基礎から学ぶことをお勧めしますu!   Pythonから始めてくださいu1   毎日1時間ずつ勉強すると効果的ですu3   この部分はもう一度復習してくださいu+   YouTube講義を参考にしてくださいu0   実習をたくさんやってみてくださいu-   エラーが出たらググってくださいu3   この資料を読んでみると役に立ちますu<   コードを直接書いてみながら学んでくださいz$I think you should try this approachz$I recommend starting with the basicszStart with Python firstz"Studying 1 hour daily is effectivez!You should review this part againzCheck out YouTube tutorialsz&Practice a lot with hands-on exercisesz#Google the error when you get stuckzReading this material will helpzLearn by writing code yourself)u4   앞으로 백엔드 개발자를 목표로 해봐요u7   다음 단계로 데이터베이스를 배워야 해요u5   웹 개발 쪽으로 방향을 잡으면 좋겠어요u=   이 커리큘럼으로 3개월 안에 완성할 수 있어요u$   나중에 AWS도 배우면 좋아요u1   풀스택 개발자가 되려면 이런 순서로u5   자격증을 먼저 따고 취업 준비를 하세요u>   프론트엔드와 백엔드 중 어디에 집중할 건가요u3   장기적으로 이런 로드맵을 추천합니다u>   최종 목표를 설정하고 역산해서 계획을 세워요uB   今後はバックエンド開発者を目指してみましょうuK   次のステップとしてデータベースを学ぶ必要がありますu3   Web開発の方向に進むといいと思いますu=   このカリキュラムで3ヶ月以内に完成できますu*   将来的にAWSも学ぶといいですよu9   フルスタック開発者になるにはこの順序でu?   資格を先に取ってから就活準備をしてくださいuK   フロントエンドとバックエンドのどちらに集中しますかu9   長期的にこのロードマップをお勧めしますuB   最終目標を設定して逆算して計画を立てましょうz(Let's aim for a backend developer careerz#The next step is to learn databasesz%I suggest focusing on web developmentz,You can complete this curriculum in 3 monthsz&Learning AWS later would be beneficialz3To become a full-stack developer, follow this orderz1Get certified first, then prepare for job huntingz6Which would you like to focus on, frontend or backend?z"I recommend this long-term roadmapz&Set your final goal and plan backwards)u   안녕u   네u   응u   아니u   모르u   그래u   뭐u	   어떻게u   고마u   재미   힘들r      좋아u   싫어u   궁금rA   u   はいu	   いいえu	   わかりu   ありがとうu   楽しhelloyesnothankfunz
don't knowhowwhatgoodbad)!u   추천u   좋을u	   하세요u   해보세요u   배우세요   복습u   참고u   실습u   연습u   효과u   도움u   방법u   읽어u	   お勧めu   してください   復習u   参考u   実習u   練習u   効果u	   役に立u   方法u	   読んで	recommendshouldtrypracticereview	effectivehelpfulsuggesttipadvice)#r   r   r   u   단계r   r   r   r   u   다음r   r   r   u   목指r(   r"   u   ステップr!   r#   r'   r    u   次r$   r%   r&   r)   	directionr-   stepr,   planr+   nextr/   r*   r.      元気   u   最高   	   爽やかu   体調いいu   よく眠れたu   ぐっすりu   快調   u   調子いいu   調子がいいu   万全u   スッキリu	   絶好調rD   u   최고   상쾌u   컨디션 좋u   잘 잤u   푹 잤u   쾌조u   괜찮      멀쩡u   건강greatawesome	refreshedzwell-rested	energeticfinerL      疲れ   眠い	   眠たい   頭痛   風邪u   熱u   体調悪いu   調子悪い	   だるい   しんどい   辛い	   無気力u	   吐き気u	   めまいu	   倦怠感   痛いu   痛むu   具合悪いu   気持ち悪いu	   寝不足u   微熱u   腹痛u   腰痛   피곤   졸려   두통   감기   열이u   컨디션 안rC      지쳐   아프	   무기력   나른u   구토u	   어지러u   권태   아파u   통증)u
   속이 안u   몸살tiredsleepyheadachesick	exhaustedunwellsluggishnauseouspainhurtsoreillu   めっちゃg      ?u	   すごくu	   とてもg?u	   本当にu	   かなりu   死ぬほどg       @u   超u	   マジでu	   非常にu   ちょっとg      ?u   少しu   ややgffffff?u   まあまあu   なんとなくu	   微妙にu   엄청u   진짜)u   매우u   너무u   정말u   죽을 만큼u   조금u   좀u   약간u   살짝very	extremelyreallysuperza bitslightlysomewhat)u   ないu	   ませんu   じゃないu   ではないu	   なくてu   なかったu   않u   안 u   못 u    없znot zdon'tzdoesn'tzno TPRc                    s   |    t fddtD }t fddtD }t fddtD }dtdtdtfdd	}|| t}|| t	}|| t
}|d
 |d  }|d
 |d  }	|d
 |d  }
||	|
d}t||jd}|||	|
fS )u5  
    텍스트를 분석하여 T(대화), P(조언), R(방향성) 분류.

    2단계 판단:
    1) 핵심 키워드 매칭 점수
    2) 예문과의 단어 겹침 유사도

    두 점수를 합산하여 가장 높은 카테고리를 선택.

    Returns:
        (result, t_total, p_total, r_total)
    c                 3        | ]}|   v rd V  qdS r6   Nr7   .0r=   r:   r>   r?   	<genexpr>F      z(classify_content_type.<locals>.<genexpr>c                 3   r   r   r   r   r   r>   r?   r   G  r   c                 3   r   r   r   r   r   r>   r?   r   H  r   r2   examplesr3   c                 S   st   t td|  }|sdS d}|D ]%}t td| }|s!qt||@ }|tt|t| }t||}q|S )Nz\w+        )setrefindallr7   lenmax)r2   r   
text_words	max_scoreexex_wordsoverlapscorer>   r>   r?   word_overlap_scoreK  s   z1classify_content_type.<locals>.word_overlap_scorerd   
   r   key)r7   sum
T_KEYWORDS
P_KEYWORDS
R_KEYWORDSstrlistfloat
T_EXAMPLES
P_EXAMPLES
R_EXAMPLESr   get)r2   
t_kw_score
p_kw_score
r_kw_scorer   t_sim_scorep_sim_scorer_sim_scoret_totalp_totalr_totalscoresresultr>   r   r?   classify_content_type6  s   


r   )Hr   u	   진척도r	   u   진행u   어디까지u   완료u   끝냈u   어제 배운u
   어제 했u   어제 공부u	   지난번u   저번u   몇 퍼센트u
   몇 챕터u
   몇 단원u   몇 강u   몇 과rN   u
   다시 보u
   다시 했u	   마무리u	   이어서u   과제u   숙제u   제출u	   미완료u   미흡r   u	   進行度u   どこまでu   完了u   終わったu	   終えたu   昨日学んだu   昨日やったu   昨日勉強u   前回u   先日u   何パーセントu   何章u   何課u   何講rO   u   もう一度u   やり直しu	   仕上げu   続きu   課題u   宿題u   提出u	   未完了u	   不十分r   zhow far	completedfinishedzyesterday learnedzyesterday studiedz	last timepreviouspercentchapterlessonlecturerT   redocontinue
incomplete
unfinished
assignmenthomework	submitted)Mr   u
   몸 상태u   체력rx   ry   u   졸리r~   r   rz   r{   r|   u   배탈u
   잠을 못u   잠이 부족u   수면u   밤새u   야근u	   좋아요u	   괜찮아u   안 좋rC   r}   u   지치r   rc   r   r   re   r
   r   u   体力rk   rm   ro   rw   rp   rq   u   熱があるu   お腹u   眠れなかったu   睡眠不足u   睡眠u   徹夜u   残業r^   u	   大丈夫u   調子が悪いru   u	   疲れたr   ra   rs   rv   rt   r   physicalstaminar   r   r   r   coldfeverstomachachezcouldn't sleepzlack of sleepsleepz	all nightovertimezfeeling goodrj   znot wellr   r   rh   	lethargicr   )Qr   u   열정u   동기u   의욕u
   하고 싶u	   열심히u   도전u   집중u   몰입u   흥미u   관심u
   하기 싫u   귀찮u   포기u   그만u
   쉬고 싶u   빨리 하고u   많이 하고u	   조금만u	   적당히u	   자신감u   확신u   불안u   걱정u   두려u	   해볼게u	   해보겠u   할 수 있u
   못 하겠r   u   意欲u   情熱u   モチベーションu   やりたいu   頑張u   挑戦u   集中u   没頭u   興味u   関心u   やりたくないu   面倒u   諦めu   やめたいu   休みたいu   早くやりたいu   たくさんu   少しだけu   ほどほどu   自信u   確信u   不安u   心配u   怖いu   やってみますu	   できるu   できない
motivationpassionwillingeagerzwant tohard	challengefocusimmerseinterestcuriousz
don't wantlazyzgive upquitzwant to rest
confidencesureanxiousworriedscaredzI'll tryzI canzI can't)cu   이해u	   이해했u
   이해 못u   이해가 안u   알겠u	   모르겠u   기억u
   기억 안u	   기억나u   까먹u   잊어u   잊었u	   어려웠u	   어려워u   쉬웠u   쉬워u   헷갈u   혼란u   개념u   원리u   뜻u   의미u   왜 그런지u   다시 설명u
   한번 더u   정리u   요약u	   맞나요u   틀렸u   정답u   오답u   점수u	   확실히u   확실하지 않u   애매u	   불확실u   理解u   理解したu   理解できないu   わかったu   わからないu	   覚えてu   覚えていないu   思い出せu	   忘れたu	   忘れてu   難しかったu	   難しいu   簡単だったu   簡単u   混乱u   混同u   概念u   原理u   意味u   なぜu   もう一度説明u   もう一回u   整理u	   まとめu   合ってますかu	   間違いu   正解u	   不正解u   点数u   確実u   確実じゃないu   曖昧u	   不確実
understand
understoodzdon't understandzget itz	don't getrememberzdon't rememberforgotforget	difficultr   easyconfused	confusingconcept	principlemeaningwhyzexplain againzone more time	summarizesummarycorrectwrongr   gradez
sure aboutznot sure	ambiguous	uncertain)r   r   r   comprehensionr6   c              
      s   |    i }t D ]\}}t fdd|D }|||< q
t| }|tk}d}|r3t||jd}t	d| d| d| d|  ||||d	S )
u  
    A/B 파트 전용: 오늘의 커리큘럼 생성에 필요한 문장인지 판별.

    4개 카테고리로 판별:
    1. progress      - 어제까지의 커리큘럼 진행도
    2. condition     - 오늘 유저의 컨디션
    3. passion       - 오늘 유저의 열정/의지
    4. comprehension - 어제 내용에 대한 유저의 이해도

    키워드 매칭 합계가 임계값 이상이면 관련 있음으로 판정.
    여러 카테고리에 매칭되면 가장 점수가 높은 카테고리를 대표로 선택.

    Returns:
        {
            "is_relevant": True/False,
            "category": "progress" | "condition" | "passion" | "comprehension" | None,
            "scores": {"progress": 0, "condition": 2, ...},
            "total_score": 2
        }
    c                 3   r   r   r   r   r   r>   r?   r     r   z)is_curriculum_relevant.<locals>.<genexpr>Nr   z#[Curriculum Relevance] is_relevant=z, category=z	, scores=z, total=)is_relevantcategoryr   total_score)
r7   _CURRICULUM_CATEGORIESitemsr   values_CURRICULUM_RELEVANCE_THRESHOLDr   r   r   info)r2   r   r  keywordsr   r  r  best_categoryr>   r   r?   is_curriculum_relevant  s4   
r  sender)IMpart)ABCDc                 C   s   t |\}}}t|\}}}}	| | d| |  }
td|  d| d| d| d| d| d|d	d
|d	d|	d	d|
  |
|||||||	dS )u  
    4차원 분류를 수행하여 최종 테이블명과 각 점수를 반환.

    Args:
        sender: "I" (AI) 또는 "M" (User)
        part: "A" / "B" / "C" / "D"
        text: 저장할 텍스트 내용

    Returns:
        {
            "table_name": "SA_TM",
            "goal_scope": "S",
            "content_type": "T",
            "h_score": 0,
            "s_score": 2,
            "t_score": 12.5,
            "p_score": 4.0,
            "r_score": 2.0,
        }
    _z[Goalskill Classifier] sender=z, part=z, goal_scope=z(H=z/S=z), content_type=z(T=.1fz/P=z/R=u   ) → table=)
table_name
goal_scopecontent_typer<   r;   t_scorep_scorer_score)r@   r   r   r  )r  r  r2   r  r<   r;   r  r  r  r  r  r>   r>   r?   classify_table  sF   	r  c                 C   sZ  |   }d}d}d}t D ]u\}}|  }||vrq|d7 }t|}||}	|d|	 }
d}t D ]\}}|  |
v rB|} nq4|	t| }|||d  }d}tD ]}|  |v rad	} nqU|rg| }|| }||7 }t	d
| d| d| d| d| 
 q|dkrdS || }t
dtdt|}td| d|dd|dd|  |S )u*  
    텍스트에서 컨디션 관련 키워드를 감지하고 1~10점 점수를 산출.
    컨디션 키워드가 없으면 None 반환 (컨디션 문장이 아님).
    알고리즘:
    1. base_score = 5 (보통)
    2. 각 키워드 매칭 → 변동값 적용
    3. 강도 수식어가 키워드 앞에 있으면 배율 적용
    4. 부정어가 키워드 뒤에 있으면 극성 반전
    5. 최종 점수를 1~10으로 클램핑

    Returns:
        int (1~10): 컨디션 점수
        None: 컨디션 관련 키워드가 없는 경우
    g      @r   r   r6   Ng      ?r   FTz[Condition Score] keyword='z	', delta=z, amplifier=z
, negated=z, final_delta=z![Condition Score Result] matched=z, total_delta=r  z, raw=z, final=)r7   CONDITION_SCORE_KEYWORDSr  r   findINTENSITY_AMPLIFIERr   NEGATION_PATTERNSr   debugr   minroundr  )r2   r:   
base_scoretotal_deltamatched_countkeyworddeltakw_lowercurrent_deltakw_posbefore_text	amplifieramp_word	amp_valueafter_start
after_near
is_negatedneg_pattern	raw_scorefinal_scorer>   r>   r?   calculate_condition_scoreB  sn   
r9  )save_to_goalskill_tablesave_admin_logsave_to_goalskill_table_scoresource_type
session_idc              
   C   s  ddl m} ddl}ddl m} d}|dkr|rzW|d}|jjd'i |}|jdd}	|	d	|f |	 }
|	  |
rn|
d
 rn|
d
 dkrn|
d
 d }ddl
m} |||}|rn|drn|d }td| d|  W n ty } ztd|  W Y d}~nd}~ww |dkr|rd| d}n	|dkrd}nd}d| d|  d}zE| }|jjd|ddid}|j }ddd |D }|rt|}tdtd|}td | d!|  |W S td"| d# W d$S  ty } ztd%| d& W Y d}~d$S d}~ww )(u  
    Gemini API로 텍스트를 1~10으로 수치화.
    source_type: 'learning' (어제 학습 자기평가) | 'mindset' (오늘 각오)
    learning의 경우, 어제 커리큘럼 내용을 기준으로 비교 판단.
    실패 시 5(중립) 반환.
    r   )get_gemini_modelN)get_db_configlearningGoalskill_DBT)
dictionaryzOSELECT daily FROM result WHERE session_id = %s ORDER BY created_at DESC LIMIT 1dailyr6   )get_today_item_infonameu(   [Gemini Score] 어제 커리큘럼 (Day z): u+   [Gemini Score] 커리큘럼 조회 실패: u&   昨日のカリキュラム内容: 「u  」

上記のカリキュラムに対するユーザーの理解度・学習達成度を1~10で判定してください。
1~2=全く理解できていない(学習していない・サボった)
3~4=少し理解した(表面的な理解・不十分)
5~6=普通(基本的な概念は理解)
7~8=よく理解した(応用もある程度可能)
9~10=完全に理解(自主的な追加学習・深い理解)ui  ユーザーが昨日の学習をどれだけ誠実に取り組んだかを1~10で細かく判定してください。
1~2=全くやっていない(完全にサボった)
3~4=少しだけやった(不十分)
5~6=普通(最低限はやった)
7~8=しっかりやった(真面目に取り組んだ)
9~10=非常に頑張った(自主的に追加学習も行った)u0  ユーザーの今日の学習に対する意気込み・覚悟を1~10で細かく判定してください。
1~2=全くやる気がない(諦め・面倒)
3~4=低い(消極的・不安)
5~6=普通(特に強い感情なし)
7~8=高い(積極的・意欲的)
9~10=非常に高い(強い決意・情熱的)ur   以下のユーザーメッセージを分析して、数値のみを返してください。

【評価基準】
u$   

【ユーザーメッセージ】
u@  

【重要な注意事項】
- 1から10の整数を1つだけ出力してください
- 極端な値(1や10)は避け、細かい数値で判定してください
- 文脈・ニュアンス・否定表現を慎重に考慮してください
- 説明や文章は一切不要です。数字のみ出力してくださいzgemini-2.5-flashtemperatureg?)modelcontentsconfig c                 s   s    | ]	}|  r|V  qd S N)isdigit)r   cr>   r>   r?   r     s    z%gemini_score_1to10.<locals>.<genexpr>r   z[Gemini Score] source=z, score=u&   [Gemini Score] 숫자 추출 실패: 'u   ' → 기본값 5r`   u   [Gemini Score] API 에러: u    → 기본값 5r>   )app.core.configr?  mysql.connectorr@  	connectorconnectcursorexecutefetchonecloseapp.models.curriculum_modulerE  r   r   r  	Exceptionwarningmodelsgenerate_contentr2   stripjoinintr   r%  error)r2   r=  r>  r?  mysqlr@  yesterday_curriculum	gs_configconnrS  rowyesterday_dayrE  	item_infoecontextpromptclientresponseresult_textdigitsr   r>   r>   r?   gemini_score_1to10  sz   

	
	
rn  c                    sD  t |||}|d }|d }|d }d}	|dv ret|}	|	d setd| d| d	 t| ||||d
 |d |d |d |d d| d
 |||||| dd|	|d
 |d |d |d |d dd
S t|}
zd}|dkr|dv rt||| d}t|| ||| nt|| ||dkr|
ndd t| ||||d
 |d |d |d |d |d
 td| d|  d| |rd| d| nd  |||||| d|
|d
 |d |d |d |d dd 	}|dur||d!< ||d"< |	dur|	|d#< |W S  t	y! } zt
d$| d%|  |||||| dt|d&W  Y d}~S d}~ww )'uR  
    INPUT 데이터를 분류하고 Goalskill_DB의 해당 테이블에 저장.
    T/P/R 모든 타입에서 실제 텍스트를 output에 저장.
    동시에 admin 테이블에 분류 점수 로그를 기록.

    ★ A/B 파트: 커리큘럼 생성에 필요한 문장만 저장 (필터링)
    ★ C/D 파트: 기존대로 모든 INPUT 저장

    Args:
        session_id: 유저 세션 ID
        sender: "I" (AI) 또는 "M" (User)
        part: "A" / "B" / "C" / "D"
        text: 저장할 텍스트 내용

    Returns:
        분류 결과 및 점수 정보를 포함한 dict
    r  r  r  N)r  r  r  z[Goalskill Skip] part=z	, sender=u1   , 커리큘럼 관련성 없음 → 저장 스킵r<   r;   r  r  r  SKIP_)
r>  r  r  
input_text	h_scoring	s_scoring	t_scoring	p_scoring	r_scoringresult_tableFnot_curriculum_relevantr4   r5   r   r   r   )
r  r  r  r  r  r>  savedskip_reason	relevancer   r  )rA  mindset)r>  r  )statusz[Goalskill Save] table=z
, session=z	, source=z	, status=rK  T)	r  r  r  r  r  r>  ry  condition_scorer   r=  r}  r{  z[Goalskill Save Error] table=z: )r  r  r  r  r  r>  ry  r_  )r  r  r   r  r;  r9  rn  r<  r:  rX  r_  r   )r>  r  r  r2   r=  r   r  r  r  r{  r~  status_scorerk  rg  r>   r>   r?   classify_and_save  s   r  c                 C   sJ   t | ||}|d |d |d | ||d |d |d |d |d d	d
S )uo   
    분류만 수행 (저장하지 않음). 디버그/테스트용.
    점수도 함께 반환합니다.
    r  r  r  r<   r;   r  r  r  rx  )r  r  r  r  r  r   )r  )r  r  r2   r   r>   r>   r?   classify_only  s   	r  rL  )(__doc__r   typingr   r   rO  r   r8   r9   r   r^  r@   r   r   r   r   r   r   r   r"  r#  r   r   CURRICULUM_PROGRESS_KEYWORDSCURRICULUM_CONDITION_KEYWORDSCURRICULUM_PASSION_KEYWORDS!CURRICULUM_COMPREHENSION_KEYWORDSr  r
  dictr  r  r9  app.models.goalskill_moduler:  r;  r<  rn  r  r  r>   r>   r>   r?   <module>   s    %%%%	
		!			"	87
2Tt
 