From ce3f56cfbbc51e32cd0a6b7e2b9f27dd9262b0f7 Mon Sep 17 00:00:00 2001 From: DarKylX Date: Wed, 21 Oct 2026 14:47:53 +0300 Subject: [PATCH 1/6] feat(vacancies): add active and archive management with UI Kit tabs --- .../feature-specs/vacancy-archive-20261021.md | 52 ++ docs/vacancy-archive/archive-modal-1440.png | Bin 0 -> 99222 bytes docs/vacancy-archive/archive-modal-390.png | Bin 0 -> 66524 bytes docs/vacancy-archive/browser-acceptance.cjs | 203 ++++++ docs/vacancy-archive/browser-results.json | 6 + docs/vacancy-archive/verification.md | 47 ++ docs/vacancy-redesign/preview/main.ts | 55 +- .../edit/project-vacancy.service.spec.ts | 119 +++- .../facades/edit/project-vacancy.service.ts | 152 ++++- .../edit/ui/project-vacancy-ui.service.ts | 12 + .../src/app/domain/vacancy/vacancy.model.ts | 4 + .../project-vacancy-step.component.html | 604 +++++++++++------- .../project-vacancy-step.component.scss | 171 +++++ .../project-vacancy-step.component.ts | 34 + .../vacancy-card/vacancy-card.component.html | 25 +- .../vacancy-card/vacancy-card.component.scss | 22 + .../vacancy-card.component.spec.ts | 23 + .../vacancy-card/vacancy-card.component.ts | 14 + 18 files changed, 1312 insertions(+), 231 deletions(-) create mode 100644 docs/feature-specs/vacancy-archive-20261021.md create mode 100644 docs/vacancy-archive/archive-modal-1440.png create mode 100644 docs/vacancy-archive/archive-modal-390.png create mode 100644 docs/vacancy-archive/browser-acceptance.cjs create mode 100644 docs/vacancy-archive/browser-results.json create mode 100644 docs/vacancy-archive/verification.md diff --git a/docs/feature-specs/vacancy-archive-20261021.md b/docs/feature-specs/vacancy-archive-20261021.md new file mode 100644 index 000000000..36678698f --- /dev/null +++ b/docs/feature-specs/vacancy-archive-20261021.md @@ -0,0 +1,52 @@ + + +# Вакансии проекта: активные и архивные + +Дизайн согласован пользователем 21.10.2026 сообщением «по размерам UI KIT, 26–27 px … можно в дев». +[Figma](https://www.figma.com/design/tvog0fpEgWgEtr7KUTjbyE/PROCOLLAB-Design-System-v1?node-id=776-5414). +Высота обеих вкладок — 27 px, без общей серой подложки; Mont в приложении. + +## Исходное и целевое поведение + +Angular dev cc95cda8: общий список вакансий, native confirm удаления, ошибка API не показывается. +API dev 1c424ff: PATCH is_active существует, но не завершает ожидающие отклики; DELETE не защищает историю. +В Figma зафиксированы два списка, перенос, возобновление набора и модалки с последствиями. +Архив соответствует is_active=false, отдельная сущность или миграция не нужны. +Создание и редактирование сохраняют существующую форму, навыки и серверные проверки. + +## Роли и правила + +Изменения доступны руководителю проекта и администрации; сервер повторно проверяет право под блокировкой. +Закрытие отклоняет только ожидающие отклики с email-уведомлением после commit. История сохраняется. +Возобновление допустимо только для опубликованного публичного проекта; прежние решения не меняются. +Наличие любых откликов запрещает удаление, включая архивные вакансии. +Блокировки согласованы с откликами: Project → Vacancy → VacancyResponse. + +## Контракт + +PATCH /vacancies/{id}/ с is_active=false/true, DELETE /vacancies/{id}/ сохраняются. +Добавляется readonly total_response_count во все представления вакансии; +response_count сохраняет прежнюю семантику ожидающих откликов. +DELETE с историей: 400 с code=vacancy_has_responses и detail; чужой объект — прежний отказ permissions. +PATCH закрытия атомарен с завершением откликов. Запрос без is_active не меняет жизненный цикл. +Frontend использует существующий UpdateVacancyUseCase и не заменяет server-side checks. + +## Acceptance criteria + +- AC1: руководитель переключает активные/архивные; счетчики соответствуют данным проекта, вкладки высотой 27 px. +- AC2: после подтвержденного успешного закрытия карточка переходит в архив; до успеха список не меняется. +- AC3: возобновление возвращает карточку в активные; прежние решения сохраняются; непубличный/черновой проект получает объяснение отказа. +- AC4: удаление без откликов требует подтверждения и обновляет список только после успеха. +- AC5: с любыми откликами удаление запрещено и через прямой API; UI объясняет причину и предлагает архив для активной вакансии. +- AC6: ошибки оставляют модалку открытой, повтор доступен, двойная отправка блокируется. Ошибочный запрос не отклоняет отклики и не удаляет навыки. +- AC7: пустые списки, неизвестное число откликов, мобильный экран 320/390, keyboard tabs, modal Escape/trap/return focus не теряют контекст и данные формы. + +## План и границы + +1. API: атомарный lifecycle, защита удаления, общий счетчик истории, regression tests. +2. Angular: состояния действий в фасаде, фильтрация и вкладки, существующие Card/Modal/Button/State, интеграция с use cases. +3. Проверки: API/Angular targeted tests, build, browser fixtures для desktop/mobile и ошибок, review от AC, связанные PR в dev. + +Backend должен попасть в dev первым. PR frontend зависит от backend; миграций нет. +Изменения React, production, глобального UI Kit и соседних страниц не входят в задачу. +Данные browser fixtures не подтверждают работу deployed API; это отдельное ограничение отчета. diff --git a/docs/vacancy-archive/archive-modal-1440.png b/docs/vacancy-archive/archive-modal-1440.png new file mode 100644 index 0000000000000000000000000000000000000000..0a453baf8060d5e12274e1e06db06ca8c7c8ec4a GIT binary patch literal 99222 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Μzp~q1xypS_Hf=QYsskqu$d84MC91 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 literal 0 HcmV?d00001 diff --git a/docs/vacancy-archive/archive-modal-390.png b/docs/vacancy-archive/archive-modal-390.png new file mode 100644 index 0000000000000000000000000000000000000000..09942f3eb6d5a2fcef245b4457a0660330a639b0 GIT binary patch literal 66524 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

(8q8dec%sB ze_^HMMAskH2+L_Jzki^D0GBsFkW!O!md91A=HfvIu!oLE+oZUOl6Oa3Q#9TodM_YJBm(p+%Vfc^A z@W!LFqbsbD(2q?eK&c^O3o+K6Scq!bkl*l!TIu&q@L`MJ38puu#4cxn^IgCzjkU`{ z4{bxmM&dTjz@2GSvVFU-g~ z=_AbP4f;|N3t){t3{_K$3K{V&ZX}+=3$Hxf;2XK-(;yHM4_&$k|ci7#P2=6^+?fVFW?b~u_F4N5*O7v4~( zL&=e%-6R}jqbJ&|J~)xWF1qy~|GtqRHNAKe8SFY2AP)2j1r`ohpyiGa6U5K)Ysqqk z@TiTcbNHz7A%5k+qDgY?Fx`@e2!1^_X^kmWU9T$QB?0u;cO~@UPF(3dVH2B{n=74; zO-$&K5X`WSG*%;r!z8wO?wRb~9hBvhTo-3whr@86^ioH9Ae>>^)67)MLc>hcOl>0@ z&(`kFUtOe!r(%?VCzf0~&qaEOdXW?=?NbaK;=QPMlO)X1jjfU^L6991Mq8jhip#na zSxqXn?SYjo*!J$cjk-jPZ+~;U=jBc(j3T{y*YmSnTY@>X;l247v)J}9jFE0+=V-u7 zC{irf^}6OoMHRVnfayW6M|L>)q+w=N{pS()xDSJ(NttbGcDDurL5F)*Bo1rb;5_TV=I< zTp{ew#KWMV9hEOD2kFkk?=DlO4nxaR!L<4-^Wbiaho7OoP%$=WF7itnJ9WulhpYLRkgeE z)HbA(qLm5k=4Ps1UV*f7=rQZU?zeQ~jXVwvWi{0?m61>am?)xiWP}+04=>2)_Bx2P z*C^3)qd|wo2g4gM8`QqIVw%P+)x`CF<9@d63WL>O;a5WCsJX{ps zqCKaJA6vHUdBWO4vhyfuZrA-n;(c~YAMc~c}>~tJC z^*08_bjfk!r?aK>sM|?tZY$0R;VLHPl__Q~v*Tt(RayJruAgnvKhe*C&N|`>m`(p5 z*?=e)SI*8-JJ3Txq$Y2Zp?j67fps)`Y8FP=zF0apJMcUt2s<6mR2j+mDXtx@BxS-Z zGf0-vO$69jga+ZL$GbIhGe2}GF8iwn^}#q!fb{2$SV($2_)e^A7X~dtYX#n zpgaMVb3b`^Zn_JZe1{q)$yYPD5@u)cp`oimUOvRP)9x~(k&W8U^>_R|Z>nmMKa!p` zm$3`<#v=~ti6v>YUPa#5h#;i#0AKFK$g6;Mq}hY^fXK$d(WetCzfe?)QE_i|S?hdH zJ9%Bx*nX0);Amcqqq#49!ssc=d-O`={G<}mZR?}_7V4W;Gk(TSN4tL4q4!>)-Zu}n z(%QMrzSY6!m0$RhI`<7=_VRGjCp>v5D*i~`M78&87Kz&bQ7@pPP9a^y3!u0`{C!!I zLS7Q%A*`lWR849#vXniaRZ4G#{Q}D>thW1#vLPd?8Cp2x={MLT4dsMaEYDdtS|PrW zq82u78-Spk^*rN=QIW8-WZa;&8ok><6BR8q{X)uHt8tLx-%R@CrvJwV0Faq*Af$AO z5OV*~fyeR9;1Z2+dYjbhFaQR9krl_-3ZU@YR=`GW#7VEDzRF%z_WfqCHGSKGnvOvL zO%Q&iSb@FRo*dUuOM5kZCG^Bs?FsW4k_bk)+0lvFzmrO0{ueKUV20eP@y{ymU+}iY zCErEGc3eIe{c~es0kHGi`R0~MBk`)(Q7xVL&U#ui_^sh8IrUb?78oZEs8)W{J46`q zqR{m8bJ0yxj!UuXZ9Vzk%{z8pLNZ3!8|BpfS9*;bE}Ao}t%T?wLcTwQ9(oJW?w=1_ z_~ysPvbrFoHyXzT;6d+7I?l>exEoc^-Uffs(HhCaS|7!#0o}5)1&)9ho0-$Bm$uN{Hc&oK|JRbCowYp7)|H%$S*r1x;)G=gZO)5|iGcQ54;3V%pox70{dLUpn z-bKW|wn@PD7%VD{4pn9@m`&yKp6CaTV%lz_uHw;;a$9+aVRyUq7?yY0?pX2Cnr1f4 z-FkUdEQj@%XDIKK6t#vL%|{L1gMOxJ`x;1Tkyl?I`IJfbj8eD8de*5^D3eY|{@vOjkM2D&F#H4W$8vAI`2Ws?G}yO_0*R_Or^aYbG25U!-;A-x6>q77gY zUbe_7#mHvgl81u5C)vYAHClG-pX67>CLc>r!KuqUQWeYklUvU%1dal>a2q;BQRgjJA(otl(1 zR{;kN4Q^;aK6Rx)eJVBcRyX58Gytr0!4bo6IUE0> zzr0ONPnOurN38vfg2xsy+|@FMhTP8k zk~Om`=Bb6@e@F2GIY%r#!_T^~JRlp=_7-Q%&ZQf2M}Kk+L!7z{S!4^KzqaU+PxBl>g*| z{~M$HuL&P1oTgpOy8S!q>z>Zt9=WfV>R+y2Lcl1bf=6#y=MbZydm`8%S$}MY2EG$X zA=hCm1;4S zsPQm#o5rpJLL`&1Q~%<)UUfZdQ|`;cG!O;eCiYbW8cyqv4gz>w$E01{vbmQi+DY^rUryPF*aR%%eiHaaZvg zlEF*3%tbCL{uI;ba13Q7r;qKXq`}*uz4BKrRVwe!FU40g>${%(`fka&7l&RlUK5o_ z)rj65#ywV^!FlN6HiW>10h!{5FJuD$~YSQb) z>_iM^GgGSSlVM$IXlL$8AvE$)EHW(8@zB@_dpO;wD+coQY^)b}FsIQ>BV-fld+x~8 z!khhSb{*&^q0~&Q-O_Mo;5kkrsZdN73}EO-O@hEo8SFaJd?|+|oE}nbLz#I*6p9?@ z??ipno+!w0vw6zQ4E|!wn9Sxw%Vn1eI&)IRHpMVltWexE; zV3bA)E&zTOIvyF%vtl7K2V<4&nXt;rZH068A=wiH7YQ?4%rh83P{H#2Hz}?4-Q*vY zuDtefz#ZOOR^j^tWm=eKGP4W0F_=G3W`D`c9pV5pvIs}*uOQCZfyu+UQtmn{oyIld zea74mC+W7`6NOwm7Bq^{Sc7MxPHHkrSSF9ya!0S@Pm?WiOs^NK%Ln8xnss92!#TrB z!4PGasd(O9;T0%S#0wWHyrs+IsXFx{M(4I@QzpQu86-pOF#cZoiR11)Yh1MAR#i!q z5?&RRVA2k^Xc*h)z0WkGC+4X)sdnd(jC_K=Ub`+lwZIGHS>xp2_6s$QLOpJ)mkEi{i*y>tT$2rQ@?o`UM%O z&Am(Z;gDlkzt|OK#ZFx@Hek(3`0>SELGV}&@L(#f%{^*xXho0j&dh7oL_K-nf5XVL(X*c-N9e)e>0&YD@*%q=jb=Gu) zFyMY^=a=zIDT^kF6lco)x8JBX>Z4jmE00Kv_9=^=F?ATW?ls7CyK4^1B3W2H zii;1afeF5y2L~kzWk>;U=5NxuceB&8k}~AaLO#rbE|fXstoNwQFcF%3*xcQba{Hom zUlxyXg{w*@`18dfzo|);k7#b5%Cql;EH7n( zy#JnBW{q6^Sw6?%;iR5n>Ory)wFYc33>8B+SGikKt?TI_d;eLCf(Nmd=r_Fo|lf^elngCdTB&Q*!|1)1G2CPxev_arv zduq4)xF+VhPtU%72Ji?};|2d(+Dyg%NarxuYw9fWldjK7%kH~zdQG&d8j7z0QCKUy zp(tl}u_8&%3cnC346ww{u65&0U#$W&IM>#>5>etpyk zS$wSOO~ZBA&y+M(61Lp4t?y}<+Kg`$Id@I^&)6<)&jP`W>ypxlL#!1IajN+Qy4Pz# zoiHv>?k1qX{*$vM2ia&MMrGQx0xMg=?@v~)Qx#Dwk}IVZ^zyGCrx11rXS4Cdi2Eh9 z(dgv~YB~L9W0J{nvR;dm4MFMeJo}(ZB^}+2Rj8jPgDWzGBVA5_}5r%B{ptvQM6|N}7-M z)7KwM@VdrIh)rthD}ck7QjjGp5BYM_OyJ2H<3fN+Bq>b-nRhNra2NMNqrL@C4M?H1 z?=Ve+Vg$zlLqx$c)_Ku~Yu-f43)BlF_IDL!XKiLUblGG#=HcZfZ)6)K)9zox)AZ|Ih+@EEz~h{K8A@6fOR`5g|A{ z8V}_Z-YKYzx@#0VknaYU_@*MWt^kymZJrSzy76vu|BB#|Q%L)=afh8VxN>BM!W_i3 zUj*vUm#{i+uAr%9C3cWSs*Zt@!rDVTdju3rv{O6(;WQf3Mm8@5{ zoIo+qg9L)_#^cyQM}xpecDpnpx9tEJ){l{>KUfoAUE9v~#eB3d>lKzNM@=k}%|q61 zR~?jKEHZL%;@>d1E8}u90DN&_?fBscFyY@Ek3%+;(7tFJ;B~C=&-vtj_&E{^k|7-B zMryot&xc~xamqc`@>}D>6wXlpZQBAIqw}MG4MGKq>^Oc2nSSHoAt!|S(iQaNe1niX z)8!cnF89G3)<$qtjyrTCPRHG1=JgwxISn#e50PBemkwN zO3W%8`E%9UxW~dqX}+c-1XVkzIFUGCHHHy|)PIUmA@Z3d7eP?Y@l;KWXsJkOMWxxm z0;|(r;E0$jCK33Js?Je`QxYaNYT$szoJ!Ez3l8yxLq&ko4ttnx23?85-)E+GpDqRf zJ&(%{Pa#PBx?89j%k@f53n7zUuOLRnlQS$@KDM64%a=_RlkfU*of^*`^aS^c>n=w2 z+NtUbKaJXbGf8zgh=)v1Apn%pJ(e)v?cmFHO(A=%jcg&8E{V~m=2j=75iD{%x=E{& zgPL<^O4*;oTNt-eVs*nYQtR70g_5!I=Klx5%0OI?x5C|G&7EchozKn$!SB%Z6UTHK zY5>xR@((J&(9$tbf9Ov%DgsqKenJkJEPV?XYS3ESC6$mVpE|Yi zsdtJvKHWFQ0fHl1^8e+u%6(15PR3(nrTt<53%5{aI48ta20GU&sCu?h4U zr;d<(18urFb}2ElCg6k1@Zh>zLYdjVo@@b9H9{P(>kKU$vr}1s$@}Tm0R1l(*^w$@ z%Gn%1GJYPOdr?@Ar{@reYRnG|{A^-kHD%fX600PEad@NIFk2a`)|@kvChuy4Q_^WY z)Nbukrk=A|ZreM(=Wdq0!Mb`h;N!_9$%FB9tNu*p9xYX?3l+PSWD z%ynaygnm}7-cEMa?9JJJ958=;jHVRq0tSFVbDxAZw+VNZlbTv#n2O>fcpp|g))|)l z+NmprEv$zMZ2YxrseF^Bx1Q!G^{_UA5D6)9#wPQIpWGs%t2}gQ?Mx~noJKhy-i?FT z&Z0A0K51T^lE>hW%>6kg6G)SZ$!0GsxL6ch*Duk6*LfmYZAH%SQ@hcMH?~-UhcWA| z=-eabP)`8lvlggERw!tCt`enCB$@Y

qkqQ$U#B&Jo(3tVK7W_=AKuQhHB2U6UM z-ac979dny(#RC8^6~@%O!WaRa%mrXHbi^1nCKs^*vQpf!P8ubmr}C%gyjgB3uf<~N z(Djs@2-TNE6-`R8H=ojJrWArIE0b+i9nkIHc-#i~m zX-)0cwSi>jO|)aNra1Z2dFEU{wO04Qvi=&A+j%0%_Z>V$9)dvHMSJ zwCz~40&`L;kk8x!BN1{d)VmjP^^EbNq~qFYF^i`u1B`QJ;w~h{eV_r%XX?8oGlafw z+bUtWioFFbsqacRnAm(#pU%q>aEwPU@drU^G>6l>VN81-SmwFr_nZETi!LLkLEx--8?2x-MAJd`H(K=EvpAX8v2sh#n`O7 z+<^j$*|GFbz=BCgweA#6ilzaSL{V-A@ktrW;*G+SxE^+A^sY23{I$+OnCf6;r`(cp z98ik3>pF(casi<_Z+K=osO5<}S0<%`n-2Bs#L{j*qWySPq*QvGV#=|ng{*oh2V!=M zSHR6_YmARxfhtzJ3b_Eysvi=$e;z%r65{%kex!4qFymP8WTLuySz73voXuKNW@R-> z8a9GgomvUm4O$J&IFC`yScPsVUOw0RM>PX>o_$BbX$H**4-n6^5(oF9FDlNcCSKJ| zG_+$4wUq9OtKlKG&{f!Zho*U_w7d+tZH=(J(9g(W3)#t1u4-rdBGHf6My*69T`CkT zYAth;qdus^TW5YOdAX9}}wjM^>w!;FjXWonqT z-@4ap~ghQ9}d|;IK#|l@eOuvi}u{?ed(Prw86|L zFXHMx5%omv^sG^W!|xZ33G8tC+CokfCy9v-Flg=mUb=dV=74^_s`#7Euj=B+)ApMv++<)(;1Yi*C`fT9@5U&V7v$rthwWa@C~SJBj)& zhfV9xni)fILYmB0J8IIVP1`_~(o8E%Lx8HesH}YuCVQRi{=M0^yJ#WfpN=RY zJ@KpN24ytsc@=efk?yFfC4{V$vnQ_?m@y_PZb74p>&{oEHa1==$H_R-RJapeXnKwV z!O-=7&}2Gb>6`IzVLIJ6wS`@tX(HAqPdkrN(#4W%c=4|)l2c`G79`?bYT4^llLBG+ z9N`U03V*PKT(~sTWdW_vYY21h9ZZMz#@t8)k)DEbOktV`l=zd=b8^Y^cG)AtYlk>8 zdM~3G%+eGp8J92d^vB4F1Rdm3Ah8^yeAAW~TVV_5K5)E?@=l@SKl;3MjM=y$qA`Y>AZdbTHPuVT+L^8xoFKDaIN)?pN-kexwm;z z*pI+!D$LbsdfI~<)KELbkLyx?w}L=HPB`ET=DP6-BZ;{To9yz!F%?d=s3-}@Y~~|( z=jRKk{L#0>B|MHOD}~#18tPiXgD-x!IB*h}k(FdJ!oRl*Vw+K3400YGzp7nRIhc6Y z1;y74IX*d^#g14V?pnYshDFSMUWM6=#^mF;wT10hq$G?$!xt64hgUjnzf*zZz`cjl zM};VIR(FgCG}Ub|2%YV=@kjQj^{<(zexG$2opifL-@z>5UjLE_DWv2b+htN?l?{}E z8C^!M8ha0LfnR%VUMm$Lrcbhl-PFKKO~Xd+m{=aYK1F$VYXPG6_{J9DkoXc3B|q{8 z7@d^$fCt7^bmIFY&T51tasZ}aHj}&35uydSXrD6tX!i8zj9pRM@QCjQW}|A zG%C(a{Z}!0``q3#|AD5zdl>@dr(6H%dGkN+lS3}ck3)ZuzF4Mg!@nh$s1q*$(#C%z~m>p_(sM$GOdA+Rp7@xNNjn&NbgRU-~^mI6jk7a(xZYH!ONGwH? zoRK{&$ckj|SGm>t1d&ervvOt1P9R9F-7*ZTd);3MTU>JWb~|@#vg{BLHK{B7gLi9(;C~^8zjHSYPv7~R6@I(^?r7{9~%*ggsp!gIKk+a=yJ!B$9Iy9p z9hZwVXDtp+D|{q)xmKrT0&pOsH$;y&zV(~byRd+d%E?<^U~OS*8Q9Vz@!N(Se-+;o6tM z4ch!UyVhTnU2{Fy*~*nPf zE9Y;GCR&Gb<6;I5448DTQ1`)FJ2zW#eW_H}C1ZDLG+X=6n^=pX_$5Y7kFsRUaYoOK zcG&~HQ|Ds_nH}1(C|Wa7DS8XxSv5P*u?3K$R$l&7TT=%e-(?8nS7nhOI4lMOd9v^! z)>qThyVuoEQA*EEcac#&Ie5ZjLzhtiM9?nEeq2^)%*eaxU^uJ>y#BBq#uvnSA;e(9IQDz*7|H~|Lf@|7Q{VoO1^qzecl2O4@jrhCa?|J2 z&&=@3`4Ev~y=o;E^?zJZ^(`3`x4M4+NKMgs*8r&Ghps5?_0KhH&~0T6^78a-i)hVn z3g`SiI&n_7&_4M|6}EZO<>+?atk56D>6jf2yNzVL4SmTp!}ZEaX)S}Zvk`YkgWW+c zciEhCygT*m!0DpmAeiyHLwhIjE+6mXan4mfmS>uIP4x7TASWAvkg34;9o#Hee3ON56&R)mCAW9{j!w@v6CyHh{E;MZ?{olHP|xhZ zjvy&n0q72)yMw;vl^B{?r6|z=%48a9qtULnj6LBb(&GWx%40GxAda1e#nw#3pzGEw zZN$hBSVl2MsGtsX+eI|7gaK zds9oK+3@{dQ8iz#7k}?WPMKw4fOQ*J(TD!srD(rX`P0?q*7)P-qhWfr94DpPRU^vQ z6a*R2R3}iurf;hjD!K)cykNXXeKyoE^DRAuOXMs|M1M}!8;u<+v5O4xMgERn?@!09 zRjE=@m*C1>*R-+L`t>!zV&$y7fKLSMuSA)tQ;Ra`aW1FNUedzpW$a;ybL+JoCE2=% zE&Bt=;o?m1;TiDC+H%fL=j5u^!+m(K&d^Kz{L{b9DeFWbOeGnjNw7e#u=&g}{ORT;L$pV3AJjlFkdS)D@s$sNoW@1e|*! z^S)oM`&(BG$gRvn;fnte0zvwQQlw!m>Pe@F$!GE-VNxalPlsb+oK1&w!GawUEAih^ zziKl&FAhyNU8LqRa|V`@bp{uwUe_ZuxGWaK8gO{Jwm6Q&?PHo9hc>-OlsQu{1QJ^V zts>B}UdY#4G$ucYdeZbGqu`tog!IP^YwC{rC*)B}(O{xc|C*$99sv;+xxFJ44eK3!Y78d{8)Qft3eLTC z_sBY@5#L&WL`x0iL1XW|RM0Pm)pd5!HLM_R{R(|C*Vc~s+dw8_x=XnD2@~gQ?4?=d zCz!>|QoO@VJcdLjw;9(P5k5XxhX)@0o!u+qdP?wHUZ*LCzoWQJU96FJR%LpA4dTa@ z$noFX%b;}Oy~aAvgWF?CBpVq#uifgI9dy} zjF24Ywm?2`tkL=nBQtP-3@A)^rWI2*Kq=j>zx#X)##6dF4@%XAHD4xcUI0H;7aN79 zK7t4+9G?%e`qaT?H^PAk{NhwZq-Ll2a;nsp1Op*c{)Jz>Ert2Uny?6&LeSH>mceC-xds&@?Bb~V~e(&ePw%8e`+ z4u(K@V2#-YC%|l(lpo~KvRAxm#P-#O4vd^gJdlW2aHX}Tjm!*n&r{m8xm#W3Mv!fN z{yPiDPxW6?OrhQL4Xz5Nr;nhXlLSgR#2Tp^stM9>uPfGIX1&kL=d@62!(s#++*!y{ zkEIh(Cw{Ww1SDuw&PzD?a*oE$m&At@@DHRAf4GokR@ww%jm;kv)*yFIIbCX(-0=|V z7MJ}&ki*MoKV{taJqqpF?tWV_^TrllQ5{10LiK;;x=Q+6IqoUt?HK#9B+4c7UH<+B z1=CRSq$t=o2FGSFz75gqV5arh29R>n>F>REsi1dHQ$t4Dy1y_6cdHbhW(>QU-ZHjn z9;OVM!bncHK(-iER=wQAyepqdmS9!r%AlxSRQi-IQiE8eRSprWo4sScGl_qrwlB>` zQRKo4{AO_6<&pIF_lcjuE*Knj7ajei(et|(@bgAWML9l%J-;yB7U_8MVHBEcB_^Hg zWR-L}YYeA~XLAUrGv-<>VZY%?1kM^k=g@DhxiY3M{eZajYIb@wR`S5H{HE_sK7C4L zqo$uzAWPS4;Uyo5LpLN*WLL|hsZr0^!+bm_H+Y%xcTnZW+7@^+U=Q-kZ-<0UhV^ZW zmj7bJ!T)-Qa0D?(2=J}v0Q^6O62PVe&+r_O@v*jbhHChjXro)jL-`kT_m5U0hOjd! z?@UIAM#U)HAsafI{VGhy4LMc*tU1tbG4My|2n|NyRBmTmfRC~i`t&bgSxZ2lf|+a>wUkdE46%D?=$N5!o1K~xd@l6)i`nwM&OEW zHZ19UAh9Iss3Z19{%RzN9i)}``Ns<5?(TQU~s!8+&o zzkkX)tbBhuHs5$En`ZqPK(4BnCQCirxQaPoL0>sB0D3-EQZHwRdrf}k*oQBfHQtrh z6sb6k{Q?47J_ZzPqQZCkG|b0&;z`d_W<-;>#Z=o!dA#r4^B&GU{Rd2?P6JLmA8~0_ z{?Wl0vL`6d6IArKF4F3z*=@D)!uk}I9{g4_12t^5s=OS*yA*t02A!}ldW9}oT!0RX zVlV3M;lwEC^KIF`zVVCc)T-$FAhVqhhaHQ7hY%l>y`MiwPYnfAJw^FeSrGbb%Bt$? zo--(g^g2|Af8;X>T(jB+2fMB}>$JUb^0;w&w8z3mbKziiP*WbC4Ky0=LhX1tJU_Dq zb4D*PhbxQCdZ5Iy*` zI}kN*0b-#`8HN@>+nnd z(njd&(w3Z^t9hkVoL8_LAPF)*D=PUavZ1mE(9$7FgFGm+{80$*2YE^gY5HTb?;bwN zMiu%;6(Lr9$ZukFeS|NPXHrW);b4012}{pH2t`}R#Fq<*WEr~(%;r?vkob=9OLPLSR-u`#t! zb+b`arJG8Zv)ms`F;l6l&F{&2)Q#9AJB0)4PH;;%cN5@x2{+uNv2B?TlIE@q21xb$6o6Zte z(>~pLC4Wa&Pufj1nXg~Z`P=HvsH?Z2(8p)BN}L1f z0Yk`Zbf`zC_1qV7rbsQJFfU!*ZltqL3U@M$41cCgu~ELZFe;@H{XOt zuw|DpO_MoqlA2lqSX6s&q2JvhR%i?Gl}1`+X*a5M#zz`uW|kQ^x+Pz!fVvxZb7wxe zHkuoY0N>6kbus>@#!Em>qzNS*n99j758_*~3T045YxAYq(IXy7Z^YiOZ}Or#wYZRd z`rz;{pNk0QSEC5e492gP_~j0-KSbMgG)$Jn%Ajpxbv=q~uBOTJX{LN*H|uzIl=Y4@ zH-4&kWY4)}|0wJxmex!2kL)$)oejE6=w|J5?R^Hf_zuA54rvLfP=u%eP^d3N46+{z z+2N(k6jPZ183tzx@1l0BaJ|fFJG!)Pr;7^F%bqXpyW-d@yGdSm*}`!R-O?^P6ny*! zc^G1|YoXkIFmbNxA8AB`syvsIp0eDK7+u#e}>H6cQ)})AYkPo`;y&y zM{P}0S4^#ae6RCNb7{y22fUQWe*BWiiw3;dZ;w|bRSlVJK+$SPA#Hc`dwJh$e<-^Y)z6o*5tgizqZ z4sE!s77C+l{3+_b`}`YLWM6UVPnd7a$^U-SpZ7^O5)@oYz{}A=IX1y$7SmOre&%nj zLCp_IjFYHNTdP04mw`ENwJh4 z^X|sHE>fd-W#g_Uu5g6Cd_*g9{jDV9E>@EKLU~Dx4$kuD*H^pmaLgiTftkHp1Bi2* z15du@GFR$#uCQ_8s)-6Ns*ELKlWa0{jAO~NlF^79abDHxk+%p0nBz09?>FqwpHBFG zr_nkvr6=nD2q+U#%Pk$&NA`eSO{gBF48KZp&nBW$t>n1@nXCd7zkeE;7Y}3(Va#Xb z7z)u#|KZM+Xmkfma7keB6trXXRB0o~5&@B|k)P&Qr#9vgFv$%f0q4fT)5=Kfu{dpl z{!Cl;_?ifo08@(Y@i}xg@=^ZE-2^Xu4ESkJQ;!6L)vbnnaU&Y^Aw!nqLpQSyC=G8K zAI8<#PWj-%?N&+MYDS_5yJBDaRTf>LHp`NbHXeN)rb=m`-;~UiJy+&mS0636Z|9Mc zAg?me|K!tZKR+9y{jq(%X^HKJ4!{HDb$`H>0lf|g)6&xx!fTe&&mAPBr=;DyPi>^s z(tXBQ-{auydeN(0Ksyew`Q|v6FbFss?NF_aSvTS?_(&eyTF^MM{=%R^sk-h4X0zN# zMYcSGgfoO`O}ty_+PuJ+M3P*^3Sx2ioId?T=_1j&W&Z(*CSkfn4lN4HCo$L4j8&2( z%e}~r`}grJndqC8OZ@~AYYIe@#Jl6;c~tuKgEI)m{4xBQnTi(Js6u*-zH8I7*&;f9 zq|La@!nSbbB|05?+q*b#2R|+uhIKsr7K!q+HVQCQkuC;;NLYh(`ZFR0E403a9jRfR z*E9-i1+i*W8a7Dylvxrddh>ZK-fV&{<43WUr=UVC`wA*IG1o(@iTYAG761 z-K?$tA$y~w{G3+E)>*f>i#Z$PF3Ye;Yp(xfR!m>ab}Dg)x(Qe4LG9 zC;e$z?$fi$*DzNn=`=$PvfACa94JPkj?a@nXZt*1-LgiH9A#Y2m6%s&JugZ>@6)LD zhI^|KUb6|jEtBWh{ob$(R1MnGmzWnxK~c&i&LF2Ae=y^S_efON8nq(hLNZx?RBS0z zrFk`IKd9Qo`#65{%F{K*B%SCv7`C*ckHo3LxRfpPHIldv_f=-g?V+RLBDH`!1w zT1Kt*xuerKi8DxGZb>DGBx4P|HrYfPs#;IQ)z9J^4*Rilx;!8Jx*MbWRD#=}{ z#xdzxRk<5+?lCt)9Zc3mHT?0$)@yo$g1lvs)sbT36-{uy7JD6;icdkHlkJ z;A;?1ZDPQ!T38HDx-c6|$%^@|xSKY3UFi6^6&{#rU6$h(GN8n zAC$3ILhZ*Rbifqa0cMv(K7lzwK9h)PVzg(ypQUkGB{D>P(|0l-jT(0mI~sD1u(Z@{ zboK>v4hqU>01w(MD@>>?RVQxB1DL;}cX@Qvt4g=itn8<~_3+5oaDw86hqXbGLRr-8 zjdL0pjZ7NBwi1v|BMCJ=Ri;cfZPiH3#K7lMBicP9^NG88w`7zU)Q=UsYqe&_XzuGB zaZ~S(RE!nu>)WMu&AIjm)w2^vR9e3tQm4XON)5T?cm^ z+-K*1-_N~OTlH4$vv2KwnGZeFU2|RCU48X&9>?#5ncBl(!kl_3^Dazj#mLU1PB+8< ziy{}1LCVq@QDE&swpLNTPm})hk1!e3;dD&J69;hOGA|b?hx^R@m|5OqH2{9$e5fiL*;UJn+cya3MCyyk@)8rao=sG9vmR>NL=* zzLQ3ae`H)9pW*G|-ypxr@?f9xI!9qO1hh-|I(L!hWU0+hc79QZ83WvnL+7tClM&w|EP1v0=byZ&B$SmtH*i z9=XBks!V!+jTQnBFQuO<#Kza{-lrwcDWd@7_8_ zz1eJec0s$cUxeKKIfw4}do~}0=O(D+ek(^8x;au4?f$($%2@^rPoqLd_Lt36FL$lJ7e zSYyxsNaXk4X|ZNKBbQ-!1SUXgK^-z-EvSH7E?nvF`X2iq8z>Av=@le6!w*Gur`4MM zV~&xNy}F8sOj0{dB`kPSth5-yQlz4~)+tu+L+2VLjR+_BVCyQ7)#7;CgZ0PSfwGo? z%bPp86PD@vU1=u?ek3}GHDau?`K%m#9Qn&=ErrnXBU(B_9_GX(zkg^eSGuA{4sUp$ z6zvJ0P$Ad^ht=fqzF<|J2@REtyw}#;B_syDS&-qlX6CR!a_8;7FGVOx!Ks70UbKAl zH|FPKF-}+Zg)RC_%+RtH+|bJ)`#r75B*`t8ngs4SO~|jj#0kU>Jy%4sUa~tniyut0 zq+7)j(#}T%A{A@Ge(o1WHUP%vQ+EDQBy*kNj4d+THFxpF^c50X>c>2#z@zlJd%w7G zBZBx#z7nG3(ph2vv*Q|$;MjPMQ;D%dgn++UoVv8W^cw5f5_Xn%Q~%-MjVONXlcq?8 zwcd#8HxWP+E4Qc$MOV;-n>ym4h1T%jKbMwd<%^E(89_=lyt+|!0IlSnzl)TGLJ7IP zZvOf!$8;5Dx8b#wV@nM-sIZKM z&y8bHFHYrVG) zQL??g(KF4zD(kbfFQ@J)#u1isQ60RA-fa^x0qGR7G3_12S-}dCz{40p&L!XbrYB4> ztabbJ@EM&N3vx_)T&~YtmrYjm{@7⪅fcuO$Yt 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 LUbI-)@WcNBqASt^ literal 0 HcmV?d00001 diff --git a/docs/vacancy-archive/browser-acceptance.cjs b/docs/vacancy-archive/browser-acceptance.cjs new file mode 100644 index 000000000..c8aa9213f --- /dev/null +++ b/docs/vacancy-archive/browser-acceptance.cjs @@ -0,0 +1,203 @@ +/** @format */ + +const { chromium } = require(process.env.PLAYWRIGHT_MODULE || "playwright"); +const assert = require("node:assert/strict"); +const fs = require("node:fs"); +const output = process.env.QA_OUTPUT || "tmp/vacancy-archive-qa"; +fs.mkdirSync(output, { recursive: true }); + +(async () => { + const browser = await chromium.launch({ + headless: true, + executablePath: process.env.CHROME_PATH, + }); + const page = await browser.newPage({ hasTouch: true }); + const errors = []; + page.on("pageerror", error => errors.push(error.message)); + let checks = 0; + const check = (value, message) => { + assert.ok(value, message); + checks++; + }; + const root = "http://127.0.0.1:4371/office/projects/5/edit?archive"; + const open = async (width = 1440, stress = false) => { + await page.setViewportSize({ width, height: 1000 }); + await page.goto(root + (stress ? "&stress" : "")); + await page.waitForSelector("app-vacancy-card"); + await page.evaluate(() => document.fonts.ready); + }; + const confirm = () => page.getByRole("dialog"); + const calls = () => page.evaluate(() => window.__vacancyPreview.lifecycle.calls); + const succeed = () => page.evaluate(() => window.__vacancyPreview.lifecycle.succeed()); + const fail = (status, code) => + page.evaluate(([s, c]) => window.__vacancyPreview.lifecycle.fail(s, c), [status, code]); + for (const width of [1440, 768, 390, 320]) { + await open(width, width === 320); + const geometry = await page.getByRole("tab").evaluateAll(nodes => + nodes.map(n => ({ + height: n.getBoundingClientRect().height, + right: n.getBoundingClientRect().right, + width: n.getBoundingClientRect().width, + })), + ); + check( + geometry.every(r => r.height === 27), + `tabs are 27px at ${width}`, + ); + check( + geometry.every(r => r.right <= width + 1), + `tabs within viewport ${width}`, + ); + check( + await page.evaluate(() => document.documentElement.scrollWidth <= innerWidth), + `no horizontal overflow ${width}`, + ); + check( + await page.evaluate(() => + [...document.fonts].some(f => /Mont/.test(f.family) && f.status === "loaded"), + ), + "Mont is loaded", + ); + check((await page.getByRole("tab", { name: "Активные · 2" }).count()) === 1, "active count"); + check((await page.getByRole("tab", { name: "Архивные · 2" }).count()) === 1, "archived count"); + const active = page.getByRole("tab", { name: "Активные · 2" }); + await active.focus(); + if (width <= 390) { + const bounds = await page.locator("#vacancy-tab-archived").boundingBox(); + await page.touchscreen.tap(bounds.x + bounds.width / 2, bounds.y + bounds.height + 4); + await page.locator('#vacancy-tab-archived[aria-selected="true"]').waitFor(); + check(true, "touch target extends beyond the 27px surface"); + await page.locator("#vacancy-tab-archived").press("Home"); + await page.locator('#vacancy-tab-active[aria-selected="true"]').waitFor(); + } + await active.press("ArrowRight"); + await page.locator('#vacancy-tab-archived[aria-selected="true"]').waitFor(); + check( + (await page.getByRole("tab", { name: "Архивные · 2" }).getAttribute("aria-selected")) === + "true", + "keyboard selection", + ); + check( + (await page.getByText("Вернуть в активные", { exact: true }).count()) === 2, + "restore actions", + ); + await page.getByRole("tab", { name: "Архивные · 2" }).press("Home"); + await page.locator('#vacancy-tab-active[aria-selected="true"]').waitFor(); + const card = page.locator("app-vacancy-card").first(); + await card.getByRole("button", { name: "Удалить", exact: true }).click(); + await confirm().waitFor(); + check( + await confirm() + .innerText() + .then(t => t.includes("нельзя удалить") && t.includes("Ожидающие решения")), + "delete restriction and consequences", + ); + check( + await confirm().evaluate(n => { + const r = n.getBoundingClientRect(); + return r.x >= 0 && r.right <= innerWidth + 1; + }), + `modal fits ${width}`, + ); + await page.screenshot({ path: `${output}/archive-modal-${width}.png`, fullPage: true }); + await page.keyboard.press("Escape"); + await confirm().waitFor({ state: "detached" }); + check((await calls()) === 0, "cancel never calls API"); + } + await open(); + await page + .locator("app-vacancy-card") + .first() + .getByRole("button", { name: "В архив", exact: true }) + .click(); + await confirm().getByRole("button", { name: "Перенести в архив", exact: true }).click(); + check((await calls()) === 1, "archive calls API once"); + check( + (await page.getByRole("tab", { name: "Активные · 2" }).count()) === 1, + "count waits for API", + ); + await fail(500); + await confirm().getByRole("alert").waitFor(); + check( + (await page.getByRole("tab", { name: "Архивные · 2" }).count()) === 1, + "failure preserves lists", + ); + await confirm().getByRole("button", { name: "Перенести в архив", exact: true }).click(); + await succeed(); + await confirm().waitFor({ state: "detached" }); + await page.getByRole("tab", { name: "Активные · 1" }).waitFor(); + check( + (await page.getByRole("tab", { name: "Архивные · 3" }).count()) === 1, + "archive counts after success", + ); + check( + await page.locator("#vacancy-tab-active").evaluate(n => document.activeElement === n), + "focus returns to surviving tab", + ); + await page.getByRole("tab", { name: "Архивные · 3" }).click(); + const restored = page.locator("app-vacancy-card").first(); + await restored.getByRole("button", { name: "Вернуть в активные", exact: true }).click(); + check( + await confirm() + .innerText() + .then(t => t.includes("Отклоненные отклики не вернутся")), + "restore preserves past decisions", + ); + await confirm().getByRole("button", { name: "Вернуть в активные", exact: true }).click(); + await succeed(); + await confirm().waitFor({ state: "detached" }); + check( + (await page.getByRole("tab", { name: "Активные · 2" }).count()) === 1, + "restore active count", + ); + await page.getByRole("tab", { name: "Активные · 2" }).click(); + await page + .locator("app-vacancy-card") + .filter({ has: page.getByRole("heading", { name: "QA", exact: true }) }) + .getByRole("button", { name: "Удалить", exact: true }) + .click(); + await confirm().getByRole("button", { name: "Удалить вакансию", exact: true }).click(); + await fail(400, "vacancy_has_responses"); + await confirm().getByRole("heading", { name: "Вакансию нельзя удалить", exact: true }).waitFor(); + check( + (await confirm() + .getByRole("heading", { name: "Вакансию нельзя удалить", exact: true }) + .count()) === 1, + "new response race is visible", + ); + await confirm().getByRole("button", { name: "Отмена", exact: true }).click(); + await confirm().waitFor({ state: "detached" }); + await page + .locator("app-vacancy-card") + .filter({ has: page.getByRole("heading", { name: "QA", exact: true }) }) + .getByRole("button", { name: "Удалить", exact: true }) + .click(); + await confirm().getByRole("button", { name: "Удалить вакансию", exact: true }).click(); + await succeed(); + await confirm().waitFor({ state: "detached" }); + check((await page.getByRole("tab", { name: "Активные · 1" }).count()) === 1, "deletion count"); + await page.evaluate(() => window.__vacancyPreview.projectUi.applySetVacancies([])); + await page.getByText("Нет активных вакансий", { exact: true }).waitFor(); + await page.getByRole("tab", { name: "Архивные · 0" }).click(); + await page.getByText("В архиве пока пусто", { exact: true }).waitFor(); + checks += 2; + check(errors.length === 0, `no browser errors: ${errors.join("; ")}`); + fs.writeFileSync( + `${output}/browser-results.json`, + JSON.stringify( + { + checks, + errors, + widths: [1440, 768, 390, 320], + scope: "local Angular browser fixtures; no live API mutations", + }, + null, + 2, + ), + ); + await browser.close(); + console.log(JSON.stringify({ checks, errors })); +})().catch(error => { + console.error(error); + process.exit(1); +}); diff --git a/docs/vacancy-archive/browser-results.json b/docs/vacancy-archive/browser-results.json new file mode 100644 index 000000000..2c4bbb879 --- /dev/null +++ b/docs/vacancy-archive/browser-results.json @@ -0,0 +1,6 @@ +{ + "checks": 58, + "errors": [], + "widths": [1440, 768, 390, 320], + "scope": "local Angular browser fixtures; no live API mutations" +} diff --git a/docs/vacancy-archive/verification.md b/docs/vacancy-archive/verification.md new file mode 100644 index 000000000..28f332814 --- /dev/null +++ b/docs/vacancy-archive/verification.md @@ -0,0 +1,47 @@ + + +# Проверка архива вакансий — 21.10.2026 + +Дизайн: [согласованный макет](https://www.figma.com/design/tvog0fpEgWgEtr7KUTjbyE/PROCOLLAB-Design-System-v1?node-id=776-5414). +Вкладки в Figma и Angular имеют высоту 27 px, без общей серой подложки. +Использованы существующие Card, Button, Modal, State, VacancySkills и VacancyStatus; Mont загружен в браузере. + +## Выполненные проверки + +| Уровень | Evidence | +| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Source | UpdateVacancyUseCase → PATCH /vacancies/{id}/, DeleteVacancyUseCase → DELETE. Состояние списка меняется после успешного ответа; форма не сбрасывается при изменении соседней карточки. | +| Angular tests | `npm run test:ci -- projects/social_platform/src/app/api/project/facades/edit/project-vacancy.service.spec.ts projects/social_platform/src/app/api/project/facades/edit/ui/project-vacancy-ui.service.spec.ts projects/social_platform/src/app/ui/widgets/vacancy-card/vacancy-card.component.spec.ts` — 3 файла, 45 тестов passed. | +| Build | `npm run build:pr` — exit 0. Preview build с существующим entry point `docs/vacancy-redesign/preview/main.ts` — exit 0. Sass deprecation warnings относятся к существующим стилям. | +| Browser | `node docs/vacancy-archive/browser-acceptance.cjs` с локальным preview на 4371 — 58 проверок, JS errors []. Ширины 1440/768/390/320; Mont; touch; tabs keyboard; модалки; счетчики; отмена; busy; повтор после ошибки; появление отклика перед удалением; пустые списки. | +| Static | ESLint измененных TS и Stylelint двух измененных SCSS — exit 0. | +| API | Связанная API-ветка от dev 1c424ff: `manage.py test vacancy.tests projects.tests.test_program_project_detail_access --noinput --keepdb` — 106 tests passed на PostgreSQL 18.1, Python 3.11.15 / Django 4.2.11. Models check и makemigrations --check --dry-run — exit 0, миграций нет. | + +[Результаты браузера](browser-results.json), [desktop](archive-modal-1440.png), [mobile](archive-modal-390.png). +Browser использует fixtures и не выполняет мутации live API или отправку писем. + +## Requirement audit + +| AC | Verdict | Evidence | +| --- | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | +| AC1 | PASS | height=27, счетчики и фильтрация проверены в браузере на четырех ширинах; геометрия карточек на desktop — две колонки по 554 px в preview. | +| AC2 | PASS | API-тест атомарного закрытия и уведомления ожидающих; browser проверяет ожидание ответа и успешный перенос. | +| AC3 | PASS для ручного возврата | Сервер отклоняет возобновление в draft/private проекте; история решений сохраняется. Повторная публикация — отдельный открытый вопрос ниже. | +| AC4 | PASS | Подтверждение и успешное удаление проверены API, unit и browser. | +| AC5 | PASS | API запрещает удаление во всех состояниях откликов и обеих вкладках; UI предлагает архив. | +| AC6 | PASS | Ошибка и повтор, защита двойного запроса, появление отклика после открытия модалки; invalid skills не закрывают вакансию и не удаляют навыки. | +| AC7 | PASS в проверенном контуре | Empty, unknown count, 320/390, keyboard tabs, Escape и focus после переноса, сохранение формы проверены. Полный accessibility audit не выполнялся. | + +## Review и открытый вопрос + +По итоговому diff проверены permissions, порядок блокировок Project → Vacancy → VacancyResponse, +сохранение response_count как числа ожидающих, отсутствие N+1 в каталоге, readonly total_response_count, +контекст проекта, server errors, Mont, фокус и отсутствие переполнения. +Кодовые замечания в проверенном контуре исправлены; связанный frontend/API diff требует совместного внедрения. + +**HOLD перед интеграцией:** существующий `projects/signals.py:update_vacancy` активирует все закрытые вакансии +при переходе проекта draft → published. Пока это правило сохранено. Пользователю задан вопрос: +оставлять архивные до ручного возврата или сохранить автопубликацию. Новая семантика и миграция без ответа не вводились. + +Не проверены deployed dev, реальная доставка email и полный backend/frontend suite. Эти проверки не объявляются пройденными. +После решения вопроса и закрытия связанности PR порядок внедрения: API → Angular → ручная dev acceptance. diff --git a/docs/vacancy-redesign/preview/main.ts b/docs/vacancy-redesign/preview/main.ts index c28d91bc7..b1ed29fbc 100644 --- a/docs/vacancy-redesign/preview/main.ts +++ b/docs/vacancy-redesign/preview/main.ts @@ -46,6 +46,7 @@ import { ok, fail } from "@domain/shared/result.type"; import { success } from "@domain/shared/async-state"; const params = new URLSearchParams(location.search); +const archiveMode = params.has("archive"); const stress = params.has("stress"); const skills = [ "TypeScript", @@ -78,6 +79,7 @@ const vacancy = (id: number, overrides: Partial = {}) => id, role: "Frontend-разработчик Angular", isActive: true, + ...(archiveMode ? { totalResponseCount: id === 10 ? 5 : id === 12 ? 8 : 0 } : {}), project, requiredSkills: skills, description: @@ -159,6 +161,9 @@ let responses = [response(1, null), response(2, true), response(3, false)]; let request = new Subject(); let calls = 0; let lastCreatePayload: any; +let actionRequest = new Subject(); +let actionCalls = 0; +let lastAction: { id: number; payload?: Partial } | null = null; const previewEditProvider = { provide: ProjectsEditInfoService, useFactory: () => { @@ -342,8 +347,14 @@ TestBed.configureTestingModule({ { provide: UpdateVacancyUseCase, useValue: { - execute: (id: number, payload: any) => - of( + execute: (id: number, payload: any) => { + if (archiveMode && "isActive" in payload) { + actionCalls++; + lastAction = { id, payload }; + actionRequest = new Subject(); + return actionRequest; + } + return of( ok( vacancy(id, { ...payload, @@ -352,10 +363,22 @@ TestBed.configureTestingModule({ ), }), ), - ), + ); + }, + }, + }, + { + provide: DeleteVacancyUseCase, + useValue: { + execute: (id: number) => { + if (!archiveMode) return of(ok(undefined)); + actionCalls++; + lastAction = { id }; + actionRequest = new Subject(); + return actionRequest; + }, }, }, - { provide: DeleteVacancyUseCase, useValue: { execute: () => of(ok(undefined)) } }, { provide: GetVacanciesUseCase, useValue: { execute: () => of(ok(vacancies)) } }, { provide: SendVacancyResponseUseCase, useValue: { execute: () => of(ok(undefined)) } }, { provide: GetVacancyResponsesUseCase, useValue: { execute: () => of(ok(responses)) } }, @@ -416,6 +439,30 @@ TestBed.compileComponents().then(async () => { list, detail, projectUi, + lifecycle: { + get calls() { + return actionCalls; + }, + succeed() { + const source = projectUi.vacancies().find(v => v.id === lastAction?.id); + actionRequest.next( + ok( + lastAction?.payload + ? { + ...source, + ...lastAction.payload, + datetimeClosed: lastAction.payload.isActive ? null : "2026-10-21T12:00:00Z", + } + : undefined, + ), + ); + actionRequest.complete(); + }, + fail(status = 500, code?: string) { + actionRequest.next(fail({ cause: { status, error: code ? { code: [code] } : {} } })); + actionRequest.complete(); + }, + }, rootSearch: TestBed.inject(SearchesService), fill() { TestBed.inject(ToggleFieldsInfoService).showFields(); diff --git a/projects/social_platform/src/app/api/project/facades/edit/project-vacancy.service.spec.ts b/projects/social_platform/src/app/api/project/facades/edit/project-vacancy.service.spec.ts index c94cc3b2d..120196e38 100644 --- a/projects/social_platform/src/app/api/project/facades/edit/project-vacancy.service.spec.ts +++ b/projects/social_platform/src/app/api/project/facades/edit/project-vacancy.service.spec.ts @@ -22,6 +22,7 @@ describe("ProjectVacancyService", () => { let uiService: ProjectVacancyUIService; let postVacancy: ReturnType; let updateVacancy: ReturnType; + let deleteVacancy: ReturnType; let editIndex: WritableSignal; const skill = { @@ -34,6 +35,7 @@ describe("ProjectVacancyService", () => { beforeEach(() => { postVacancy = vi.fn(() => of(ok(Object.assign(new Vacancy(), { id: 10 })))); updateVacancy = vi.fn(() => of(ok(Object.assign(new Vacancy(), { id: 10 })))); + deleteVacancy = vi.fn(() => of(ok(undefined))); editIndex = signal(null); TestBed.configureTestingModule({ @@ -56,7 +58,7 @@ describe("ProjectVacancyService", () => { }, { provide: PostVacancyUseCase, useValue: { execute: postVacancy } }, { provide: UpdateVacancyUseCase, useValue: { execute: updateVacancy } }, - { provide: DeleteVacancyUseCase, useValue: { execute: vi.fn() } }, + { provide: DeleteVacancyUseCase, useValue: { execute: deleteVacancy } }, ], }); @@ -76,6 +78,121 @@ describe("ProjectVacancyService", () => { }); } + function seedActionVacancy(isActive = true, totalResponseCount = 0): Vacancy { + const vacancy = Object.assign(new Vacancy(), { + id: 11, + role: "Тестировщик платформы", + isActive, + totalResponseCount, + }); + uiService.applySetVacancies([vacancy]); + return vacancy; + } + + it("фильтрует списки и меняет статус только после ответа, защищая двойное подтверждение", () => { + const vacancy = seedActionVacancy(true, 3); + const request = new Subject(); + updateVacancy.mockReturnValue(request); + uiService.vacancyForm.patchValue({ role: "Несохраненный текст" }); + service.changeVacancyStatus(11); + service.confirmAction(); + service.confirmAction(); + service.closeAction(); + expect(updateVacancy).toHaveBeenCalledTimes(1); + expect(updateVacancy).toHaveBeenCalledWith(11, { isActive: false }); + expect(service.activeVacancies()).toHaveLength(1); + expect(service.archivedVacancies()).toHaveLength(0); + expect(service.action()).not.toBeNull(); + request.next(ok({ ...vacancy, isActive: false })); + request.complete(); + expect(service.activeVacancies()).toHaveLength(0); + expect(service.archivedVacancies()).toHaveLength(1); + expect(service.action()).toBeNull(); + expect(service.actionBusy()).toBe(false); + expect(uiService.vacancyForm.value.role).toBe("Несохраненный текст"); + service.activeTab.set("archived"); + expect(service.visibleVacancies()).toHaveLength(1); + }); + + it("предлагает архив вместо удаления с обработанными откликами", () => { + seedActionVacancy(true, 2); + service.removeVacancy(11); + expect(service.action()?.kind).toBe("blocked-delete"); + service.confirmAction(); + expect(deleteVacancy).not.toHaveBeenCalled(); + expect(updateVacancy).toHaveBeenCalledWith(11, { isActive: false }); + }); + + it("закрывает объяснение удаления архивной вакансии без запроса", () => { + seedActionVacancy(false, 2); + service.removeVacancy(11); + expect(service.actionLabel()).toBe("Понятно"); + service.confirmAction(); + expect(deleteVacancy).not.toHaveBeenCalled(); + expect(updateVacancy).not.toHaveBeenCalled(); + expect(service.action()).toBeNull(); + }); + + it("показывает отказ сервера при отклике, появившемся после открытия модалки", () => { + seedActionVacancy(); + deleteVacancy.mockReturnValue( + of(fail({ cause: { status: 400, error: { code: ["vacancy_has_responses"] } } })), + ); + service.removeVacancy(11); + service.confirmAction(); + expect(service.action()?.kind).toBe("blocked-delete"); + expect(uiService.vacancies()).toHaveLength(1); + expect(service.actionSuccess()).toBe(""); + expect(service.actionBusy()).toBe(false); + }); + + it.each(["result", "network"])( + "сохраняет карточку и позволяет повторить удаление после %s", + kind => { + seedActionVacancy(); + deleteVacancy.mockReturnValue( + kind === "result" + ? of(fail({ cause: { status: 500 } })) + : throwError(() => new Error("network")), + ); + service.removeVacancy(11); + expect(deleteVacancy).not.toHaveBeenCalled(); + service.confirmAction(); + expect(service.actionError()).toContain("повторите"); + expect(service.action()).not.toBeNull(); + expect(uiService.vacancies()).toHaveLength(1); + deleteVacancy.mockReturnValue(of(ok(undefined))); + service.confirmAction(); + expect(uiService.vacancies()).toHaveLength(0); + expect(service.actionSuccess()).toBe("Вакансия удалена"); + }, + ); + + it("возобновляет набор и показывает объяснение непубличного проекта", () => { + const vacancy = seedActionVacancy(false, 5); + updateVacancy.mockReturnValue( + of(fail({ cause: { status: 400, error: { is_active: ["Сначала опубликуйте проект"] } } })), + ); + service.changeVacancyStatus(11); + service.confirmAction(); + expect(service.actionError()).toBe("Сначала опубликуйте проект"); + expect(service.archivedVacancies()).toHaveLength(1); + updateVacancy.mockReturnValue(of(ok({ ...vacancy, isActive: true }))); + service.confirmAction(); + expect(updateVacancy).toHaveBeenLastCalledWith(11, { isActive: true }); + expect(service.activeVacancies()).toHaveLength(1); + }); + + it("сохраняет идентичность редактируемой карточки при удалении соседней", () => { + const first = seedActionVacancy(); + uiService.applySetVacancies([first, Object.assign(new Vacancy(), { id: 12, isActive: true })]); + editIndex.set(1); + service.removeVacancy(11); + service.confirmAction(); + expect(editIndex()).toBe(0); + expect(uiService.vacancies()[0].id).toBe(12); + }); + it("добавляет вакансию и открывает подтверждение только после успешного ответа", () => { const request = new Subject(); postVacancy.mockReturnValue(request); diff --git a/projects/social_platform/src/app/api/project/facades/edit/project-vacancy.service.ts b/projects/social_platform/src/app/api/project/facades/edit/project-vacancy.service.ts index 8bb5c051b..fed380fe4 100644 --- a/projects/social_platform/src/app/api/project/facades/edit/project-vacancy.service.ts +++ b/projects/social_platform/src/app/api/project/facades/edit/project-vacancy.service.ts @@ -1,6 +1,6 @@ /** @format */ -import { DestroyRef, inject, Injectable } from "@angular/core"; +import { computed, DestroyRef, inject, Injectable, signal } from "@angular/core"; import { Validators } from "@angular/forms"; import { ValidationService } from "@corelib"; import { ProjectVacancyUIService } from "./ui/project-vacancy-ui.service"; @@ -11,6 +11,15 @@ import { PostVacancyUseCase } from "../../../vacancy/use-cases/post-vacancy.use- import { DeleteVacancyUseCase } from "../../../vacancy/use-cases/delete-vacancy.use-case"; import { failure, initial, loading } from "@domain/shared/async-state"; import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; +import { finalize, Observable } from "rxjs"; +import { Result } from "@domain/shared/result.type"; +import { Vacancy } from "@domain/vacancy/vacancy.model"; + +type VacancyActionKind = "archive" | "restore" | "delete" | "blocked-delete"; +interface VacancyAction { + kind: VacancyActionKind; + vacancy: Vacancy; +} /** Сервис для управления вакансиями проекта. */ @Injectable() @@ -31,6 +40,40 @@ export class ProjectVacancyService { private readonly vacancyIsSubmitting = this.projectVacancyUIService.vacancyIsSubmitting; private readonly vacancySubmitInitiated = this.projectVacancyUIService.vacancySubmitInitiated; + readonly action = signal(null); + readonly actionBusy = signal(false); + readonly actionError = signal(null); + readonly actionSuccess = signal(""); + readonly activeTab = signal<"active" | "archived">("active"); + readonly activeVacancies = computed(() => + this.projectVacancyUIService.vacancies().filter(v => v.isActive), + ); + readonly archivedVacancies = computed(() => + this.projectVacancyUIService.vacancies().filter(v => !v.isActive), + ); + readonly visibleVacancies = computed(() => + this.activeTab() === "active" ? this.activeVacancies() : this.archivedVacancies(), + ); + readonly actionTitle = computed(() => { + switch (this.action()?.kind) { + case "archive": + return "Перенести вакансию в архив?"; + case "restore": + return "Вернуть вакансию в активные?"; + case "delete": + return "Удалить вакансию?"; + default: + return "Вакансию нельзя удалить"; + } + }); + readonly actionLabel = computed(() => { + const action = this.action(); + if (action?.kind === "restore") return "Вернуть в активные"; + if (action?.kind === "delete") return "Удалить вакансию"; + if (action?.kind === "blocked-delete" && !action.vacancy.isActive) return "Понятно"; + return "Перенести в архив"; + }); + constructor() { this.vacancyForm .get("skills") @@ -41,7 +84,7 @@ export class ProjectVacancyService { } public submitVacancy(projectId: number) { - if (this.projectVacancyUIService.vacancyIsSubmittingFlag()) return; + if (this.projectVacancyUIService.vacancyIsSubmittingFlag() || this.actionBusy()) return; // Настройка валидаторов для обязательных полей this.vacancyForm.get("role")?.setValidators([Validators.required]); this.vacancyForm.get("skills")?.setValidators([Validators.required]); @@ -126,14 +169,105 @@ export class ProjectVacancyService { } public removeVacancy(vacancyId: number): void { - if (!confirm("Вы точно хотите удалить вакансию?")) return; - this.deleteVacancyUseCase - .execute(vacancyId) - .pipe(takeUntilDestroyed(this.destroyRef)) - .subscribe(result => { - if (!result.ok) return; + this.openAction(vacancyId, "delete"); + } + + changeVacancyStatus(vacancyId: number): void { + const vacancy = this.projectVacancyUIService.vacancies().find(v => v.id === vacancyId); + if (vacancy) this.openAction(vacancyId, vacancy.isActive ? "archive" : "restore"); + } - this.projectVacancyUIService.applyRemoveVacancy(vacancyId); + closeAction(): void { + if (this.actionBusy()) return; + this.action.set(null); + this.actionError.set(null); + } + + private openAction(vacancyId: number, kind: VacancyActionKind): void { + if (this.actionBusy() || this.projectVacancyUIService.vacancyIsSubmittingFlag()) return; + const vacancy = this.projectVacancyUIService.vacancies().find(v => v.id === vacancyId); + if (!vacancy) return; + const hasResponses = (vacancy.totalResponseCount ?? vacancy.responseCount ?? 0) > 0; + this.action.set({ kind: kind === "delete" && hasResponses ? "blocked-delete" : kind, vacancy }); + this.actionError.set(null); + this.actionSuccess.set(""); + } + + confirmAction(): void { + const action = this.action(); + if (!action || this.actionBusy() || this.projectVacancyUIService.vacancyIsSubmittingFlag()) + return; + if (action.kind === "blocked-delete" && !action.vacancy.isActive) { + this.closeAction(); + return; + } + const current = this.projectVacancyUIService.vacancies().find(v => v.id === action.vacancy.id); + if (!current) { + this.actionError.set("Вакансия больше недоступна. Обновите страницу проекта."); + return; + } + if ( + action.kind === "delete" && + (current.totalResponseCount ?? current.responseCount ?? 0) > 0 + ) { + this.action.set({ kind: "blocked-delete", vacancy: current }); + return; + } + const kind = action.kind === "blocked-delete" ? "archive" : action.kind; + this.actionBusy.set(true); + this.actionError.set(null); + const request: Observable> = + kind === "delete" + ? this.deleteVacancyUseCase.execute(current.id) + : this.updateVacancyUseCase.execute(current.id, { isActive: kind === "restore" }); + request + .pipe( + finalize(() => this.actionBusy.set(false)), + takeUntilDestroyed(this.destroyRef), + ) + .subscribe({ + next: result => { + if (!result.ok) { + this.handleActionError(result.error.cause, kind); + return; + } + if (kind === "delete") this.projectVacancyUIService.applyRemoveVacancy(current.id); + else this.projectVacancyUIService.applyLifecycleVacancy(result.value as Vacancy); + this.actionSuccess.set( + kind === "delete" + ? "Вакансия удалена" + : kind === "restore" + ? "Вакансия возвращена в активные" + : "Вакансия перенесена в архив. История откликов сохранена.", + ); + this.action.set(null); + }, + error: error => this.handleActionError(error, kind), }); } + + private handleActionError(error: unknown, kind: string): void { + const response = error as { status?: number; error?: Record } | null; + const body = response?.error; + const code = body?.["code"]; + if ( + kind === "delete" && + (code === "vacancy_has_responses" || + (Array.isArray(code) && code.includes("vacancy_has_responses"))) + ) { + const current = this.action(); + if (current) this.action.set({ ...current, kind: "blocked-delete" }); + return; + } + const detail = body?.["is_active"]; + this.actionError.set( + response?.status === 403 + ? "Нет доступа к управлению этой вакансией. Обратитесь к руководителю проекта." + : response?.status === 404 + ? "Вакансия больше недоступна. Обновите страницу проекта." + : Array.isArray(detail) && typeof detail[0] === "string" + ? detail[0] + : "Не удалось выполнить действие. Вакансия не изменена. Проверьте соединение и повторите попытку.", + ); + } } diff --git a/projects/social_platform/src/app/api/project/facades/edit/ui/project-vacancy-ui.service.ts b/projects/social_platform/src/app/api/project/facades/edit/ui/project-vacancy-ui.service.ts index d14e349f1..c81125877 100644 --- a/projects/social_platform/src/app/api/project/facades/edit/ui/project-vacancy-ui.service.ts +++ b/projects/social_platform/src/app/api/project/facades/edit/ui/project-vacancy-ui.service.ts @@ -154,7 +154,19 @@ export class ProjectVacancyUIService { } applyRemoveVacancy(vacancyId: number): void { + const editIndex = this.projectFormService.editIndex(); + const editedId = editIndex === null ? null : this.vacancies()[editIndex]?.id; this.vacancies.update(list => list.filter(v => v.id !== vacancyId)); + if (editedId === vacancyId) this.applyResetVacancyForm(); + else if (editedId !== null && editedId !== undefined) { + const nextIndex = this.vacancies().findIndex(v => v.id === editedId); + this.projectFormService.editIndex.set(nextIndex >= 0 ? nextIndex : null); + } + } + + applyLifecycleVacancy(vacancy: Vacancy): void { + // Изменение статуса соседней карточки не сбрасывает несохраненную форму. + this.vacancies.update(list => list.map(item => (item.id === vacancy.id ? vacancy : item))); } applySubmitVacancy(vacancy: Vacancy): void { diff --git a/projects/social_platform/src/app/domain/vacancy/vacancy.model.ts b/projects/social_platform/src/app/domain/vacancy/vacancy.model.ts index c6ff05ed0..736f70a18 100644 --- a/projects/social_platform/src/app/domain/vacancy/vacancy.model.ts +++ b/projects/social_platform/src/app/domain/vacancy/vacancy.model.ts @@ -19,6 +19,10 @@ export class Vacancy { specialization?: string; datetimeCreated!: string; datetimeUpdated!: string; + datetimeClosed?: string | null; + /** Ожидающие решения отклики; полная история приходит отдельным полем. */ + responseCount?: number; + totalResponseCount?: number; hasResponded = false; canRespond = false; canManageResponses = false; diff --git a/projects/social_platform/src/app/ui/pages/projects/edit/components/project-vacancy-step/project-vacancy-step.component.html b/projects/social_platform/src/app/ui/pages/projects/edit/components/project-vacancy-step/project-vacancy-step.component.html index 784a93155..7e2f60509 100644 --- a/projects/social_platform/src/app/ui/pages/projects/edit/components/project-vacancy-step/project-vacancy-step.component.html +++ b/projects/social_platform/src/app/ui/pages/projects/edit/components/project-vacancy-step/project-vacancy-step.component.html @@ -1,234 +1,406 @@ -

-
- @if (showInputFields()) { -
- @if (role; as role) { -
- - - @if ((role | controlError: "required") && vacancySubmitInitiated()) { -
- {{ errorMessage.VALIDATION_REQUIRED }} -
- } -
- } - @if (description) { -
- - - @if ((description | controlError: "required") && vacancySubmitInitiated()) { -
- {{ errorMessage.VALIDATION_REQUIRED }} -
- } -
- } - -
-
- @if (requiredExperience; as requiredExperience) { -
- - - @if (requiredExperience | controlError: "required") { -
- {{ errorMessage.VALIDATION_REQUIRED }} -
- } -
- } - @if (workFormat; as workFormat) { -
- - - @if (workFormat | controlError: "required") { -
- {{ errorMessage.VALIDATION_REQUIRED }} -
- } -
- } -
- - @if (isCityVisible()) { - @if (city; as city) { -
- - - @if ((city | controlError: "required") && vacancySubmitInitiated()) { -
- {{ errorMessage.VALIDATION_REQUIRED }} -
- } -
- } +
+
+

Вакансии проекта

+

Управляйте набором в команду и сохраняйте историю откликов.

+
+ @if (!showInputFields()) { + + Создать вакансию + + } +
+
+ + +
+

+ {{ + vacancyActions.activeTab() === "active" + ? "Активные вакансии принимают отклики в опубликованном публичном проекте." + : "Набор закрыт. Здесь хранятся вакансии и история откликов." + }} +

+@if (vacancyActions.actionSuccess()) { +

+ {{ vacancyActions.actionSuccess() }} +

+} + +
+
+
+ @if (showInputFields()) { + + @if (role; as role) { +
+ + + @if ((role | controlError: "required") && vacancySubmitInitiated()) { +
+ {{ errorMessage.VALIDATION_REQUIRED }} +
+ } +
+ } + @if (description) { +
+ + + @if ((description | controlError: "required") && vacancySubmitInitiated()) { +
+ {{ errorMessage.VALIDATION_REQUIRED }} +
+ } +
} -
- @if (salary; as salary) { -
- - - @if ((salary | controlError: "required") && vacancySubmitInitiated()) { -
- {{ errorMessage.VALIDATION_REQUIRED }} -
- } -
- } - @if (workSchedule; as workSchedule) { -
- - - @if (workSchedule | controlError: "required") { -
- {{ errorMessage.VALIDATION_REQUIRED }} -
- } -
+
+
+ @if (requiredExperience; as requiredExperience) { +
+ + + @if (requiredExperience | controlError: "required") { +
+ {{ errorMessage.VALIDATION_REQUIRED }} +
+ } +
+ } + @if (workFormat; as workFormat) { +
+ + + @if (workFormat | controlError: "required") { +
+ {{ errorMessage.VALIDATION_REQUIRED }} +
+ } +
+ } +
+ + @if (isCityVisible()) { + @if (city; as city) { +
+ + + @if ((city | controlError: "required") && vacancySubmitInitiated()) { +
+ {{ errorMessage.VALIDATION_REQUIRED }} +
+ } +
+ } } -
-
- - @if (skills; as skills) { -
- - @if (skills | controlError: "required") { -
- {{ errorMessage.VALIDATION_REQUIRED }} -
- } + + + @if (skills; as skills) { +
+ + @if (skills | controlError: "required") { +
+ {{ errorMessage.VALIDATION_REQUIRED }} +
+ } +
+ } + + } + + {{ + isEditing() + ? "Сохранить изменения" + : showInputFields() + ? "Добавить вакансию" + : "Создать вакансию" + }} + + + @if (vacancySubmitFailed()) { + + } +
+ +
+
    + @for (vacancy of visibleVacancies(); track vacancy.id) { +
  • + +
  • } - - } - - {{ - isEditing() - ? "Сохранить изменения" - : showInputFields() - ? "Добавить вакансию" - : "Создать вакансию" - }} - - - @if (vacancySubmitFailed()) { +
+
+ + @if (!visibleVacancies().length) { + class="vacancy-empty" + kind="empty" + [title]=" + vacancyActions.activeTab() === 'active' ? 'Нет активных вакансий' : 'В архиве пока пусто' + " + > + {{ + vacancyActions.activeTab() === "active" + ? "Создайте вакансию или верните существующую из архива." + : "Вакансии и история откликов появятся здесь после переноса в архив." + }} + }
+
-
-
    - @for (vacancy of vacancies(); track vacancy.id) { -
  • - -
  • +@if (vacancyActions.action(); as action) { + +
    + +

    {{ vacancyActions.actionTitle() }}

    +
    +

    {{ action.vacancy.role }}

    + @switch (action.kind) { + @case ("restore") { +

    + Вакансия снова будет принимать новые отклики. Возобновить набор можно только в + опубликованном публичном проекте. +

    +

    История и прежние решения сохранятся. Отклоненные отклики не вернутся в ожидание.

    + } + @case ("delete") { +

    + Вакансия будет удалена без возможности восстановления. Если хотите временно завершить + набор, перенесите ее в архив. +

    +

    Удалить вакансию можно только при отсутствии откликов.

    + } + @default { + @if (action.kind === "blocked-delete") { +

    + На вакансию уже есть отклики. Чтобы сохранить историю кандидатов, удаление + недоступно, даже после переноса в архив. +

    + } + @if (action.vacancy.isActive) { +

    + Вы закроете набор. Вакансия перестанет принимать новые отклики. История сохранится, + вернуться к набору можно позже. +

    +

    + Ожидающие решения отклики будут отклонены. Кандидаты получат уведомления по + электронной почте. +

    + } + } + } +
    + @if (vacancyActions.actionError(); as error) { + } -
-
- - @if (!vacancies().length) { - - } -
+
+ Отмена + {{ + vacancyActions.actionBusy() ? "Выполняем…" : vacancyActions.actionLabel() + }} +
+ + +} @if (createdVacancyId(); as vacancyId) { >(ElementRef); private readonly injector = inject(Injector); private readonly skillSearch = viewChild(AutoCompleteInputComponent); private readonly vacancySubmitButton = viewChild>( @@ -112,6 +114,38 @@ export class ProjectVacancyStepComponent { protected readonly vacancySubmitFailed = computed(() => isFailure(this.projectVacancyUIService.vacancyIsSubmitting()), ); + protected readonly vacancyActions = this.projectVacancyInfoService; + protected readonly visibleVacancies = this.projectVacancyInfoService.visibleVacancies; + + constructor() { + effect(() => { + if (!this.vacancyActions.actionSuccess()) return; + afterNextRender( + () => { + this.element.nativeElement + .querySelector('[role="tab"][aria-selected="true"]') + ?.focus(); + }, + { injector: this.injector }, + ); + }); + } + + onVacancyTabKey(event: KeyboardEvent): void { + const keys = ["ArrowLeft", "ArrowRight", "Home", "End"]; + if (!keys.includes(event.key)) return; + event.preventDefault(); + const tab = + event.key === "Home" + ? "active" + : event.key === "End" + ? "archived" + : this.vacancyActions.activeTab() === "active" + ? "archived" + : "active"; + this.vacancyActions.activeTab.set(tab); + this.element.nativeElement.querySelector(`#vacancy-tab-${tab}`)?.focus(); + } protected readonly inlineSkills = this.searchesService.inlineSkills; protected readonly projectId = this.projectsEditInfoService.profileId; diff --git a/projects/social_platform/src/app/ui/widgets/vacancy-card/vacancy-card.component.html b/projects/social_platform/src/app/ui/widgets/vacancy-card/vacancy-card.component.html index 2c18bf3a7..3a32309be 100644 --- a/projects/social_platform/src/app/ui/widgets/vacancy-card/vacancy-card.component.html +++ b/projects/social_platform/src/app/ui/widgets/vacancy-card/vacancy-card.component.html @@ -5,7 +5,7 @@

{{ item.role }}

@@ -13,10 +13,33 @@

{{ item.role }}

Ищем: {{ item.specialization }}

} + @if (manageLifecycle()) { +
+ {{ + item.totalResponseCount === undefined + ? "Вакансия и отклики" + : "Отклики · " + item.totalResponseCount + }} + — {{ item.role }} + + @if (!item.isActive && item.datetimeClosed) { +

В архиве с {{ item.datetimeClosed | date: "dd.MM.yyyy" }}

+ } + }
Редактировать + @if (manageLifecycle()) { + + {{ item.isActive ? "В архив" : "Вернуть в активные" }} + + } { let component: VacancyCardComponent; @@ -14,6 +15,7 @@ describe("VacancyCardComponent", () => { await TestBed.configureTestingModule({ imports: [VacancyCardComponent], providers: [ + provideRouter([]), provideNgxMask(), { provide: AuthRepositoryPort, @@ -43,6 +45,27 @@ describe("VacancyCardComponent", () => { }; } + it("показывает архив, историю и действие возврата в управляемой карточке", () => { + fixture.componentRef.setInput("manageLifecycle", true); + fixture.componentRef.setInput("vacancy", { ...createVacancy(false), totalResponseCount: 4 }); + fixture.detectChanges(); + expect(fixture.nativeElement.textContent).toContain("В архиве"); + expect(fixture.nativeElement.textContent).toContain("Вернуть в активные"); + expect(fixture.nativeElement.querySelector(".vacancy__responses").textContent).toContain("4"); + const changed = vi.fn(); + component.changeStatus.subscribe(changed); + fixture.nativeElement.querySelectorAll(".vacancy__actions button")[1].click(); + expect(changed).toHaveBeenCalledWith(1); + }); + + it("не подменяет неизвестное число откликов нулем", () => { + fixture.componentRef.setInput("manageLifecycle", true); + fixture.detectChanges(); + expect(fixture.nativeElement.querySelector(".vacancy__responses").textContent).toContain( + "Вакансия и отклики", + ); + }); + it("should create", () => { expect(component).toBeTruthy(); }); diff --git a/projects/social_platform/src/app/ui/widgets/vacancy-card/vacancy-card.component.ts b/projects/social_platform/src/app/ui/widgets/vacancy-card/vacancy-card.component.ts index 28843d704..a3bb8918d 100644 --- a/projects/social_platform/src/app/ui/widgets/vacancy-card/vacancy-card.component.ts +++ b/projects/social_platform/src/app/ui/widgets/vacancy-card/vacancy-card.component.ts @@ -8,6 +8,9 @@ import { Vacancy } from "@domain/vacancy/vacancy.model"; import { IconComponent, ButtonComponent } from "@ui/primitives"; import { VacancyStatusComponent } from "../vacancy-status/vacancy-status.component"; import { VacancySkillsComponent } from "../vacancy-skills/vacancy-skills.component"; +import { DatePipe } from "@angular/common"; +import { RouterLink } from "@angular/router"; +import { AppRoutes } from "@api/paths/app-routes"; @Component({ selector: "app-vacancy-card", @@ -19,15 +22,26 @@ import { VacancySkillsComponent } from "../vacancy-skills/vacancy-skills.compone ButtonComponent, VacancyStatusComponent, VacancySkillsComponent, + DatePipe, + RouterLink, ], changeDetection: ChangeDetectionStrategy.OnPush, }) export class VacancyCardComponent { readonly vacancy = input(); readonly disabled = input(false); + readonly manageLifecycle = input(false); + readonly changeStatus = output(); + protected readonly AppRoutes = AppRoutes; readonly remove = output(); readonly edit = output(); + onChangeStatus(event: MouseEvent): void { + event.stopPropagation(); + event.preventDefault(); + if (!this.disabled() && this.vacancy()) this.changeStatus.emit(this.vacancy()!.id); + } + onRemove(event: MouseEvent): void { event.stopPropagation(); event.preventDefault(); From c202991cbeea993e15de12a55a52c3dc986d8936 Mon Sep 17 00:00:00 2001 From: DarKylX Date: Wed, 21 Oct 2026 15:16:46 +0300 Subject: [PATCH 2/6] docs(vacancies): record persistent archive rule and migration --- docs/feature-specs/vacancy-archive-20261021.md | 10 ++++++++-- docs/vacancy-archive/verification.md | 18 ++++++++++-------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/docs/feature-specs/vacancy-archive-20261021.md b/docs/feature-specs/vacancy-archive-20261021.md index 36678698f..a1ddb0767 100644 --- a/docs/feature-specs/vacancy-archive-20261021.md +++ b/docs/feature-specs/vacancy-archive-20261021.md @@ -11,7 +11,8 @@ Angular dev cc95cda8: общий список вакансий, native confirm удаления, ошибка API не показывается. API dev 1c424ff: PATCH is_active существует, но не завершает ожидающие отклики; DELETE не защищает историю. В Figma зафиксированы два списка, перенос, возобновление набора и модалки с последствиями. -Архив соответствует is_active=false, отдельная сущность или миграция не нужны. +Архив соответствует is_active=false, отдельная сущность не нужна. +В API добавлен внутренний resume_on_publish для отличия архива от временного скрытия вместе с черновиком. Создание и редактирование сохраняют существующую форму, навыки и серверные проверки. ## Роли и правила @@ -19,6 +20,8 @@ API dev 1c424ff: PATCH is_active существует, но не заверша Изменения доступны руководителю проекта и администрации; сервер повторно проверяет право под блокировкой. Закрытие отклоняет только ожидающие отклики с email-уведомлением после commit. История сохраняется. Возобновление допустимо только для опубликованного публичного проекта; прежние решения не меняются. +По ответу пользователя 21.10.2026 архивные вакансии остаются в архиве до ручного возврата, +в том числе при повторной публикации проекта. Новые вакансии черновика публикуются вместе с проектом. Наличие любых откликов запрещает удаление, включая архивные вакансии. Блокировки согласованы с откликами: Project → Vacancy → VacancyResponse. @@ -40,6 +43,7 @@ Frontend использует существующий UpdateVacancyUseCase и - AC5: с любыми откликами удаление запрещено и через прямой API; UI объясняет причину и предлагает архив для активной вакансии. - AC6: ошибки оставляют модалку открытой, повтор доступен, двойная отправка блокируется. Ошибочный запрос не отклоняет отклики и не удаляет навыки. - AC7: пустые списки, неизвестное число откликов, мобильный экран 320/390, keyboard tabs, modal Escape/trap/return focus не теряют контекст и данные формы. +- AC8: повторная публикация проекта сохраняет архив, дату закрытия и историю. Ручной возврат разрешен после публикации; новые вакансии черновика продолжают публиковаться вместе с проектом. ## План и границы @@ -47,6 +51,8 @@ Frontend использует существующий UpdateVacancyUseCase и 2. Angular: состояния действий в фасаде, фильтрация и вкладки, существующие Card/Modal/Button/State, интеграция с use cases. 3. Проверки: API/Angular targeted tests, build, browser fixtures для desktop/mobile и ошибок, review от AC, связанные PR в dev. -Backend должен попасть в dev первым. PR frontend зависит от backend; миграций нет. +Backend с миграцией vacancy.0011 должен попасть в dev первым. PR frontend зависит от backend. +Старые закрытые вакансии, в том числе в черновиках, остаются закрытыми: причина прежнего закрытия не сохранялась. +Миграция добавляет внутренний флаг с default=false и не меняет статусы/даты; нужные старые записи можно вернуть вручную. Изменения React, production, глобального UI Kit и соседних страниц не входят в задачу. Данные browser fixtures не подтверждают работу deployed API; это отдельное ограничение отчета. diff --git a/docs/vacancy-archive/verification.md b/docs/vacancy-archive/verification.md index 28f332814..5ea10619e 100644 --- a/docs/vacancy-archive/verification.md +++ b/docs/vacancy-archive/verification.md @@ -15,7 +15,7 @@ | Build | `npm run build:pr` — exit 0. Preview build с существующим entry point `docs/vacancy-redesign/preview/main.ts` — exit 0. Sass deprecation warnings относятся к существующим стилям. | | Browser | `node docs/vacancy-archive/browser-acceptance.cjs` с локальным preview на 4371 — 58 проверок, JS errors []. Ширины 1440/768/390/320; Mont; touch; tabs keyboard; модалки; счетчики; отмена; busy; повтор после ошибки; появление отклика перед удалением; пустые списки. | | Static | ESLint измененных TS и Stylelint двух измененных SCSS — exit 0. | -| API | Связанная API-ветка от dev 1c424ff: `manage.py test vacancy.tests projects.tests.test_program_project_detail_access --noinput --keepdb` — 106 tests passed на PostgreSQL 18.1, Python 3.11.15 / Django 4.2.11. Models check и makemigrations --check --dry-run — exit 0, миграций нет. | +| API | Связанная API-ветка от dev 1c424ff: `manage.py test vacancy.tests projects.tests.test_project_signals projects.tests.test_program_project_detail_access --noinput --keepdb` — 119 tests passed на PostgreSQL 18.1, Python 3.11.15 / Django 4.2.11. Models check и makemigrations --check --dry-run — exit 0; миграция vacancy.0011 проверена upgrade-тестом на старых записях. | [Результаты браузера](browser-results.json), [desktop](archive-modal-1440.png), [mobile](archive-modal-390.png). Browser использует fixtures и не выполняет мутации live API или отправку писем. @@ -26,22 +26,24 @@ Browser использует fixtures и не выполняет мутации | --- | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | | AC1 | PASS | height=27, счетчики и фильтрация проверены в браузере на четырех ширинах; геометрия карточек на desktop — две колонки по 554 px в preview. | | AC2 | PASS | API-тест атомарного закрытия и уведомления ожидающих; browser проверяет ожидание ответа и успешный перенос. | -| AC3 | PASS для ручного возврата | Сервер отклоняет возобновление в draft/private проекте; история решений сохраняется. Повторная публикация — отдельный открытый вопрос ниже. | +| AC3 | PASS | Сервер отклоняет возобновление в draft/private проекте; история решений сохраняется. | | AC4 | PASS | Подтверждение и успешное удаление проверены API, unit и browser. | | AC5 | PASS | API запрещает удаление во всех состояниях откликов и обеих вкладках; UI предлагает архив. | | AC6 | PASS | Ошибка и повтор, защита двойного запроса, появление отклика после открытия модалки; invalid skills не закрывают вакансию и не удаляют навыки. | | AC7 | PASS в проверенном контуре | Empty, unknown count, 320/390, keyboard tabs, Escape и focus после переноса, сохранение формы проверены. Полный accessibility audit не выполнялся. | +| AC8 | PASS | API и signal tests: архив сохраняется при повторной публикации до ручного возврата; даты/решения сохранены. Новая вакансия черновика публикуется; миграция не меняет старые статусы/даты. | -## Review и открытый вопрос +## Review и внедрение По итоговому diff проверены permissions, порядок блокировок Project → Vacancy → VacancyResponse, сохранение response_count как числа ожидающих, отсутствие N+1 в каталоге, readonly total_response_count, контекст проекта, server errors, Mont, фокус и отсутствие переполнения. Кодовые замечания в проверенном контуре исправлены; связанный frontend/API diff требует совместного внедрения. -**HOLD перед интеграцией:** существующий `projects/signals.py:update_vacancy` активирует все закрытые вакансии -при переходе проекта draft → published. Пока это правило сохранено. Пользователю задан вопрос: -оставлять архивные до ручного возврата или сохранить автопубликацию. Новая семантика и миграция без ответа не вводились. +Пользователь подтвердил: «Оставлять архивные вакансии в архиве до ручного возврата». +Сервер отличает архив от вакансий, временно скрытых вместе с черновиком. Архив при публикации не меняется. +Миграция vacancy.0011 добавляет внутренний resume_on_publish с default=false; старые закрытые записи, +включая черновики, сохраняются в архиве, поскольку причина закрытия ранее не фиксировалась. -Не проверены deployed dev, реальная доставка email и полный backend/frontend suite. Эти проверки не объявляются пройденными. -После решения вопроса и закрытия связанности PR порядок внедрения: API → Angular → ручная dev acceptance. +Не проверены deployed dev, реальная доставка email и полный frontend suite. Эти проверки не объявляются пройденными. +Полный backend suite запускает CI PR. Порядок внедрения: API + миграция → Angular → ручная dev acceptance. From fcd256a687eefe837187b7eda7232c165b5051fa Mon Sep 17 00:00:00 2001 From: DarKylX Date: Wed, 21 Oct 2026 15:24:07 +0300 Subject: [PATCH 3/6] fix(vacancies): show server reason when restoration is denied --- docs/vacancy-archive/browser-acceptance.cjs | 19 ++++++++++-- docs/vacancy-archive/browser-results.json | 11 +++++-- docs/vacancy-archive/verification.md | 6 ++-- docs/vacancy-redesign/preview/main.ts | 11 +++++-- .../edit/project-vacancy.service.spec.ts | 31 ++++++++++--------- .../facades/edit/project-vacancy.service.ts | 8 +++-- 6 files changed, 59 insertions(+), 27 deletions(-) diff --git a/docs/vacancy-archive/browser-acceptance.cjs b/docs/vacancy-archive/browser-acceptance.cjs index c8aa9213f..22ad6c6d2 100644 --- a/docs/vacancy-archive/browser-acceptance.cjs +++ b/docs/vacancy-archive/browser-acceptance.cjs @@ -29,8 +29,11 @@ fs.mkdirSync(output, { recursive: true }); const confirm = () => page.getByRole("dialog"); const calls = () => page.evaluate(() => window.__vacancyPreview.lifecycle.calls); const succeed = () => page.evaluate(() => window.__vacancyPreview.lifecycle.succeed()); - const fail = (status, code) => - page.evaluate(([s, c]) => window.__vacancyPreview.lifecycle.fail(s, c), [status, code]); + const fail = (status, code, detail) => + page.evaluate( + ([s, c, d]) => window.__vacancyPreview.lifecycle.fail(s, c, d), + [status, code, detail], + ); for (const width of [1440, 768, 390, 320]) { await open(width, width === 320); const geometry = await page.getByRole("tab").evaluateAll(nodes => @@ -144,6 +147,18 @@ fs.mkdirSync(output, { recursive: true }); "restore preserves past decisions", ); await confirm().getByRole("button", { name: "Вернуть в активные", exact: true }).click(); + const unpublished = "Возобновить набор можно только в опубликованном публичном проекте."; + await fail(400, undefined, unpublished); + await confirm().getByRole("alert").waitFor(); + check( + (await confirm().getByRole("alert").innerText()) === unpublished, + "server reason is visible", + ); + check( + (await page.getByRole("tab", { name: "Архивные · 3" }).count()) === 1, + "denial keeps archive", + ); + await confirm().getByRole("button", { name: "Вернуть в активные", exact: true }).click(); await succeed(); await confirm().waitFor({ state: "detached" }); check( diff --git a/docs/vacancy-archive/browser-results.json b/docs/vacancy-archive/browser-results.json index 2c4bbb879..48fbbcb33 100644 --- a/docs/vacancy-archive/browser-results.json +++ b/docs/vacancy-archive/browser-results.json @@ -1,6 +1,11 @@ { - "checks": 58, + "checks": 60, "errors": [], - "widths": [1440, 768, 390, 320], + "widths": [ + 1440, + 768, + 390, + 320 + ], "scope": "local Angular browser fixtures; no live API mutations" -} +} \ No newline at end of file diff --git a/docs/vacancy-archive/verification.md b/docs/vacancy-archive/verification.md index 5ea10619e..ceadfc74f 100644 --- a/docs/vacancy-archive/verification.md +++ b/docs/vacancy-archive/verification.md @@ -11,9 +11,9 @@ | Уровень | Evidence | | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Source | UpdateVacancyUseCase → PATCH /vacancies/{id}/, DeleteVacancyUseCase → DELETE. Состояние списка меняется после успешного ответа; форма не сбрасывается при изменении соседней карточки. | -| Angular tests | `npm run test:ci -- projects/social_platform/src/app/api/project/facades/edit/project-vacancy.service.spec.ts projects/social_platform/src/app/api/project/facades/edit/ui/project-vacancy-ui.service.spec.ts projects/social_platform/src/app/ui/widgets/vacancy-card/vacancy-card.component.spec.ts` — 3 файла, 45 тестов passed. | +| Angular tests | `npm run test:ci -- projects/social_platform/src/app/api/project/facades/edit/project-vacancy.service.spec.ts projects/social_platform/src/app/api/project/facades/edit/ui/project-vacancy-ui.service.spec.ts projects/social_platform/src/app/ui/widgets/vacancy-card/vacancy-card.component.spec.ts` — 3 файла, 46 тестов passed. | | Build | `npm run build:pr` — exit 0. Preview build с существующим entry point `docs/vacancy-redesign/preview/main.ts` — exit 0. Sass deprecation warnings относятся к существующим стилям. | -| Browser | `node docs/vacancy-archive/browser-acceptance.cjs` с локальным preview на 4371 — 58 проверок, JS errors []. Ширины 1440/768/390/320; Mont; touch; tabs keyboard; модалки; счетчики; отмена; busy; повтор после ошибки; появление отклика перед удалением; пустые списки. | +| Browser | `node docs/vacancy-archive/browser-acceptance.cjs` с локальным preview на 4371 — 60 проверок, JS errors []. Ширины 1440/768/390/320; Mont; touch; tabs keyboard; модалки; счетчики; отмена; busy; повтор после ошибки; появление отклика перед удалением; пустые списки; объяснение отказа возврата в непубличном/черновом проекте. | | Static | ESLint измененных TS и Stylelint двух измененных SCSS — exit 0. | | API | Связанная API-ветка от dev 1c424ff: `manage.py test vacancy.tests projects.tests.test_project_signals projects.tests.test_program_project_detail_access --noinput --keepdb` — 119 tests passed на PostgreSQL 18.1, Python 3.11.15 / Django 4.2.11. Models check и makemigrations --check --dry-run — exit 0; миграция vacancy.0011 проверена upgrade-тестом на старых записях. | @@ -26,7 +26,7 @@ Browser использует fixtures и не выполняет мутации | --- | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | | AC1 | PASS | height=27, счетчики и фильтрация проверены в браузере на четырех ширинах; геометрия карточек на desktop — две колонки по 554 px в preview. | | AC2 | PASS | API-тест атомарного закрытия и уведомления ожидающих; browser проверяет ожидание ответа и успешный перенос. | -| AC3 | PASS | Сервер отклоняет возобновление в draft/private проекте; история решений сохраняется. | +| AC3 | PASS | Сервер отклоняет возобновление в draft/private проекте; история решений сохраняется. UI показывает причину из API и для строки, и для массива; browser проверяет отказ и повтор. | | AC4 | PASS | Подтверждение и успешное удаление проверены API, unit и browser. | | AC5 | PASS | API запрещает удаление во всех состояниях откликов и обеих вкладках; UI предлагает архив. | | AC6 | PASS | Ошибка и повтор, защита двойного запроса, появление отклика после открытия модалки; invalid skills не закрывают вакансию и не удаляют навыки. | diff --git a/docs/vacancy-redesign/preview/main.ts b/docs/vacancy-redesign/preview/main.ts index b1ed29fbc..9ca96b2af 100644 --- a/docs/vacancy-redesign/preview/main.ts +++ b/docs/vacancy-redesign/preview/main.ts @@ -458,8 +458,15 @@ TestBed.compileComponents().then(async () => { ); actionRequest.complete(); }, - fail(status = 500, code?: string) { - actionRequest.next(fail({ cause: { status, error: code ? { code: [code] } : {} } })); + fail(status = 500, code?: string, isActiveError?: string) { + actionRequest.next( + fail({ + cause: { + status, + error: isActiveError ? { is_active: isActiveError } : code ? { code: [code] } : {}, + }, + }), + ); actionRequest.complete(); }, }, diff --git a/projects/social_platform/src/app/api/project/facades/edit/project-vacancy.service.spec.ts b/projects/social_platform/src/app/api/project/facades/edit/project-vacancy.service.spec.ts index 120196e38..02c9b44b3 100644 --- a/projects/social_platform/src/app/api/project/facades/edit/project-vacancy.service.spec.ts +++ b/projects/social_platform/src/app/api/project/facades/edit/project-vacancy.service.spec.ts @@ -168,20 +168,23 @@ describe("ProjectVacancyService", () => { }, ); - it("возобновляет набор и показывает объяснение непубличного проекта", () => { - const vacancy = seedActionVacancy(false, 5); - updateVacancy.mockReturnValue( - of(fail({ cause: { status: 400, error: { is_active: ["Сначала опубликуйте проект"] } } })), - ); - service.changeVacancyStatus(11); - service.confirmAction(); - expect(service.actionError()).toBe("Сначала опубликуйте проект"); - expect(service.archivedVacancies()).toHaveLength(1); - updateVacancy.mockReturnValue(of(ok({ ...vacancy, isActive: true }))); - service.confirmAction(); - expect(updateVacancy).toHaveBeenLastCalledWith(11, { isActive: true }); - expect(service.activeVacancies()).toHaveLength(1); - }); + it.each(["Сначала опубликуйте проект", ["Сначала опубликуйте проект"]])( + "возобновляет набор и показывает объяснение непубличного проекта: %s", + detail => { + const vacancy = seedActionVacancy(false, 5); + updateVacancy.mockReturnValue( + of(fail({ cause: { status: 400, error: { is_active: detail } } })), + ); + service.changeVacancyStatus(11); + service.confirmAction(); + expect(service.actionError()).toBe("Сначала опубликуйте проект"); + expect(service.archivedVacancies()).toHaveLength(1); + updateVacancy.mockReturnValue(of(ok({ ...vacancy, isActive: true }))); + service.confirmAction(); + expect(updateVacancy).toHaveBeenLastCalledWith(11, { isActive: true }); + expect(service.activeVacancies()).toHaveLength(1); + }, + ); it("сохраняет идентичность редактируемой карточки при удалении соседней", () => { const first = seedActionVacancy(); diff --git a/projects/social_platform/src/app/api/project/facades/edit/project-vacancy.service.ts b/projects/social_platform/src/app/api/project/facades/edit/project-vacancy.service.ts index fed380fe4..ad24dff08 100644 --- a/projects/social_platform/src/app/api/project/facades/edit/project-vacancy.service.ts +++ b/projects/social_platform/src/app/api/project/facades/edit/project-vacancy.service.ts @@ -265,9 +265,11 @@ export class ProjectVacancyService { ? "Нет доступа к управлению этой вакансией. Обратитесь к руководителю проекта." : response?.status === 404 ? "Вакансия больше недоступна. Обновите страницу проекта." - : Array.isArray(detail) && typeof detail[0] === "string" - ? detail[0] - : "Не удалось выполнить действие. Вакансия не изменена. Проверьте соединение и повторите попытку.", + : typeof detail === "string" + ? detail + : Array.isArray(detail) && typeof detail[0] === "string" + ? detail[0] + : "Не удалось выполнить действие. Вакансия не изменена. Проверьте соединение и повторите попытку.", ); } } From 8c596da07f0740c3a6f7080b652a63c270a4094e Mon Sep 17 00:00:00 2001 From: DarKylX Date: Wed, 21 Oct 2026 15:33:59 +0300 Subject: [PATCH 4/6] docs(vacancies): record passing PostgreSQL CI --- docs/vacancy-archive/verification.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/vacancy-archive/verification.md b/docs/vacancy-archive/verification.md index ceadfc74f..372c7a19d 100644 --- a/docs/vacancy-archive/verification.md +++ b/docs/vacancy-archive/verification.md @@ -46,4 +46,6 @@ Browser использует fixtures и не выполняет мутации включая черновики, сохраняются в архиве, поскольку причина закрытия ранее не фиксировалась. Не проверены deployed dev, реальная доставка email и полный frontend suite. Эти проверки не объявляются пройденными. -Полный backend suite запускает CI PR. Порядок внедрения: API + миграция → Angular → ручная dev acceptance. +Полный backend suite подтвержден [PostgreSQL CI](https://github.com/PROCOLLAB-github/api/actions/runs/39598299814) +на финальном runtime SHA c92d997: 1296 tests, OK; отдельные 39 locking/response tests — OK; +миграции применены к пустой PostgreSQL 15. Порядок внедрения: API + миграция → Angular → ручная dev acceptance. From b352cf6e04136710ca4cbc0ac329b0034bce855e Mon Sep 17 00:00:00 2001 From: DarKylX Date: Wed, 21 Oct 2026 15:38:43 +0300 Subject: [PATCH 5/6] docs(vacancies): complete verification and review report --- docs/vacancy-archive/verification.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/vacancy-archive/verification.md b/docs/vacancy-archive/verification.md index 372c7a19d..0ecbb5bc6 100644 --- a/docs/vacancy-archive/verification.md +++ b/docs/vacancy-archive/verification.md @@ -49,3 +49,12 @@ Browser использует fixtures и не выполняет мутации Полный backend suite подтвержден [PostgreSQL CI](https://github.com/PROCOLLAB-github/api/actions/runs/39598299814) на финальном runtime SHA c92d997: 1296 tests, OK; отдельные 39 locking/response tests — OK; миграции применены к пустой PostgreSQL 15. Порядок внедрения: API + миграция → Angular → ручная dev acceptance. + +Дополнительный локальный полный прогон с --keepdb завершился `1296 tests, 1 error` в неизмененном +`users.tests.test_university_import`: в сохраненной базе после предыдущих TransactionTestCase не осталось +справочника, который этот тест ожидает от data migration. Отдельный повтор этого теста на новой изолированной +PostgreSQL прошел (`1 test, OK`); полный CI на чистой базе прошел (`1296 tests, OK`). +Локальный полный прогон не объявляется успешным. Оба остальных API CI checks (Tests и Lint) — success. + +Итог review: требования AC1–AC8 подтверждены в указанном контуре; открытых BLOCKER/MAJOR нет. +Оба PR направлены в dev и готовы к merge в указанном порядке; merge/deploy выполняет пользователь. From e216c3b83014a76b0e25f5972b07713d1da58360 Mon Sep 17 00:00:00 2001 From: DarKylX Date: Wed, 21 Oct 2026 15:44:58 +0300 Subject: [PATCH 6/6] style(vacancies): format verification artifacts for dev CI --- docs/vacancy-archive/browser-results.json | 9 ++----- docs/vacancy-archive/verification.md | 32 +++++++++++------------ 2 files changed, 18 insertions(+), 23 deletions(-) diff --git a/docs/vacancy-archive/browser-results.json b/docs/vacancy-archive/browser-results.json index 48fbbcb33..883b2ee7d 100644 --- a/docs/vacancy-archive/browser-results.json +++ b/docs/vacancy-archive/browser-results.json @@ -1,11 +1,6 @@ { "checks": 60, "errors": [], - "widths": [ - 1440, - 768, - 390, - 320 - ], + "widths": [1440, 768, 390, 320], "scope": "local Angular browser fixtures; no live API mutations" -} \ No newline at end of file +} diff --git a/docs/vacancy-archive/verification.md b/docs/vacancy-archive/verification.md index 0ecbb5bc6..6ea1ecf60 100644 --- a/docs/vacancy-archive/verification.md +++ b/docs/vacancy-archive/verification.md @@ -8,13 +8,13 @@ ## Выполненные проверки -| Уровень | Evidence | -| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Source | UpdateVacancyUseCase → PATCH /vacancies/{id}/, DeleteVacancyUseCase → DELETE. Состояние списка меняется после успешного ответа; форма не сбрасывается при изменении соседней карточки. | -| Angular tests | `npm run test:ci -- projects/social_platform/src/app/api/project/facades/edit/project-vacancy.service.spec.ts projects/social_platform/src/app/api/project/facades/edit/ui/project-vacancy-ui.service.spec.ts projects/social_platform/src/app/ui/widgets/vacancy-card/vacancy-card.component.spec.ts` — 3 файла, 46 тестов passed. | -| Build | `npm run build:pr` — exit 0. Preview build с существующим entry point `docs/vacancy-redesign/preview/main.ts` — exit 0. Sass deprecation warnings относятся к существующим стилям. | -| Browser | `node docs/vacancy-archive/browser-acceptance.cjs` с локальным preview на 4371 — 60 проверок, JS errors []. Ширины 1440/768/390/320; Mont; touch; tabs keyboard; модалки; счетчики; отмена; busy; повтор после ошибки; появление отклика перед удалением; пустые списки; объяснение отказа возврата в непубличном/черновом проекте. | -| Static | ESLint измененных TS и Stylelint двух измененных SCSS — exit 0. | +| Уровень | Evidence | +| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Source | UpdateVacancyUseCase → PATCH /vacancies/{id}/, DeleteVacancyUseCase → DELETE. Состояние списка меняется после успешного ответа; форма не сбрасывается при изменении соседней карточки. | +| Angular tests | `npm run test:ci -- projects/social_platform/src/app/api/project/facades/edit/project-vacancy.service.spec.ts projects/social_platform/src/app/api/project/facades/edit/ui/project-vacancy-ui.service.spec.ts projects/social_platform/src/app/ui/widgets/vacancy-card/vacancy-card.component.spec.ts` — 3 файла, 46 тестов passed. | +| Build | `npm run build:pr` — exit 0. Preview build с существующим entry point `docs/vacancy-redesign/preview/main.ts` — exit 0. Sass deprecation warnings относятся к существующим стилям. | +| Browser | `node docs/vacancy-archive/browser-acceptance.cjs` с локальным preview на 4371 — 60 проверок, JS errors []. Ширины 1440/768/390/320; Mont; touch; tabs keyboard; модалки; счетчики; отмена; busy; повтор после ошибки; появление отклика перед удалением; пустые списки; объяснение отказа возврата в непубличном/черновом проекте. | +| Static | ESLint измененных TS и Stylelint двух измененных SCSS — exit 0. | | API | Связанная API-ветка от dev 1c424ff: `manage.py test vacancy.tests projects.tests.test_project_signals projects.tests.test_program_project_detail_access --noinput --keepdb` — 119 tests passed на PostgreSQL 18.1, Python 3.11.15 / Django 4.2.11. Models check и makemigrations --check --dry-run — exit 0; миграция vacancy.0011 проверена upgrade-тестом на старых записях. | [Результаты браузера](browser-results.json), [desktop](archive-modal-1440.png), [mobile](archive-modal-390.png). @@ -22,15 +22,15 @@ Browser использует fixtures и не выполняет мутации ## Requirement audit -| AC | Verdict | Evidence | -| --- | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | -| AC1 | PASS | height=27, счетчики и фильтрация проверены в браузере на четырех ширинах; геометрия карточек на desktop — две колонки по 554 px в preview. | -| AC2 | PASS | API-тест атомарного закрытия и уведомления ожидающих; browser проверяет ожидание ответа и успешный перенос. | -| AC3 | PASS | Сервер отклоняет возобновление в draft/private проекте; история решений сохраняется. UI показывает причину из API и для строки, и для массива; browser проверяет отказ и повтор. | -| AC4 | PASS | Подтверждение и успешное удаление проверены API, unit и browser. | -| AC5 | PASS | API запрещает удаление во всех состояниях откликов и обеих вкладках; UI предлагает архив. | -| AC6 | PASS | Ошибка и повтор, защита двойного запроса, появление отклика после открытия модалки; invalid skills не закрывают вакансию и не удаляют навыки. | -| AC7 | PASS в проверенном контуре | Empty, unknown count, 320/390, keyboard tabs, Escape и focus после переноса, сохранение формы проверены. Полный accessibility audit не выполнялся. | +| AC | Verdict | Evidence | +| --- | -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| AC1 | PASS | height=27, счетчики и фильтрация проверены в браузере на четырех ширинах; геометрия карточек на desktop — две колонки по 554 px в preview. | +| AC2 | PASS | API-тест атомарного закрытия и уведомления ожидающих; browser проверяет ожидание ответа и успешный перенос. | +| AC3 | PASS | Сервер отклоняет возобновление в draft/private проекте; история решений сохраняется. UI показывает причину из API и для строки, и для массива; browser проверяет отказ и повтор. | +| AC4 | PASS | Подтверждение и успешное удаление проверены API, unit и browser. | +| AC5 | PASS | API запрещает удаление во всех состояниях откликов и обеих вкладках; UI предлагает архив. | +| AC6 | PASS | Ошибка и повтор, защита двойного запроса, появление отклика после открытия модалки; invalid skills не закрывают вакансию и не удаляют навыки. | +| AC7 | PASS в проверенном контуре | Empty, unknown count, 320/390, keyboard tabs, Escape и focus после переноса, сохранение формы проверены. Полный accessibility audit не выполнялся. | | AC8 | PASS | API и signal tests: архив сохраняется при повторной публикации до ручного возврата; даты/решения сохранены. Новая вакансия черновика публикуется; миграция не меняет старые статусы/даты. | ## Review и внедрение