Ë
    ¨mjbn  ã            
       óÞ
  — d dl mZmZmZmZmZ d dlmZmZ d dl	m
Z
 d dlmZ d dlm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mZmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.  ed	g¬
«      Z/de0dz  de0dz  fd„Z1dede2fd„Z3dede2fd„Z4dede2fd„Z5dede2fd„Z6dede7defd„Z8dede2fd„Z9e/ju                  de d¬«       edd¬«       ee
«       ee«      fde0dz  ded efd!„«       Z;e/ju                  d"e<e#   d#¬«       ee
«       ee«      fded efd$„«       Z=e/ju                  d%e#d&¬«       ee
«       ee«      fde7ded efd'„«       Z>e/j                  d"e#ej€                  d(¬)«       ee
«       ee«      fd*e"ded efd+„«       ZAe/j                  d,e#ej€                  d-¬)«       ee
«       ee«      fd*e$ded efd.„«       ZBe/j‡                  d%e#d/¬«       ee
«       ee«      fde7d*e%ded efd0„«       ZDe/j‹                  d%ed1¬«       ee
«       ee«      fde7ded efd2„«       ZFe/ju                  d3e<e'   d4¬«       ee
«       ee«      fde7ded efd5„«       ZGe/j                  d6e'ej€                  d7¬)«       ee
«       ee«      fd*e&ded efd8„«       ZHe/j‡                  d9e'd:¬«       ee
«       ee«      fd;e7d*e(ded efd<„«       ZIe/j‹                  d9ed=¬«       ee
«       ee«      fd;e7ded efd>„«       ZJe/ju                  d?e<e-   d@¬«       ee
«       ee«      fd;e7ded efdA„«       ZKe/j                  dBe-ej€                  dC¬)«       ee
«       ee«      fd*e,ded efdD„«       ZLe/j‡                  dEe-dF¬«       ee
«       ee«      fdGe7d*e.ded efdH„«       ZMe/j‹                  dEedI¬«       ee
«       ee«      fdGe7ded efdJ„«       ZNe/ju                  dKe<e*   dL¬«       ee
«       ee«      fdGe7ded efdM„«       ZOe/j                  dNe*ej€                  dO¬)«       ee
«       ee«      fd*e)ded efdP„«       ZPe/j‡                  dQe*dR¬«       ee
«       ee«      fdSe7d*e+ded efdT„«       ZQe/j‹                  dQedU¬«       ee
«       ee«      fdSe7ded efdV„«       ZRe/ju                  dWe<e   dX¬«       ee
«       ee«      fdSe7ded efdY„«       ZSe/j                  dZeej€                  d[¬)«       ee
«       ee«      fd*eded efd\„«       ZTe/j‡                  d]ed^¬«       ee
«       ee«      fd_e7d*eded efd`„«       ZUe/j‹                  d]eda¬«       ee
«       ee«      fd_e7ded efdb„«       ZVy)cé    )Ú	APIRouterÚDependsÚHTTPExceptionÚQueryÚstatus)ÚSessionÚselectinload)Úget_db)Úrequire_admin_token)ÚUser)	ÚProgrammeAssessmentÚProgrammeLevelÚProgrammeModuleÚnormalize_programme_level_slugÚnormalize_programme_module_kindÚprogramme_level_slug_strÚprogramme_module_kind_strÚProgrammeSessionÚProgrammeWeek)Úserialize_programme_catalog)ÚMessageÚ ProgrammeAssessmentCreateRequestÚProgrammeAssessmentOutÚ ProgrammeAssessmentUpdateRequestÚProgrammeCatalogResponseÚProgrammeIdRequestÚProgrammeLevelCreateRequestÚProgrammeLevelOutÚProgrammeLevelTreeCreateRequestÚProgrammeLevelUpdateRequestÚProgrammeModuleCreateRequestÚProgrammeModuleOutÚProgrammeModuleUpdateRequestÚProgrammeSessionCreateRequestÚProgrammeSessionOutÚProgrammeSessionUpdateRequestÚProgrammeWeekCreateRequestÚProgrammeWeekOutÚProgrammeWeekUpdateRequestzadmin-programme)ÚtagsÚlevelNÚreturnc                 ó¬   — | �| j                  «       sy 	 t        | «      S # t        $ r*}t        t        j
                  t        |«      ¬«      |‚d }~ww xY w)N©Ústatus_codeÚdetail)Ústripr   Ú
ValueErrorr   r   ÚHTTP_400_BAD_REQUESTÚstr)r+   Úes     ú@/var/www/html/kelly/kelly-backend/app/routers/admin/programme.pyÚ_parse_level_slugr7   0   sP   € Ø€}˜EŸK™KœMØð[Ü-¨eÓ4Ð4øÜò [Ü¬×(CÑ(CÌCÐPQËFÔSÐYZÐZûð[ús   •
   	A©%AÁAÚac                 óJ   — | j                   | j                  | j                  dœS )N©ÚidÚ
sort_orderÚtitler:   )r8   s    r6   Ú_serialize_assessmentr>   9   s   € Ø—$‘$ a§l¡l¸Q¿W¹WÑEÐEó    Úsc                 óÞ   — t        | j                  d„ ¬«      }| j                  | j                  | j                  | j
                  t        |«      |D �cg c]  }t        |«      ‘Œ c}dœS c c}w )Nc                 ó   — | j                   S ©N©r<   ©Úxs    r6   Ú<lambda>z$_serialize_session.<locals>.<lambda>>   s   € °a·l²lr?   ©Úkey)r;   Úsession_numberr=   Úadmin_checkedÚassessments_countÚassessments)ÚsortedrM   r;   rJ   r=   rK   Úlenr>   )r@   rM   r8   s      r6   Ú_serialize_sessionrP   =   sa   € Ü˜Ÿ™Ñ,BÔC€Kà�d‰dØ×*Ñ*Ø—‘ØŸ™Ü  Ó-Ù:EÓF¹+°QÔ-¨aÕ0¸+ÑFñð ùò Gs   ÁA*Úwc                 óî   — t        | j                  d„ ¬«      }t        d„ |D «       «      }| j                  | j                  | j
                  t        |«      ||D �cg c]  }t        |«      ‘Œ c}dœS c c}w )Nc                 ó   — | j                   S rC   )rJ   rE   s    r6   rG   z!_serialize_week.<locals>.<lambda>J   s
   € °×0@Ò0@r?   rH   c              3   óF   K  — | ]  }t        |j                  «      –— Œ y ­wrC   )rO   rM   )Ú.0r@   s     r6   Ú	<genexpr>z"_serialize_week.<locals>.<genexpr>K   s   è ø€ ÐA¹°1œC §¡×.¹ùó   ‚!)r;   Ú
week_indexÚdisplay_labelÚsessions_countrL   Úsessions)rN   r[   Úsumr;   rX   rY   rO   rP   )rQ   r[   Útotal_assessmentsr@   s       r6   Ú_serialize_weekr^   I   sj   € Ü�a—j‘jÑ&@ÔA€HÜÑA¹ÓAÓAÐà�d‰dØ—l‘lØŸ™Ü˜h›-Ø.Ù4<Ó=±H¨qÔ'¨Õ*°HÑ=ñð ùò >s   ÁA2Úmc                 ó<  — t        | j                  d„ ¬«      }t        d„ |D «       «      }t        d„ |D «       «      }| j                  t	        | j
                  «      | j                  | j                  t        |«      |||D �cg c]  }t        |«      ‘Œ c}dœS c c}w )Nc                 ó   — | j                   S rC   )rX   rE   s    r6   rG   z#_serialize_module.<locals>.<lambda>W   s   € ¨!¯,ª,r?   rH   c              3   óF   K  — | ]  }t        |j                  «      –— Œ y ­wrC   )rO   r[   )rU   rQ   s     r6   rV   z$_serialize_module.<locals>.<genexpr>X   s   è ø€ Ð8±%¨Qœ˜QŸZ™ZŸ±%ùrW   c              3   óh   K  — | ]*  }|j                   D ]  }t        |j                  «      –— Œ Œ, y ­wrC   )r[   rO   rM   )rU   rQ   r@   s      r6   rV   z$_serialize_module.<locals>.<genexpr>Y   s'   è ø€ ÐR¹°1ÀqÇzÄzÀ!œC §¡×.ÀzÐ.¹ùó   ‚02)r;   ÚkindÚdisplay_namer<   Úweeks_countrZ   rL   Úweeks)
rN   rh   r\   r;   r   re   rf   r<   rO   r^   )r_   rh   Útotal_sessionsr]   rQ   s        r6   Ú_serialize_modulerj   V   sˆ   € Ü�1—7‘7Ñ 6Ô7€EÜÑ8±%Ó8Ó8€NÜÑR¹ÓRÓRÐà�d‰dÜ)¨!¯&©&Ó1ØŸ™Ø—l‘lÜ˜5“zØ(Ø.Ù.3Ó4©e¨”/ !Õ$¨eÑ4ñ	ð 	ùò 5s   ÂBÚdbÚlevel_idc                 óÀ  — | j                  t        «      j                  t        t        j                  «      j                  t
        j                  «      j                  t        j                  «      j                  t        j                  «      «      j                  t        j                  |k(  «      j                  «       }|st        t        j                   d¬«      ‚|S ©NúLevel not foundr.   )Úqueryr   Úoptionsr	   Úmodulesr   rh   r   r[   r   rM   Úfilterr;   Úfirstr   r   ÚHTTP_404_NOT_FOUND)rk   rl   r+   s      r6   Ú_load_level_fullrv   f   s˜   € à
�‰”Ó ß	‰Üœ×/Ñ/Ó0ß‰\œ/×/Ñ/Ó0ß‰\œ-×0Ñ0Ó1ß‰\Ô*×6Ñ6Ó7ó	

÷ 
‰”×!Ñ! XÑ-Ó	.ß	‰‹ð 
ñ Ü¬×(AÑ(AÐJ[Ô\Ð\Ø€Lr?   c                 ób  — t        | j                  d„ ¬«      }t        d„ |D «       «      }t        d„ |D «       «      }t        d„ |D «       «      }| j                  t	        | j
                  «      | j                  | j                  t        |«      ||||D �cg c]  }t        |«      ‘Œ c}dœ	S c c}w )Nc                 ó   — | j                   S rC   rD   rE   s    r6   rG   z_level_out.<locals>.<lambda>x   s   € °!·,²,r?   rH   c              3   óF   K  — | ]  }t        |j                  «      –— Œ y ­wrC   )rO   rh   )rU   r_   s     r6   rV   z_level_out.<locals>.<genexpr>y   s   è ø€ Ð4©G q”c˜!Ÿ'™'—l©GùrW   c              3   óh   K  — | ]*  }|j                   D ]  }t        |j                  «      –— Œ Œ, y ­wrC   )rh   rO   r[   )rU   r_   rQ   s      r6   rV   z_level_out.<locals>.<genexpr>z   s%   è ø€ ÐK±'¨QÀ1Ç7Ä7¸aœ˜QŸZ™ZŸÀ7˜±'ùrd   c              3   óŠ   K  — | ];  }|j                   D ]*  }|j                  D ]  }t        |j                  «      –— Œ Œ, Œ= y ­wrC   )rh   r[   rO   rM   )rU   r_   rQ   r@   s       r6   rV   z_level_out.<locals>.<genexpr>{   s9   è ø€ Ðe¹°1ÈÏÌÀAÐZ[×ZdÔZdÐUVœC §¡×.ÐZdÐ.ÈÐ.¹ùs   ‚AA)	r;   Úslugrf   r<   Úmodules_countrg   rZ   rL   rr   )
rN   rr   r\   r;   r   r|   rf   r<   rO   rj   )r+   rr   Útotal_weeksri   r]   r_   s         r6   Ú
_level_outr   w   s    € Ü�U—]‘]Ñ(>Ô?€GÜÑ4©GÓ4Ó4€KÜÑK±'ÓKÓK€NÜÑe¹ÓeÓeÐà�h‰hÜ(¨¯©Ó4Ø×*Ñ*Ø×&Ñ&Ü˜W›Ø"Ø(Ø.Ù29Ó:±'¨QÔ% aÕ(°'Ñ:ñ
ð 
ùò ;s   ÂB,z/programme/catalogzGet full programme hierarchy)Úresponse_modelÚsummaryz?Optional level filter: beginner, hb, intermediate, hi, advanced)ÚdescriptionÚ_c                 ó.   — t        |t        | «      ¬«      S )N)Ú
level_slug)r   r7   )r+   rk   rƒ   s      r6   Úget_programme_catalogr†   �   s   € ô ' rÔ6GÈÓ6NÔOÐOr?   z/programme/levelszList all programme levelsc                 óÞ  — | j                  t        «      j                  t        t        j                  «      j                  t
        j                  «      j                  t        j                  «      j                  t        j                  «      «      j                  t        j                  «      j                  «       }|D �cg c]   }t        j                  t!        |«      «      ‘Œ" c}S c c}w rC   )rp   r   rq   r	   rr   r   rh   r   r[   r   rM   Úorder_byr<   Úallr   Úmodel_validater   )rk   rƒ   ÚlevelsÚlvs       r6   Úlist_levelsr�   ž   s£   € ð 	�‰”Ó ß	‰Üœ×/Ñ/Ó0ß‰\œ/×/Ñ/Ó0ß‰\œ-×0Ñ0Ó1ß‰\Ô*×6Ñ6Ó7ó	

÷ 
‰”.×+Ñ+Ó	,ß	‰‹ð ñ HNÓNÁvÀÔ×,Ñ,¬Z¸«^Õ<ÀvÑNÐNùÒNs   Ã%C*z/programme/levels/{level_id}zGet one level with full treec                 óV   — t        || «      }t        j                  t        |«      «      S rC   )rv   r   rŠ   r   ©rl   rk   rƒ   r+   s       r6   Ú	get_levelr�   µ   s&   € ô ˜R Ó*€EÜ×+Ñ+¬J°uÓ,=Ó>Ð>r?   zCreate a new programme level)r€   r/   r�   Úbodyc                 ó`  — 	 t        | j                  «      }|j                  t        «      j                  t        j                  |k(  «      j                  «       rt        t        j                  d¬«      ‚t        || j                  j                  «       | j                  ¬«      }|j                  |«       |j!                  «        t#        ||j$                  «      }t'        j(                  t+        |«      «      S # t        $ r*}t        t        j
                  t        |«      ¬«      |‚d }~ww xY w)Nr.   ú#Level with this slug already exists©r|   rf   r<   )r   r|   r2   r   r   r3   r4   rp   r   rs   rt   ÚHTTP_409_CONFLICTrf   r1   r<   ÚaddÚcommitrv   r;   r   rŠ   r   )r‘   rk   rƒ   Úslug_strr5   r+   s         r6   Úcreate_levelr™   Ã   sä   € ð[Ü1°$·)±)Ó<ˆð 
‡x�x”Ó×&Ñ&¤~×':Ñ':¸hÑ'FÓG×MÑMÔOÜ¬×(@Ñ(@ÐInÔoÐoÜ °t×7HÑ7H×7NÑ7NÓ7PÐ]a×]lÑ]lÔm€EØ‡F�Fˆ5„MØ‡I�I„KÜ˜R §¡Ó*€EÜ×+Ñ+¬J°uÓ,=Ó>Ð>øô ò [Ü¬×(CÑ(CÌCÐPQËFÔSÐYZÐZûð[ús   ‚C: Ã:	D-Ä%D(Ä(D-z/programme/levels/fullzWCreate a new programme level with full nested tree (modules/weeks/sessions/assessments)c                 ó¦	  — 	 t        | j                  «      }|j                  t        «      j                  t        j                  |k(  «      j                  «       rt        t        j                  d¬«      ‚	 t        || j                  j                  «       | j                  ¬«      }|j                  |«       |j!                  «        | j"                  D �]í  }	 t%        |j&                  «      }t)        |j*                  ||j                  j                  «       |j                  ¬«      }|j                  |«       |j!                  «        t-        «       }	|j.                  D �]^  }
|
j0                  |	v r+t        t        j
                  d|
j0                  › d|› �¬«      ‚|	j                  |
j0                  «       t3        |j*                  |
j0                  |
j4                  j                  «       ¬«      }|j                  |«       |j!                  «        t-        «       }|
j6                  D �]’  }|j8                  |v r5t        t        j
                  d	|j8                  › d
|
j0                  › �¬«      ‚|j                  |j8                  «       t;        |j*                  |j8                  |j<                  j                  «       t?        |j@                  «      ¬«      }|j                  |«       |j!                  «        t-        «       }|jB                  D ]©  }|j                  |v r5t        t        j
                  d|j                  › d|j8                  › �¬«      ‚|j                  |j                  «       |j                  tE        |j*                  |j                  |j<                  j                  «       ¬«      «       Œ« �Œ• �Œa �Œð |jG                  «        tM        ||j*                  «      }tO        jP                  tS        |«      «      S # t        $ r*}t        t        j
                  t        |«      ¬«      |‚d}~ww xY w# t        $ r*}t        t        j
                  t        |«      ¬«      |‚d}~ww xY w# t        $ r |jI                  «        ‚ tJ        $ r:}|jI                  «        t        t        j
                  t        |«      ¬«      |‚d}~ww xY w)zE
    Admin UI helper: create a full custom level in one request.
    r.   Nr“   r”   ©rl   re   rf   r<   zDuplicate week_index z in module ©Ú	module_idrX   rY   zDuplicate session_number z in week_index ©Úweek_idrJ   r=   rK   z Duplicate assessment sort_order z in session_number )Ú
session_idr<   r=   )*r   r|   r2   r   r   r3   r4   rp   r   rs   rt   r•   rf   r1   r<   r–   Úflushrr   r   re   r   r;   Úsetrh   rX   r   rY   r[   rJ   r   r=   ÚboolrK   rM   r   r—   ÚrollbackÚ	Exceptionrv   r   rŠ   r   )r‘   rk   rƒ   r˜   r5   r+   Úmod_inÚkind_strÚmodÚseen_week_indexesÚweek_inÚweekÚseen_session_numbersÚsess_inÚsessÚseen_sort_ordersÚa_ins                    r6   Úcreate_level_fullr±   Û   s   € ð[Ü1°$·)±)Ó<ˆð 
‡x�x”Ó×&Ñ&¤~×':Ñ':¸hÑ'FÓG×MÑMÔOÜ¬×(@Ñ(@ÐInÔoÐoðR[ÜØØ×*Ñ*×0Ñ0Ó2Ø—‘ô
ˆð
 	�‰ˆuŒØ
�‰Œ
à—l•lˆFðcÜ:¸6¿;¹;ÓG�ô "ØŸ™ØØ#×0Ñ0×6Ñ6Ó8Ø!×,Ñ,ô	ˆCð �F‰F�3ŒKØ�H‰HŒJô +.«%ÐØ!Ÿ<�<�Ø×%Ñ%Ð):Ñ:Ü'Ü$*×$?Ñ$?Ø!6°w×7IÑ7IÐ6JÈ+ÐV^ÐU_Ð`ôð ð "×%Ñ% g×&8Ñ&8Ô9ä$Ø!Ÿf™fØ&×1Ñ1Ø")×"7Ñ"7×"=Ñ"=Ó"?ô�ð
 —‘�t”Ø—‘”
ä14³Ð$Ø&×/Õ/�GØ×-Ñ-Ð1EÑEÜ+Ü(.×(CÑ(CØ%>¸w×?UÑ?UÐ>VÐVeÐfm×fxÑfxÐeyÐ#zôð ð )×,Ñ,¨W×-CÑ-CÔDä+Ø $§¡Ø'.×'=Ñ'=Ø%Ÿm™m×1Ñ1Ó3Ü&*¨7×+@Ñ+@Ó&Aô	�Dð —F‘F˜4”LØ—H‘H”Jä14³Ð$Ø '× 3Ô 3˜ØŸ?™?Ð.>Ñ>Ü"/Ü,2×,GÑ,GØ)IÈ$Ï/É/ÐIZÐZmÐnu÷  oEñ  oEð  nFð  (Gô#ð ð )×,Ñ,¨T¯_©_Ô=ØŸ™Ü/Ø+/¯7©7Ø+/¯?©?Ø&*§j¡j×&6Ñ&6Ó&8ôõò !4ò%  0ò# (ð# #ðF 	�	‰	Œô ˜R §¡Ó*€EÜ×+Ñ+¬J°uÓ,=Ó>Ð>øôy ò [Ü¬×(CÑ(CÌCÐPQËFÔSÐYZÐZûð[ûô& ò cÜ#´×0KÑ0KÔTWÐXYÓTZÔ[ÐabÐbûðcûôB ò Ø
�‰ŒØÜò [Ø
�‰ŒÜ¬×(CÑ(CÌCÐPQËFÔSÐYZÐZûð[úsU   ‚P Á6A!Q4 ÃP>Ã-K'Q4 Ð	P;Ð%P6Ð6P;Ð>	Q1Ñ%Q,Ñ,Q1Ñ1Q4 Ñ4"SÒ5SÓSz2Update a programme level display name / sort orderc                 ó€  — |j                  t        | «      }|st        t        j                  d¬«      ‚|j
                  �|j
                  j                  «       |_        |j                  �|j                  |_        |j                  «        t        ||j                  «      }t        j                  t        |«      «      S rn   )Úgetr   r   r   ru   rf   r1   r<   r—   rv   r;   r   rŠ   r   )rl   r‘   rk   rƒ   r+   s        r6   Úupdate_levelr´   J  s“   € ð �F‰F”> 8Ó,€EÙÜ¬×(AÑ(AÐJ[Ô\Ð\Ø×ÑÐ$Ø!×.Ñ.×4Ñ4Ó6ˆÔØ‡�Ð"ØŸ?™?ˆÔØ‡I�I„KÜ˜R §¡Ó*€EÜ×+Ñ+¬J°uÓ,=Ó>Ð>r?   zIDelete a programme level (cascades to modules/weeks/sessions/assessments)c                 óÂ   — |j                  t        | «      }|st        t        j                  d¬«      ‚|j                  |«       |j                  «        t        d¬«      S )Nro   r.   zLevel deleted©Úmessage)r³   r   r   r   ru   Údeleter—   r   r�   s       r6   Údelete_levelr¹   a  sK   € ð �F‰F”> 8Ó,€EÙÜ¬×(AÑ(AÐJ[Ô\Ð\Ø‡I�IˆeÔØ‡I�I„KÜ˜?Ô+Ð+r?   z$/programme/levels/{level_id}/moduleszList modules for a levelc                 óJ  — |j                  t        | «      }|st        t        j                  d¬«      ‚|j                  t        «      j                  t        t        j                  «      j                  t        j                  «      j                  t        j                  «      «      j                  t        j                  | k(  «      j!                  t        j"                  «      j%                  «       }|D �cg c]   }t'        j(                  t+        |«      «      ‘Œ" c}S c c}w rn   )r³   r   r   r   ru   rp   r   rq   r	   rh   r   r[   r   rM   rs   rl   rˆ   r<   r‰   r"   rŠ   rj   )rl   rk   rƒ   r+   rr   r_   s         r6   Úlist_modulesr»   w  sÑ   € ð �F‰F”> 8Ó,€EÙÜ¬×(AÑ(AÐJ[Ô\Ð\à
�‰”Ó!ß	‰Üœ×.Ñ.Ó/ß‰\œ-×0Ñ0Ó1ß‰\Ô*×6Ñ6Ó7ó

÷
 
‰”×(Ñ(¨HÑ4Ó	5ß	‰”/×,Ñ,Ó	-ß	‰‹ð ñ NUÓUÉWÈÔ×-Ñ-Ô.?ÀÓ.BÕCÈWÑUÐUùÒUs   Ã8%D z/programme/moduleszCreate a module inside a levelc                 óx  — |j                  t        | j                  «      st        t        j
                  d¬«      ‚	 t        | j                  «      }|j                  t        «      j                  t        j                  | j                  k(  t        j                  |k(  «      j                  «       }|rt        t        j                  d¬«      ‚t        | j                  || j                   j#                  «       | j$                  ¬«      }|j'                  |«       |j)                  «        |j+                  |«       |j                  t        «      j-                  t/        t        j0                  «      j/                  t2        j4                  «      j/                  t6        j8                  «      «      j                  t        j:                  |j:                  k(  «      j                  «       }t=        j>                  tA        |«      «      S # t        $ r*}t        t        j                  t        |«      ¬«      |‚d }~ww xY w)Nro   r.   z2Module with this type already exists in this levelr›   )!r³   r   rl   r   r   ru   r   re   r2   r3   r4   rp   r   rs   rt   r•   rf   r1   r<   r–   r—   Úrefreshrq   r	   rh   r   r[   r   rM   r;   r"   rŠ   rj   )r‘   rk   rƒ   r§   r5   Úexistingr¨   s          r6   Úcreate_moduler¿   ’  s¥  € ð �6‰6”. $§-¡-Ô0Ü¬×(AÑ(AÐJ[Ô\Ð\ð[Ü2°4·9±9Ó=ˆð 	�‰”Ó!ß	‰”×(Ñ(¨D¯M©MÑ9¼?×;OÑ;OÐS[Ñ;[Ó	\ß	‰‹ð ñ
 Ü¬×(@Ñ(@ÐI}Ô~Ð~Ü
Ø—‘ØØ×&Ñ&×,Ñ,Ó.Ø—?‘?ô	€Cð ‡F�Fˆ3„KØ‡I�I„KØ‡J�Jˆs„Oà
�‰”Ó!ß	‰”œo×3Ñ3Ó4×AÑAÄ-×BXÑBXÓY×fÑfÔgw÷  hDñ  hDó  Eó  
Fß	‰”×"Ñ" c§f¡fÑ,Ó	-ß	‰‹ð	 ô ×,Ñ,Ô->¸sÓ-CÓDÐDøô1 ò [Ü¬×(CÑ(CÌCÐPQËFÔSÐYZÐZûð[ús   ½H È	H9È%H4È4H9z/programme/modules/{module_id}z)Update a module display name / sort orderr�   c                 óš  — |j                  t        | «      }|st        t        j                  d¬«      ‚|j
                  �|j
                  j                  «       |_        |j                  �|j                  |_        |j                  «        |j                  t        «      j                  t        t        j                  «      j                  t        j                  «      j                  t        j                   «      «      j#                  t        j$                  | k(  «      j'                  «       }t)        j*                  t-        |«      «      S ©NúModule not foundr.   )r³   r   r   r   ru   rf   r1   r<   r—   rp   rq   r	   rh   r   r[   r   rM   rs   r;   rt   r"   rŠ   rj   )r�   r‘   rk   rƒ   r¨   s        r6   Úupdate_modulerÃ   ¼  sø   € ð �&‰&” )Ó
,€CÙÜ¬×(AÑ(AÐJ\Ô]Ð]Ø×ÑÐ$Ø×,Ñ,×2Ñ2Ó4ˆÔØ‡�Ð"ØŸ™ˆŒØ‡I�I„Kà
�‰”Ó!ß	‰”œo×3Ñ3Ó4×AÑAÄ-×BXÑBXÓY×fÑfÔgw÷  hDñ  hDó  Eó  
Fß	‰”×"Ñ" iÑ/Ó	0ß	‰‹ð	 ô ×,Ñ,Ô->¸sÓ-CÓDÐDr?   u=   Delete a module (cascades weeks â†’ sessions â†’ assessments)c                 óÜ  — |j                  t        «      j                  t        t        j                  «      j                  t
        j                  «      j                  t        j                  «      «      j                  t        j                  | k(  «      j                  «       }|st        t        j                  d¬«      ‚|j                  |«       |j!                  «        t#        d¬«      S )NrÂ   r.   zModule deletedr¶   )rp   r   rq   r	   rh   r   r[   r   rM   rs   r;   rt   r   r   ru   r¸   r—   r   )r�   rk   rƒ   r¨   s       r6   Údelete_modulerÅ   Ø  s¥   € ð 	�‰”Ó!ß	‰Üœ×.Ñ.Ó/ß‰\œ-×0Ñ0Ó1ß‰\Ô*×6Ñ6Ó7ó

÷
 
‰”×"Ñ" iÑ/Ó	0ß	‰‹ð ñ Ü¬×(AÑ(AÐJ\Ô]Ð]Ø‡I�Iˆc„NØ‡I�I„KÜÐ+Ô,Ð,r?   z$/programme/modules/{module_id}/weekszList weeks for a modulec                 ó  — |j                  t        | «      st        t        j                  d¬«      ‚|j                  t        «      j                  t        t        j                  «      j                  t        j                  «      «      j                  t        j                  | k(  «      j                  t        j                  «      j!                  «       }|D �cg c]   }t#        j$                  t'        |«      «      ‘Œ" c}S c c}w rÁ   )r³   r   r   r   ru   rp   r   rq   r	   r[   r   rM   rs   r�   rˆ   rX   r‰   r(   rŠ   r^   )r�   rk   rƒ   rh   rQ   s        r6   Ú
list_weeksrÇ   ÷  s·   € ð �6‰6”/ 9Ô-Ü¬×(AÑ(AÐJ\Ô]Ð]à
�‰”Óß	‰”œm×4Ñ4Ó5×BÑBÔCS×C_ÑC_Ó`Ó	aß	‰”×'Ñ'¨9Ñ4Ó	5ß	‰”-×*Ñ*Ó	+ß	‰‹ð 
ñ JOÓOÉÀAÔ×+Ñ+¬O¸AÓ,>Õ?ÈÑOÐOùÒOs   Ã%Dz/programme/weekszCreate a week inside a modulec                 ó¸  — |j                  t        | j                  «      st        t        j
                  d¬«      ‚|j                  t        «      j                  t        j                  | j                  k(  t        j                  | j                  k(  «      j                  «       }|rt        t        j                  d¬«      ‚t        | j                  | j                  | j                  j                  «       ¬«      }|j                  |«       |j                  «        |j!                  |«       |j                  t        «      j#                  t%        t        j&                  «      j%                  t(        j*                  «      «      j                  t        j,                  |j,                  k(  «      j                  «       }t/        j0                  t3        |«      «      S )NrÂ   r.   z(Week index already exists in this modulerœ   )r³   r   r�   r   r   ru   rp   r   rs   rX   rt   r•   rY   r1   r–   r—   r½   rq   r	   r[   r   rM   r;   r(   rŠ   r^   )r‘   rk   rƒ   r¾   r«   s        r6   Úcreate_weekrÉ     s>  € ð �6‰6”/ 4§>¡>Ô2Ü¬×(AÑ(AÐJ\Ô]Ð]à
�‰”Óß	‰”×'Ñ'¨4¯>©>Ñ9¼=×;SÑ;SÐW[×WfÑWfÑ;fÓ	gß	‰‹ð ñ
 Ü¬×(@Ñ(@ÐIsÔtÐtÜ 4§>¡>¸d¿o¹oÐ]a×]oÑ]o×]uÑ]uÓ]wÔx€DØ‡F�Fˆ4„LØ‡I�I„KØ‡J�JˆtÔà
�‰”Óß	‰”œm×4Ñ4Ó5×BÑBÔCS×C_ÑC_Ó`Ó	aß	‰”× Ñ  D§G¡GÑ+Ó	,ß	‰‹ð	 	ô ×*Ñ*¬?¸4Ó+@ÓAÐAr?   z/programme/weeks/{week_id}zUpdate a week label or indexrŸ   c                 ó`  — |j                  t        | «      }|st        t        j                  d¬«      ‚|j
                  �|j
                  j                  «       |_        |j                  �|j                  |_        |j                  «        |j                  t        «      j                  t        t        j                  «      j                  t        j                  «      «      j                  t        j                   | k(  «      j#                  «       }t%        j&                  t)        |«      «      S ©NúWeek not foundr.   )r³   r   r   r   ru   rY   r1   rX   r—   rp   rq   r	   r[   r   rM   rs   r;   rt   r(   rŠ   r^   )rŸ   r‘   rk   rƒ   r«   s        r6   Úupdate_weekrÍ   .  sØ   € ð �6‰6”- Ó)€DÙÜ¬×(AÑ(AÐJZÔ[Ð[Ø×ÑÐ%Ø!×/Ñ/×5Ñ5Ó7ˆÔØ‡�Ð"ØŸ/™/ˆŒØ‡I�I„Kà
�‰”Óß	‰”œm×4Ñ4Ó5×BÑBÔCS×C_ÑC_Ó`Ó	aß	‰”× Ñ  GÑ+Ó	,ß	‰‹ð	 	ô ×*Ñ*¬?¸4Ó+@ÓAÐAr?   z1Delete a week (cascades sessions and assessments)c                 ó¢  — |j                  t        «      j                  t        t        j                  «      j                  t
        j                  «      «      j                  t        j                  | k(  «      j                  «       }|st        t        j                  d¬«      ‚|j                  |«       |j                  «        t        d¬«      S )NrÌ   r.   zWeek deletedr¶   )rp   r   rq   r	   r[   r   rM   rs   r;   rt   r   r   ru   r¸   r—   r   )rŸ   rk   rƒ   r«   s       r6   Údelete_weekrÏ   J  s�   € ð 	�‰”Óß	‰”œm×4Ñ4Ó5×BÑBÔCS×C_ÑC_Ó`Ó	aß	‰”× Ñ  GÑ+Ó	,ß	‰‹ð	 	ñ Ü¬×(AÑ(AÐJZÔ[Ð[Ø‡I�Iˆd„OØ‡I�I„KÜ˜>Ô*Ð*r?   z#/programme/weeks/{week_id}/sessionszList sessions for a weekc                 óÒ  — |j                  t        | «      st        t        j                  d¬«      ‚|j                  t        «      j                  t        t        j                  «      «      j                  t        j                  | k(  «      j                  t        j                  «      j                  «       }|D �cg c]   }t        j                   t#        |«      «      ‘Œ" c}S c c}w rË   )r³   r   r   r   ru   rp   r   rq   r	   rM   rs   rŸ   rˆ   rJ   r‰   r%   rŠ   rP   )rŸ   rk   rƒ   r[   r@   s        r6   Úlist_sessionsrÑ   e  sª   € ð �6‰6”- Ô)Ü¬×(AÑ(AÐJZÔ[Ð[à
�‰Ô!Ó"ß	‰”Ô.×:Ñ:Ó;Ó	<ß	‰Ô ×(Ñ(¨GÑ3Ó	4ß	‰Ô"×1Ñ1Ó	2ß	‰‹ð ñ PXÓXÉxÈ!Ô×.Ñ.Ô/AÀ!Ó/DÕEÈxÑXÐXùÒXs   Â<%C$z/programme/sessionszCreate a session inside a weekc                 ó”  — |j                  t        | j                  «      st        t        j
                  d¬«      ‚|j                  t        «      j                  t        j                  | j                  k(  t        j                  | j                  k(  «      j                  «       }|rt        t        j                  d¬«      ‚t        | j                  | j                  | j                  j                  «       | j                  ¬«      }|j                  |«       |j!                  «        |j#                  |«       |j                  t        «      j%                  t'        t        j(                  «      «      j                  t        j*                  |j*                  k(  «      j                  «       }t-        j.                  t1        |«      «      S )NrÌ   r.   z*Session number already exists in this weekrž   )r³   r   rŸ   r   r   ru   rp   r   rs   rJ   rt   r•   r=   r1   rK   r–   r—   r½   rq   r	   rM   r;   r%   rŠ   rP   )r‘   rk   rƒ   r¾   r®   s        r6   Úcreate_sessionrÓ   {  sB  € ð �6‰6”- §¡Ô.Ü¬×(AÑ(AÐJZÔ[Ð[à
�‰Ô!Ó"ß	‰Ô ×(Ñ(¨D¯L©LÑ8Ô:J×:YÑ:YÐ]a×]pÑ]pÑ:pÓ	qß	‰‹ð ñ
 Ü¬×(@Ñ(@ÐIuÔvÐvÜØ—‘Ø×*Ñ*Ø�j‰j×ÑÓ Ø×(Ñ(ô	€Dð ‡F�Fˆ4„LØ‡I�I„KØ‡J�JˆtÔà
�‰Ô!Ó"ß	‰”Ô.×:Ñ:Ó;Ó	<ß	‰Ô ×#Ñ# t§w¡wÑ.Ó	/ß	‰‹ð	 	ô ×-Ñ-Ô.@ÀÓ.FÓGÐGr?   z /programme/sessions/{session_id}z Update a session title or numberr    c                 ó`  — |j                  t        | «      }|st        t        j                  d¬«      ‚|j
                  �|j
                  j                  «       |_        |j                  �|j                  |_        |j                  �|j                  |_        |j                  «        |j                  t        «      j                  t        t        j                  «      «      j                  t        j                  | k(  «      j!                  «       }t#        j$                  t'        |«      «      S ©NúSession not foundr.   )r³   r   r   r   ru   r=   r1   rJ   rK   r—   rp   rq   r	   rM   rs   r;   rt   r%   rŠ   rP   )r    r‘   rk   rƒ   r®   s        r6   Úupdate_sessionr×   ¡  så   € ð �6‰6Ô" JÓ/€DÙÜ¬×(AÑ(AÐJ]Ô^Ð^Ø‡z�zÐØ—Z‘Z×%Ñ%Ó'ˆŒ
Ø×ÑÐ&Ø"×1Ñ1ˆÔØ×ÑÐ%Ø!×/Ñ/ˆÔØ‡I�I„Kà
�‰Ô!Ó"ß	‰”Ô.×:Ñ:Ó;Ó	<ß	‰Ô ×#Ñ# zÑ1Ó	2ß	‰‹ð	 	ô ×-Ñ-Ô.@ÀÓ.FÓGÐGr?   z'Delete a session (cascades assessments)c                 óh  — |j                  t        «      j                  t        t        j                  «      «      j                  t        j                  | k(  «      j                  «       }|st        t        j                  d¬«      ‚|j                  |«       |j                  «        t        d¬«      S )NrÖ   r.   zSession deletedr¶   )rp   r   rq   r	   rM   rs   r;   rt   r   r   ru   r¸   r—   r   )r    rk   rƒ   r®   s       r6   Údelete_sessionrÙ   ¿  s‚   € ð 	�‰Ô!Ó"ß	‰”Ô.×:Ñ:Ó;Ó	<ß	‰Ô ×#Ñ# zÑ1Ó	2ß	‰‹ð	 	ñ Ü¬×(AÑ(AÐJ]Ô^Ð^Ø‡I�Iˆd„OØ‡I�I„KÜÐ,Ô-Ð-r?   z,/programme/sessions/{session_id}/assessmentsz#List assessment tasks for a sessionc                 ó†  — |j                  t        | «      st        t        j                  d¬«      ‚|j                  t        «      j                  t        j                  | k(  «      j                  t        j                  «      j                  «       }|D �cg c]   }t        j                  t        |«      «      ‘Œ" c}S c c}w rÕ   )r³   r   r   r   ru   rp   r   rs   r    rˆ   r<   r‰   r   rŠ   r>   )r    rk   rƒ   rM   r8   s        r6   Úlist_assessmentsrÛ   Ú  s˜   € ð �6‰6Ô" JÔ/Ü¬×(AÑ(AÐJ]Ô^Ð^à
�‰Ô$Ó%ß	‰Ô#×.Ñ.°*Ñ<Ó	=ß	‰Ô%×0Ñ0Ó	1ß	‰‹ð	 ñ VaÓaÑU`ÐPQÔ"×1Ñ1Ô2GÈÓ2JÕKÐU`ÑaÐaùÒas   Â%B>z/programme/assessmentsz*Create an assessment task inside a sessionc                 ó˜  — |j                  t        | j                  «      st        t        j
                  d¬«      ‚|j                  t        «      j                  t        j                  | j                  k(  t        j                  | j                  k(  «      j                  «       }|rt        t        j                  d¬«      ‚t        | j                  | j                  j                  «       | j                  ¬«      }|j                  |«       |j                  «        |j!                  |«       t#        j$                  t'        |«      «      S )NrÖ   r.   z>Assessment with this sort_order already exists in this session)r    r=   r<   )r³   r   r    r   r   ru   rp   r   rs   r<   rt   r•   r=   r1   r–   r—   r½   r   rŠ   r>   )r‘   rk   rƒ   r¾   Ú
assessments        r6   Úcreate_assessmentrÞ   ï  sø   € ð �6‰6Ô" D§O¡OÔ4Ü¬×(AÑ(AÐJ]Ô^Ð^à
�‰Ô$Ó%ß	‰Ô#×.Ñ.°$·/±/ÑAÔCV×CaÑCaÐei×etÑetÑCtÓ	uß	‰‹ð ñ
 Ü¬×(@Ñ(@ð  JJô  Kð  	KÜ$Ø—?‘?Ø�j‰j×ÑÓ Ø—?‘?ô€Jð
 ‡F�Fˆ:ÔØ‡I�I„KØ‡J�JˆzÔÜ!×0Ñ0Ô1FÀzÓ1RÓSÐSr?   z&/programme/assessments/{assessment_id}z-Update an assessment task title or sort orderÚassessment_idc                 óv  — |j                  t        | «      }|st        t        j                  d¬«      ‚|j
                  �|j
                  j                  «       |_        |j                  �|j                  |_        |j                  «        |j                  |«       t        j                  t        |«      «      S )NúAssessment not foundr.   )r³   r   r   r   ru   r=   r1   r<   r—   r½   r   rŠ   r>   )rß   r‘   rk   rƒ   rÝ   s        r6   Úupdate_assessmentrâ     s�   € ð —‘Ô+¨]Ó;€JÙÜ¬×(AÑ(AÐJ`ÔaÐaØ‡z�zÐØŸ:™:×+Ñ+Ó-ˆ
ÔØ‡�Ð"Ø $§¡ˆ
ÔØ‡I�I„KØ‡J�JˆzÔÜ!×0Ñ0Ô1FÀzÓ1RÓSÐSr?   zDelete an assessment taskc                 óÂ   — |j                  t        | «      }|st        t        j                  d¬«      ‚|j                  |«       |j                  «        t        d¬«      S )Nrá   r.   zAssessment deletedr¶   )r³   r   r   r   ru   r¸   r—   r   )rß   rk   rƒ   rÝ   s       r6   Údelete_assessmenträ   %  sM   € ð —‘Ô+¨]Ó;€JÙÜ¬×(AÑ(AÐJ`ÔaÐaØ‡I�IˆjÔØ‡I�I„KÜÐ/Ô0Ð0r?   )WÚfastapir   r   r   r   r   Úsqlalchemy.ormr   r	   Úapp.databaser
   Úapp.dependenciesr   Ú
app.modelsr   Úapp.programme.models_programmer   r   r   r   r   r   r   r   r   Ú(app.programme.services.programme_servicer   Úapp.schemasr   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   r)   Úrouterr4   r7   Údictr>   rP   r^   rj   Úintrv   r   r³   r†   Úlistr�   r�   ÚpostÚHTTP_201_CREATEDr™   r±   Úputr´   r¸   r¹   r»   r¿   rÃ   rÅ   rÇ   rÉ   rÍ   rÏ   rÑ   rÓ   r×   rÙ   rÛ   rÞ   râ   rä   © r?   r6   Ú<module>rõ      s£	  ðß DÕ Dß 0å Ý 0Ý ÷
÷ 
õ 
õ Q÷÷ ÷ ÷ ÷ ñ ñ, 
Ð*Ð+Ô	,€ð[˜S 4™Zð [¨C°$©Jó [ðFÐ0ð F°Tó Fð	Ð*ð 	¨tó 	ð
�}ð 
¨ó 
ð˜ð ¨Tó ð ˜ð ¨Cð °Nó ð"�nð ¨ó ð, ‡�ØØ+Ø*ð ó ñ ˜dÐ0qÔrÙ˜&“/ÙÐ)Ó*ñPØ�‰:ðPàðPð òPóð
Pð ‡�ØØÐ)Ñ*Ø'ð ó ñ ˜&“/ÙÐ)Ó*ñOØðOàòOóð
Oð$ ‡�Ø"Ø$Ø*ð ó ñ ˜&“/ÙÐ)Ó*ñ?Øð?àð?ð ò?óð
?ð ‡�ØØ$Ø×'Ñ'Ø*ð	 ó ñ ˜&“/ÙÐ)Ó*ñ?Ø
%ð?àð?ð ò?óð?ð$ ‡�ØØ$Ø×'Ñ'Øeð	 ó ñ ˜&“/ÙÐ)Ó*ñf?Ø
)ðf?àðf?ð òf?óðf?ðR ‡�Ø"Ø$Ø@ð ó ñ ˜&“/ÙÐ)Ó*ñ	?Øð?à
%ð?ð 	ð?ð ò	?óð
?ð$ ‡�Ø"ØØWð ó ñ ˜&“/ÙÐ)Ó*ñ
,Øð
,àð
,ð ò
,óð

,ð" ‡�Ø*ØÐ*Ñ+Ø&ð ó ñ ˜&“/ÙÐ)Ó*ñVØðVàðVð òVóð
Vð, ‡�ØØ%Ø×'Ñ'Ø,ð	 ó ñ ˜&“/ÙÐ)Ó*ñ!EØ
&ð!Eàð!Eð ò!Eóð!EðH ‡�Ø$Ø%Ø7ð ó ñ ˜&“/ÙÐ)Ó*ñ	EØðEà
&ðEð 	ðEð ò	Eóð
Eð. ‡�Ø$ØØKð ó ñ ˜&“/ÙÐ)Ó*ñ-Øð-àð-ð ò-óð
-ð4 ‡�Ø*ØÐ(Ñ)Ø%ð ó ñ ˜&“/ÙÐ)Ó*ñPØðPàðPð òPóð
Pð" ‡�ØØ#Ø×'Ñ'Ø+ð	 ó ñ ˜&“/ÙÐ)Ó*ñBØ
$ðBàðBð òBóðBð6 ‡�Ø Ø#Ø*ð ó ñ ˜&“/ÙÐ)Ó*ñ	BØðBà
$ðBð 	ðBð ò	Bóð
Bð. ‡�Ø ØØ?ð ó ñ ˜&“/ÙÐ)Ó*ñ+Øð+àð+ð ò+óð
+ð, ‡�Ø)ØÐ+Ñ,Ø&ð ó ñ ˜&“/ÙÐ)Ó*ñYØðYàðYð òYóð
Yð" ‡�ØØ&Ø×'Ñ'Ø,ð	 ó ñ ˜&“/ÙÐ)Ó*ñHØ
'ðHàðHð òHóðHð@ ‡�Ø&Ø&Ø.ð ó ñ ˜&“/ÙÐ)Ó*ñ	HØðHà
'ðHð 	ðHð ò	Hóð
Hð2 ‡�Ø&ØØ5ð ó ñ ˜&“/ÙÐ)Ó*ñ.Øð.àð.ð ò.óð
.ð, ‡�Ø2ØÐ.Ñ/Ø1ð ó ñ ˜&“/ÙÐ)Ó*ñbØðbàðbð òbóð
bð  ‡�ØØ)Ø×'Ñ'Ø8ð	 ó ñ ˜&“/ÙÐ)Ó*ñTØ
*ðTàðTð òTóðTð2 ‡�Ø,Ø)Ø;ð ó ñ ˜&“/ÙÐ)Ó*ñ	TØðTà
*ðTð 	ðTð ò	Tóð
Tð$ ‡�Ø,ØØ'ð ó ñ ˜&“/ÙÐ)Ó*ñ
1Øð
1àð
1ð ò
1óñ

1r?   