From 8996f5b43288ef2a467376946f97b3128e3e797b Mon Sep 17 00:00:00 2001 From: Hyungi Ahn Date: Sat, 25 Oct 2025 14:01:44 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EB=AA=A8=EB=93=A0=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=EC=97=90=EC=84=9C=20=EC=B5=9C=EC=8B=A0=EC=88=9C=20?= =?UTF-8?q?=EC=A0=95=EB=A0=AC=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ๐Ÿ“… Sorting Order Improvements: - ๋ชจ๋“  ์ด์Šˆ ๋ชฉ๋ก์—์„œ ์ตœ์‹  ํ•ญ๋ชฉ์ด ์œ„๋กœ ์˜ค๋„๋ก ์ •๋ ฌ ์ˆœ์„œ ํ†ต์ผ - report_date ๊ธฐ์ค€ ๋‚ด๋ฆผ์ฐจ์ˆœ(DESC) ์ •๋ ฌ๋กœ ์ผ๊ด€์„ฑ ํ™•๋ณด ๐Ÿ”ง Backend API Updates: - GET /api/issues/: order_by(Issue.report_date.desc()) ์ถ”๊ฐ€ - GET /api/issues/admin/all: order_by(Issue.report_date.desc()) ์ถ”๊ฐ€ - GET /api/reports/issues: order_by(Issue.report_date.desc()) ๋ณ€๊ฒฝ ๐ŸŽจ Frontend Sorting Updates: - issues-inbox.html: created_at โ†’ report_date ๊ธฐ์ค€ ์ •๋ ฌ - issues-management.html: created_at โ†’ report_date ๊ธฐ์ค€ ์ •๋ ฌ - issues-archive.html: updated_at/created_at โ†’ report_date ๊ธฐ์ค€ ์ •๋ ฌ - ํ๊ธฐํ•จ 'completed' ์ •๋ ฌ: disposed_at ์šฐ์„ , ์—†์œผ๋ฉด report_date ์‚ฌ์šฉ ๐Ÿ“‹ Consistency Improvements: - ์ˆ˜์‹ ํ•จ, ๊ด€๋ฆฌํ•จ, ํ๊ธฐํ•จ ๋ชจ๋“  ํŽ˜์ด์ง€์—์„œ ๋™์ผํ•œ ์ •๋ ฌ ๊ธฐ์ค€ ์ ์šฉ - ๋ฐฑ์—”๋“œ API์™€ ํ”„๋ก ํŠธ์—”๋“œ ์ •๋ ฌ ๋กœ์ง ์ผ์น˜ - ์‚ฌ์šฉ์ž ๊ฒฝํ—˜ ํ–ฅ์ƒ: ์ตœ์‹  ์ด์Šˆ๋ฅผ ๋จผ์ € ํ™•์ธ ๊ฐ€๋Šฅ ๐Ÿš€ User Experience: - ์ตœ์‹  ๋ถ€์ ํ•ฉ ์‚ฌํ•ญ์„ ์ฆ‰์‹œ ํ™•์ธ ๊ฐ€๋Šฅ - ์‹œ๊ฐ„์ˆœ ์ •๋ ฌ๋กœ ์—…๋ฌด ์šฐ์„ ์ˆœ์œ„ ํŒŒ์•… ์šฉ์ด - ์ผ๊ด€๋œ ์ •๋ ฌ ์ˆœ์„œ๋กœ ์‚ฌ์šฉ์ž ํ˜ผ๋ž€ ๋ฐฉ์ง€ Expected Result: โœ… ๋ชจ๋“  ์ด์Šˆ ๋ชฉ๋ก์—์„œ ์ตœ์‹  ํ•ญ๋ชฉ์ด ๋งจ ์œ„์— ํ‘œ์‹œ โœ… ๋ฐฑ์—”๋“œ API์™€ ํ”„๋ก ํŠธ์—”๋“œ ์ •๋ ฌ ๋กœ์ง ์ผ์น˜ โœ… ์ˆ˜์‹ ํ•จ/๊ด€๋ฆฌํ•จ/ํ๊ธฐํ•จ ์ •๋ ฌ ์ˆœ์„œ ํ†ต์ผ โœ… ์‚ฌ์šฉ์ž๊ฐ€ ์ตœ์‹  ์ด์Šˆ๋ฅผ ์šฐ์„ ์ ์œผ๋กœ ํ™•์ธ ๊ฐ€๋Šฅ --- .../routers/__pycache__/inbox.cpython-311.pyc | Bin 17900 -> 18454 bytes .../__pycache__/issues.cpython-311.pyc | Bin 9842 -> 10718 bytes .../__pycache__/reports.cpython-311.pyc | Bin 6792 -> 6846 bytes backend/routers/issues.py | 6 ++++-- backend/routers/reports.py | 2 +- frontend/issues-archive.html | 8 ++++---- frontend/issues-inbox.html | 6 +++--- frontend/issues-management.html | 6 +++--- 8 files changed, 15 insertions(+), 13 deletions(-) diff --git a/backend/routers/__pycache__/inbox.cpython-311.pyc b/backend/routers/__pycache__/inbox.cpython-311.pyc index 0794dd77dc8065dad9a5e34b10db5c25ef3cbd88..2d394061798d694a14fe18ea21a3505af46401a3 100644 GIT binary patch delta 5892 zcmds5eQaA-6@Smah&hCN!_MP)2&_CrleU1tnJoz>$sDloIsqkf1Ew|Mw$5S%21BPmZ4L`FcN< zsC%+`s%2jbk!+GmXa%htCrh3SHc5H~en#0BR>O;}ylpVJf>x<6HP~RbNK4-0u3*GL ztEq3v&%>myt7a*1!49V2XB5#Mq#;^M>z3*-IH1kJe{3JvAkzlbtw!>eX`>pUP4H`0 zt7(g>9Il|@Q}P8c^NMLq+Sdk-wWDJ;+R9(I-xiI4LYo@0lw7pEOsONU)L|)gsN4YIqfu1qLif!1D0D@cLU&%F4;9+X&JNmN*15;*Tu)bC zAP^V$8HH9uoNa0&&ytR{_Oi&DMim+>Gulh5cS+Gz%g;Mjl2DXn{9{Mdv4`U`iE%Za z7#mYHjsH|WO~U+cC05Z2!)0ufDhn?^rX07C4z9SPm0c*cCnhJOPQJ+nlwTys6^@J$0lW$8ph$1?99WUdI;Qs06D z5XaBY`?}X;JV{NPRke6Bb!d9-eGYa$>IJRqPrPvbsl^YUyBN8?c=m%I{wVUn51#(; zxrOU5zQ%v=>*l}k#kkM^jDl;PoH7CiP{NHb;*DSR#xJ|#*F4^5w>`P- zxjmA5! zZ3mdHgaC`ef7=k_l|3G>ZkDfD0YuPt>RwRNj{NCF%qr=8rK>KWz^V0`R!{sI zYdqT!Y|o{apA|OK%A8cqBW!Oz)ivt4{<)GriNYj6Z6BgfX}a><0BYsM5T5BUt%4a_ zz7;x>Ru;u1y@l98z5G&3C}AmB-Z~3a0bDB}ELJaQvx0i!P+_ew+_`z*3)m@qTSKc0 zoAZgZ&_IFo=KgkAqk~s@z90{u*vl6iTjg!$*f#3pZ!|TLn?-;(HM={(n1#P-nXLzJ zt;B!aIW9qaEx#ukhSw^BqJ_nDbU z_)B4d%lvn}z10C2)~8?Q6Xawhdd4WCN1hk!(V;8Obo; z+B!W(!+dyQ}fh>q`>T$u<8s7Ekr-;bANID(cTP_lB+F}ZLG(93Em#7>Y~ z@K7=gT-N|S;&tZ8U=A-YqOe0SlyxDWA+!>%rsZBXBAmzIHVRmfe=8ny0>C@ZNfc4s zLItQ-;}HA{y#d9ScAb-67u>K0OWXOPy;j@+!)Ts=+#8tp7tS@GI>2Vl zi*|6;!lJaCZ!L^gk+g8iR@91?yJQpOu9o?P0=qzBHX4AW1D_ri6o9*0{%UmOKf;~7 z;!%LR<15nCKsShXreb=M#x*^m&uW>96hMK&3z*4NQdQHFsf3=KPJLnoD=aNw!#;C=4Km*hjS8W6L{o|@0PuAe$Bz`2R>C@~H_7&*S z$j1lXhxy&JCgdRfe0=D$r9Kv?xQskDJ)6?=X)NQwxEo0doy*vhsW^Ka-FyNFgv9bI zQ-!aEWNJJvY-D78nkF7$Uqvmi`Gkn`)$2MVVoig>XM9MB1qH8@V;Xx2y02Z<*X<|Z z_LW;dwhu%=vi(teEEZ$<{UNFtaTVDYlX0fXe8$96i7D`v|Ks)t=5Yz5%_VOpW5K=w zO-5F?=3%^#R$_z5$E%R*LNb6vWN>j+_!3sFp_y321j@wYNo;VD_~#FTFyr1jH>S?u zX%jmjV~6)z)MX52#m(?>4fa=PuOy!(!K2#NC5n}0Q5&!%T#4Yio~N;adiDbNC+G~<1#7|rbS=m9LR z&hRr>#sN=0UA)&A-Xj>EHnFF~5{VICme^X9;&T4Yb^Fvbot;$gVBd!-VyLzNn>1_Z z@!@~gye$n~F8<>Ow)}~|wI#6Ay`2yxD(APexmLR(D+{?I1?sX+!MY^3FI&*t z(D|cXvUOf19a)>`bkN2JMjFuY4tGKrMk)*=b1m4Nm4)0eELg*^V5K}o!yQ*id)6jo wqkQ#9BibExuSb7@2&?e_TChJWqtLL4oM93<>?lay9!lnxzcsRzI52+y0%fjAYybcN delta 5058 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 rkFDir7RI z&iTG`zdbW^XMW%JLyPjUEW0@v8`}Qtd{p|Sve(86Ntm6s1=z2|O#op8+8In^>YX4Oseo1StAu_}8FSxRzLu5o=%%)|9ZFVcR8VUTuBk%RPA9G#PvaEA5}FP?KqVasn*{|lTkI6)N*!J)8p)G@g@H@u&#xv zj|2P!#}H?F-wg#=M2ZZW4o)e&cy#3GwOvMV^<;3}L~va;SZ4(5vU0s4*H6k@C*-Z; z2eWd6Ava9QjT3U?xBjf$Y{<=%a?6C=l9gKxxpnCIDbY8ypW+|A?yilgiLTz-SWiz} z0OIk$_$`=^*4Q|1FGsk`gPclKTMw5Yrv<{L_-+tphsvMeF`{iYE+v3sWyq-ZlzkMk zTl0(_Sx_S^sHtC2<4DmZOjhUsk&~vN1^Ro^R1sDDLZ?ow3tXN z=2_xC?MT^ZMaprbfccjBf&9^3BRC*;VO}gfw&J+%|Fji6bp@#c*jeJhb6}OfHkKb5 z4m}(jni;(vdU)sjFYjLkE|kAMJTvlMD1YX5{)12Q*DoPS!Wqsu!&6deMk>A1bG7g0;5}Pb+F?jL zOrCSCnEqRMbDUN_AuB};X-mW`K+*Z6xc%OuthCdRcA75G z{%~`i;7vYLcO;{YOzuxq;-E*Ee=`OexbSK9?^`^)kR_R+U z8~{d3xA_uw?>-dwBg~eu2mUum6ML~J;n;)h3+#T;Vc``BPo~4g-}4I>xJt@Ngsm!B z56j{uwKdI9tJ?uWFz9Lsa+0d`Xh|(zAZ`e^^ce*kd=E)(puPi`X+3~U_ zZwF|!3L%bgh}|z+DRe^kUD_;rNY>(4lHxO_cpW*ue;}C?cjNYN?Z*!)#cpX7;TS?E z6UzhSRC;CkXXIcJS!8kmQ*PPh;XExWrhp_oO8=!JhP2!)z|_eV7Mm`N+?>m6iWuQK z3x4A{TfIT*OdB%Ku&QvF-K_{544@8RnZwyKNAd}COlQq8nl;A=*I9t(&l+T#X+vgX J`fhlf`~|BQ=cxby delta 1054 zcma))U2F_d6vyYzes*T>?sn}~chqjXAGVuzRjY`PZVDNl4>Cl@c&%(ykbtNaOc=PPH2DmEJ2_=Kgg;4b)oeSOhQwXRJ~%ddzkWYj2iLAavBK{&hk! zX56uM+Sq=BOH&vem&=(18Mhxs<#LcbQ7Fn1bHRIgHl$q}q zd8%_TmgnID55MH`XFNWn<#~O9*T3X5p79xZ-c;aC(9SCpW4t@3>)M{aEg7|U=bmmG zwJ|ZQxE{s%`I`W4sl_4c(Sx=j5nBm>H{ya10SUfH3bU4)!#1G{GuR}vLwh8y*zr?X zE{P|+yVw8z+UWR|f$H(0W8;@bpy&yTNe4XkDpgIG*XJUV4!x0dDPSixAGW$;&{96R zvIV!TIJ4UkZ}90COrO9#;P%!3{}&rae5aW*B96(~zD!>(yQO=ts*TxItuM2)=PfX( z@E>Gp0DnqqL!V7#cnLDmO1P!0Fj4`V)w>X5`Xa(&!ctfqJiwO0{a~*>O@ZamsC3vi zpxkW?C@(Dk7UV(^wgd)4v$5<+sDZV@_fWM&UL!cOkAC?eQty7pZ z*(@U^31wbWCPj56e6$GStO9E`MT$&^3yIiarDibkG%_=R-C?{84PmHGel{_=% H)DE*B1V#|l diff --git a/backend/routers/__pycache__/reports.cpython-311.pyc b/backend/routers/__pycache__/reports.cpython-311.pyc index 9303efd6f9b45a20ba2ad43ddd529583ad65a98f..aa0ab6d503172ca020cff9f2d3067a5eed54bebc 100644 GIT binary patch delta 169 zcmeA$-Dk?XoR^o20SN3P|76H)1xM}klUROq@1zeK@S(GN9XW?U7z`a?Kzm18J zXYvX`bGBP7DXGQDlkW?9as>l5`T=qA&dEkXm2%f*j4sI-U6e7oB4cuq*Ypan>2+Sq zOT3mBd9APTT5sMfw26r^Y;%FA6eDBY=5DbLMn#YTMR7o4B}0)Sh%FB!esS33=BJeA Oq}mnbY&MYyVFCcSmNAq7 delta 123 zcmdmI+F{DOoR^o20SHPap2-m1$h(i1v2XJkURTD+KY95l3-K#&PUlZyV&tBDM$mjR zr;sOC5Kyfj5ErkV93xaIbdgu@3a{REUZYFAMi+TauJD>{{w%bKi7|BZGEpf;#@NjV Y#X1<-K$?nTC;LlCF=lVhk_ce}0L^VACIA2c diff --git a/backend/routers/issues.py b/backend/routers/issues.py index f812072..45cee33 100644 --- a/backend/routers/issues.py +++ b/backend/routers/issues.py @@ -65,7 +65,8 @@ async def read_issues( if status: query = query.filter(Issue.status == status) - issues = query.offset(skip).limit(limit).all() + # ์ตœ์‹ ์ˆœ ์ •๋ ฌ (report_date ๊ธฐ์ค€) + issues = query.order_by(Issue.report_date.desc()).offset(skip).limit(limit).all() return issues @router.get("/admin/all", response_model=List[schemas.Issue]) @@ -93,7 +94,8 @@ async def read_all_issues_admin( if status: query = query.filter(Issue.status == status) - issues = query.offset(skip).limit(limit).all() + # ์ตœ์‹ ์ˆœ ์ •๋ ฌ (report_date ๊ธฐ์ค€) + issues = query.order_by(Issue.report_date.desc()).offset(skip).limit(limit).all() return issues @router.get("/{issue_id}", response_model=schemas.Issue) diff --git a/backend/routers/reports.py b/backend/routers/reports.py index 5bf90f9..e3dbad5 100644 --- a/backend/routers/reports.py +++ b/backend/routers/reports.py @@ -92,7 +92,7 @@ async def get_report_issues( if current_user.role == UserRole.user: query = query.filter(Issue.reporter_id == current_user.id) - issues = query.order_by(Issue.report_date).all() + issues = query.order_by(Issue.report_date.desc()).all() return [{ "id": issue.id, diff --git a/frontend/issues-archive.html b/frontend/issues-archive.html index 6cdd746..e070e84 100644 --- a/frontend/issues-archive.html +++ b/frontend/issues-archive.html @@ -395,15 +395,15 @@ filteredIssues.sort((a, b) => { switch (sortOrder) { case 'newest': - return new Date(b.updated_at || b.created_at) - new Date(a.updated_at || a.created_at); + return new Date(b.report_date) - new Date(a.report_date); case 'oldest': - return new Date(a.updated_at || a.created_at) - new Date(b.updated_at || b.created_at); + return new Date(a.report_date) - new Date(b.report_date); case 'completed': - return new Date(b.updated_at || b.created_at) - new Date(a.updated_at || a.created_at); + return new Date(b.disposed_at || b.report_date) - new Date(a.disposed_at || a.report_date); case 'category': return (a.category || '').localeCompare(b.category || ''); default: - return new Date(b.updated_at || b.created_at) - new Date(a.updated_at || a.created_at); + return new Date(b.report_date) - new Date(a.report_date); } }); } diff --git a/frontend/issues-inbox.html b/frontend/issues-inbox.html index e4ba2b0..18f2e09 100644 --- a/frontend/issues-inbox.html +++ b/frontend/issues-inbox.html @@ -703,14 +703,14 @@ filteredIssues.sort((a, b) => { switch (sortOrder) { case 'newest': - return new Date(b.created_at) - new Date(a.created_at); + return new Date(b.report_date) - new Date(a.report_date); case 'oldest': - return new Date(a.created_at) - new Date(b.created_at); + return new Date(a.report_date) - new Date(b.report_date); case 'priority': const priorityOrder = { 'high': 3, 'medium': 2, 'low': 1 }; return (priorityOrder[b.priority] || 1) - (priorityOrder[a.priority] || 1); default: - return new Date(b.created_at) - new Date(a.created_at); + return new Date(b.report_date) - new Date(a.report_date); } }); } diff --git a/frontend/issues-management.html b/frontend/issues-management.html index e612071..6071939 100644 --- a/frontend/issues-management.html +++ b/frontend/issues-management.html @@ -406,14 +406,14 @@ const priorityOrder = { 'high': 3, 'medium': 2, 'low': 1 }; return (priorityOrder[b.priority] || 1) - (priorityOrder[a.priority] || 1); case 'newest': - return new Date(b.created_at) - new Date(a.created_at); + return new Date(b.report_date) - new Date(a.report_date); case 'oldest': - return new Date(a.created_at) - new Date(b.created_at); + return new Date(a.report_date) - new Date(b.report_date); case 'status': const statusOrder = { 'new': 4, 'processing': 3, 'pending': 2, 'completed': 1 }; return (statusOrder[b.status] || 0) - (statusOrder[a.status] || 0); default: - return new Date(b.created_at) - new Date(a.created_at); + return new Date(b.report_date) - new Date(a.report_date); } }); }