From 9f595406865f37e34817680ab56241057275dbe8 Mon Sep 17 00:00:00 2001 From: Alex Blank Date: Thu, 11 Jun 2026 14:55:34 +0200 Subject: [PATCH] cleaned up --- backend/app/__pycache__/main.cpython-314.pyc | Bin 2481 -> 4302 bytes .../__pycache__/backups.cpython-314.pyc | Bin 288 -> 3245 bytes .../__pycache__/dashboard.cpython-314.pyc | Bin 295 -> 3632 bytes .../__pycache__/executions.cpython-314.pyc | Bin 298 -> 2312 bytes .../__pycache__/settings.cpython-314.pyc | Bin 291 -> 3314 bytes .../backup/__pycache__/engine.cpython-314.pyc | Bin 7263 -> 7721 bytes .../__pycache__/__init__.cpython-314.pyc | Bin 939 -> 1055 bytes backend/backup_tool.db | Bin 53248 -> 53248 bytes .../.openspec.yaml | 2 - .../dockerize-and-pyproject-setup/design.md | 77 ------------------ .../dockerize-and-pyproject-setup/proposal.md | 29 ------- .../specs/docker-deployment/spec.md | 42 ---------- .../specs/python-packaging/spec.md | 32 -------- .../dockerize-and-pyproject-setup/tasks.md | 32 -------- 14 files changed, 214 deletions(-) delete mode 100644 openspec/changes/dockerize-and-pyproject-setup/.openspec.yaml delete mode 100644 openspec/changes/dockerize-and-pyproject-setup/design.md delete mode 100644 openspec/changes/dockerize-and-pyproject-setup/proposal.md delete mode 100644 openspec/changes/dockerize-and-pyproject-setup/specs/docker-deployment/spec.md delete mode 100644 openspec/changes/dockerize-and-pyproject-setup/specs/python-packaging/spec.md delete mode 100644 openspec/changes/dockerize-and-pyproject-setup/tasks.md diff --git a/backend/app/__pycache__/main.cpython-314.pyc b/backend/app/__pycache__/main.cpython-314.pyc index 17db055973f760a28a30d2be669f5cbda228533e..d2a6ce25cee7a520f53c47c107961aafa8240c81 100644 GIT binary patch literal 4302 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 diff --git a/backend/app/routers/__pycache__/backups.cpython-314.pyc b/backend/app/routers/__pycache__/backups.cpython-314.pyc index 7e6f953f89fc1445895ff5927fabf3e4f48b8e39..7ba129c954258e557e8f15d3cba825b2fe389fcd 100644 GIT binary patch literal 3245 zcmds3&2JM&6rb5$f7_do5Yi@)Zvrk5LrB7>KnX2zN}8GlSv@4U8+((OI<`BzQ4>%r zLn{^31Fcl4mC6BC9Ei$+N=Q9$A^Zi2Oyy)$1XVB1Eomewdg^;)Zvx??m-f<;_PsZ6 zX5PGc`+IL@hZ^t_XqP&rv&S5S{DvL7L0`0$_bDMca)xNMkA$g3!;&S1WlOF{oz$m< z9hO7La-TEovRpz|`rKiUn&-EPd4EGz4o@W|-Mb+B9P0nS_ywV?;|) zCHQ}2_*Png+a=Z7Jfjr8RD&)V6B#UZRn+u=^y<$^8y5$F)n;@&tjAhwB^ZgC}Hm~rkh z<9bSGCYSY8Dkw7yHFpANCQ=p?!N*9oHZ-s*9Py_Bl(7=xSOchV2lF(LMF{qz%BpV; zes%Eb$o1%V=|WxSTwUkwkwRDRTvuAYH3 zP@Cq|ro7sc>z(&iYEpa)Swix0fNZCeUMZAlc2$%|jYfUU? zh*bxzSVnSPUP5+rv*@vE7>=)Q3Y}HR{tlfIWa)no*(li`Cd3A%&7T7&0PI!Z&dO1F z8~BZFRK>C}xC&*BYLX_~1$~T0WdYS40;eCU~y-{u=Hdq=wh$K9#4VV@zI#U3@#-TyrPKVSSD@6GAxz`&hXBgR#-DGLQJ!I zAlz9(E~2D$71Um=u*DI!2Szr)XTAsI1(0r^t82gA_0xeL58U<4?d{9gy`8T-Q3#v> zFb66Nf!4V|Yd)|&cl@Dm!!K&>4SBZX_p%wwVidr`fE)yWv_bws3*)MvpKy4KM;{O`8^hE_Y zD!(ja>Isx{1kk!>m+bW!R!=lVbKvC)W&8|$P4M|ejyMMx<`&zI1YalIH4g6tebhLo zmeK}pbOXwH(6cT(*iKxt3rQOi%mz#)oXwr_%=mcHVj)nP&t^iPIK@teeJ}&l&b$QV z-%N%_UjLQg<=~gc^WNHmQah{E&KEUb>?kNzvr5&xziPI6+pKTbLrzeQX)6IfwH}nWQl#6E4g@!G*N6^P zCYxk^1`{7N~ zme4JIST_xZuW{~0m3ViV#hciN3KPxiCifSA;wjOEJGb~$l%W`ji&c~&)`_m+f0!mB z3yasV`!HCYNEt`iF&M)4jrl#0C7DwCkaW(G&Ics)fNXg{svnSgA+-JKsra_-mgmO# z`<_EN=OgO+yyim9rDNBWYlA;GwC8H_bnn6&dv3M<5PFPntQDC^9ZM2OOI{+m#pHn- zhjHHih5bkGI`5P{#)}Q-9axe;T2gV|mJ3@heUhhj3x|5{cHKGp7|RIGssBR)Nu1$t DsPk_{ delta 179 zcmZ20xqyjJn~#@^0SNMRn6ereCh|!*XaIQ)3~>xWjGhc0j3tcn46%%g3_(mm%zBJL zEaprg)eHIW=2NFy9}}qIfZ8EZQxu{ NeTCDyiLD6aOaQO?C;b2b diff --git a/backend/app/routers/__pycache__/dashboard.cpython-314.pyc b/backend/app/routers/__pycache__/dashboard.cpython-314.pyc index d5a77301ee2e137a952ec32965468d2993e5d0be..e4f4bf2c2803e0dca1e702aa0c98be0530c1519f 100644 GIT binary patch literal 3632 zcmbsrTWlN0aqoCM9w|zqD48NDS}#hp7(Hl7ekk%ImTISz%-9TF@FS2+oXC?zm*TN^ z%UBZnp+0~XL4ka`DBu_fU>Fb(BMlH2Fj@pQ5T{=}TnefS2S(ARfd6bOXwZIj_NW!* z$VOvyf!mp#xt*Pv-FXZ)HM$UtsU!TA|2Po(J6*70-$Azj3CISzj8fbTigTEY^O*0V zYktNS7qDRAwi$a|#A4im9dQXu7EPFO#+}$1cVSn&0XJAQ`;0r@h#M_joN08WGm2= zPAOnH$`K)v*D*kGNx_-i0&KC(std#o)45e8TgD)rh|_ZR$K?{}(sWkVmlsr7%U!}U z)-?~PxZV_#OZixiafovlg&kr^Qx@~9M8NWrPPiDH)ubtUNiFJ1W<>=(veX+p9zoQb zHu$#tVA?=wbeW&{B|6CKkId4MoMeMoyo|>q6!8pnT&Q2 zq&CB+x5Bi6zD0*P@hP1?9J0VRkdb8*Md)zC_Y3&87eK*Y)MeR~WERsucE%jF+!}KN z!;&Jy>aYjRNo1vOJrv2O$nusIB_A~fHh`TGG<0`jdOW0kg z#HG1p%l_T$C7<99?J$?D`=gOm;?wB=wB5^2{64n7RCin2_R6{oub_Jy)3OfX-s-yh z>U4%NUB3(W`Q4tjzq0P)oS&VO3^J?^LAMZFB|8~bhfJrr9!9(DPw~fhUh&YLS6Fhq zf|p+Wx_j9f-{*#3_`3U zU4SZJUslVS4#hyu7nEGoP8#Ga&cCZ1 z(MhwWWR)V$PyuBqS)^r$ps>QIM-LK5ZKY_?vmlM8Wn#~&|IIFnvOK#+0;il2k=$!-&$r7E+S*yMn+yziSIjpWzuNK z68}CQGd7K0ojM}YT^}0FS)|o!UReK;q2AH8Gr*yhP3ItTA4AQ3BBJiz>+9FnA4*NX z!SAoXxBk2E^~kk|+1z7Fy;W(zkOnqeKkB&EaYrzsCr#q-Cj#a#4w_7&O1HHHJX7EOE^UY6=d^-8@oz{dl3k5x}3j1viS>@9Qf zg4uns8oXE$+P4Bj)xfwB7&ik)tAWW%VDe52sPv794)$M9{5G-a|0r}TWQLC24LtCE z`Fi3np+rRpY=!%8PTrWTn>%zpb}eQ$zh+88`Aj))24J0yd0rk?gr5z z5D^%y`X>zkgz2BG`cE7F)29DSML6(}hQL-^*Oo85)iJ!~KlCuzS?M}#21mbX5Z&Sv zB-+JiZ@^7GbED9C?wN!-lH5}l==;QYaX=bVLD%k28m-)hF4k2YqZ1DXmdw=`cDdSA-k-stc@tEctocCd|uUPMT7|6 zW!4jm75r9yuu_AS6^Mw}O8MfFMq51Mh8}hVT7G#!))kGue&V7etIyW0j8sb_R_bY> zES+i~>$POy-P`tGvN%Mn^~A&mL1qQjEu_)@pcZ=4NswJGD5tdq&}cWH&%^Y@#&O&u z6!{9p9-*j#qL0v+fyTZQ^-0}Us>tD3J-nJqB@G~AT>-hfy{>xWjGhc0j3tcn46%%g3_(mm%zBJL zEaprg)eHHKn OAbW+=zKN{}7%Q6rR~#|NrJ6($-0urj->MS0$lo8dVqw*i}@SO=XqT?rLLi5|@qF%uGa5 zKr$^7Tq_~<(gTMcTEU@LL?y_Lqb(Pu9TByN3%w;oD&oeQb=D3)g%cy~d*8g7dGqG^ zn>QW}hx`cI`h;{vRuKAGbe!he1H1hgp(?tJRGdaB%y3F#Qc7m>fUrqvCFNo+8_Q{T z%ELT1R?^;-kNIruO8Zj*7O=599ZZE-Xb*=0M+Q(H4zGwcM@ z)~Y}6%ST@7-)9LpYx2?%$_K_FUeR90YOoKfp+00rO+4N-BG&mFzu|mDeZHp%c#8hT zQNxEJx%o&tI zKaRPZ8m3WTfRx!1723UIFs--%D0t3Vm{~Ilt77fdNJ6ia5{A>K+~3A=iMuPrSS+n^ zh3QL_;{>b^6N6T)GBvant7w=7k(a&PAdzJmzTG1rswj&tOOu}^MkPV)Jkfo}8LO=Gpr+~Nvc+^}Xd3ASw?X)57l_Z74 znuzNWDgU~^hd9Nlg?#X$~jG9Jg$*6mptZ`gczS zimt%!Yq%=Uy8Nhuvp5rKuXB*IJ`-^)ZS9Ozq^vZIJZSdFgj~XLd_L~wo+c>_BH|<> zFz&TT(IDEwI`>ni6J``OopGgT&;s|+f^O=Ba#=UcxJ*QU8BdTvhLn7XxiJJ*Pv+>D*6$IjfJ-JG7QPtR>mU#w4G zY)sELVwW0Sxy?|n`sTxqzMHWdu|~(xX2(dqW2Dh>ta|QYpr@wv?6^=kkAJ6~;QCrJ zlzatmL~wFk*@%t+hWqeAD-f+z{OC{g7Qd>9eD?&1|Dv}l<@SmWLJ7zy(L&V%?T zj!)KOllKpPJMi_u_p|lW7aOs68eQ|7p?P3;w0AQauSesJ=x8aWkI@1?)Y7p^X zfcu5XelKXVd<2An3imqYo%^4pIok;3qWS2_kT$y@*crQvY=$@MhIbk~uA0VKatihk z1({w4u`OeaAESvnn%F{#Ep%uL^=+YnEi}A^rhf8u*7`^9P2U@P;7eBBPq63H{*U`V zd;JTgHgf8R!O3cW1D}3$eEeSaOYNC>7ItMMO>Iknw*5%*irKZ`q1xE1VrKHu*_rPa Tzp#mn0Ts7BK^r z++r&N%dTYj4AL>#hsnj5!zMRBr8Fniu80RH#0bR2;y~g9Gb1D8T?W~QoI)3*v^Usn O(7VFv*u+)@awhO8#@?pd=1ho-~xGH;2=st)c&g99WLy^qx zF_9c3Wj=t&NCKy5(HMyX_`wC@_QgR8w2zJR4_J@`+J^{s(EzRAsH#Zex6UkiqQkgO z^OgZ_c6N7e?q>EkvojtF`UuePrlnI?T!j1`Cl0|}(Do7~q(+`2I!%%UwP-@Jq=anA z!?-3Tm4wT330Y3M6RM>OSxI^lUdtp$)qbbrR12_GD2FX;j2os2X}GX5#}XQWB02m6Q~>LbOj zBAse35-avU?1nSp`&jA%OOXys-C$|FW%jN?zrUp@Sc-L6>eajV5UuAnTG3?NJCjQ4 z<*H>eTm6YyF-v)F2NTaclltjO&a7C4a_JJa12cTJlsjf}4s(s#Zf+LMoCT6{w7_w6 zpERv({sc(sG1IaNrIVV({O}1o*qT3E$s3k=Iv6)9g*b2OaNFZZnq<2x%v>z2*otMG zcDbB4i#ZH;E93+ZPljiEFR&U(ljo$z-XtUsYd<2tpi5Mz3$W9q zI0dJr+xU(x9EJWwvZs9BuBlkHnYC%Vyjtnk(@NE1v=vdHjTtd%jwE&?=XU zLWT%|3zaw%LE}5FOjK6wKsIZXN@WWi&1P927!AO~W58xRr7ohBb#4&~ZTviX%B#bjCTNlT)C#LTmC-myc9vnx<4oyFEH+ zO?lgEj^ylBq_nh$sO0G0X}Lf(I&2a55x|pm5Wt3D4I#rH2X-5LzZL6w|In`wonO3o{KN7_Y@!~V zs6BN(+;jHTGp}xhhwI@z>)|~c;eEBlb$_h(^DP$%#qaPiy#4y_89%*9XS~Yq_kncU z9e??GbM=*P;0FVTzq9=iuF79>qZS=kg)6{D3eT;BcCaI-<^8R_lOasb1%!eio$8Vr zzVKVX{^>}of{Z|BjVzX{r91@N&mqgIJez~MV7v3CWfY2<$}qBb0n+u-lF3Xq0;_hk z3C?V}WM<1OTY`~c!fA@w7pKSuQB!pwi4YmvfvX>DTx*N{7`7tt@LvM^7Fg>;lj}p1 zf13OA)1N&3*U9y%r#6P>He!i-FaZD#b=O1t*F*a^LRxL^ra$^+=z)*rt5b8=LW!#$ zfO51pzvU&NB)!8C39rvcGY`|x6gu;e@|o)alt;UOe*?^j5CP^VK=?jj*5x(^;t+j^ z1_HYovQW$0Y*iHRCeURziV9fSz7y?u9DEEIqCJ9W2lk~m(2!yLs(ZBIg7M#O;_cZ| zL24o&{cvap`F{W;w2&|TV2}^UzAy5Xw6cSIO(5UtcF1v>!U%SdPMut+D3DcH$~q{m zIC(fseing>eh({YrG#-41Xd8H9pvO@XD$yD(8u%dp!Qeq@rELDb`5TaQFweJccpo_ z|3|=z?RwEDR!z;AM7CN%0@nKyL08`<$`6a&<()Vv81`0Y6nmaZxoTF z3$FLu;1JLVCK<8$hFu2LEjkkTcB>FMly!QRLz|p(`&10)t9}{y?CZGjq zc9=3$P;t$R@@dPJs>Se(E)kLW&91=n1lX*RK-srjb<$=qAYu>{(_bsZvHSpTN+Uy18LgtH+$=bjMow_mp@a0GT zc;strz_w)~O*bTv8a^U5{Y P)z?_Lgyz2_r-uC($Psf7 delta 179 zcmew)xtNJhn~#@^0SF3on6jD}Ch|!*XaIQ)3~>xWjGhc0j3tcn46%%g3_(mm%zBJL zEaprg)eH#mn0Ts7BK^r z++r&N%dTYj4AL=qIg^tShfQvNN@-52T@epZh!Kd3#el>IW=2NFy9}}qIfZ8EZ;;x+ NbA{8kiLD6aOaPg#CprKC diff --git a/backend/backup/__pycache__/engine.cpython-314.pyc b/backend/backup/__pycache__/engine.cpython-314.pyc index 9d2814814e93cf5e9075a9456713f68a51f67d14..ceb472caf373307ebb82d9a9fc05318e106df37c 100644 GIT binary patch delta 1585 zcmai!e{54#6vyxBdwpG3+V$saU)Q>BE$!ZZVA;CKQU+|y;g1?eUt4e^F5TLV!fcz@ z4kd~ZG3-CH<;G}YqSJqL@sA}eCQ}jvgai#n=DG#)g28|M!^99ajN=azz4w)Y{^d*F z=bm%!{hoVXb9(OXS=ei8H5qFWc^bPlC*HNsnOyMkTjRTS4hZ+p&Owl^RLYDDo` zCyE;)8hR9=vLgA;cAP1mmO-CMJwhIoa&G$>kLo*yvUtv5(?N<) zIU@|V7+q}2Ff@rj)w=P^oE87NND6{I=1}AFq~x5Qj1^(rb&ZxHW+EvhdVqFpfSZn?&B-4gabdy0)u}^yrg>69swnL}3hnV-6Vwnf$m&Es2zJ&+Op_slNxCEoVEsX&!DYJ$`b!sOTRj zP-;(Rv&Bb+>Q!5<5wax#&szko&*vkpdCAhEQ`@Vb#lKsQz}V7&^%6k%qP+uRe{jg# z_Qk;Bp@l;gPh?hq#~YZJR$8LViHf&>w)T$4KYwsV>{*UfJO^g=cWvI!h1+ibEqC-M zcXWC1@(U|NuT%N*xhoNLHY)zrg^hQ!<#nE$mriR>)qDP4rB~$?n0hH z*a#!X2yAe8#&Ps4PkQy8K3%d4uINDuuvcoEsNDuqh`rLzQoEzikf=vjdqHYpukPz> zB+j)4klNX6zJnZbt_ML1v)4oQ#Qu&sXe7%GGf1864GT+czRxZ7q93~Y1+v^Ufz-|3 ztn2S3&Z_Y&PZvK(J?v_LrFOH8XjY>jMcLK8R9`_}QbolJ$xgQN6s@!p0?HPkyX`8& zDmztn1IbhAQ5jVuz4nBQS+hXGUbAN9sO@5icCFq}pA0i=!9J91W!8gQl6AdROG4{m z^5ys!exTP%yWnYxCIV3-YpETm+W#|C&f~N*0K(D*=Vt)Bu_%a~MAZp=RM=@#`;BH+ zxZ~;4@vJQ8@vIRcMZi^5JgkJp8(P>(-!4;s8w`8vf2{>>d8RYw^eGzY4a%uKf^ zjN~l^2_DXnLAa#>t>Zo-*y89^+f=97R)*1OoBl)uval@_c|}tw$!}5r2!5k}rdKgn zdw$pBmRJ8$>NN|fs-)#AHG5wxWTvOG`{WOZORFk%;hi4Q{xfRZV$T3HJwTMI delta 1196 zcmZ{j&2Jk;6u{^0tk-tj-K=-xjXxXPN!D3tqt=aEP*S&UN>m9WH5=1L;!wH7r7j_f zcAZ`#ln4n`;!u%}IB-HjLLxVWRSCo?QKV7|DsgitMyUS)hr~#@C*aK*!~rqV{NDGQ z@s8it)U%hA7ZtgW;2JlDTfb}D${f#Ors;3%sqa@26?It-1R$Ac8QiD%s!%p zSsne(0MFnx*$pSc9R|lBLdEUo5YIPAm(;-*JM_3k4?Owxsh)he*z;rWgcyT~W_hq?$3~X84J}z=SUkcepvU3(} zRop3-GHC1$fvt1hd#2PW8t_#l@+{aZRMqj;o(9TOjgMXnpAxSb~77cRt5JXXL? zijVtC=g`*pbkBe-1?@%#=>Z&v_c zzY$I^|1V1p1IPdX diff --git a/backend/backup/adapters/__pycache__/__init__.cpython-314.pyc b/backend/backup/adapters/__pycache__/__init__.cpython-314.pyc index a160e9feda243927d6f3f448d76216ac42aa08d1..797a5420e39cadac9fb600302ba351ee485e3666 100644 GIT binary patch delta 361 zcmZ3@KA%Hfn~#@^0SHc;GG+Z^WMFs<;=lkKl<_%fqPnhC9AglRC%Xqn35Prbkj?7J z>A_XPCC?DV7RwgI9?KEL5zD2|T*4j1Db5hYCC-o|P{I?$t<0dwGcnKDT$Aw@S8%Y0 zV@hH{Noo<0$M2F@l9-fOoC+1X#hR0!oS1Wqxwtsv7DozHa^ngyMphA^J9sA_X8gj& z2V@oTPu|NUEiMdX-r`PAEs0Nrm{}wZR`#CBid_`Q^3&v zf*V9|fCzCA0n)gVp$Md_2y85eO>TZlX-=wLkvvcg7%U9MhCt#2Gb1D8eFmAk4Dw(k reV0M?0~-S?Pe;rR7S0Z<8!UVi_&>0-@G~`Vf9GLgR0JBy#J~UmdCpIu delta 244 zcmbQwv6@|7n~#@^0SK~GnX+0K85kaeI55BjWqfv;sIDshM<&sf49#464Z#3s&= zBT&K-#IDSs$uY6dnEe)OPJVJ?&c+{NjI07ceVmhpnZB@r%r4@d%*!k-&JSeX;!aO3 ziBC*PEGS7WDiQ}PvuCzq7X-5WG&v_XFw4cVgS4=L2w@NbQnZqx2&AG2Yy^i*ZhlH> zPO4pzG*AraWQJlzAn}2jk&*E}gUnq9c_8}0#=y$c5%YnWiJz%~`#T2f_(U0JM)8daOX>yKct0@kuiy{h`@y$>&x7~FWZc{PCnD8%g73oF)+0cf@I)DBM&XSKOX_)8_!cnmuiy{h`@y$hv!K8PzRe5zQW$wy_}?<{ V|Kb16|B3%CQ1~wY=C|{O4FI&I7TN#+ diff --git a/openspec/changes/dockerize-and-pyproject-setup/.openspec.yaml b/openspec/changes/dockerize-and-pyproject-setup/.openspec.yaml deleted file mode 100644 index 81cd71f..0000000 --- a/openspec/changes/dockerize-and-pyproject-setup/.openspec.yaml +++ /dev/null @@ -1,2 +0,0 @@ -schema: spec-driven -created: 2026-05-11 diff --git a/openspec/changes/dockerize-and-pyproject-setup/design.md b/openspec/changes/dockerize-and-pyproject-setup/design.md deleted file mode 100644 index ae7e113..0000000 --- a/openspec/changes/dockerize-and-pyproject-setup/design.md +++ /dev/null @@ -1,77 +0,0 @@ -## Context - -The backup tool currently uses a flat `requirements.txt` for Python dependencies and requires manual setup (venv, pip install, npm install). There is no standardized deployment method, making it difficult to run in production or share with team members. The codebase needs modern Python packaging and containerization for reliable, repeatable deployments. - -Current state: -- `backend/requirements.txt` with pinned versions -- Manual venv creation and dependency installation -- No Dockerfile or docker-compose setup -- Frontend served via Vite dev server in development - -## Goals / Non-Goals - -**Goals:** -- Replace `requirements.txt` with a standard `pyproject.toml` with proper project metadata -- Add multi-stage Dockerfile for the backend -- Add `docker-compose.yml` to orchestrate backend + frontend + optional services -- Support both development (volume mounts, hot reload) and production (optimized builds) modes -- Maintain backward compatibility with existing manual setup - -**Non-Goals:** -- No changes to application code or API behavior -- No database migration (SQLite remains file-based) -- No Kubernetes or cloud-specific deployment configs -- No changes to frontend build tooling - -## Decisions - -**1. Poetry vs setuptools for pyproject.toml** -- **Decision**: Use setuptools with `pyproject.toml` (PEP 621) -- **Rationale**: Simpler, no additional tool dependency. setuptools is mature and widely supported. Poetry adds complexity without clear benefit for this project size. -- **Alternative considered**: Poetry - rejected to avoid adding a new tool dependency - -**2. Multi-stage Dockerfile** -- **Decision**: Use multi-stage build with separate builder and runtime stages -- **Rationale**: Smaller final image, faster builds via layer caching. Builder stage installs build dependencies, runtime stage has only necessary files. -- **Alternative considered**: Single-stage - rejected due to larger image size - -**3. Backend-only container vs full-stack** -- **Decision**: Provide both options via docker-compose profiles -- **Rationale**: Default `docker-compose up` runs full stack. Users can run `docker-compose --profile dev up` for development with hot reload. -- **Alternative considered**: Separate frontend container - included as option but not default - -**4. Base image choice** -- **Decision**: `python:3.14-slim` for runtime, `python:3.14` for builder -- **Rationale**: Slim reduces attack surface and image size. Full image in builder for compiling native extensions if needed. -- **Alternative considered**: Alpine - rejected due to musl libc compatibility issues with some Python packages - -**5. Frontend serving in Docker** -- **Decision**: Build frontend in Docker and serve via backend static files in production -- **Rationale**: Single container to deploy. In development, use Vite dev server with proxy. -- **Alternative considered**: Separate nginx container - rejected to keep deployment simple - -## Risks / Trade-offs - -- **[Risk] Python 3.14 compatibility**: Some dependencies may not have pre-built wheels for Python 3.14 - - **Mitigation**: Use slim image, test build early, pin compatible versions - -- **[Risk] Docker image size**: Including Node.js for frontend build increases image size - - **Mitigation**: Multi-stage build ensures Node.js tooling is not in final image - -- **[Risk] File permissions with SQLite**: Container user may not have write access to SQLite DB file - - **Mitigation**: Create volume for data directory, set proper user/permissions in Dockerfile - -## Migration Plan - -1. Create `pyproject.toml` with all dependencies from `requirements.txt` -2. Create Dockerfile and docker-compose.yml -3. Test build locally with `docker compose up` -4. Verify all tests pass in container -5. Update README with Docker instructions -6. Keep `requirements.txt` temporarily, mark as deprecated -7. After validation, remove `requirements.txt` - -## Open Questions - -- Should we add a healthcheck endpoint to docker-compose? -- Do we need docker-compose override files for different environments? diff --git a/openspec/changes/dockerize-and-pyproject-setup/proposal.md b/openspec/changes/dockerize-and-pyproject-setup/proposal.md deleted file mode 100644 index b9674c7..0000000 --- a/openspec/changes/dockerize-and-pyproject-setup/proposal.md +++ /dev/null @@ -1,29 +0,0 @@ -## Why - -The current backup tool uses a simple `requirements.txt` for dependency management and lacks containerization. This makes deployment inconsistent across environments and complicates dependency resolution. Converting to a proper `pyproject.toml` setup and adding Docker support will provide reproducible builds, standardized packaging, and one-command deployment for users. - -## What Changes - -- **Convert backend to pyproject.toml**: Replace `requirements.txt` with a modern `pyproject.toml` including project metadata, dependencies, build system, and optional dev/test dependencies -- **Add Dockerfile**: Multi-stage Docker build for the Python backend with proper layer caching -- **Add docker-compose.yml**: Orchestrate backend + frontend services with volume mounts and environment configuration -- **Add .dockerignore**: Optimize build context and exclude unnecessary files -- **Update README**: Add Docker deployment instructions -- **Frontend containerization (optional)**: Dockerfile for production frontend build served via nginx or integrated into backend static serving - -## Capabilities - -### New Capabilities -- `docker-deployment`: Container-based deployment with Docker and docker-compose for consistent environments -- `python-packaging`: Modern Python packaging with pyproject.toml, proper dependency groups, and build tooling - -### Modified Capabilities -- None (this is a build/deployment improvement, no spec-level behavior changes) - -## Impact - -- **Build system**: Replaces `requirements.txt` with `pyproject.toml` (standard modern Python practice) -- **Deployment**: New Docker-based deployment path alongside existing manual setup -- **CI/CD**: Enables standardized container builds for CI pipelines -- **Developer experience**: `docker compose up` to start full stack instead of manual venv + npm setup -- **No API changes**: All existing endpoints and functionality remain unchanged diff --git a/openspec/changes/dockerize-and-pyproject-setup/specs/docker-deployment/spec.md b/openspec/changes/dockerize-and-pyproject-setup/specs/docker-deployment/spec.md deleted file mode 100644 index 38e0578..0000000 --- a/openspec/changes/dockerize-and-pyproject-setup/specs/docker-deployment/spec.md +++ /dev/null @@ -1,42 +0,0 @@ -## ADDED Requirements - -### Requirement: Docker image builds successfully -The Docker image SHALL build without errors from the project root using `docker build`. - -#### Scenario: Build from project root -- **WHEN** developer runs `docker build -t backup-tool .` -- **THEN** the image builds successfully with all dependencies installed - -### Requirement: Docker Compose orchestrates full stack -The `docker-compose.yml` SHALL start both backend and frontend services with a single command. - -#### Scenario: Start full stack -- **WHEN** developer runs `docker compose up` -- **THEN** backend API is accessible on port 8000 -- **AND** frontend is accessible on port 3000 -- **AND** services can communicate with each other - -### Requirement: Development mode supports hot reload -The Docker setup SHALL support development mode with file watching and automatic reloading. - -#### Scenario: Backend code changes trigger reload -- **WHEN** developer modifies a Python file in development mode -- **THEN** the backend service restarts automatically -- **AND** changes are reflected without manual container rebuild - -### Requirement: Production mode uses optimized build -The production Docker setup SHALL use multi-stage builds and serve static files efficiently. - -#### Scenario: Production deployment -- **WHEN** developer runs `docker compose -f docker-compose.yml up` in production configuration -- **THEN** frontend assets are built and served by the backend -- **AND** no development servers are running -- **AND** image size is minimized - -### Requirement: Data persistence across restarts -The Docker setup SHALL preserve SQLite database and backup files across container restarts. - -#### Scenario: Container restart preserves data -- **WHEN** docker containers are stopped and restarted -- **THEN** all existing backups and job history are preserved -- **AND** no data loss occurs diff --git a/openspec/changes/dockerize-and-pyproject-setup/specs/python-packaging/spec.md b/openspec/changes/dockerize-and-pyproject-setup/specs/python-packaging/spec.md deleted file mode 100644 index 710a779..0000000 --- a/openspec/changes/dockerize-and-pyproject-setup/specs/python-packaging/spec.md +++ /dev/null @@ -1,32 +0,0 @@ -## ADDED Requirements - -### Requirement: pyproject.toml replaces requirements.txt -The project SHALL use `pyproject.toml` as the primary dependency and build configuration file. - -#### Scenario: Install from pyproject.toml -- **WHEN** developer runs `pip install -e .` -- **THEN** all runtime dependencies are installed correctly -- **AND** the package is installed in editable mode - -### Requirement: Dependencies are properly declared -The `pyproject.toml` SHALL declare all runtime, development, and optional dependencies in appropriate groups. - -#### Scenario: Install with dev dependencies -- **WHEN** developer runs `pip install -e ".[dev]"` -- **THEN** testing tools (pytest, pytest-asyncio) are installed -- **AND** development tools are available - -### Requirement: Package metadata is complete -The `pyproject.toml` SHALL include project metadata such as name, version, description, authors, and license. - -#### Scenario: Package info is accessible -- **WHEN** user queries package metadata via `pip show backup-tool` -- **THEN** name, version, description, and author information are displayed - -### Requirement: Console scripts are defined -The `pyproject.toml` SHALL define console entry points for running the application. - -#### Scenario: Run via CLI command -- **WHEN** user runs `backup-tool` or `uvicorn backup_tool.main:app` -- **THEN** the application starts successfully -- **AND** the console script is properly registered diff --git a/openspec/changes/dockerize-and-pyproject-setup/tasks.md b/openspec/changes/dockerize-and-pyproject-setup/tasks.md deleted file mode 100644 index 88b0591..0000000 --- a/openspec/changes/dockerize-and-pyproject-setup/tasks.md +++ /dev/null @@ -1,32 +0,0 @@ -## 1. Python Packaging (pyproject.toml) - -- [x] 1.1 Create `backend/pyproject.toml` with project metadata, dependencies, and build system -- [x] 1.2 Migrate all dependencies from `requirements.txt` to `pyproject.toml` -- [x] 1.3 Add optional dependency groups: `[dev]` for pytest, `[prod]` for gunicorn -- [x] 1.4 Add console script entry point for `backup-tool` CLI -- [x] 1.5 Test `pip install -e .` works correctly -- [x] 1.6 Remove `backend/requirements.txt` or mark as deprecated - -## 2. Docker Configuration - -- [x] 2.1 Create `.dockerignore` to optimize build context -- [x] 2.2 Create `backend/Dockerfile` with multi-stage build (builder + runtime) -- [x] 2.3 Create `docker-compose.yml` for full stack orchestration -- [x] 2.4 Add docker-compose profiles for dev (hot reload) and prod modes -- [x] 2.5 Ensure SQLite database and backups persist across container restarts - -## 3. Integration and Testing - -- [x] 3.1 Test Docker image builds successfully from project root -- [x] 3.2 Test `docker compose up` starts both backend and frontend -- [x] 3.3 Verify backend hot reload works in development mode -- [x] 3.4 Verify production mode serves static frontend files -- [x] 3.5 Run existing test suite inside Docker container -- [x] 3.6 Test data persistence: create backup, restart containers, verify data exists - -## 4. Documentation - -- [x] 4.1 Update `README.md` with Docker installation instructions -- [x] 4.2 Document environment variables for Docker configuration -- [x] 4.3 Add troubleshooting section for common Docker issues -- [x] 4.4 Document both manual and Docker deployment paths