From 7cad6cc8c4b3115e8c9a1066c9d1f2823d6863b7 Mon Sep 17 00:00:00 2001 From: Cizz22 Date: Mon, 26 Jan 2026 16:47:59 +0700 Subject: [PATCH] add validation --- src/__pycache__/__init__.cpython-311.pyc | Bin 143 -> 155 bytes src/__pycache__/api.cpython-311.pyc | Bin 5606 -> 5618 bytes src/__pycache__/config.cpython-311.pyc | Bin 4753 -> 4765 bytes src/__pycache__/enums.cpython-311.pyc | Bin 1065 -> 1077 bytes src/__pycache__/exceptions.cpython-311.pyc | Bin 7492 -> 7504 bytes src/__pycache__/logging.cpython-311.pyc | Bin 1585 -> 1597 bytes src/__pycache__/main.cpython-311.pyc | Bin 5301 -> 5458 bytes src/__pycache__/models.cpython-311.pyc | Bin 5626 -> 7210 bytes src/__pycache__/rate_limiter.cpython-311.pyc | Bin 335 -> 347 bytes src/acquisition_cost/router.py | 18 +++++++------- src/acquisition_cost/schema.py | 15 +++++++++++- src/auth/__pycache__/__init__.cpython-311.pyc | Bin 148 -> 160 bytes src/auth/__pycache__/model.cpython-311.pyc | Bin 535 -> 547 bytes src/auth/__pycache__/service.cpython-311.pyc | Bin 3809 -> 3821 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 152 -> 164 bytes src/database/__pycache__/core.cpython-311.pyc | Bin 8688 -> 8700 bytes .../__pycache__/service.cpython-311.pyc | Bin 6538 -> 6550 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 153 -> 165 bytes .../__pycache__/model.cpython-311.pyc | Bin 5772 -> 5784 bytes .../__pycache__/router.cpython-311.pyc | Bin 11691 -> 12638 bytes .../__pycache__/schema.cpython-311.pyc | Bin 14057 -> 14969 bytes .../__pycache__/service.cpython-311.pyc | Bin 27937 -> 30107 bytes src/equipment/router.py | 18 +++++++------- src/equipment/schema.py | 15 +++++++++++- .../__pycache__/__init__.cpython-311.pyc | Bin 160 -> 172 bytes .../__pycache__/model.cpython-311.pyc | Bin 2597 -> 2609 bytes .../__pycache__/router.cpython-311.pyc | Bin 2565 -> 2448 bytes .../__pycache__/schema.cpython-311.pyc | Bin 3298 -> 3767 bytes .../__pycache__/service.cpython-311.pyc | Bin 2918 -> 2930 bytes src/equipment_master/router.py | 12 ++++------ src/equipment_master/schema.py | 8 ++++++- src/manpower_cost/router.py | 11 ++++----- src/manpower_cost/schema.py | 7 +++++- src/manpower_master/router.py | 11 ++++----- src/manpower_master/schema.py | 6 ++++- .../__pycache__/__init__.cpython-311.pyc | Bin 154 -> 166 bytes .../__pycache__/model.cpython-311.pyc | Bin 1086 -> 1098 bytes .../__pycache__/router.cpython-311.pyc | Bin 6338 -> 6400 bytes .../__pycache__/schema.cpython-311.pyc | Bin 3658 -> 4232 bytes .../__pycache__/service.cpython-311.pyc | Bin 14413 -> 14425 bytes src/masterdata/router.py | 11 +++++---- src/masterdata/schema.py | 14 ++++++++++- src/masterdata_simulations/router.py | 13 +++++------ src/masterdata_simulations/schema.py | 15 +++++++++++- src/models.py | 22 +++++++++++++++++- .../__pycache__/config.cpython-311.pyc | Bin 1365 -> 2358 bytes .../equipment/__pycache__/Eac.cpython-311.pyc | Bin 15393 -> 15454 bytes .../__pycache__/Prediksi.cpython-311.pyc | Bin 48359 -> 48371 bytes .../insert_actual_data.cpython-311.pyc | Bin 51493 -> 51684 bytes .../equipment/__pycache__/run.cpython-311.pyc | Bin 2998 -> 3010 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 160 -> 172 bytes .../__pycache__/model.cpython-311.pyc | Bin 2635 -> 2647 bytes .../__pycache__/router.cpython-311.pyc | Bin 4670 -> 4682 bytes .../__pycache__/schema.cpython-311.pyc | Bin 7964 -> 7976 bytes .../__pycache__/service.cpython-311.pyc | Bin 3703 -> 3715 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 166 -> 178 bytes .../__pycache__/model.cpython-311.pyc | Bin 5383 -> 5395 bytes .../__pycache__/router.cpython-311.pyc | Bin 8177 -> 8286 bytes .../__pycache__/schema.cpython-311.pyc | Bin 11852 -> 11864 bytes .../__pycache__/service.cpython-311.pyc | Bin 14629 -> 14724 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 152 -> 164 bytes .../__pycache__/model.cpython-311.pyc | Bin 1764 -> 1776 bytes .../__pycache__/router.cpython-311.pyc | Bin 4586 -> 4598 bytes .../__pycache__/schema.cpython-311.pyc | Bin 3950 -> 4380 bytes .../__pycache__/service.cpython-311.pyc | Bin 3884 -> 3895 bytes 65 files changed, 139 insertions(+), 57 deletions(-) diff --git a/src/__pycache__/__init__.cpython-311.pyc b/src/__pycache__/__init__.cpython-311.pyc index 426c2483b7abe0c04ad706bbaffb96541c02573f..e77fc34eab78f10577e5e8b33172b6cd8183cd84 100644 GIT binary patch delta 46 zcmeBYoXyC+oR^o20SL^Vl}+R}71z_x$j?pHPb?`))OSfOOU=nI$W6^Fndt2T03WRm AEC2ui delta 34 ocmbQu*w4tloR^o20SFG}@=WA5KO;XkRX?$$C{f=fwJbF!zaTd?uVnK@R#5=} DhZ+!K delta 37 rcmeyQ{Y;yCIWI340}#aSx8KOUo0VHuKO;XkRX;H^H-Gb8R#5=})hY{X diff --git a/src/__pycache__/config.cpython-311.pyc b/src/__pycache__/config.cpython-311.pyc index 75cf140eb8909cd0b7ab09711250958a841c3510..3b7dbb132bdc08fc557351d781fce4c718f91cfa 100644 GIT binary patch delta 49 zcmbQJI#-o@IWI340}z-!E8EDuh(%mSKO;XkRX?$$C{f=fwJbF!zaTd?uVnKMmYci) DV^a`3 delta 37 rcmbQMI#HE-IWI340}yDwNZ81|h=p50KO;XkRX;H^H-GaHmYci)yrc_T diff --git a/src/__pycache__/enums.cpython-311.pyc b/src/__pycache__/enums.cpython-311.pyc index 1c7f55dffce2941e40ae018e187ca20210650e2f..abe88c698f09e41f6a1b6e5df4a7bd9b6d0ddb5d 100644 GIT binary patch delta 49 zcmZ3pOK%Ns-IX=l&J5LT9%rVUyz%cSF$;qX&)m1 DR)!C3 delta 37 rcmdnWv66#(IWI340}vd{<=My`%ET?NpOK%Ns-Kvdo4>i7X&)m1unG!P diff --git a/src/__pycache__/exceptions.cpython-311.pyc b/src/__pycache__/exceptions.cpython-311.pyc index 7d640202233d987df0160c50a164d1772cc8afb0..ababe77ca7f67fcd6db37565e0195e0990c630f5 100644 GIT binary patch delta 49 zcmX?Nb-{{zIWI340}z-!E8EDO$SiK4pOK%Ns-IX=l&J5LT9%rVUyz%cSF*XB`K%-W Db%_v6 delta 37 rcmca$b;OE$IWI340}vd{<=M!c$jq&xpOK%Ns-Kvdo4>i4`K%-W#{CO4 diff --git a/src/__pycache__/logging.cpython-311.pyc b/src/__pycache__/logging.cpython-311.pyc index d73f73cf59a5cbb7ff7e24e344f4bc61018590e3..bf15d54830b941f2b2f3a08216cad1fb2726c01b 100644 GIT binary patch delta 49 zcmdnUvzLc^IWI340}z-!E8ECj$tbR?pOK%Ns-IX=l&J5LT9%rVUyz%cSF*XEaS;mu DU(64) delta 37 rcmdnXvyq2;IWI340}vd{<=Mzx$;hp!pOK%Ns-Kvdo4IJot9s%lrFgzV|Y_@q5n>D5>vj z*`?s?KnH#Gq4zP}V1$Lu@myLoAt3 z+BDYAz%;waF0oG5wG%13u@AK_nhL|9uFRao`tTpmO+ek6wTBv8?M|spR<~{le*%L)TnPFuM`Nb?_CafDADsS8g+Na=HRe2e#cjSlI)p0_3RLFs1 zSlm!%U=7T|Y7X+2{mm1jDckLh(veE9w_k3nBa2}15aM`Ln3TQjONXwZTW!o3rm5%Q zsl^BEUEeGnwSW4;?s=?DRl-f{Qio{csxWhCiZYr=B*I7S_x=m+1&kippZuz41ikp( zN^@XR3I&Qhlg#}cfp^=B!Oq|mcJLlFRoPfw=EV2V<%f*y2M?- E0k_V`d;kCd delta 815 zcmah{&1(};5Z||(&8JNbel+&Wq#A3I(xOQaG|h)Kwc6^jhecSHzG+O|?1qunoGdnZC-^`o$@ip}!8GbW17L-ul zcPDG#$6tn{Wb@tpBhry2AUk=12!Z7;k)#9EzGwx+uXHgu7^Ea3K@o1$h*m=E1eE9$ zou)H%ws*d(A`i7MS{X7>-nlu5^~}J7^8U)P&u8ShPI>><02=;7g2sCBu8d7l`$8l- zr&YiYtLFwO32xI1Vh1=*5Gs`PE{@h{Ynb;9SB%sqI-;0f8l`N@bbimH-N9M!{#$9t zp_fNbiY6hBHK{$%=xJ%||LqVsZcCGVQJGLTu;3nlp`^)z^GTVIogZq7OfMqIRjSZ> zEBzAuquHg0b{&?CTHWR)UxMWLwl7XH&U0T{In!r1p~WJ|WpQD0{Bv+Qat&QKuw|I0 zZo%UgOY^g#3d!;Zp(%9@v4Zm?v@1sijftyct7w`EnpiBxvOE-?RM#=uorPE*fkh1F&z_2yWyI(Wwt5k%x<@Uv8w_Rqp&QRBY(bb)3yl( s*1%A_<>o8gz@b72`6h*){{5WS5wENsdL>_!e?0Y@`1zO9&pe{ZA7gc(SO5S3 diff --git a/src/__pycache__/models.cpython-311.pyc b/src/__pycache__/models.cpython-311.pyc index a9da149f568aa7685f90372070048e5eee6d8a37..2fa68597da898fcd2e7a24fcf4de9f86eb529379 100644 GIT binary patch delta 3478 zcmai0O>7&-72YM6%l{w!P!eTP|FTV~lG?_Kg;+=&*%Fb)pi81!*){rg`xvs&QuPzV3#&rb{#HJ9Y#IfYZ4swj!@ z6jZn7kvy7L@@hWG$8;{$uLY!l7Lnb@7~oOLB^Tol^oNzUAb&ui&m-Qa95D zK^NL`fClb8O%KzAK@+Ld^fFBoXqrhk>DdyXAKZKW`k1x_w5>(rsT;1JDWjllBmH%{ z0j6sQT}MN|K?g@%N^FaVq2S&dYKZmdgdWF;hd9VkY+uDOr!F3Pb(~SVfEsTY_=MuT z!X>(&Vdn&IdlcCqMph#U!FDG}j?iqz7A|CU-wH#6!~!k^o{l)Fjv~m8TVgBCTut3o-e@LKY3#3$B;0N@Lh!O zA+Rwc@Ma5zLRPU|h^K5vR;jmq8tJFaZtr}}@@aF;`@8-#AWbDa^ncn8niqUs(K;{B zqOG&$9pBZOt+VFeeU}rjvr*S^20PA}ANu=i9cRpV2W)<`Mff9u7Nnn`2Wd0*? z9HQb1UK(cMNN(7Fsh*=GO zG-tcWEyyc7vYKBlsF0KC#kF)!)(FMFFU5Le2UqlbE=_Woyh5m67Xe$Wc}?E~>MY#) z`{pO1L4P&Uao1Ii#Vt>V`O8pmk;VNg=u-*ds23oiD6TV0lPE*L#nq<(N(a9kN5JLV z;TmBVWiMW%ptZmx%~RoD_>V-?{7bkqRu|0$92sH$e&lSe--0aGIqT}MKwLz` zl&f9Dtq3?_#&;>A;(k@oH4-hm%JRm$o5NOQv=SNJ zj*OPh-yN_7;EYy;(Q0SU#?U6ex%g1BIwvcgliQt>rBwNxB}_uA2$R*G!HvS^+~XFj zXQI+GvE4IKEWLO4)`s)m9ZQ&iRuLwueaAPWo5tfwt8c2(H?`e2ReHbNu`%!q?nZ=m^ov`l9gC;JC-~&leC0nMMzfLj+F^ac;0FoskDu3w~c@q zrzMO)s|X`IA}5A+9K362L)hWqaR|FkP_2K&l!wyV5eTD@ILS8Dk8ROdTZNpb0>+2M zR>U_q0{-hEtZRy#gA*3@po}FC+lGDm4OLb%*NL{acPK-B5FvyRHviZ>SY)TB&>?j! zPc_hMhAgo-ye$ltxf07mVv;P$6z+GlaIH*o$J4D`3yI;a&r1Ts7X6cp69>j z;?}oYm3zbbf33>-OYnR0x0VHdILO2Cpb^T6U6j5!RP~xt^!{WZ%tI&}p?qc+r7vEi HVv+qXM;;+v delta 1945 zcmZ`(O>7%Q6y6`(yY|{^J3o#c+llkn$_Y)16h(-JB%&!nLO4}^)OH1RHr`3IW`EMz zH7FO-LoRS4%%vwTNTI-?LOF4x5^%0KMSB8n{2WrzN+>7hjT72z+ufaSXWsYTn>X{` z%r~zckEvg!QVEVe5A38_jPI#={@&jCp&gzxI776eT9p1HR?L<($(A+Qj%#toMXiLb zXo{WGl6Fc<*{Y`6X)VpTn3b`!T9)-CtHbWpI_)m4i;ZQg+sPoJ)3worZrU#KBG)QqDqN}ZxJduhr(~cFy=D2PdY+C2Tp@o( znyEaHBF@nt?k9S5iti(Lqf305{1tU7DisGY%k+HYU}^?_#D?X0u*M4RBipf?RP``6 zsq}*fC?%|r9%*29h<1ad=j*=Nu#vy%8q7hUG%VfoP9(2@ehC1A#eD!QlpOg;`X$DM zIkG5!d9y;PAl7os+btBxPRp|Nbqm$1aeM)c#sMY(E&{MP(zF*uS}oHEqJWcuU>f1s zra*m)T#c{B*=#T-KL|PUWBl&m>vT}7$}gWHNj^@Lxz6PbNF1jSq?(@V)REJ04TQbW9tW{@VEApS`W9{8 z9Qj!tCQsDL4%_opDyvl^&rU!k7{no07|a=5p&f6U!kz!$BOwt@9C6RXBal6Q0fE~& z2d88!n@2EJRmWXy;|%aw3PHldjqwI6Ukq0o?j>p=x6=t+9602( zY_GkPn7iIY4ZnR)u;a@P96LO$JXki^=B<%jL>;%V=YyYTSk-yx^mVecXNtmZ>>m6N8pE2( diff --git a/src/__pycache__/rate_limiter.cpython-311.pyc b/src/__pycache__/rate_limiter.cpython-311.pyc index 75029b1f710337947d585bfe414201a482ed9190..edd79a50934be24789cf487b5aceefe9d8ea0382 100644 GIT binary patch delta 46 zcmX@lbeoBLIWI340}z-!E1Sr@Puxg9BR@A)Ke41JQQsxCEHx*;AU8FyWa5=-07o(p A`v3p{ delta 34 ocmcc3be@TOIWI340}vd{<(bI6k6TSYBR@A)KQS{mf8v8`0Hl@*;{X5v diff --git a/src/acquisition_cost/router.py b/src/acquisition_cost/router.py index 86e201d..3e9c4cb 100644 --- a/src/acquisition_cost/router.py +++ b/src/acquisition_cost/router.py @@ -1,14 +1,15 @@ -from typing import Optional -from fastapi import APIRouter, HTTPException, status, Query +from typing import Annotated, Optional +from fastapi import APIRouter, Depends, HTTPException, status, Query +from pydantic import ValidationError from src.acquisition_cost.model import AcquisitionData -from src.acquisition_cost.schema import AcquisitionCostDataPagination, AcquisitionCostDataRead, AcquisitionCostDataCreate, AcquisitionCostDataUpdate +from src.acquisition_cost.schema import AcquisitionCostDataPagination, AcquisitionCostDataRead, AcquisitionCostDataCreate, AcquisitionCostDataUpdate, ListQueryParams from src.acquisition_cost.service import get, get_all, create, update, delete from src.database.service import CommonParameters, search_filter_sort_paginate from src.database.core import DbSession from src.auth.service import CurrentUser -from src.models import StandardResponse +from src.models import CommonParams, StandardResponse router = APIRouter() @@ -17,14 +18,13 @@ router = APIRouter() async def get_yeardatas( db_session: DbSession, common: CommonParameters, - items_per_page: Optional[int] = Query(5), - search: Optional[str] = Query(None), + params: Annotated[ListQueryParams, Query()], ): - """Get all acquisition_cost_data pagination.""" + """Get all acquisition_cost_data pagination.""" get_acquisition_cost_data = await get_all( db_session=db_session, - items_per_page=items_per_page, - search=search, + items_per_page=params.items_per_page, + search=params.search, common=common, ) # return diff --git a/src/acquisition_cost/schema.py b/src/acquisition_cost/schema.py index 4c80f8a..ec995a3 100644 --- a/src/acquisition_cost/schema.py +++ b/src/acquisition_cost/schema.py @@ -3,7 +3,7 @@ from typing import List, Optional from uuid import UUID from pydantic import Field -from src.models import DefaultBase, Pagination +from src.models import CommonParams, DefaultBase, Pagination class AcquisitionCostDataBase(DefaultBase): @@ -31,3 +31,16 @@ class AcquisitionCostDataRead(AcquisitionCostDataBase): class AcquisitionCostDataPagination(Pagination): items: List[AcquisitionCostDataRead] = [] + + +class ListQueryParams(CommonParams): + items_per_page: Optional[int] = Field( + default=5, + ge=1, + le=1000, + description="Number of items per page" + ) + search: Optional[str] = Field( + default=None, + description="Search keyword" + ) \ No newline at end of file diff --git a/src/auth/__pycache__/__init__.cpython-311.pyc b/src/auth/__pycache__/__init__.cpython-311.pyc index e42b5d501a8fb9db5018a502a71ae35baf18f743..1f96561d3e1e1f7d5597419568cfc8486b1abfe2 100644 GIT binary patch delta 46 zcmbQjxPXy+IWI340}z-!E1Sq|DsHTwk)NBYpIB0qsPB?mmYS1akeixUGSS-;03r4c AKmY&$ delta 34 ocmZ3$IE9gWIWI340}vd{<(bHB%B`-Sk)NBYpO~4OKQY`B0E=1)C;$Ke diff --git a/src/auth/__pycache__/model.cpython-311.pyc b/src/auth/__pycache__/model.cpython-311.pyc index 628300a98685d725385f12350a82f596998e1b83..6ed8b4451d7d37f3c22ea1c5f810b104f73d0ba4 100644 GIT binary patch delta 48 zcmbQvvY3T?IWI340}z-!E8ED;&nRx7pOK%Ns-IX=l&J5LT9%rVUyz%cS29_Z@e=?x CBo4{| delta 36 qcmZ3?GM$BcIWI340}vd{<=M#1&&aK!pOK%Ns-Kvdn?Ko*@e=@<=n1j_ diff --git a/src/auth/__pycache__/service.cpython-311.pyc b/src/auth/__pycache__/service.cpython-311.pyc index daf1c8333770a8e7bec23a46b02343c1f8d32543..80b0e7beb6ac0adaf7181436f57d02409e3fc145 100644 GIT binary patch delta 49 zcmaDT`&O2FIWI340}z-!E8EDulS$l2KO;XkRX?$$C{f=fwJbF!zaTd?uVnLiCLtaG DfL{8=)$;7RupOK%Ns-Kvdo4@%slMoL8!paJ# diff --git a/src/database/__pycache__/__init__.cpython-311.pyc b/src/database/__pycache__/__init__.cpython-311.pyc index 72fb57c1819d074cdb374c36908e0aa65964ccf6..9e47e16c73f58e41e35ff41162e1984bb3983bf5 100644 GIT binary patch delta 46 zcmbQixP*~=IWI340}z-!E1Sq|DsHZyk)NBYpIB0qsPB?mmYS1akeixUGSS-?03*r{ APyhe` delta 34 ocmZ3&ID?UUIWI340}vd{<(bHB%B`)Rk)NBYpO~4OKQY`F0F0gqH~;_u diff --git a/src/database/__pycache__/core.cpython-311.pyc b/src/database/__pycache__/core.cpython-311.pyc index 565023f2bd6a085aa58ac1cf060bbbe61e97166e..27b7124b1a4855c68cf76f4ae0b5f076a930ff76 100644 GIT binary patch delta 49 zcmez1{KuJlIWI340}z-!E8EDO!6I&~pOK%Ns-IX=l&J5LT9%rVUyz%cSF*W|rAQV4 DiVqNS delta 37 rcmez4{K1)fIWI340}vd#;INT9gN0jNKO;XkRX;H^H-B>%OOY%9<9rM9 diff --git a/src/database/__pycache__/service.cpython-311.pyc b/src/database/__pycache__/service.cpython-311.pyc index 1744fccb026e4c13a755b3e11987f46de43cc0d1..460ed970bb0f1ba2226834abdf1c9b9b663b5c03 100644 GIT binary patch delta 49 zcmeA&o@UIwoR^o20SL^Vm2KpfWfeEm&&bbB)lV!bO4N5rElbVGFUU>JE7@$!8ZH6= DQ{)cO delta 37 rcmbPc+-1zYoR^o20SJumSa0N(W#!h=&&bbB)lbaK&EIU#8ZH6=uJZ}W diff --git a/src/equipment/__pycache__/__init__.cpython-311.pyc b/src/equipment/__pycache__/__init__.cpython-311.pyc index 419a16b9eea66fb130f3e40122f6129468859461..b02635a93704235fe424090f6fc18911c4d493d6 100644 GIT binary patch delta 46 zcmbQqxRjB5IWI340}z-!E1Sq|DsG{lk)NBYpIB0qsPB?mmYS1akeixUGSS-)03<&S AQ~&?~ delta 34 ocmZ3=IFpfkIWI340}vd{<(bHB%B`cHk)NBYpO~4OKQY`70F3VmJOBUy diff --git a/src/equipment/__pycache__/model.cpython-311.pyc b/src/equipment/__pycache__/model.cpython-311.pyc index 7b84e7eadfeddd9a9bf947b2f980ec3ac0a2ee1d..b3f5ccbfb9c483b4dee7e4fb0365ec7674283390 100644 GIT binary patch delta 49 zcmeCtouSLUoR^o20SL^Vm2Kqy!zym7pOK%Ns-IX=l&J5LT9%rVUyz%cSF%}%tx5m@ DZ59uv delta 37 rcmbQC+oQ|9oR^o20SF9=%{FrXVdd7;&&bbB)lbaK&EG7?RwV!cv-k=v diff --git a/src/equipment/__pycache__/router.cpython-311.pyc b/src/equipment/__pycache__/router.cpython-311.pyc index 5ba274eeb297784462188b9f38a11e21eb22c181..bf2c1d1fc47380543402fd00e1b7df0294d3ddef 100644 GIT binary patch delta 3998 zcmcf^TWlLyb!Kc&96L@Or|~0+6DM)fI8NfEX&&1)X+x9rvDr4=wyHF{U9aQ0X`S`h z&K(=3-jm*c>G#Wx-*dSf0z7yAay9jSc&pL>(zZXS6+6dU()F4{aqzu0?Npq=YfCq1F2$uaDvca3r?+kg znl-QD)qILi^DBOiu1jzIpleg>R=TwwrAG@ZVXar`3fq75hmeD6p{ zwLxW28&Zb&*_j^JVoFRKQAYT=Aw8v~g_0!PM!YCFRLV3+dn?iob)ZK2I7oMwq@y71M(J^s9^~~k zR3mXhwVo3q!+*k(idc;L*-R#zPvnWpF4{K4dbVxbj2W%RvV~0kMWQ8AnN;TTVrqrF zNc3DbqZ4D#VoJ}SEfBiCl%NSsk2J6gaw_1zO!Dz0ip6PJE}jNK_EUL#k7P6)%W7IS zW6H3v)%A@T4s|)M6J1YbGlrbxWJAtzrAbSv=5dkXeFNUVX4oUY-zTkBI$}dwm5>7; z)@JYAW69TRB6cOKkys*66R|mRm87$ri#h8@`wjzB6kdH5z#rk?E#dEO zp}l9PIk@8sZug`xx04#4o7IDdXAeqiK4 z{Pdag@r5%NPS0^$BNo%v8Dx?vNoJ|4W5B>VdWa1=NIHv0JLGXWl_4rc>vT*VSQQH00>eJ=%!+3p{@e4Gr4v6n)o#$2k(>MQ zD*ABG>$klEs1xjG-WP(?u)E$8GdeD z=ukyC#7pyqfPa(6UZO#`!;EfCCD{1Il>(rLfYs=JR=vk7bwihd@hZIfNdTp4a0t!O z2dlsI7ClRkJWJc2j-_J5)4yBuzjLIlQ}Ew-D79|9+baxZ7;ee-5rbwZ0jM*j9jghy5ggTIJS7 z=N06}w85>HTK(-Q*nSgU-37pm#I7vZ>Tk`_X|~mR&uoTOHq|yZQF0>$oKKWHwp4Xj zreO|MmHoZ8h)n~QZ?oUDff)~b+S^4Z@39POnqjAck*-VpsH0iAL?A?mRb#KCZQ3-k)#C2 zd3<@DwjmE13$uksf(zZ`k^qeQ${jlV%_ndpObgtmmMSA&2Zkd1b?7xP;$YW5Hjl!Y z<`D3hmYU`^B23d@cRer%lQUGv!2l&{NG~LlFz#0h>GZl8UOUCVpq>uzCg2Q5Necbo z@$LX@L@rN0m@ei$6>lis{dnNO6hSp^Q%#j4Zvpxb?4$0VLyi2nM;2RnWWIpR7EQlg z@`?Q_+%;!TJfOh6epsG1v=ebWzNLwbT1-10kK@r^ukA~K{})^A{mvxzMC7C)=ht)a zVWr4Mu|p{)z^Ge+YE0x(6z68uZS^eJ=bLdN@*MIt>ohrBN#3xQRY{sQAQ}71*!v_| zPhNp9GP~B-(MR_pQwstwa<)9hN$Ay7lCTf@`kN^CE`+RI2)fyaePOu=w-=aWUnhJ7 z2KKdX_9CJWfYF4y@Kd>*(8(~g6QTQ%*pEav5)*~|m0{hygGP`xfHVivxDPtTk0%c) zeAu!D=uE=`%|H($pH)pI^YkKeEFi!S#3moI6sH@V_0)pJx{TC4NI<& zr7Z333XY%H4}%4TG?}5_f};qp{zb^bu0<5Z9bvHejGq+N7!1lWhSsI*hIOw__DdKWQ)0tT__iE4g$iLk8xR${$?(KTr*FX z#p4otC)&v_MIFo=9Xe3VtpoK2pkX;Foh~n+;H0#K3UJ{p{In*XEi0HDDPGPM*KPvw is5Fl}xPahM={O4F0!RwF;dDhjAw7I2>X)oICH@0{gqw;0 delta 3250 zcmcImTWlj&8J-#2<4f#Ze2JaJiQ_nSGO^=q?qN6G3nbgXZg#t5sjAs_y|(8h@z!Iz zXKd(}g>2O#RH>ruo|R}N1iPpzR2B3gFZ2Oa5HCnPR4ho5A5dSo^r6BCA)rtE{~6o4 zA%T#XWd1q-<@;~vKPUNJ?wxC$-}iW20z97^UM*~l-0ciq8?_0-w**bl#G;^!s;En< zBqA>rExJ{;>NeG;%c`u~RXdkkiVoeWI{DgKbg3?|wG}&bx9ZkCs)x(vVyE7v-hHvp z$60%^R}ZQ|J*0;8KK1Soqa`kO6i4)!I?C71Vq8zC3BGm}$MkV^Tvt?u^Bu(rJ*g)3 zl$zqayEv(*)wDjPPI2B-JfTmk)1n{=#QGLg_YRiGA9aSzJeXxyM4wI2I>|J9-xe-{ znO*CCO9VrB&4|R)T+tO?REch6DuiY#*)39+4U(n#?Yy-; zh=L%)`XzY(s@3zt^R1TAKQOK2ohk}p%uz&arrI?pohnC&cZ%k1m!inzG@5BDWokUO**RZ^j| zpnE}bxfGEuv1h!g4%E?AB(vRQDgW0j%TACh z2dbk_qBSq=29yR&-D?!|S}|KC`!VTLpg7MO!F6$w{kU(Gc|8GE3N5lX2NTY>rRHw3 zC;HDMd7~wYR~B#O+s$Bnujksqcpu;GpRqj+q8j@{{|0zIIWTb0vqV+)%YlVR)8$~x zCB1goO(d+?u7l_fTMwg~hvAE7ZlLiZ60@c)Qr#~nQ>BE^ENEYa*YE%_ho~V7Hs_rc zy2w(456$t(u}6cmea#fY=x_{3tA#lh848Q@Y1kv!2<-x*c+Bpaeo$IKf}Nx{kvxl}h(t$H zLQ)1&_unkzJY@9j^Kfo5<`mQCKxKF)fb#KZ5wlI6Lv5l4Sbc|WM1KuUO^m#27E}cx z&9M(hBI5MDSZE=HJnu>KRC9wGw*pdkwkLQ0K*LO4iuKxF0R1mmA@(fz|84B=(US<; zMsf;>Vl^wjg@R_(k4Gap-Zcm9Me&iYeFM|IGe4_T3qrWo4xUcQ@Z!%oiF)h2bX zA1CPy&VZs6u0I_|9fld}169<#_{tkP<4hS)GwX{_j`b-W>w_~Wp1ZYDl7ct6-<*5C z^PPL|$=S_f_D@ax)akS{Fh2j|L?*iFvKU0yF1PG`IV+?E#K?Tw!7_Up*>aANt=K+i zVwmeNS4P@ta5muVHJoU00&tER&Sh{;;6&`aT=5@vf$7H1s`MTs%mbXaCWY7Fe8AP! z=zIp}2d*9qMg;`~Nj18^I#P_=ix!G(Zptl2wYaADv!Vq29iC^ro;vB)B= zPz>o-S<4y4_ynHFPiApWBOlqC-42LVDA2A_RTFWC zyRX>qm70VkiyS2D{ISkS(>W&cBa)WM=Y}b0|m&vwj(HCO1CEw*(huw-)$|U*T`JQe%8#A`_W*5WiThR zvT5Et$3pMJTp4K|Td=iZb;)3}%=N-4;tOjxusl}asM)}}HXb|Y zt9w-hh3las*{ct&(s-MX*u)v1ipse2?%N=mAR73CCEIQ6_@^vP+kmGzosJFQa8uf%9TD}^=+ zJcX?kEEEhmN3HD?0tB`1B(q&Xz6eY84Km!`usN~w3;gw-Tk(a&;O)fV-NfL6xo&2B zp{e_Beb0g!R)e?AgC)Hyicp!{@4kbskUKp)NKa2a+rdCbHXJuWtFg3%m|7-k$!548 zr*GJupUP5?En~7Vjw;M4Q**b3{DYm&_w5n`@ ziwnAIAfsvrrm%8q<=whSe}qK@kogtlPW0 zN>dY>&W>Tl3ld$Bu?ppxq%S93Gz7yS7^Z^MX>kZk%E)+Q>&kV}3TFy~24I;&@tO1cW`-_; z#zZv$!2N3(%azm7gQa2(#2w!!&^Nl$Nx?ym#=H1))Vx66jEC*CNoc**3*@W#p=9p@ z^T_Ydj^?7RVh*C66{Z$uo?D{cSyxkRJ{J delta 1118 zcmaKqTSydP6vyZ6Wp>B8?0wyfnwzV#>t%H_H&ZAHQ42M?fLJmu?wA|8YqLuaS#%*N zfdw7DCFlWGM|DyO(qUwKc$Lj3KP3fbkk* z3F9PY>bC0$Pqu=@ZLqLtWfsD$18NBB73(~w87t@)fE%w zDe!k{%uATBpwE@?AEZJh_!_o@4(+-&c%}5|ZUTO`x`3WG`0#`%C>s2jvbli4 zX~UeBZMQd(=!#Lq1$zU~=%FLn;%Ie7QY7Tb@q*^u-$>}p$ zIcE{Ycq*07#uzu@Eu%5kIVA#I+RjUSf<>=K$l zz_UUCDwSKpONLgfNIvbU1*Ba2?G}JN3OGH^yRJbVNNSi&tZfI3M#CT_z!@tr7eh>+h_8 zLv8Xba)I+q-r$ASJXI)@`&QKK>N;x1Ydb!LdDxYw3T1L|Ma{0RqcWUs2}e2TgFLml a-l$vA$m-v`3YS|#0tFDxt0G6qXZ!~A5el^c diff --git a/src/equipment/__pycache__/service.cpython-311.pyc b/src/equipment/__pycache__/service.cpython-311.pyc index c619640b67417f4fa759935de47760f5b27bcb5f..e36c7b96aa0c53a192b2b7fea45745b390ec2775 100644 GIT binary patch delta 3261 zcmbVO4NP0t6~6b`&wm&&*am|kHviZVX#U9B@*4srloG;EOCT+I;XM<~kHhs#+S2Dh z+Ns*2Nu|9_gS2QR)0Q!{(h|LG>NHiW+Et=!)Yy*GY@V{I)6y;KqB={mOzqU}-e(MT z;!WMI{l0h3x!*na-t*2o_nnTy?|uR^ew3bW0HoD@d}REc$rm$haN%5qfz4|anuI+b zCXeop-aR!?^e1J#;e4pU1dgE&3XU)G)gI)3yj)2-GmL)a;fCMGxb=4UL zfY%tzm00sk|E;$$OG?`b7U1LC0@+fwHzVOEV3snM%$T!V=geowVqPOxyagmjoEwN1|{J%RirN=_0b&afvja#Ju0k{GrWjKU;F9%T%!tt39p2B}agm?bG4a7g*Q zL9)-X0MJX?AmvLAMI*hlgdK27S!knVLRFIUm`mKKI8Z=xif$Zw(AJD{#M*VU*Orha zXY#a&;nM<6aZ93~Oqb0YB`4lgZnke1*Rlfuaoak_YsVwyze_7fSom}dD=bW)2)C5v z!6JOF*v=M9#Y=^Fle46?MA9Lxr1Ne_&`A=(KDv15jVO{D^W3 zHtr5KK6YuJCph-hrP;X~06Y#`m|O81>A4L+JJU%G?Mx3717HtxfFZ1QW;AXbWe5uo zZoZCxzU2md1}|?Ng!MAqR>Z)4a>;gvfunNy{YO-3QN8c5C?KzId>Wswe}(-GS+5t@ zHx$~kkLR6e`r)ofY2BN(kq3IirM)42Uqs(0&oq3hhVNo-$A0)8etSn7`ym-KhrjHY zl%Hy~!75repCi}JqiO&i1`wPCB2g2~n-IVf#51PielICH@fKi2Z9*m~p<9=|Bva!} zVrUlga6+;CCl1bNwsizlVtQg2ahJI+d)HilbwWwSt0t73kdXQHq zr}o!$M?yf7Ud6K$%Ivem{k_gRdCmXfoQ;RzUUxaXHrZXg$l{so4UDM6=XU1d?-%8y zuf4T2)Hti%!iY9{!?|r%+}v)pr4BBy!>8M=xT4uwokUm*FRz}tXO|`l7`o=AHSs5!Q{=} z#nt=|Ty;uryp)sYraz@3C$VAH-Re6$Ejp1f#f?voPmeh#$324c0OuEYr*GOR9u%CT zoG6U>(9?+KHabtiP9Um60)LHWZdBt#-1L|bWyg>pOn19fQMI4*2&kWS>PFGHI6lfv zx-95|QbK~%g;Hf`N+TI(_K7}p{9txPk zZVEjFqAK6CfF2~0ON;hX>w6R~QTTwo+5r86ibDj*27FKY=}Wr$m4P->t8GjWM@DH> zM%JP-LZgEIM7qC6lHUIrfxnX9Jh*DMN6e*{&6QzuWytJ~(0}cG*HvrY)%2W5dc|^e zD825DO<`mG6-A#@3^7)vH^g)x(-ce7yCTM}8(OvAa0?K) zV*m#0ar=qAA-yA_ci{Y81uzr8ziX=@W(KSwW&@TDc<=os9)szH+T*n$gFRxfUp6?x z21m$H6fqRdx8Bx(EXzXcqW0ykprvf7C1fg(n98r1a~AxI-*`C?%ylipcyzB=au-#L zZKn*2nM+*AQW>#S#eyQPE_rI`0)_Rw3sF@`J|*wM z_+&?+=^{1KHy>FjMDVXW>exRM@mKPf9asfF#<=Sz?B9stkMcv0h){cth~4Nf`0Z}D z<~kj64gbCS0rn;lugRNs&p`4}73*@3gZ(EFIr)6g=Q{W^yt20~F~U4l5C4ICh8l}M zr{otX+#wKEAK{Qc%8rY|lpoRW2Xqsk9kQsT5&r`>N18Km`1mx4=g2F>nv=$2AjQR6C&NtSbh{ZAHD( V7wjEa89bk%=y$^oh^r@W{~K!`@!J3Z delta 1664 zcmaJjcCIAMZ1BymyW#}<{v%xE-=@9D?3YU63oljnWT zbKY~_bKg@}$;(S5@73H~1Bav2urvJU!DsVqWb6&UK>({@x_{ttZEuIz9;z7P#X;nq zjEe_CcMNGo5#z2z97@DP7bnJB8Ob*Flt3g6ykROw<&~ zW7lRwG1E0O`7my_Oi=SI;keguCWn$w^C!)+KOJ)%%@;MIc2MW82>5F4I1!H*mbkP&Z1;v(OvD|J+IqVq@YZiwi z!%>*UQJmo@LPzV(o1~6$(qig}V}mI!Y7r~o4O|ha%FNS zL+X~xA2=It5{>A}_}BzH=$ShCW{Yr~Tz6|n z#4+u^WGqe#;%ewGweX4uOkO+jKuLSC;HBOfCw5zDpHf2gQV!KeTxmac5>ZN1syjnn zn^HZut55sod(tspmr(xo+*uxblZW+QtKIj1tE3EGDBof%rE91Bw1oO-nfhJ1p1>c0 zcUGO|rCpd;+6`wb7D+iAt9%n0*2M*BKdSKdx*KJZ#MU2X@CbuP8BhiagCh(krmJ_7 zqp+)bKfG1tgVWVxB&a%S{wDm2L7l37fcRIt=8V2Gj=5md`wz_r_ACVUV7%DYwb0f# zx9`w=+vq~uC@Qe2?q?{h9f$JZH8Kf~4Lzh@jcq95Nw0eHPM#+N>T`D;*1#(*cBtC? znDrw(eHgz`tOVgl{2k@48=$9ktEy|bs3qs&($;?RA=EcE35#e|pt*HKU1_ut_16Z6 z27bHmxb9)yZgWE#waP3awdgLjjk;Q7IZ&A%}7aRyfqmb8Zlq}Y-WmP65)#o;AmHoGz?tw9_{_lw;mJ3!al}Kug|3nH~|6m``*bSJKum1zeV1i-* diff --git a/src/equipment/router.py b/src/equipment/router.py index 962643f..b4da517 100644 --- a/src/equipment/router.py +++ b/src/equipment/router.py @@ -1,4 +1,4 @@ -from typing import List, Optional +from typing import Annotated, List, Optional from fastapi import APIRouter, HTTPException, status, Query from fastapi.responses import StreamingResponse import json @@ -13,6 +13,7 @@ from src.equipment.schema import ( EquipmentTop10Pagination, EquipmentUpdate, CountRemainingLifeResponse, + ListQueryParams, ) from src.equipment.service import ( get_master_by_assetnum, @@ -34,7 +35,7 @@ from src.modules.equipment.Eac import Eac from src.database.service import CommonParameters, search_filter_sort_paginate from src.database.core import DbSession, CollectorDbSession from src.auth.service import CurrentUser, Token -from src.models import StandardResponse +from src.models import CommonParams, StandardResponse router = APIRouter() @@ -43,15 +44,14 @@ router = APIRouter() async def get_equipments( db_session: DbSession, common: CommonParameters, - items_per_page: Optional[int] = Query(5), - search: Optional[str] = Query(None), + params: Annotated[ListQueryParams, Query()], ): """Get all equipment pagination.""" # return equipment_data = await get_all( db_session=db_session, - items_per_page=items_per_page, - search=search, + items_per_page=params.items_per_page, + search=params.search, common=common, ) return StandardResponse( @@ -119,7 +119,7 @@ async def simulate_equipment(db_session: DbSession, assetnum: str): "/count-remaining-life", response_model=StandardResponse[CountRemainingLifeResponse], ) -async def get_count_remaining_life_equipment(db_session: DbSession, common: CommonParameters): +async def get_count_remaining_life_equipment(db_session: DbSession, common: CommonParameters, params: Annotated[CommonParams, Query()]): count = await get_count_remaining_life(db_session=db_session, common=common) return StandardResponse( data=count, @@ -130,7 +130,7 @@ async def get_count_remaining_life_equipment(db_session: DbSession, common: Comm "/top-10-replacement-priorities", response_model=StandardResponse[EquipmentTop10Pagination], ) -async def get_calculated_top_10_replacement_priorities(db_session: DbSession, common: CommonParameters): +async def get_calculated_top_10_replacement_priorities(db_session: DbSession, common: CommonParameters, params: Annotated[CommonParams, Query()]): equipment_data = await get_top_10_replacement_priorities(db_session=db_session, common=common) return StandardResponse( data=equipment_data, @@ -141,7 +141,7 @@ async def get_calculated_top_10_replacement_priorities(db_session: DbSession, co "/top-10-economic-life", response_model=StandardResponse[EquipmentTop10Pagination], ) -async def get_calculated_top_10_economic_life(db_session: DbSession, common: CommonParameters): +async def get_calculated_top_10_economic_life(db_session: DbSession, common: CommonParameters, params: Annotated[CommonParams, Query()]): equipment_data = await get_top_10_economic_life(db_session=db_session, common=common) return StandardResponse( data=equipment_data, diff --git a/src/equipment/schema.py b/src/equipment/schema.py index d6a6a30..897fdf3 100644 --- a/src/equipment/schema.py +++ b/src/equipment/schema.py @@ -3,7 +3,7 @@ from typing import List, Optional from uuid import UUID from pydantic import Field -from src.models import DefaultBase, Pagination +from src.models import CommonParams, DefaultBase, Pagination MAX_PRICE = 1_000_000_000_000_000 # thousands of trillion @@ -150,3 +150,16 @@ class CountRemainingLifeResponse(DefaultBase): safe: int warning: int critical: int + +class ListQueryParams(CommonParams): + items_per_page: Optional[int] = Field( + default=5, + ge=1, + le=1000, + description="Number of items per page" + ) + search: Optional[str] = Field( + default=None, + description="Search keyword" + ) + diff --git a/src/equipment_master/__pycache__/__init__.cpython-311.pyc b/src/equipment_master/__pycache__/__init__.cpython-311.pyc index 96296b7534b1d42609bcbddc2bd497da400957f7..3b9c39e615c3436c71014422438a9d8d3a8b2e07 100644 GIT binary patch delta 46 zcmZ3$xQ3B?IWI340}z-!E1Sq|DsHczk)NBYpIB0qsPB?mmYS1akeixUGSNE}04H(| AZ~y=R delta 34 ocmZ3(xPXy+IWI340}vd{<(bHB%5AKlk)NBYpO~4OKQTNM0FNdKSO5S3 diff --git a/src/equipment_master/__pycache__/model.cpython-311.pyc b/src/equipment_master/__pycache__/model.cpython-311.pyc index 96af68bfca5efe4501d04cdd560717227f74f769..ab67e13d532f65332c62d0f9aa37c1c8092ee2b9 100644 GIT binary patch delta 49 zcmZ1~vQdP4IWI340}z-!E8EDO$|`Q7pOK%Ns-IX=l&J5LT9%rVUyz%cSF*X9brlN$ DUAPaT delta 37 rcmdlevQ&h7IWI340}vd{<=M!c%F1n^pOK%Ns-Kvdo4>i8brlN$w9E>M diff --git a/src/equipment_master/__pycache__/router.cpython-311.pyc b/src/equipment_master/__pycache__/router.cpython-311.pyc index 4a8bc0b85381d3ef5ad6e496f2efc49c2a02c552..213dc4d24cce80cc3154ab744b4afdd016d3591a 100644 GIT binary patch delta 859 zcmZ`$O=uHA6rR~hHa{k9em6}THPk|h*7i{G4;2MV(PGhhC`4%3WTrKe&9<|fpc1K2 z6$B5KIrQo&Z80}5LJwX%OAk4OoC;p_7AYdsi*M2<_=9iveeY-9&%8I!Bd^0F8-BkR z0d4)L6ppC~eU?U-IwxT4<<>^-T{ME3AVw5XS21LSGhri=iF9mtF=}WT4I>3HZw=z# zb_<|PjK$szti3<0F^&3Ig!&m~0f_S*#EGjova+DkzGsfV65}$lSLZi{_A@67#(SQ+ zx28Z#-~*yZpjCh+792GAPt`#hx{K1`uQD`ETApjAk}3A^Lrg?b8H`3Im&=7EgO%)C zx@9wdr_A^x@j_W#X?bZbYcb0zn5CAQHw{C|C7tVrl_!U-rEmeS0`ENrm_`__BO8Ny zNLA%Q&jP)7YtVaDs;G+VxaNeZfIB2!lD-LIdk#$yRYH|I`Ezs_%`ua9wmfhzm?2xB zVw4PsPvk<@$=#5|6A}g`BqhLuLkicV9+Mz9-U_nr7P3ZX4VL8qe+p>-^7wtzVB@;Y z_3`Vh!ir{RU1H90JGBf!U*LO+zWdPe)6LL8BQ(_PkG^`+j2&&nM&EsK{KPmVw$*h! zBW7Jig$Km8D={CGtwWvG7SE4S-PUuu#m4d`XFM$ZDmTmU9xbxSY<@y|h-Gtr3bZZ6 zhe7ZmfPMER!=&XRyTZ?bDK~Aciu3MDa&8Cx_ZJ`Cvp1A}tTqGjHUYWoOSYXL+bZ&F qJKD+3$<4{FsruB8Hqr2%X}jbR>cTgIlxf_+H`}sAdsu9E=6?a6R>Hmj delta 953 zcmZuvO=uHA6rS0?{M-CAe@#nUTWNww(L+@{32m%~)?jW?3^6lJ7rIH@-Cm?np)DR1 zX&IpvdWaykU_E&e@#4XIg&vl@D0tD6E5(ame3LfT2H)qaIYA?&i()F$M6yli_5CEc6Y5Y1M+_1^ zt{@SJlaRl3SY*aax|ijSL-z1P{@vvtK%!KpL6*m}iyB zP?c12&y#P#fve*gZ2Jf`D!SS*TV#Wl^~$V$LN%#olp0hoHOf_5;Z@t_0L$uwElGbX6VQ|Sn%YL05ovmwhw5)1%mXh)b6;fZ}xsQGZ zQU4h$oU*#2R{YfKhthA1PqGKfI_r1Mu~k=G3G&@S?3F7%5C&)~dVL<+ZHrZE+M;0s zQfsC@1UdG})f>40fOo<80NxQX#uf{?dsy0Ch+W=A|9RQE`^KUh4z& zHgnc+ra7@a_-yj|q~i-=#X;b#VA2s`{_O8{WWK1NU~(hT9NO&Lmbc|Mr+3rYkLm1Q zI=h?9?sZ*pT%6=af#_=C(Ujxikrze#HVRLsj;ccGFjjtuNXX$me9aL!EzQn(ZvO$@ Cyw|`0 diff --git a/src/equipment_master/__pycache__/schema.cpython-311.pyc b/src/equipment_master/__pycache__/schema.cpython-311.pyc index f165132e49d6f65468f9341fd1710a97780cb675..92bb2e67e99b75b663ce09fbf96cc0485369da10 100644 GIT binary patch delta 1318 zcmZ`&O-vI(7@g_1+okQ6mbPfC6^l@91Zpq@4h0hsj4?DdYC@U_*{~C7!nS3)kZ5A) z!Gi~lkRg$ii5CnZ#wZ8R9=zyi@@oz{7ZSih@MOAPL=URyB;DUnl zan9eQYZY98b83?=ih zjZwla+QZ{NO18JVH zTqQk!lLpy=S08n3%L@WgUD(RN5NuK5;5`(Q1l}Vi0f>T*CHjHrXA8aod&~WNo%r%J&pt&26|s(ru3JdQMTxkH2gLSAWZjkH zp)M7@oKcQ2Zo%MUOOwW9GyL_*R&;z}u_Ru`q*gNty}n53-8>B;{s-6t*H*A(5~DU# zC3L2$-657-BO0BZYrb5r`F()m#KcAiA$JB~2*9!L0muPld9UR;)c^hpX!mqi{pyOc z9$8a&++Dmi++Dlf>3V);YJGO?_KrKvTf?2+O{VG-52sdUAMsp@w}wC-*zW-<f@Bg604t@cf0|CSU delta 858 zcmZuvJ#5oJ6uz?)*KyDJC4oQ-u9QOEQleCfU_c!h3KD7-U_lC1C7*<)I6>FI1Y%)e zjZW-L<)>oGz}yM3F(Qv_WkNz?=)`?5EVw=SKE3z8_w(JIKQI1h`tN+-V`d#DBJNK7 zCKr<{cegmR*liX$uUIrEy?vXp1G8uAp&-sRTtSKq=M(1{ZeDtmxAm98nEr{hlEtJI z75BMmZ1%s#WhyS2isFfi3UOt_RpfkTXf>+dV`1$GZ9<;9(e7A|<3xsbst0_XThsUa z1?MGw*}k+^Hc6?yH&&`*EQMpKs(}yew?TH?X+It%vb`H8BmLZ7aRd^C{%C)4nlrPX zyVI({JOii$&H;!%4{L!yf6XlvCmFS7!m4nE_&fKFZ6P&OrBbo81Rba2Y+dcuGYJF#u`22#>7R^oz5@#j**c zRvh*2D_?K8(XEWcITVm461xHyVpRZG1*`!`>{VFn`n$VS&*;V&wXBPUKfI~)-tb0d z%m(;8B>`w)rbP!tM;~}yK?i`}3u}5?Y;V!?(R&2QqBFN)(OjzhzuU2UGZ{rs2Xa$g gH+lFw_ulBA;!)$;H+IT5jrIWI340}vd{<=M#X%fxM@pOK%Ns-Kvdo4+}qiJ21s#1INP diff --git a/src/equipment_master/router.py b/src/equipment_master/router.py index a9844ae..a201d76 100644 --- a/src/equipment_master/router.py +++ b/src/equipment_master/router.py @@ -3,7 +3,7 @@ from typing import Annotated, List, Optional from src.models import StandardResponse from .service import get_all_master, get_master from fastapi import APIRouter, HTTPException, Query, status -from .schema import EquipmentMasterPaginated, EquipmentMasterRead +from .schema import EquipmentMasterPaginated, EquipmentMasterQuery, EquipmentMasterRead from src.database.service import search_filter_sort_paginate, CommonParameters from src.database.core import DbSession @@ -14,14 +14,12 @@ router = APIRouter() async def get_all_equipment_master_tree( db_session: DbSession, common: CommonParameters, - parent_id: Annotated[Optional[str], Query(description="Parent ID")] = None, - search: Optional[str] = Query(None), - items_per_page: Optional[int] = Query(5), + params: Annotated[EquipmentMasterQuery, Query()], ): equipment_masters = await get_all_master( - parent_id=parent_id, - search=search, - items_per_page=items_per_page, + parent_id=params.parent_id, + search=params.search, + items_per_page=params.items_per_page, db_session=db_session, common=common, ) diff --git a/src/equipment_master/schema.py b/src/equipment_master/schema.py index ed7baf1..50f3247 100644 --- a/src/equipment_master/schema.py +++ b/src/equipment_master/schema.py @@ -3,7 +3,7 @@ from typing import ForwardRef, List, Optional from uuid import UUID from pydantic import Field -from src.models import DefaultBase, Pagination +from src.models import CommonParams, DefaultBase, Pagination class EquipmentMasterBase(DefaultBase): @@ -42,3 +42,9 @@ class EquipmentMasterRead(EquipmentMasterBase): class EquipmentMasterPaginated(Pagination): items: List[EquipmentMasterRead] = [] + + +class EquipmentMasterQuery(CommonParams): + parent_id : Optional[str] = None + items_per_page : Optional[int] = 5 + search : Optional[str] = None \ No newline at end of file diff --git a/src/manpower_cost/router.py b/src/manpower_cost/router.py index 45c4d8d..6cd01ac 100644 --- a/src/manpower_cost/router.py +++ b/src/manpower_cost/router.py @@ -1,8 +1,8 @@ -from typing import Optional +from typing import Annotated, Optional from fastapi import APIRouter, HTTPException, status, Query from src.manpower_cost.model import ManpowerCost -from src.manpower_cost.schema import ManpowerCostPagination, ManpowerCostRead, ManpowerCostCreate, ManpowerCostUpdate +from src.manpower_cost.schema import ManpowerCostPagination, ManpowerCostRead, ManpowerCostCreate, ManpowerCostUpdate, QueryParams from src.manpower_cost.service import get, get_all, create, update, delete from src.database.service import CommonParameters, search_filter_sort_paginate @@ -17,14 +17,13 @@ router = APIRouter() async def get_yeardatas( db_session: DbSession, common: CommonParameters, - items_per_page: Optional[int] = Query(5), - search: Optional[str] = Query(None), + params: Annotated[QueryParams, Query()], ): """Get all acquisition_cost_data pagination.""" get_acquisition_cost_data = await get_all( db_session=db_session, - items_per_page=items_per_page, - search=search, + items_per_page=params.items_per_page, + search=params.search, common=common, ) # return diff --git a/src/manpower_cost/schema.py b/src/manpower_cost/schema.py index 0c56142..293936d 100644 --- a/src/manpower_cost/schema.py +++ b/src/manpower_cost/schema.py @@ -3,7 +3,7 @@ from typing import List, Optional from uuid import UUID from pydantic import Field -from src.models import DefaultBase, Pagination +from src.models import CommonParams, DefaultBase, Pagination class ManpowerCostBase(DefaultBase): @@ -31,3 +31,8 @@ class ManpowerCostRead(ManpowerCostBase): class ManpowerCostPagination(Pagination): items: List[ManpowerCostRead] = [] + + +class QueryParams(CommonParams): + items_per_page: Optional[int] = Field(5) + search: Optional[str] = Field(None) \ No newline at end of file diff --git a/src/manpower_master/router.py b/src/manpower_master/router.py index 45c4d8d..6cd01ac 100644 --- a/src/manpower_master/router.py +++ b/src/manpower_master/router.py @@ -1,8 +1,8 @@ -from typing import Optional +from typing import Annotated, Optional from fastapi import APIRouter, HTTPException, status, Query from src.manpower_cost.model import ManpowerCost -from src.manpower_cost.schema import ManpowerCostPagination, ManpowerCostRead, ManpowerCostCreate, ManpowerCostUpdate +from src.manpower_cost.schema import ManpowerCostPagination, ManpowerCostRead, ManpowerCostCreate, ManpowerCostUpdate, QueryParams from src.manpower_cost.service import get, get_all, create, update, delete from src.database.service import CommonParameters, search_filter_sort_paginate @@ -17,14 +17,13 @@ router = APIRouter() async def get_yeardatas( db_session: DbSession, common: CommonParameters, - items_per_page: Optional[int] = Query(5), - search: Optional[str] = Query(None), + params: Annotated[QueryParams, Query()], ): """Get all acquisition_cost_data pagination.""" get_acquisition_cost_data = await get_all( db_session=db_session, - items_per_page=items_per_page, - search=search, + items_per_page=params.items_per_page, + search=params.search, common=common, ) # return diff --git a/src/manpower_master/schema.py b/src/manpower_master/schema.py index 0c56142..24aab80 100644 --- a/src/manpower_master/schema.py +++ b/src/manpower_master/schema.py @@ -3,7 +3,7 @@ from typing import List, Optional from uuid import UUID from pydantic import Field -from src.models import DefaultBase, Pagination +from src.models import CommonParams, DefaultBase, Pagination class ManpowerCostBase(DefaultBase): @@ -31,3 +31,7 @@ class ManpowerCostRead(ManpowerCostBase): class ManpowerCostPagination(Pagination): items: List[ManpowerCostRead] = [] + +class QueryParams(CommonParams): + items_per_page: Optional[int] = Field(5) + search: Optional[str] = Field(None) \ No newline at end of file diff --git a/src/masterdata/__pycache__/__init__.cpython-311.pyc b/src/masterdata/__pycache__/__init__.cpython-311.pyc index 32396611605057ee0aad64bf3abdcab039cabf15..dfa83926cf8035de3bce28b2a5f8fa5e5623e3f0 100644 GIT binary patch delta 46 zcmbQmxQvl|IWI340}z-!E1Sq|DsHKtk)NBYpIB0qsPB?mmYS1akeixUGSS-~03@^y ASO5S3 delta 34 ocmZ3+IE#^cIWI340}vd{<(bHB%B`!Pk)NBYpO~4OKQY`N0F6KiKmY&$ diff --git a/src/masterdata/__pycache__/model.cpython-311.pyc b/src/masterdata/__pycache__/model.cpython-311.pyc index 892b12a129b5f9502e020012a0ebbb13e4536700..33963a2ae202c65c69e456eb89a9a95b924d1876 100644 GIT binary patch delta 49 zcmdnTaf*X`IWI340}z-!E8EB&z$9*_pOK%Ns-IX=l&J5LT9%rVUyz%cSF$;c=>{VJ DUmp*# delta 37 rcmX@bv5$j$IWI340}w=gGvCM^z{IVkpOK%Ns-Kvdo4>h;=>{VJyu1qL diff --git a/src/masterdata/__pycache__/router.cpython-311.pyc b/src/masterdata/__pycache__/router.cpython-311.pyc index e6ba131f010677816939f78e36202cac1e0fa795..05d712641219aed263516bbcc0a857d2e8efd256 100644 GIT binary patch delta 2195 zcma)6OK%fb6rS;T#*f7BXC6)*ngmP|hgS$x2myr@RVq-LvbYP}iRU^G=Gx}Y1e87$ zs&?5$r7N{kH>DB+(V|LKR$X+{UqB@m(QJy;B9)yhid4}>d(Jfugrq8C&zW=2IrH7` zJnsCo_u9VITaiduf$N*Ut}HGk6y;Z3bS~+E#iIdDQNBAl3vzF`Xp$`?q>y3U;|`8uEX{qE0UtryX+yhgY1xc zxBUtmCc~=YQ>cCu^7*!tpkj~_I&wWLKI%%>tOy;Z@tzIeo#;&;#KPUatQaj?aaynv zRHfa372J$f^F4dFW?0Ej{G0t`w6oO-D+OC6o`r9_RhsUs`K`H$U?O^A1WnW^m(@1^OdFnwEK#yc=?yli4tmZl_J(CXh7 zt`AvVcv(28Q(+6tgf;NCQW|`S-79Hc=y<)}a7~w5VqQBHE2&=BTg#NMoHMz}oV7dJ zpela$X9kR>G*n^aH!cITkKuk)7tv%s=UY-ct`B@m8v`OH^+9nc6c-ou@qr>lc+o|d zGN;m{ywWu1sb@IU#@wIAFkDmovKlU z5MCA{aO}t^syjiHbe=*zfFcOOOP-#cJy$uf=RoDm+1bj>*>}#Il&o%Ryof<%5ew#f z$1pTHPu&VL9hY*;bWMH;jN{^X@Ul7~)`H))H#{unLxUB$m*4Z(O-8+Nl~e3OWp0IM z5VM_i8~-pGUPUnt!s%3j%N-N#H=p11C`26+4??q%3DDltC+C*!OMKVbO!zlna37dT zKwRvLOiUw(+e#_LPk`cS%|?^M=T6~AaA}y$Caqf>KX^QX7X9i1<&+;2pGQWHZPbTP zVE_{5IS{3;HtStzkgO4$zXrndW9xYt*IDs*WJ(gLF=Bf|vakQJO%kIL)OZ{jM%N&rX zBMa&oys-?&jN^ItG{@!guzCI_q{s0Hz&tOzvW*<;%1@!dy2>s;2_Av8mu-5K*T9C~ zE@uv^+|pE4T`wr(cmMk@E@uuV?<;%mZvKl~nSW0E;;OM8?`di9yx-m5(&5=Mlt}io uOV_8aPklXoWBP7(_r311RscOpNBp5FzSq@z>P!m}TBB=`-1n*<>HZ6?In*Ek delta 2160 zcma)6U1(fI6rQ{HXYcN2|FXN;%_iI3tx4NW+Q$AFkY$a9-DTq^{Y;z~ck~__I z?nY?|q+s7HsElX@A1X+-T13fe#37F660T8=hiFJcJLKxz zpawUo$t`N}Fbyle?%F&;BcL0O=|*{s#*}WkJv>h1JV6sYNt1jfMN>RY(`qs7_VNtP z@GQ;p9L@1Q+Q;)W&kMAmKyA057ip0X&;eyf+(BNVC8bB*Exb(2N{_h}UZquyga|XP zK@6XF10r-Q+j=##ZW0-bMOKK@!>TOazwW*fzZQa1FoOX&VJC4-10T#yzT~~W*^rZB zB`3{_PA}8g6B~$52JE2?d)9Wcm&|}$q60j0#of%_?`5B0I3S;NU+ zx$~jH^|a!xTObhN4mIE zj~%O1U@3)XJ6j%#S3sUGJ~kfYuKWPbsFR!~waP6lN-ZQ`)hAcK)XSQ6%LKk99q`p95ZKt2hA(@wor_dH}*!EtwVY<`imv3i3q%DvXU z>Ikg#!Soo2zu@m8xzkIE)pn-T&JVYfxz#tV?V6=Nu~U8>p2!cuMllQmz6?(S5g4Bc z%cNa6jD)W10im6s`_X`gVu7&%1yRF=#2jm#-dGe*fpb*O+UK-U*|xt3J~%EfN6Ol; zyb&pk;I#|_HUj){bUcmX00<8=4(I?c|BmF%gJ6!!X!K-!6toNG*qJ4FL2O%Hi2f0> zp9EJ8Xv&x4yT&n;>!g+u6QKBdbFnFspowSDwCc?!JL`xDdho&X&DZCdVB(PcCO$k7 zgpOn*lX59iD1J89QK3e-P0Iphq>(D zM4W_87jWZya>3pu-%9t&A2X*`u&}kAzSTP4Y@D4Fh$65H{O~OFe!bZc7{OY5qGsb_ z)H~){*CMQ~teLz^zO1lB@ea>Nl7m=ATi?%D?da>-?fghR* z`t!s7+w!|yMgE%0Nu%$-IhzcRT%G*1`q8nEkF^J@S0=9xeK7UmR4035HJ!f4qfo_l-x^6`xW>eN3v2_4mb(Vp*waMzC2sr*-(fz1C0 D>$ao~ diff --git a/src/masterdata/__pycache__/schema.cpython-311.pyc b/src/masterdata/__pycache__/schema.cpython-311.pyc index 9fab2405e9ec4e78f755854bd8c8f6c58873239b..a10aa605ae97827489d31490175077430ad0a92d 100644 GIT binary patch delta 1450 zcmZuxO-vI(6rSB}xBJts6exoH6$GRW0gMEQ663#U0+BS)q|uP3JJQB3C9?&CiI#&0 z5bsqlZZ|1U_p0`wBeX(Q_R&u*omYg5|PPmVuxN5TcgGY zg^)FPypgs9rvqnDYxzs8Y=Rl4mM^SIghha}j&V`JodT}v7*{R0C~(!(^l8=zt_HYT z8am*t{km%HSc)X-cv9*K%N6}v#-(FLn-(@6NN;566#uQvs~W_zDqaY*K8&JSjZgp<=i! z+w0)Hc9{+=!w+1g3cZ=xQm)sfY%ZUr%tTIHLDBu9gGCF9mJqLBZ29Oh>}eyQJzJoc u*;Nq07v*jMZYvW17QRx~`GcJB--t!dNyC~h!A_3DQep?ayC+a$lm7saNf_Ax delta 966 zcmZXTO=}ZD7{_Ol&31RQyGavU)0f!v&A3FeSW8h6Jt!(3O2u1lA-j^5tP7J=@E|Gb z!E2Znzkwni^C|SyV+jg=0EL1V=|PKL6`vC40)I@eQaXG? zk5bg;CFPYmBZgx+{y|yU%fp-n<^)EWXPv0oWAkuagd-ii=&=%(*b`d-7J(&!&*YCF zIjgztDD>TC5JtR^SyN2}n8RC{L#l2_o9~$m!{2I#_ARV)z@&8n%OZdwb|>u}n=Qj# z1}*{d=&)9R3NR^zbhZkNcfi)LTn8|U$u?nDCHQOYS3F>qNBX@7iC*KRILAQ_faET= za4^146z$-?Y``4;S8s18N+}|Gq>~CO-gq#`4hQ_GDYxV!G{_c3YI)@A!AvO_58*+kGo| hnx>SVkn%Ae{=?qMFCLSrXXxar)FzZ}o&xgt{{u*Frv(52 diff --git a/src/masterdata/__pycache__/service.cpython-311.pyc b/src/masterdata/__pycache__/service.cpython-311.pyc index 24d5f9c046f23d0dd78a0c52b7966e48390905f2..6e87b5b7b77f83fd4440a5a8123c6b4a64ac5ab8 100644 GIT binary patch delta 49 zcmX?GaI=7WIWI340}z-!E8EEZhfCZ-KO;XkRX?$$C{f=fwJbF!zaTd?uVk|jx3w++ Do~RI+ delta 37 rcmcavaJGPZIWI340}yz|cx~kV!^N$mpOK%Ns-Kvdo4;9(+gcX@+Q|zx diff --git a/src/masterdata/router.py b/src/masterdata/router.py index f10682d..0784e67 100644 --- a/src/masterdata/router.py +++ b/src/masterdata/router.py @@ -1,7 +1,9 @@ -from typing import Optional, List +from typing import Annotated, Optional, List from fastapi import APIRouter, HTTPException, status, Query from sqlalchemy import Select + +from src.manpower_cost.schema import QueryParams from .model import MasterData from .schema import ( MasterDataPagination, @@ -23,15 +25,14 @@ router = APIRouter() async def get_masterdatas( db_session: DbSession, common: CommonParameters, - items_per_page: Optional[int] = Query(5), - search: Optional[str] = Query(None), + params: Annotated[QueryParams, Query()], ): """Get all documents.""" # return master_datas = await get_all( db_session=db_session, - items_per_page=items_per_page, - search=search, + items_per_page=params.items_per_page, + search=params.search, common=common, ) return StandardResponse( diff --git a/src/masterdata/schema.py b/src/masterdata/schema.py index a18df1d..015cda5 100644 --- a/src/masterdata/schema.py +++ b/src/masterdata/schema.py @@ -2,7 +2,7 @@ from datetime import datetime from typing import List, Optional from uuid import UUID -from pydantic import Field +from pydantic import BaseModel, Field from src.models import DefaultBase, Pagination from src.auth.service import CurrentUser @@ -50,3 +50,15 @@ class MasterDataRead(MasterdataBase): class MasterDataPagination(Pagination): items: List[MasterDataRead] = [] + + +class QueryParams(BaseModel): + items_per_page: Optional[int] = Field( + 5, + ge=1, + description="Items per page" + ) + search: Optional[str] = Field( + None, + description="Search keyword" + ) diff --git a/src/masterdata_simulations/router.py b/src/masterdata_simulations/router.py index b3b9661..3aae5fe 100644 --- a/src/masterdata_simulations/router.py +++ b/src/masterdata_simulations/router.py @@ -1,4 +1,4 @@ -from typing import List, Optional +from typing import Annotated, List, Optional from uuid import UUID from fastapi import APIRouter, HTTPException, Query, status @@ -12,6 +12,7 @@ from src.masterdata_simulations.schema import ( MasterDataSimulationPagination, MasterDataSimulationRead, MasterDataSimulationUpdate, + QueryParams, ) from src.masterdata_simulations.service import ( bulk_update, @@ -30,15 +31,13 @@ router = APIRouter() async def get_masterdata_simulations( db_session: DbSession, common: CommonParameters, - simulation_id: UUID = Query(..., description="Simulation identifier"), - items_per_page: Optional[int] = Query(5), - search: Optional[str] = Query(None), + params: Annotated[QueryParams, Query()], ): master_datas = await get_all( db_session=db_session, - items_per_page=items_per_page, - simulation_id=simulation_id, - search=search, + items_per_page=params.items_per_page, + simulation_id=params.simulation_id, + search=params.search, common=common, ) return StandardResponse(data=master_datas, message="Data retrieved successfully") diff --git a/src/masterdata_simulations/schema.py b/src/masterdata_simulations/schema.py index 0d5f89f..d3e2093 100644 --- a/src/masterdata_simulations/schema.py +++ b/src/masterdata_simulations/schema.py @@ -4,7 +4,7 @@ from uuid import UUID from pydantic import Field from src.masterdata.schema import MasterdataBase -from src.models import DefaultBase, Pagination +from src.models import CommonParams, DefaultBase, Pagination class MasterDataSimulationBase(MasterdataBase): @@ -38,3 +38,16 @@ class MasterDataSimulationRead(MasterDataSimulationBase): class MasterDataSimulationPagination(Pagination): items: List[MasterDataSimulationRead] = [] + + +class QueryParams(CommonParams): + simulation_id: UUID = Field( + ..., + description="Simulation identifier", + ) + items_per_page: Optional[int] = Field( + 5, + ge=1, + description="Items per page" + ) + search: Optional[str] = Field(None) \ No newline at end of file diff --git a/src/models.py b/src/models.py index 0941dce..c00e8dd 100644 --- a/src/models.py +++ b/src/models.py @@ -1,6 +1,6 @@ # src/common/models.py from datetime import datetime -from typing import Generic, Optional, TypeVar +from typing import Generic, List, Optional, TypeVar import uuid from pydantic import BaseModel, Field, SecretStr from sqlalchemy import Column, DateTime, String, func, event @@ -72,6 +72,8 @@ class DefaultBase(BaseModel): validate_assignment = True arbitrary_types_allowed = True str_strip_whitespace = True + extra = "forbid" + populate_by_name=True json_encoders = { # custom output conversion for datetime @@ -99,3 +101,21 @@ class StandardResponse(BaseModel, Generic[T]): data: Optional[T] = None message: str = "Success" status: ResponseStatus = ResponseStatus.SUCCESS + + +class CommonParams(DefaultBase): + # This ensures no extra query params are allowed + current_user: Optional[str] = Field(None, alias="currentUser") + page: int = Field(1, gt=0, lt=2147483647) + items_per_page: int = Field(5, gt=-2, lt=2147483647) + query_str: Optional[str] = Field(None, alias="q") + filter_spec: Optional[str] = Field(None, alias="filter") + sort_by: List[str] = Field(default_factory=list, alias="sortBy[]") + descending: List[bool] = Field(default_factory=list, alias="descending[]") + exclude: List[str] = Field(default_factory=list, alias="exclude[]") + all_params: int = Field(0, alias="all") + + # Property to mirror your original return dict's bool conversion + @property + def is_all(self) -> bool: + return bool(self.all_params) \ No newline at end of file diff --git a/src/modules/__pycache__/config.cpython-311.pyc b/src/modules/__pycache__/config.cpython-311.pyc index 23843b8fab6926f4b54a07d8a33074193aeafc14..899fccb1f5710932c1507aefd54aca1a5c872a56 100644 GIT binary patch literal 2358 zcmd5+O=ufO6rSCcto2&IwxrsYW3L;BMi!Pz96|}EAlnKpxV9s?q}j`|)~;>YTCF-e ziDP32V*<^wl!C9JEl$$}(o@Ny7x&bo1Ui_7g+gheHx)M!0)@`3es&exJ(j*<-@JMA z=IxvJzIl&*J`P~I_WRw!-(3LwN)|2ZZVD$n1;7E2flL*F(3mNKvevXfE7UsEI`YWX zlANlj(tP@(jNxmm78kNhM(@nR++1d6X(4Ny_-&nKGa$Cl%w#jO znfav;({tj-xlGo$aOT!xI+we(kexLKMcdVzM~BbeYoE0Pwc>UJMb`OdMy-j|g4F-y zN6ZdDH$d$Q0I=SckpmgXQDMYdUMz+zEH>82YwMp;hZr?a+sN4kJ0J%x0_3-C#sG}% zQYd6=WO|3{L;wYD<2vtB_c3;JO=*+b1oxQRV3Ue7^H1DHm%Ln(RK;-J(G_U0Wl7gJ zH7FadHBCo`tE@q^eK`Z626~C`Mi|UVLqkec#4Xi!VXpntI6_~F|ev2 z@l4k+hW(Q0bRDxjP^Z1_@NfL(8vm}@H)@6wW@OR~T{J@@^`5R#?oWW(UxZcI3w1vT zUaGKTugsos9nfwEGg)87|K5wyDmztUrz-5!aiH%ZYK>Qz>TY}h&w2#^cYpF4_<>8u zm?IEON13Cj8_Q?oZVY4Wzrx))*mmF$1#$FELcJ{s02Fq}QCmKRZE6SXP%E^B?|$3P z!Z(dbahinj{YHmt;+wutH}Q?74tzrr==R9J!}ogJ4@t0))B*MoM&39i4;7M^4#`tK z7sZfV4!(t1oG~~DWP`RWZfc^u3++B~GJuh}aDgyCIC)euCP; zN-R+cBr0s;JnW{v4^`R88ar8GC(p+&33fmIPI??1jdRlh=ICm0nqz+A+*poBt-KnH zzNH(qrsHlRp*5pRDwma#Y#}KdOzlMhN7rr5ZJTEG2r&BaSXcm ztnmwA9#$e7NM!jQt4!w|)g!qmbL#hAhj zB$-kegBdhgUV;?*OA)ulrDOrZO zT#ii4%LQzi_p&-NO5pbZKW|QPc7yHZ>7b6PP+GJ|Mu!GA{miZu)fTINSK?znMTa&qn7bsT*3U{zg zD;YimnG9g3{Nk|5%}*)KNwq7I1&T2Oaj_YY_`uA_$asT+zX1#33$N+@_nYxr# diff --git a/src/modules/equipment/__pycache__/Eac.cpython-311.pyc b/src/modules/equipment/__pycache__/Eac.cpython-311.pyc index 88ac350a4bbe2d08fcaef8ce6651741472f81025..f995beca26db8654922800e942ede9622957973f 100644 GIT binary patch delta 291 zcmZ2jaj$}RIWI340}z-!E6enl$ScV>ZK8UDuwV*X3u6>_Do+Y~HWNs?XyU|KOI(;3 zQpHk5mN7CgtOjBTn9Y#FKbIL*jFBOQDVRZ-Ayr(3p-3T00;o?kMF2<&q)JTAV^o%v zh?W4UNMVWsvdS6D87i0~8Oj+!Vwyse*D=l(x7N?d&rQ`&EGbIVcS$Wv&B-swP0cIW z9KvL5E?LE`kXl%p2^J|XN(H%(14w8}PM&PJld*KNhm`^2deM`NKMq4k@+wqhz$UvqD&9~ delta 235 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 delta 37 rcmX>kzD=BaIWI340}#A2@!H7!fsI>VKO;XkRX;H^H-EDb`vw*O#{>%g diff --git a/src/plant_masterdata/__pycache__/__init__.cpython-311.pyc b/src/plant_masterdata/__pycache__/__init__.cpython-311.pyc index 0dacd0ef74580ee23653caf432f7f99052ee8830..4265a64ef23c721d980c34aaa381bb2ea747ba7e 100644 GIT binary patch delta 46 zcmZ3$xQ3B?IWI340}z-!E1Sq|DsHczk)NBYpIB0qsPB?mmYS1akeixUGSNE}04H(| AZ~y=R delta 34 ocmZ3(xPXy+IWI340}vd{<(bHB%5AKlk)NBYpO~4OKQTNM0FNdKSO5S3 diff --git a/src/plant_masterdata/__pycache__/model.cpython-311.pyc b/src/plant_masterdata/__pycache__/model.cpython-311.pyc index 79a319353964754edb05a9c6c9919bb0225ce312..99b6c2c7e3b52a96ace9aca2a780572b87a7148b 100644 GIT binary patch delta 49 zcmX>ta$SUbIWI340}z-!E8EDO&n9l8pOK%Ns-IX=l&J5LT9%rVUyz%cSF*X4?HDrv DZLSa> delta 37 rcmcaEa$1CYIWI340}vd{<=M!c&&F+_pOK%Ns-Kvdo4h@^#~6Dz-bEo diff --git a/src/plant_masterdata/__pycache__/schema.cpython-311.pyc b/src/plant_masterdata/__pycache__/schema.cpython-311.pyc index 511e8aaa4c13f3ca9db9ba6a66740e6e61090784..823d5e6288bae7e301b59c7431d516c9c697b967 100644 GIT binary patch delta 49 zcmbPZx5AElIWI340}z-!E8EBT>CpOK%Ns-IX=l&J5LT9%rVUyz%cSF$;Sdy6mt DXfO}t delta 37 rcmZ2sH^+{9IWI340}vd{<=My`#LaD}pOK%Ns-Kvdo4>h)dy6mtyu1p` diff --git a/src/plant_masterdata/__pycache__/service.cpython-311.pyc b/src/plant_masterdata/__pycache__/service.cpython-311.pyc index 6c73eb8f2aae4ff8de7cc44ceba403a40a6bb42b..3c35788bbe598f2736a9d06961c7ebc40f065243 100644 GIT binary patch delta 49 zcmew^(=5xqoR^o20SL^Vm2KqCWEQv6&&bbB)lV!bO4N5rElbVGFUU>JE7@Gn{DTVs DX*v)w delta 37 rcmZpc{Vv13oR^o20SFG}@@(YJWac)~&&bbB)lbaK&EMS3{DTVsyrc^m diff --git a/src/plant_transaction_data/__pycache__/__init__.cpython-311.pyc b/src/plant_transaction_data/__pycache__/__init__.cpython-311.pyc index 009eeeeaf3e4f35107a7c140a5216ca835cc1840..d00d1287ef59cc7963da2b841eaaa1ce3c58835e 100644 GIT binary patch delta 46 zcmZ3+xQUT_IWI340}z-!E1Sq|D(d DY7h_l delta 37 rcmbQN)vm?8oR^o20SH7UMQ`N3#LI1_pOK%Ns-Kvdo4@%BuRJ>dwgn2Q diff --git a/src/plant_transaction_data/__pycache__/router.cpython-311.pyc b/src/plant_transaction_data/__pycache__/router.cpython-311.pyc index 1d092061851887287f8029e239a569028b44f085..23d529e3bf59ebd175a56c7d215f1320a8c77ae5 100644 GIT binary patch delta 322 zcmexpf6sw;IWI340}z-!E6Y5wkvEQA+*v;(KQ~oBv7{(b-zBvyH7CCyH#M(ha~V4q zACmy%WJU?o$iCK^iyUhX-2ji0+Jt?f%F4OnGdW$`U4w-l*tEn5Q~FBSndNSh{XUS WKC&}0F@0eG5+B$=Vm6a|@VQDnOABFqasLc5lCVsLy<0stqml8aoFVMrTb0da(IWI340}z-!E8EDuRzloaKO;XkRX?$$C{f=fwJbF!zaTd?uVnLKiB3@f Dlco_Z delta 37 rcmcZ+b0&s+IWI340}wnp;{ATS diff --git a/src/plant_transaction_data/__pycache__/service.cpython-311.pyc b/src/plant_transaction_data/__pycache__/service.cpython-311.pyc index 9ececfd61e67aaaeb68ebc3dd1a4268052022bbd..db047658614f008584c75eb67965db4d34613d99 100644 GIT binary patch delta 281 zcmZ2l)Kbj5oR^o20SL^Vm1VBq$UBEc+(kblKQ~oBv7{(b-zBvyH7CCyH#M(h^A?uV zyo_fiHwf*V{9lNdk!>=+n65Z81H)<{hJad@8m1!88kPm@lQ#;9G73&UXed6pPMC{H zh+(pUusG8KE}*!`5$D|6~Ot@yR)IoJ=JGlg|rFGICCCR2QE7N7#f>bh4pH z6eIWK9uc+4+eK0s&rFsPb=;gUdO(=**<=Gv8RiE?5_6K$li-SSR@(rTdE+U(jpSIAXHIX#Rl;g-Z-cSDTj6K4AQvmn%T99#zYPr z&=X`29`uYccrl!e2mb{Q9yXhhc=BjU;6ya>y{%v@Om{xJGv7Dgee-71pXqmfiT9co zC(!ag>XrHUQsS`WFP$osse5>0c@-YDJz>cpECE`QD=il7OTR|CLw#%dzi{JmS9QN&Qk0EJIFd%Cp-4BXIX*lp*I^(v-CV! zhQZ3tRLiK8VbWca&A2zB<1)TUBvxNVFG`Z;ew8O)`tn0QV+o#>{7BVeyd2u~Ay73! zuuz+a0B^_(iAj$GU4$693u7=2P5R^m-28Caw0)^=V?b~3_Ql++RpmLu5k~GNuXEFS zQsp%#_mB^n<+72pMLGA3yX&#`2Yv^yK5?Guwj(OFN4jI_HLJ#-AD`lefGQc+4Vw?| z7m|io**%i(Tqn=cr@$LK964Z=oydpdsOwP=4qXcE>)H{ z2w)4*I6~x9BNUFN8U(NrhT;75#?f8<*p3wF%^XxWqgwJj6JBj>GuA(B-KIrY`qboO;ub8EpxcvfCNVKRxJLH5JTknt-_?*$N^r7! Vv3O+zXSe=IcO>_7;!^~7^9SB#9X|j7 delta 852 zcmZvY&ubGw6vt<}+0E?l6)9BFR-;(AZIY&?4YW}#XnGLz5J3oN2<}Q3cC#?MUNr~3 z8|Uh|B6`bT;KiGegOsp;gGeQwdUD>xD&2N==EK|hzW04I^S<1gXhBV1E`ebAqMsPRzu z^<0`M(hRPdr!-4w7T0WF%hlQM@EXCH+zkBCWB2h*UHRL2av%*~;_s5;;TCc)v3>cD zVsMR`!yobn#s(`Dn=|fZ_LwZKS|G?AnH2QW%Kxz z%s!JwEt8Uz(s?L_`_cu#6~I-Fk7&Y)j@;^A9QoC55XEd@-UdUISbQxBww9LsUKnG@aNS{eR!MK>By5xn*uuXRl0Bu0TP~qy~Ec z(WVN2qC<^6u`aN0=H^=N5b(D21|a9O4tsz_wqcbN;j+$M_8K{dIwTg3v(NO}1QoE% zu)S&sFZg}nI_#ERYh_wOpH-sR^TUJ^NQQ@;KC5^ZaV>EoVRiDTN2I|^UxfZ`+TdlF vuVj~fwVRJFj?jrYMwQW7^H4dDw-3>2yxslm0uc%pGY4IWI340}wp?=aRX6BX1rvx0ZfJer~FMVrFjs=1I&oOw24PsgniRx&$mP Ysaaf9v$~>Yb&<#V3Xk>XRcyT+0QUP9jQ{`u