11import datetime
2- from collections .abc import Sequence
32from uuid import UUID
43
54from fastapi import APIRouter , HTTPException
5+ from sqlalchemy .orm import selectinload
66from sqlmodel import col , select
77
88from backend .api .dependencies import UserDep
99from backend .api .dependencies .get_session import SQLSessionDep
10- from common .database .postgres_models import UserTemplate
10+ from common .database .postgres_models import TemplateQuestion , TemplateType , UserTemplate
1111from common .services .template_manager import TemplateManager
1212from common .settings import get_settings
1313from common .types import (
1414 CreateUserTemplateRequest ,
1515 PatchUserTemplateRequest ,
16+ Question ,
1617 TemplateMetadata ,
18+ TemplateResponse ,
1719)
1820
1921templates_router = APIRouter (tags = ["Templates" ])
@@ -34,45 +36,84 @@ def get_templates(user: UserDep) -> list[TemplateMetadata]: # noqa: ARG001
3436
3537
3638@templates_router .get ("/user-templates" )
37- async def get_user_templates (user : UserDep , session : SQLSessionDep ) -> Sequence [ UserTemplate ]:
38- return (
39+ async def get_user_templates (user : UserDep , session : SQLSessionDep ) -> list [ TemplateResponse ]:
40+ templates = (
3941 await session .exec (
4042 select (UserTemplate )
4143 .where (UserTemplate .user_id == user .id )
4244 .order_by (col (UserTemplate .updated_datetime ).desc ())
4345 )
4446 ).all ()
4547
48+ return [
49+ TemplateResponse (
50+ id = template .id ,
51+ updated_datetime = template .updated_datetime ,
52+ name = template .name ,
53+ content = template .content ,
54+ description = template .description ,
55+ type = template .type ,
56+ questions = None ,
57+ )
58+ for template in templates
59+ ]
60+
4661
4762@templates_router .get ("/user-templates/{template_id}" )
48- async def get_user_template (user : UserDep , session : SQLSessionDep , template_id : UUID ) -> UserTemplate :
63+ async def get_user_template (user : UserDep , session : SQLSessionDep , template_id : UUID ) -> TemplateResponse :
4964 template = (
50- await session .exec (select (UserTemplate ).where (UserTemplate .id == template_id , UserTemplate .user_id == user .id ))
65+ await session .exec (
66+ select (UserTemplate )
67+ .where (UserTemplate .id == template_id , UserTemplate .user_id == user .id )
68+ .options (selectinload (UserTemplate .questions ))
69+ )
5170 ).first ()
5271
5372 if not template :
5473 raise HTTPException (404 )
5574
56- return template
75+ return TemplateResponse (
76+ id = template .id ,
77+ name = template .name ,
78+ updated_datetime = template .updated_datetime ,
79+ content = template .content ,
80+ description = template .description ,
81+ type = template .type ,
82+ questions = None
83+ if template .type == TemplateType .DOCUMENT
84+ else [
85+ Question (id = question .id , title = question .title , description = question .description , position = question .position )
86+ for question in template .questions
87+ ],
88+ )
5789
5890
5991@templates_router .post ("/user-templates" )
60- async def create_user_template (
61- user : UserDep , session : SQLSessionDep , request : CreateUserTemplateRequest
62- ) -> UserTemplate :
92+ async def create_user_template (user : UserDep , session : SQLSessionDep , request : CreateUserTemplateRequest ):
6393 template = UserTemplate (
64- name = request .name , content = request .content , description = request .description , user_id = user .id
94+ name = request .name ,
95+ content = request .content ,
96+ description = request .description ,
97+ user_id = user .id ,
98+ type = request .type ,
99+ questions = [
100+ TemplateQuestion (
101+ position = question .position ,
102+ title = question .title ,
103+ description = question .description ,
104+ ) # type: ignore # noqa: PGH003
105+ for question in (request .questions or [])
106+ ],
65107 )
108+
66109 session .add (template )
67110 await session .commit ()
68- await session .refresh (template )
69- return template
70111
71112
72113@templates_router .patch ("/user-templates/{template_id}" )
73114async def edit_user_template (
74115 user : UserDep , session : SQLSessionDep , template_id : UUID , request : PatchUserTemplateRequest
75- ) -> UserTemplate :
116+ ) -> TemplateResponse :
76117 template = (
77118 await session .exec (select (UserTemplate ).where (UserTemplate .id == template_id , UserTemplate .user_id == user .id ))
78119 ).first ()
@@ -86,12 +127,44 @@ async def edit_user_template(
86127 template .content = request .content
87128 if request .description is not None :
88129 template .description = request .description
130+ if request .questions is not None :
131+ questions = list (
132+ (await session .exec (select (TemplateQuestion ).where (TemplateQuestion .user_template_id == template_id ))).all ()
133+ )
134+ for question in request .questions :
135+ if isinstance (question , Question ):
136+ existing_idx = next ((i for i , q in enumerate (questions ) if q .id == question .id ), None )
137+ if existing_idx :
138+ existing = questions .pop (existing_idx )
139+ existing .title = question .title
140+ existing .description = question .description
141+ existing .position = question .position
142+ continue
143+
144+ session .add (
145+ TemplateQuestion (
146+ user_template_id = template_id ,
147+ position = question .position ,
148+ title = question .title ,
149+ description = question .description ,
150+ )
151+ )
152+ for remaining_question in questions :
153+ await session .delete (remaining_question )
89154
90155 template .updated_datetime = datetime .datetime .now (tz = datetime .UTC )
91156
92157 await session .commit ()
93158
94- return template
159+ return TemplateResponse (
160+ id = template .id ,
161+ name = template .name ,
162+ updated_datetime = template .updated_datetime ,
163+ content = template .content ,
164+ description = template .description ,
165+ type = template .type ,
166+ questions = None ,
167+ )
95168
96169
97170@templates_router .delete ("/user-templates/{template_id}" )
@@ -108,20 +181,44 @@ async def delete_user_template(user: UserDep, session: SQLSessionDep, template_i
108181
109182
110183@templates_router .post ("/user-templates/{template_id}/duplicate" )
111- async def duplicate_user_template (user : UserDep , session : SQLSessionDep , template_id : UUID ) -> UserTemplate :
112- template = (
113- await session .exec (select (UserTemplate ).where (UserTemplate .id == template_id , UserTemplate .user_id == user .id ))
184+ async def duplicate_user_template (user : UserDep , session : SQLSessionDep , template_id : UUID ) -> TemplateResponse :
185+ original_template = (
186+ await session .exec (
187+ select (UserTemplate )
188+ .where (UserTemplate .id == template_id , UserTemplate .user_id == user .id )
189+ .options (selectinload (UserTemplate .questions ))
190+ )
114191 ).first ()
115192
116- if not template :
193+ if not original_template :
117194 raise HTTPException (404 )
118195
119- new_template = UserTemplate (
120- user_id = user .id , name = template .name + " (Copy)" , description = template .description , content = template .content
196+ template = UserTemplate (
197+ user_id = user .id ,
198+ name = original_template .name + " (Copy)" ,
199+ description = original_template .description ,
200+ content = original_template .content ,
201+ type = original_template .type ,
202+ questions = [
203+ TemplateQuestion (
204+ position = question .position ,
205+ title = question .title ,
206+ description = question .description ,
207+ ) # type: ignore # noqa: PGH003
208+ for question in original_template .questions
209+ ],
121210 )
122211
123- session .add (new_template )
212+ session .add (template )
124213 await session .commit ()
125- await session .refresh (new_template )
214+ await session .refresh (template )
126215
127- return new_template
216+ return TemplateResponse (
217+ id = template .id ,
218+ updated_datetime = template .updated_datetime ,
219+ name = template .name ,
220+ content = template .content ,
221+ description = template .description ,
222+ type = template .type ,
223+ questions = None ,
224+ )
0 commit comments