Sub-task EP-07-T05-S02 Yuqori 07_tasks erpbom-backend

R28 — transitive predecessor tasklarni avto qayta ochish

Bajarildi
Status:

Tavsif

Operatsiya `k` da `b` dona brak bo'lsa: `k` ning BARCHA transitive predecessor operatsiya-tasklarida (DAG bo'yicha yuqoriga; yig'ishda ikkala tarmoq ham) `qty_confirmed -= b` va `completed -> in_progress`; `required_qty` O'ZGARMAYDI. Tegishli kasblarga `chain.reopened` outbox qatori.

Texnik ko'rsatma

Agent uchun

Gating (R20) tabiiy ravishda `k` ni ushlab turadi — alohida blok qo'yilmaydi. Qayta ochilish soni CHEKLANMAYDI (Q12).

Qabul mezonlari (DoD)

4 / 4 bajarildi

  • AC18: 8.1 marshrutida yig'ish operatsiyasidagi 1 dona brak IKKALA tarmoqning barcha tasklarini 1 donaga qayta ochadi

    qa-1 · 1 о аввал

  • `required_qty` hech qayerda o'zgarmaydi

    qa-1 · 1 о аввал

  • Qayta ochilgandan keyin `k` ning bromi bloklanadi (predecessor `completed` emas)

    qa-1 · 1 о аввал

  • Har qayta ochilgan task uchun `chain.reopened` outbox qatori yoziladi (kasb bo'yicha)

    qa-1 · 1 о аввал

O'zgargan fayllar

3 ta

  • modified src/test/java/uz/erpbom/tasks/service/WorkReviewServiceAccrualOrderTest.java
  • modified src/test/java/uz/erpbom/tasks/controller/WorkReviewChainReopenIntegrationTest.java
  • modified src/main/java/uz/erpbom/tasks/service/WorkReviewService.java

Izoh qoldirish

Tarix

25 yozuv

  • ✎

    finalize-ep-07 yangiladi

    Yangilandi: pr_url

  • 💬

    unknown-agent izoh qoldirdi

    [lead/EP-07-T05-S03 QA dan] KUZATUV (bloklamaydi) — R28 zanjirida qulf tartibi nazariy deadlock berishi mumkin: `review` da task(325) -> production_run(400), so'ng `reopenTransitivePredecessors`(710) yana boshqa `tasks` qulflaydi, ya'ni run -> task tartibi paydo bo'ladi. Amalda PG `40P01` ni `isLockTimeoutFailure` ushlaydi va 409 STOCK_BUSY qaytadi — ma'lumot buzilmaydi, faqat liveness masalasi. Yuk ostida tez-tez 409 chiqsa, R28 ni predecessor tasklarni run qulfidan OLDIN olish tartibiga o'tkazish ko'rib chiqilsin.

  • ⇄

    unknown-agent statusni o'zgartirdi Review → Bajarildi

  • 💬

    unknown-agent izoh qoldirdi

    [lead] BLOK YOPILDI — commit 522a8ef. Biznes qarori (VARIANT A, CLAMP) kodga kiritildi: WorkReviewService.java:690 `subtract(brakQty).max(BigDecimal.ZERO)`. Lead MUSTAQIL mutatsiya tasdig'i (coder hisobotiga tayanmasdan): (1) `.max(BigDecimal.ZERO)` olib tashlanganda WorkReviewChainReopenIntegrationTest 7 dan 1 tasi YIQILADI; (2) tiklangach 7/7 yashil, exit 0; (3) daraxtda faqat `A openapi/v1/tasks.yaml`, kontrakt commit'ga tushmagan. S02 ning qolgan 4 mezoni avvalgi QA passida o'ldiruvchi mutatsiyalar bilan tasdiqlangan edi; bu commit faqat blok sababini yopadi. Shu asosda `review -> done`. Doc qarzi ochiq: 07_tasks.md §5 R28 bu chegara qoidasini umuman yozmagan — talab boyitish sessiyasida kiritilishi kerak.

  • ⇄

    backend-1 statusni o'zgartirdi Ishlanyapti → Review

  • 💬

    backend-1 izoh qoldirdi

    Fix: reopenTransitivePredecessors endi qty_confirmed ni max(0, qty_confirmed-brak_qty) bilan CLAMP qiladi (biznes qarori 2026-08-26, VARIANT A — 409 rad varianti QABUL QILINMADI). Yangi integratsion test secondSequentialTerminalBrakOnSharedAncestorClampsQtyConfirmedAtZero — QA repro stsenariysini (A->B, A->C, required=2, ikkinchi terminal brak) aynan qamraydi: ikkinchi review 200 qaytaradi, taskA.qty_confirmed=0 (manfiy emas), workC status=rejected (submitted da qotmaydi). Mutatsiya tasdiqlandi: .max(BigDecimal.ZERO) olib tashlanganda test 500 bilan yiqildi, tiklangach 200. grep MUTANT src/ bo'sh. Commit 522a8ef1. uz.erpbom.tasks.** 242/242, uz.erpbom.employees.** 252/252, 0 failure/0 error.

  • ✎

    backend-1 yangiladi

    Yangilandi: commit_sha

  • ⇄

    backend-1 statusni o'zgartirdi Bloklangan → Ishlanyapti

  • 💬

    unknown-agent izoh qoldirdi

    [lead] BIZNES QARORI KELDI (foydalanuvchi, 2026-08-26): variant A — CLAMP. qty_confirmed = max(0, qty_confirmed - brak_qty). Ya'ni umumiy ajdodga ega ikki voris ketma-ket terminal brak olsa, ajdodning qty_confirmed 0 dan pastga tushmaydi; 500/deadlock yo'qoladi va work qotib qolmaydi. 409 bilan rad etish varianti QABUL QILINMADI. Keyingi qadam: WorkReviewService.java:597 da `.max(BigDecimal.ZERO)` qo'shiladi + shu holatni qo'riqlaydigan test yoziladi, so'ng S02 blocked -> review. Doc qarzi: 07_tasks.md R28 bu holatni umuman yozmagan — talab boyitish sessiyasida §4 reopen bilan kiritilishi kerak (lead xotirasiga yozildi).

  • ⇄

    unknown-agent statusni o'zgartirdi Review → Bloklangan

    BIZNES BO'SHLIG'I — R28 da manfiy qty_confirmed holati yozilmagan. Umumiy ajdodga ega ikki parallel voris ketma-ket terminal brak olsa qty_confirmed manfiyga tushadi va chk_tasks_qty_confirmed_non_negative (V25__tasks.sql:85) yiqiladi -> 500 INTERNAL_ERROR, rollback, work abadiy `submitted` da qotadi. WorkReviewService.java:597 da subtract(brakQty) pastki chegarasiz. Yechim varianti (clamp 0 / 409 rad / boshqa) spec da YO'Q -> foydalanuvchi qarori kutilmoqda. Qamrov testlari alohida commit qilindi (83adbf9); kod tuzatishi qaror kelgach kiritiladi.

  • 💬

    qa-1 izoh qoldirdi

    QA (qa-1) tekshiruvi — HEAD 9e3b392. 1) O'LCHOV: `uz.erpbom.tasks.**` 228/228 yashil (toza surefire, o'zim yurgizdim). Men qo'shgan 2 test bilan **230/230**, 0 failure/0 error. 2) MEZONLAR 4/4 — har biri o'ldiruvchi mutatsiya bilan tasdiqlandi (izolyatsiyalangan git worktree, javap bilan bytecode tasdig'i): - AC18 ikkala tarmoq: mutant `predecessorOperationIds().stream().limit(1)` -> 2 test yiqildi. - required_qty o'zgarmaydi: mutant `setRequiredQty(... - b)` -> 3 test yiqildi. - gating: assembly testi 409 TASK_WAITING_FOR_PREDECESSORS oladi. - chain.reopened: V28 CHECK'da `chain.reopened` + object_type `task` bor (migratsiya haqiqatan shart emas), payload'da profession_id bor. - transitivlik (bobo): mutant "bir bosqichli BFS" -> 3 test yiqildi. 3) NUQSON (mezonlardan tashqarida, LEKIN technical_notes'dagi "Qayta ochilish soni CHEKLANMAYDI (Q12)" ga ZID) — HTTP 500 + qotib qolgan work: Umumiy ajdodga ega IKKI parallel voris ketma-ket brak olsa, ajdodning qty_confirmed'i MANFIY ga tushadi va DB CHECK yiqiladi. - Fayl: src/main/java/uz/erpbom/tasks/service/WorkReviewService.java:597 — `predecessorTask.setQtyConfirmed(predecessorTask.getQtyConfirmed().subtract(brakQty))`, pastki chegara YO'Q. - Konstreynt: src/main/resources/db/migration/V25__tasks.sql:85 `chk_tasks_qty_confirmed_non_negative`. - Takrorlash (real HTTP probe bilan tasdiqlandi): DAG A->B, A->C; required_qty=2; A `completed` (qty_confirmed=2); B va C ga bittadan `submitted` work (claimed_qty=2). review(workB, confirmed_qty=0, is_brak=true) -> 200, A: qty_confirmed=0, in_progress. review(workC, confirmed_qty=0, is_brak=true) -> **500 INTERNAL_ERROR** (`{"code":"INTERNAL_ERROR"}`), butun tranzaksiya rollback: A hamon 0, workC hamon `submitted` — qayta urinish ham har safar 500 (work abadiy qotadi, nazoratchi uni yopolmaydi). - Kutilgan: yo 0 gacha clamp, yo aniq biznes xatosi (409) — 500 EMAS. R28 bu holatni yozmagan (spec bo'shlig'i): qaysi variant to'g'ri ekani PM/biznes qaroriga muhtoj. 4) TEST BO'SHLIQLARI — men to'ldirdim, ishchi daraxtda `M` holatida (commit qilinmagan; lead commit qiladi): src/test/java/uz/erpbom/tasks/controller/WorkReviewChainReopenIntegrationTest.java - `terminalBrakRejectionReopensPredecessorsByFullClaimedQty`: TERMINAL brak yo'li (confirmed_qty=0 + is_brak=true) hech qayerda xatti-harakat darajasida qoplanmagan edi (AccrualOrderTest'da marshrut BO'SH -> R28 no-op). Mutant `if (effectiveIsBrak && confirming)` 4 testdan TIRIK o'tardi (javap: ikkita ifeq) — endi o'ladi. - FIXTURE BIR XILLIGI: uch musbat testda `b` HAR DOIM 1 edi -> mutant `subtract(BigDecimal.ONE)` + `payload brak_qty=ONE` TIRIK qolardi (javap: getstatic BigDecimal.ONE). Yangi testlarda b=3 va b=2 -> o'ladi. - `brakDoesNotTouchNonPredecessorTasksInSameRun` (DAG A->B, A->C, B->D): hech bir testda ajdod BO'LMAGAN task yo'q edi -> mutant "DAG qirralarini umuman o'qimay, marshrutdagi k dan boshqa BARCHA operatsiyani qayta och" TIRIK qolardi. Endi o'ladi (C tegilmaydi, D tegilmaydi). 5) KUZATUV (kod o'zgarishi shart emas): - `sharedAncestorInDiamondDagIsReopenedOnlyOnce` javadocidagi da'vo ("visited to'plamisiz ikki marta ayrilardi") NOTO'G'RI: visited'ni ArrayList'ga almashtirib dublikat qoldirsam ham test yashil — `findByProductionRunIdAndVariantOperationIdIn` ning SQL `IN` i o'zi dedup qiladi. Xatti-harakat to'g'ri, lekin bu o'qdagi "regressiya himoyasi" dekorativ. - `chain.reopened` dedup kaliti `chain.reopened:task:{id}`: bitta task worker sikli (2-5 s) ichida ikki marta qayta ochilsa (3-banddagi yo'l aynan shunday), ikkinchi outbox qatori `ON CONFLICT ... DO NOTHING` bilan jimgina yo'qoladi -> kasb ikkinchi xabarnomani olmaydi. 6) CROSS-CUTTING: @Transactional ichida (review) ✓ · tenant_id/schema mexanikasi qo'shilmagan ✓ · migratsiya yo'q ✓ · outbox biznes yozuv bilan bir tranzaksiyada, tashqi broker/kesh yo'q ✓ · precision tegilmagan ✓ · fizik DELETE yo'q ✓ · log'ga parol/token yozilmagan ✓. XULOSA: 4 mezon bajarilgan, ammo 3-banddagi 500 (qotib qoladigan work) tufayli `review` da qoldirildi.

  • ✓

    qa-1 qabul mezonini belgiladi

    ✓ Har qayta ochilgan task uchun `chain.reopened` outbox qatori yoziladi (kasb bo'yicha)

  • ✓

    qa-1 qabul mezonini belgiladi

    ✓ Qayta ochilgandan keyin `k` ning bromi bloklanadi (predecessor `completed` emas)

  • ✓

    qa-1 qabul mezonini belgiladi

    ✓ `required_qty` hech qayerda o'zgarmaydi

  • ✓

    qa-1 qabul mezonini belgiladi

    ✓ AC18: 8.1 marshrutida yig'ish operatsiyasidagi 1 dona brak IKKALA tarmoqning barcha tasklarini 1 donaga qayta ochadi

  • ⇄

    backend-1 statusni o'zgartirdi Ishlanyapti → Review

  • 💬

    backend-1 izoh qoldirdi

    R28 amalga oshirildi: WorkReviewService#review — effectiveIsBrak bo'lganda (S03 bilan bir xil shart) k operatsiyasining marshrut DAG'idagi BARCHA transitiv predecessor tasklarida qty_confirmed -= b, completed->in_progress; required_qty tegilmaydi. DAG BFS (ProductionRoute/RouteOperation) + visited to'plami — romb DAG'da umumiy ajdod FAQAT BIR MARTA ayriladi (regressiya testi bilan tasdiqlangan). Har predecessor uchun chain.reopened outbox (V28 CHECK'da allaqachon bor, migratsiya shart bo'lmadi). 4 ta yangi integratsiya testi (WorkReviewChainReopenIntegrationTest): (1) 8.1 misoli — yig'ish, 2 tarmoq, 5 ta task 1 donaga qayta ochiladi (AC18) + gating tasdiqi (claim -> 409 TASK_WAITING_FOR_PREDECESSORS); (2) 3 bosqichli chiziqli zanjir — grandparent ham (tranzitiv, bevosita emas) qayta ochiladi; (3) romb DAG — umumiy ajdod 1 marta (double-decrement regressiyasi); (4) manfiy test — rework (is_brak=false) R28'ni ISHGA TUSHIRMAYDI. uz.erpbom.tasks.**: 228/228 (224 bazaviy + 4 yangi), 0 failure/0 error. uz.erpbom.employees.**: 252/252, 0/0. Commit 9e3b392, branch feat/EP-07-erpbom-backend.

  • 📄

    backend-1 fayllarni qayd etdi

    3 ta fayl qayd etildi

  • ✎

    backend-1 yangiladi

    Yangilandi: branch, commit_sha

  • ✓

    backend-1 qabul mezonini belgiladi

    ✓ Har qayta ochilgan task uchun `chain.reopened` outbox qatori yoziladi (kasb bo'yicha)

  • ✓

    backend-1 qabul mezonini belgiladi

    ✓ Qayta ochilgandan keyin `k` ning bromi bloklanadi (predecessor `completed` emas)

  • ✓

    backend-1 qabul mezonini belgiladi

    ✓ `required_qty` hech qayerda o'zgarmaydi

  • ✓

    backend-1 qabul mezonini belgiladi

    ✓ AC18: 8.1 marshrutida yig'ish operatsiyasidagi 1 dona brak IKKALA tarmoqning barcha tasklarini 1 donaga qayta ochadi

  • ⇄

    backend-1 statusni o'zgartirdi Backlog → Ishlanyapti

  • ✦

    pm-agent yaratdi

    R28 — transitive predecessor tasklarni avto qayta ochish

Ma'lumot

Agent
—
Olingan
—
Boshlandi
26.08.2026 00:01
Tugadi
26.08.2026 03:11
Baho
6 soat
Spec
erp/docs/modules/07_tasks.md#5
Branch
feat/EP-07-erpbom-backend
Commit
522a8ef1ec67

Bog'liqliklar

Bundan oldin tugashi kerak

Yo'q — bu ish mustaqil.

Agent uchun

Bu ishni AI agent quyidagicha oladi:

curl -s -X POST https://pmboard.ferp.uz/api/items/EP-07-T05-S02/claim \
  -H "X-Agent: backend-dev-1"

Tugatgach:

curl -s -X POST https://pmboard.ferp.uz/api/items/EP-07-T05-S02/status \
  -H "X-Agent: backend-dev-1" \
  -H "Content-Type: application/json" \
  -d '{"status":"review","note":"..."}'