From acb9958059c964167f6da326b9f49bd430670e51 Mon Sep 17 00:00:00 2001 From: ali_mohaghegh Date: Wed, 2 Sep 2026 18:15:57 +0330 Subject: [PATCH] docs+data: refresh demo dumps (clean seeded state) + restore/seeder docs - backups/procurement.dump regenerated from the clean seeded state (was the junk test data); README documents both the app seeder and the restore path - docs/casdoor-auth.md: later-batch changelog (fulfillment split, demo seeder, API-driven topics, hub-and-spoke, count modal, FOUND ceiling, semantic colors) --- README.md | 30 ++++++++++++++++++++---------- backups/procurement.dump | Bin 93162 -> 94340 bytes docs/casdoor-auth.md | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index f63715f..db1ebf1 100644 --- a/README.md +++ b/README.md @@ -201,7 +201,7 @@ docker exec -it procurement-postgres psql -U postgres -d procurement The databases are **not** in git — Docker volumes hold the data. To let everyone see the same system state, the repo ships exact database dumps in -`backups/` (taken 2026-09-02). After a fresh boot: +`backups/`. After a fresh boot: ```powershell powershell -ExecutionPolicy Bypass -File .\backups\restore.ps1 # Windows @@ -209,16 +209,26 @@ bash backups/restore.sh # Linux / Git ``` This **replaces all data** in the `procurement` and `casdoor` databases with -the committed state (users + roles, projects, warehouses, quotes with -receipts, inventory rows, Casdoor org/app/users). To create a fresh dump of -your own current state: +the committed state — a clean, realistic demo: 3 projects × 2 warehouses, +4 suppliers, 12 materials across all 8 categories, and 4 quotes covering +every lifecycle state (offered / in-transit / partially received / +completed) with matching stock. -```powershell -docker compose stop api casdoor -docker exec procurement-postgres pg_dump -U postgres -d procurement -Fc > backups/procurement.dump # (Git Bash: use -f inside the container + docker cp) -docker exec procurement-postgres pg_dump -U postgres -d casdoor -Fc > backups/casdoor.dump -docker compose start casdoor api -``` +Two alternative ways to get a clean state: + +1. **App seeder** (realistic demo data, keeps the Casdoor org as-is): + ```powershell + docker exec procurement-api sh -c "cd /srv/backend && python -m tools.seed" + ``` +2. **Casdoor seeder** (creates org `inventory` + app + users razaei / + mousavi / mohaghegh / tester — run once after a fresh volume): + ```powershell + python backend/tools/seed_casdoor.py # from the host, or from the api container + ``` + +To create a fresh dump of your own current state: stop `api` + `casdoor`, +`docker exec procurement-postgres pg_dump -U postgres -d procurement -Fc` +(+ the `casdoor` DB) into `backups/`, then start them again. ## Common operations diff --git a/backups/procurement.dump b/backups/procurement.dump index fc2bae18053132728aebb41231f00c4cf972effb..f5368d8e1840e5cdfc652f6d8b2cf195d31bd34d 100644 GIT binary patch delta 10144 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 delta 8965 zcmXY01ymJl5a!a|jWkNfrMtUBkPb;H>4v3C8l+1k1nH1QIwUS7jdXW6Jn*^a%-%io z$C>Y&ng7nt2Cu;FPQwwZ%1A1yf-s?A5kVj*B&g?${pE&GMJS>Ry(Uwmqss(B_Ll{{ zD50RJcOV4`@<%5npR?~^*(ffcFlJi1`x8i z&c7K_e;1$IPCzf|Bo5e3fJSSw?72Y58m9jyX#E9v`f(cC%B*J4ffNKCVwSk;_ynD3 zUbE)}3xX!HNIY?VfQGTGId%bokPj{YE#&>XGp1WRGK$qd7587&k=qD#p;h8f_jTwD z>%;;NPY_!Txo7KpI501mkE>>7z907QBS%g7@)b1li@Q=bHa}AoY1e zkId+V)@Xe&YVcaUroO#Hhf%}=m43(TBs$IIN0Zi1uRH>V5xQbIa1Qx~xOtgj@T}Q* zae{xfOlQ)09&|KN!JDP}&+W2#;YvoLs9lWhrZ2|Z(C&xqg~NAZX899Jj`s`PT|C^~ zI)j~HT$UfDuBp7#yxj=6A49Hznc+MWBHJ>g5?`@js-jBObheHA9C_8dge|$271Y0c z!?8g%CDGlP<4c(IA{#BHrxKGj3(|qgWVvDJEm0=(Wbd=Ltx_lr75npXx2VGk*EhS(}mh;}^j4R>sgn6ZiR{j(kk z5;jb~nBU3^+bT6HenvL~4(x~funGd}IIfC)&%&=HaV>v%;rNP>$MzWoDEyZEn;9S| zK8)vw=x6cBl!~fCg9f8Q?U_X$#T)%dj6Fc@fL)@=VME6A_J>8Ahpj@5rK2n7U(8}K z<@v5^i-eiNqS`~OjYJ%tJ~_G25Ic`iPew{jD+-q!!G5u^h;Qym%WJM4Va&g?Zlv(afusSo zzagXMiqrDy#)_(jZy6NRku;8cZgRq-M#7u@AH)f=YLV+IWcpG0r%sJQ~ab& zN7GA#p=k+>a?4+&9r}Q6TRtB@_rs^~Lp&zZ91xbXaSGF+-=f1bY?- z_1P2C6rJ3tfIvp99s`~Zz*k^eY&aN$36<(iwTUOBU5gGd64XhQaM@d~7ZxII&dR2KA5yJ^vXh zTJ&H1x2uX>8vCND$PPBh_-2uB&9bSAZ%5>EP-v z<>9e%>2OKq-QD8a@Z;Kv#TQW|@c@5>e5KA_uc4$*`R^u-+dNY{KZdcR+ATw!`M1Bd z^Yh^Rrp-@O-5t2qI+d@BA|EKr&a6*7le*ly9k^*P^qas8zprJ;arKn#fX$rl7gA}j ziP)m-DS*QENpCdzCRII89FiJ6DWsY@R6WA&tPmHC=tV|WpvazhCFa@-2G&qMk#=}LGG7|c& zH1W|`deb}lY?HwZlle%p3yr~3RdYrbr{vWSmw?NSoVzrhhk(H>xYBHbV-NX1Yr z7^E3d>X4a+r~;bUj_b;7)4Ajg+bBNuthiWhDBoip8AM3=m)#04E|&Z2;?HB?m{)9w zaHDh1kq6Y$gfQIB;hDxHm14ySR97jh^grZqdbq-$+H7!l_~EeU{iP7|fa+Y5z0qiO zHM>*wouG~_(dA;~O^w_{JjykT={J;3Lhz%ja8caGXd-Np2HlNooj-v4+bofc*sp2a z9o~oz5P{}T?f8A*p5rVft1+A-o17&QO8RB!baGOoMMH@kemmvc&}+;zg?C1AP8!w5 z0SNH>vK!U2MF(!<&b_VTzyLB&lEf=z#OQO?7DHRB)b+yA3!2JJXpyZvTRIhXz62xW zynq_@mGIkUfzWXGp}a&6tg^}nCARj*u^Xv(lq!3Zu5CyU++P?GM+{)gu`3%=S=_!i z!Y7TPzxmaR22<>h!9HUVDAjV+hL@D1r77S^7hZZ-aO8i;;_&`*A8;KhxF-;M6w~%? zfy;sPt(_qBi^k3W<5u~F+wo`d$ow2P=m-Z!goQLW9wTES(i0e6hu=$7?lT}5v*>?2 zBvNm1j)75h4th%j%h1X8yIHent44q>otP?KbOuJhsr>^vIyPwrnHEZqQf?>w>VBoN zfjU}RAn;~ti}HT?sO9U?Eb(+&Dg`HjZ6eajR~Y6XS0N!4sx>^;<{?cSEw(P5tRTVG zmM2DTMYJloSpr&4RG&H6DaBdsFhMfQ80N2s9Dc;}vf3WFR9Z0^%teEV>Ut6Al9~Z7 zG~N3keXZUSgYwu%&!56acYZM7WZk;|Ap%f}FBlL1Vyqhl+rMBO^}52{q1N&TWe7~#>RNpfMv5l+fH6n?_T7M(_TU>X9~3n#Z;PRR!m zQ5bgT=L+HCmF{82YDm9YpUfbW7kJFwVYMy#Tge4vj2iSz@)N1hZ@R!`hw_=%LXl0KT>rg4brAWfQP(OC7$vQg-SX z)9}M}Wf1=3LUP!~fAGf9ABj|(0B4KOo;t_f(Ou@`E#~Z1i$cdD+-a%WR}Q<~L~XhN z5KeIb4iOW})|;5{vSuL>#^m}cllY9zQ6}Ruv~15D0L3$2PTtqzmC2?PqC5lZqKiW- z89sIlAt3PfiRj6v)v&@S&)Iw8e^Q_{UN{MVmgnMbs1fhEVt{KWygK#N)k!!olyzx* z!p?;qN3s~;_AP9mrs-$zIw|nD)_?N_w>||@eOR-sLbtvXk(J{3Lz49C@xIzY>uS-$ zd(3w-Nt~T|LQ%HFt*NwS^P%d_;U%;bfoLv`UR-01oRR6A^xz2Ad|3x|!i?7(^#^+w zOXr@k;I>)`=usHI z)q(G|eem!lciQ$?EqCwghv)Ub3p%E13eJ)5wlD(1Ef*cH^ih321qAnwd?pz`jp3}d z@Q4~^Nk!XShN^1aAwmLM$;V^&@rQ05u)C{%fN@+RC^gRoBh@I#?ar_Lkb81Lm&Hi< zbZ`A=Yjyjni^O#`IJD(bL$$q#4KtFkIjxQltmPJU0+`lulOt`k%BJD$ev>bc0P z9m@t_`b-c)P9^SW^3PAAFMi_vpOpAPyXOij81i%}E|GVQnc)EEy&|zo)BidIb^ttF zx?+*%ikc(g4~5ZvoI&|MAy(I4fb?5~SS`14Q%o5jNwI!U!LUO>6F%l$DB+)6&(Fa; zkS{63@Ugq?3Yc`(fz#_8D?qUhZu0cQh1b2`z0aj{+s{9vA1bN{r-;#H6^&QbJ}kbr zpn~8%A&gER|K{&J<%bHwi&8g9wX^>WPI-X27G$1>*L@RZ2E%TW8U-5Ai}d8|XejLA zXUD1Z$b2mk-U>HUQ?JV3cKr*#SQig|5uuA4%SoM6D78<-gSC;q*p7)!$|Xst?J;>rjRRh8(l zZV>PHs;Le}5^JzTVYV|Ph_enkPxwp3>-z4ldrpz;HWT3?$l!yc$j_0bt*%-@Kyh&K zbaZdpoaaJ_b#Qvkk4<7IN5r={NQ~Ma6qSQmFR7P+2Hzn{j=7}Lw-1v(PE|XHw2v)b zoe5HlC{;avb8m2UHgPUODXhIVM7+*S`iYV3_uJ#K6!eHP2`cDbbsDLt+1m`tt)9c4lVgho)fo_zWuIDCEo> z#*Ko9+S2lQAm-^9gAczyw%<{xJN>fBt#`R^AnH5e5&HP3|1V!8Uh<{tSv)eChgD>VV)51P#p~E|Pf$Cyb_*TAPkHlB@ zsbgDiLghz$Rf|hGufNt2gUY2Tq|w{-zq}jJ>394!LpTdX;?RnfEooULp*gUQ=4i>H zJMBn%!CYoU2U*H3b5t~Z z;2}(T5hhDSP#Ay0wHR5OBq%sM&c--Zx2C&{CgOK-k6b0}w_orHG-51T?MWp}0B(ex z>jVGv8UK(HXo+***Ey%_2lrvCoicXGrr!8E-=qu zI}jP?Y-vkeb9QeCI9K#J>y?m7OIYweY*Zja1k=LB)7_y;M?#LZMWe{Cv4S4xu=7>d z9lC+sfX>?_i6|P4kQMqcB5~gU%5FN{UnjAb0Cln1XSRR*( zCM;N*{YHp}GTO)y)>~vA6h()Q;{~Dv9x{JsqMNANnrc5COn=J{#k@hoL$IJ6)QXP3DVl2ZM#M|7W-|EQ$AbxL-#2& z{6>UC-e@6R>ABEYpa)&U2^4zx_7)pvElfTcu|+VXA<7lA zPqtNqyt={x5sW?J*xkd-a&j8q^V8KszV{|o(q00Evxb->B?f(iv?t7Nd_s<-94Bu% zfL7sRi!P+>a_@T=A*|AsZElev>+9xOwEUqa&-6&a`Gsrl3`O)J54UYi=_va%yr$vO zjYY!j!`|C&;{DHDyyUdjPDq=Se(JQQQ86LX2b6V=>R6@CvasA{iCP%jO|sp>a6d5nt%K;wQD@0 zwQEr_lwlBMyRs|SYtdSn8z^YZnL$4O@*bF|010&0()$)g^HFkl7ctB@pD!pR=F_vX zYO;dEeDXT)^}=?j@c^=M zaWD6Umcy(DuI|`5isl|xAoasv_O|B0}uJm(NF>&wCa=G!G z*XC#i;m=S_$XA4upJk>?WAPPfcgHJT{OWgMgzRggxjgNMXosF4{ScHpOPFs}Z<&2F zlMLbZ;OkAJ1W8WKm&Q)x`vhGNybpk~xjmGGKh6ozg_A+VoY<9V2(m)h0`$Pl_kg8P zlx>p7um=lqP86??HwRaBA14y{AN<%3jqb_UWUua^j>x#k^QT~UAJ0b!N;!@ra>=;A zOnl@s2t10g{+)fswFI(!Blcdu_$#@gw~D22xI6N7(KR!A<<<)9jVYsF{gDZi^a=^&7)cFcM(Hsp)QZ*aCYh^(xY`)cuHOG$I(pYY0JxktzyIL zyDx$nMOKIG>2njwET+neQ5vhmD{sFvsiCAveN`EkxL!nrUI2|9%=%83;4sVuf>g=D#B2P{o`?eTmMZKC^9$TIwmHq&!nlqrt& zyd9paek_+eQrW z+xJnFnQ-(;JSdjexNmKF!SOcs;wn?ElG1Ex_;H_Lnm8wn%wc+n2hR(b+HWSju7sPs zrcHCD9QAg{ZWR>~vBtCBT<&<4!@v2vPfIUo6qx<`r@eRHHtY$1-Lw&<_ZH7$sYma^ zXv;+4r)Jg0YO{0VBEp*C%BnZI@O%w|SAo6lohc4n*Mw{2(K~|g1V$Rx{DLPnD~D6J z8;0J?0N;{+(J;yQ=aZvtdt4)l7?U!0`=8Bv)n+?=%alv z+c(Rda2~CuQ%;OuUU6qQTQqiXtwy#sL9!A3rO7QV2IJ9w_^sN28iTOVUb>{L(68t- z{iGvH92}wO^?{a1=L(}7%Z!c2&B#54MyJB@e$;Ym3-6=(9&=9&YfC4C@_}0Y{09)$ z)IHHJwfHJdtZX}0#*J{Mv4sS=rG=`kvX9{X>~~Xh?C}MbpQ9vm&MY6;3Y87`-}zSb zyQAbR3^_MQ%|K8933zI>K#^{T#evQ z#OGoz`eiQrI}3BjyQ@!KiqEJz>Q3>mZcJe#*nEDSSf1*9m@C3R^v9!aX6a zChW|%BWfTIn7p6g_Efd=u1UdaX3OT8X_vFUKs3!%8Ru9d<|U`4>z3nu#q!Cl^NTDJ z+m6yNRPPf_9es)E^e-DL>3WZFc)vRe5{;m1r8^MWpwZ*k;obdwUFq$WWGSI zp<`1KZ&Fco@`J}d?%o48ug)7MPP3AaYJG|}1eljT+$aya>$d%`y3Z-!0K5uf#t5`L z67T{5-?F8hW92Y+{+5ZAEc7E6kD@LC(m(&J?jb-C*=;q&85YEWDxNS~CRj}sIQv8v zgR-$nz>-S)^Gf;Q=c5$lYTO8`GJIC~)_weE;$znNQ9eNXAh5F}_w-NoM85OXH_;bM z{)9vgF0A}l0;#{0K+ezNk%=~3h1Si62-VL2Cj^mgrgD(S`1q09=QgoCMq^TPMhjg% zk&+RYJxGuVs7Mh8+qm9^=Dx+;MRH>a$}qd>jGE{YuQyia?FChv1z6GqkHu5Hj=5t~ zS*RySD#s}P#d8APqTfm~#u~FE(0dJI)=T?R+CDcmpd?>xfcyWwFiyw`h7whJZ&9NG zVkLtup8MR>S%$})q<4Z=VcD4vCZ(-9(*W{KmnS5S&Me*vQsnQ$uLgYaicqzoWNbt~ zYoO^+lf&c04oDiK3{ww~Q8ox|pfQqnI9SBSEx`)*@?U@tGB37|tgCHftA@5P76KoF z+`DPJH|~7^Ioi%FTa2b+EbDv3q^a9Mn=5ms>A{NwuNyw`=3{OGv)`ucD!J4X!m{j4k_%#IWVC+JrDI&2{V3lPD7|wHPLVZ#?jAfolj4zC z5GU~5JwTP%OVhCZIVzfPQMJYNfd){HyQBW&(!q@)$qaWIKUcE8j_zEBJieIg#gs}d zfSy(COv=)bFw~xeNHZ0zOBL|$f?gr?nl}`^uNOzq$A6o902`6eR2yEJ)z63g*JsuR zceZMfmN9_&XY%lU3K9Lz8DLPLcRjab`{TDWovy)3ySe@T)T=;PlN4ht`rZ#YCez6^ za!X>KuBJ~W_WtJ-jh;a}ni-M5w=!<6C(8p1fA+5y#EN^*jVcAz ziPn^guJWf!cf{mSR-}B!MNmhXnML|Qnai!^a?&$vsPIH`v&RoPLjWk{{A6C@<2gXY zUIN7JS)M-$bv9%DZSc&L2WE~%(}?I@;)%hfTk@-~EUP0g)W~gCF1fI+3$;2aUNZFZCdqr#ZB8hUi)&{QM6b3me( ze@HQggvUmD9E znOTrlH5f6}&=rr0$U&k-**PNvW*XfOJe;tTP)MyF4qSvhU1`WrJxfD(R_YlXJg`5o zDJeN*FVNGdGqebH=^K!WWrFAQDLl=#%Za?+VcYpeZXLTmwk-UqsF<$5xWt;Y75s^c zQB*X6*s$Ul5RYOEQ_i?zs$5I^haD^B)W2bSojMgc%Ckb2J#L7!#Hz=mHdv5zn9C&A zI2uo#Z*#mZh`V|{DZ=$Jo65gdeNOI@POm!wps}Dz7wGEmI(lNTB9a-XrqAPI+&D@Y z6rqWouVz}xsPNcNIkE+H0~>!&9^V8d>m;$~4^BcwsjZW$iw3_Jxx$WNLB)@W{)w`a zD6k<+PRKkFAOcDXkHn8d=A~&&oR|ijlX*K=#aBCQ9@d|cvFKsAvMD&Yma*BDi1b_B z3nGJsIo^)IAbR?vtM?~aV!%mAxDHM~Y&e~H937K%oK7&wY7$U#Ks583dK6I6l<8d`mpl9(dBzKSHH7A z1k3=lM$8y@-)Y0I2(}I;dS;?)Vn4ch6@KjN`6L^ape{^Nmk*|~`MPP*s?Dnn_nRt6 zU2~UGlcy`6Un3Zh{i^3#=Fj!H-3B7G++Pg&8J~P~H~6rDWp(x5Pn-ozdTP`DwweKv z79*)8mB7R*Z8zM|LDgNm?g!D3!iAfhH3FqKm$hnCbR&DS(NZ#rhEwxG^M<{r_Tl5_ zqb_(Nm@!8nOMK#0RDzP+6yN-2*LADv1mz_`L*2nY}gvzqj`u_W)%JO0DOLRYnx6(@{i~RqO z1B`*yNng5XUQ6`b9CPtz1G-0)yr5{iSp<_eUj~Gr2T)Pva-2O@*ssOn192-)UX)Xa7v~1uMuL)UI!^kiG72cv9^@Wz*WIgD7WKli`hyEJGr~K zWA}@`i`66KgSKyXlWM3rH2bc^*3B9Y6k)U5;j_~zARuuFePyTc9A1wfx@Ldam_KoE zY<%1YSL8V+a?oO