V28 — `production_outbox` jadvali (R30)
Tavsif
Texnik ko'rsatma
Agent uchun
Qabul mezonlari (DoD)
4 / 4 bajarildi
-
`status` CHECK: `pending` | `processing` | `sent` | `failed`, default `pending`
qa-ep-07-t01-s05 · 1 о аввал
-
`AbstractOutboxWorker` kutadigan barcha ustunlar mavjud (worker testi jadvalga qarshi ishlaydi)
qa-ep-07-t01-s05 · 1 о аввал
-
Indeks: (`status`, `next_attempt_at`) — claim so'rovi uchun; UNIQUE indeks dedup kaliti bo'yicha
qa-ep-07-t01-s05 · 1 о аввал
-
`event_type` CHECK ro'yxatida 07 hodisalari bor: `production_run.create_from_order`, `task.available`, `work.submitted`, `work.rejected`, `work.confirmed`, `chain.reopened`, `order.recheck`
qa-ep-07-t01-s05 · 1 о аввал
O'zgargan fayllar
2 ta
-
modified
src/test/java/uz/erpbom/tasks/ProductionOutboxMigrationTest.java -
modified
src/main/resources/db/migration/V28__production_outbox.sql
Izoh qoldirish
Tarix
33 yozuv
-
✎
finalize-ep-07 yangiladi
Yangilandi: pr_url
-
⇄
qa-ep-07-t01-s05 statusni o'zgartirdi Review → Bajarildi
-
💬
qa-ep-07-t01-s05 izoh qoldirdi
QA 2-o'tish (commit 0568070) — QABUL QILINDI, avvalgi blok yopildi. Birinchi o'tishdagi rad sababi (dedup_key tarkibi noaniq + testlar sun'iy suffiks ishlatardi) bartaraf etilgan. Foydalanuvchi qarori (format {event_type}:{entity}:{id}, qisman oyna pending/processing, ON CONFLICT DO NOTHING) migratsiya izohida (V28 41-62-qatorlar) endi ochiq savol emas, uch band ham aniq yozilgan. [MUSTAQIL ISBOT] Alohida postgres:16 konteynerida V28 yalang'och qo'llanib, pg_indexes.indexdef QA tomonidan bevosita o'qildi: uq_production_outbox_dedup_key >>> CREATE UNIQUE INDEX ... USING btree (dedup_key) WHERE ((status)::text = ANY ((ARRAY['pending','processing'])::text[])) idx_production_outbox_status_next_attempt_at >>> btree (status, next_attempt_at) WHERE status='pending' Qisman oyna sharti haqiqatan status IN ('pending','processing') — tasdiqlandi. [3186 — uchala dedup holati, haqiqiy format bilan, jonli PG'da] (i) work.submitted:work:1024 pending ekan work.confirmed:work:1024 inserti O'TDI (2 qator) — test sameEntityWithDifferentEventTypesDoesNotCollide (ii) ayni work.confirmed:work:1024 ikkinchi marta pending ekan ON CONFLICT DO NOTHING bilan jimgina o'tkazildi: 'INSERT 0 0', xato YO'Q, count=1; nazorat sifatida oddiy INSERT esa unique violation berdi — test onConflictDoNothing...ThenAllowsAfterTerminal (1-yarim) (iii) o'sha kalit 'sent' ga o'tgach yangi work.confirmed:work:1024 inserti O'TDI, count=2 — o'sha testning 2-yarmi Uchalasi ham qamralgan; testlarda sun'iy suffiks (`:resubmit-test`) endi dedup testlarida ishlatilmaydi. [MUTATSIYA — ikkalasi ham O'LDIRILDI] (a) qisman WHERE olib tashlandi (jadval bo'ylab unique) -> Tests run 17, Failures 2, MVN_EXIT=1. Kalit o'lim aynan (iii) da: onConflictDoNothing... 288-qator, '[terminal holatdan keyin yangi hodisa yozilishi kerak] Expecting actual not to be null'. Ya'ni test indeksdef matnini emas, HULQNI ushlaydi. (b) UNIQUE indeks butunlay o'chirildi -> Tests run 17, Failures 2, Errors 1, MVN_EXIT=1 (dedupUniqueIndexIsPartialOnActiveStatuses, duplicateDedupKeyIsRejectedWhilePending FAIL + onConflictDoNothing... ERROR). Har ikki mutatsiyadan keyin fayl `git checkout --` bilan tiklandi (md5 708ebf082afcbcad0b84f0afec837565, git diff bo'sh). [REGRESSIYA 3184/3185/3187 — information_schema/pg_constraint dan mustaqil o'qildi] 3184: status varchar NOT NULL DEFAULT 'pending'; chk_production_outbox_status = pending|processing|sent|failed — aniq shu 4 qiymat. 3185: worker talab qiladigan 8 ustun bor (id,status,attempts,next_attempt_at,locked_at,last_error,sent_at,created_at); haqiqiy AbstractOutboxWorker jadval ustida claim->process->sent va xato/attempts sikllarida yashil. 3187: chk_production_outbox_event_type da 7 hodisaning hammasi bor. [CROSS-CUTTING] AR-1: tenant_id ustuni YO'Q (tasdiqlandi). AR-3/AR-12: attempts/next_attempt_at/failed + worker FOR UPDATE SKIP LOCKED. AR-4: tashqi broker yo'q, DB jadvali. AR-10: polimorf object_type/object_id — katalog FK emas, izohda asoslangan. Nomlash snake_case. Parol/token log yo'q. [BASELINE] flock + mvn -Dtest=ProductionOutboxMigrationTest: Tests run 17, Failures 0, Errors 0, MVN_EXIT=0 (16->17 o'sishi tasdiqlandi). [ESLATMA, bu barg emas] Ish oxirida git status'da parallel agentlarning ochiq o'zgarishlari ko'rindi: V25__tasks.sql, V27__wage_entries_work_fk.sql, entity/Work.java (+ staged openapi/v1/tasks.yaml). QA ularga tegmadi — S02/S04/S06 hududi.
-
✓
qa-ep-07-t01-s05 qabul mezonini belgiladi
✓ `event_type` CHECK ro'yxatida 07 hodisalari bor: `production_run.create_from_order`, `task.available`, `work.submitted`, `work.rejected`, `work.confirmed`, `chain.reopened`, `order.recheck`
-
✓
qa-ep-07-t01-s05 qabul mezonini belgiladi
✓ Indeks: (`status`, `next_attempt_at`) — claim so'rovi uchun; UNIQUE indeks dedup kaliti bo'yicha
-
✓
qa-ep-07-t01-s05 qabul mezonini belgiladi
✓ `AbstractOutboxWorker` kutadigan barcha ustunlar mavjud (worker testi jadvalga qarshi ishlaydi)
-
✓
qa-ep-07-t01-s05 qabul mezonini belgiladi
✓ `status` CHECK: `pending` | `processing` | `sent` | `failed`, default `pending`
-
⇄
coder-ep-07-t01-s05 statusni o'zgartirdi Ishlanyapti → Review
-
✎
coder-ep-07-t01-s05 yangiladi
Yangilandi: commit_sha
-
📄
coder-ep-07-t01-s05 fayllarni qayd etdi
2 ta fayl qayd etildi
-
✓
coder-ep-07-t01-s05 qabul mezonini belgiladi
✓ Indeks: (`status`, `next_attempt_at`) — claim so'rovi uchun; UNIQUE indeks dedup kaliti bo'yicha
-
✎
coder-ep-07-t01-s05 yangiladi
Yangilandi: technical_notes
-
⇄
coder-ep-07-t01-s05 statusni o'zgartirdi Tayyor → Ishlanyapti
Agent ishni boshladi
-
⚑
coder-ep-07-t01-s05 ishga oldi
-
⇄
team-lead-pm statusni o'zgartirdi Bloklangan → Tayyor
Spec bo'shligi foydalanuvchi qarori bilan yopildi — izohga qara.
-
💬
team-lead-pm izoh qoldirdi
🔓 BLOK YECHILDI — foydalanuvchi qarori (2026-08-25, team-lead-pm orqali): 1) dedup_key FORMATI = {event_type}:{entity}:{id} — mas. work.confirmed:work:1024. R30 dagi {entity}:{id} yetarli emas edi: bitta work uchun submitted/rejected/confirmed bir xil kalit berardi. 2) NOYOBLIK OYNASI = qisman UNIQUE, faqat status IN (pending, processing) — migratsiyada allaqachon shunday, o‘zgarmaydi. Yakunlangan (sent/failed) qatordan keyin ayni entity uchun yangi hodisa yozilaveradi (R11 rework, R25 recheck, R28 zanjir). 3) ON CONFLICT SEMANTIKASI = INSERT ... ON CONFLICT DO NOTHING — R8 tasdiq tranzaksiyasi HECH QACHON unique violation bilan rollback bo‘lmasin. Bajarilishi kerak: V28 dagi izohni shu qarorga moslash (kalit formati endi ochiq savol emas) va shu uch bandni technical_notes ga yozish. Yozuvchi xizmat (T05-S04) shu formatga majbur. ⚠️ Doc qarzi: 07_tasks §5 R30 matni hali eski ({entity}:{id}) — CLAUDE.md §5 sikli bilan alohida talab sessiyasida yangilanadi. Kod shu qarorga tayanadi.
-
⇄
qa-ep-07-t01-s05 statusni o'zgartirdi Review → Bloklangan
Spec bo’shligi (07_tasks §5 R30): dedup kalitining TARKIBI (event_type kalitga kiradimi) va NOYOBLIK OYNASI (butun jadval vs faqat pending/processing) belgilanmagan; UNIQUE indeks enforcement mexanizmi ekani ham spec da yo’q — talab faqat mezon 3186/technical_notes dan keladi. R11/R25/R28 takroriy hodisani TALAB qiladi (iqtiboslar izohda), spec kaliti {entity}:{id} esa work.submitted/rejected/confirmed uchun bir xil -> R8 tasdiq tranzaksiyasi unique violation bilan rollback bo’lishi mumkin. 3184/3185/3187 tasdiqlangan, testlar 16/16 yashil, 2 mutatsiya killed. Kerak: R30 ga 3 ta aniqlik (kalit tarkibi, oyna, ON CONFLICT semantikasi).
-
💬
qa-ep-07-t01-s05 izoh qoldirdi
QA (qa-EP-07-T01-S05) — SPEC BO'SHLIG'I. 3186 tasdiqlanmadi; bu coder aybi EMAS. TASDIQLANDI: 3184 ✓ · 3185 ✓ · 3187 ✓. Testlar: 16/16, BUILD SUCCESS (flock ostida `mvn -Dtest=ProductionOutboxMigrationTest test`, EXIT=0). MUTATSIYA TEKSHIRUVI (ikkalasi ham "killed"; fayl `git checkout` bilan tiklandi, 76a3aa4 ga nisbatan diff = 0 qator): M1) V28 event_type CHECK dan 'order.recheck' olib tashlandi -> allSevenTasksEventTypesAreAccepted:174 YIQILDI. M2) chk_production_outbox_status butunlay o'chirildi -> invalidStatusIsRejectedByCheckConstraint:142 YIQILDI. 3185 testi kuchli: haqiqiy AbstractOutboxWorker real migratsiyalangan jadval ustida yuradi (claim -> process -> sent/failed), mock emas. Worker SQL'idan mustaqil chiqarilgan majburiy ustunlar {id, status, attempts, next_attempt_at, locked_at, last_error, sent_at, created_at} — 8 tasi ham bor. `updated_at` worker'da umuman uchramaydi, uni chiqarib tashlash TO'G'RI qaror (S05 description'idagi "updated_at" so'zi technical_notes/javadoc ro'yxatiga zid — description matni tuzatilsa yaxshi). Claim indeksining qisman bo'lishi (WHERE status='pending') postgresql skill §8 ga AYNAN mos. === 3186 — dedup UNIQUE indeksi: NEGA BLOKLANDI === Masala coder qo'ygan "partial vs table-wide" ramkasidan chuqurroq. (a) Spec HAQIQATAN takroriy hodisani talab qiladi — 07_tasks.md §5 dan iqtibos: R11: "rad etilgan ish **ayni `work_id`** ustida qayta ishlanadi (yangi `works` qatori yaratilmaydi)"; R25: "har work `confirmed` bo'lganda (va sikl `completed` bo'lganda) 07 06_orders ga **'qayta tekshir' event** yuboradi" -> bitta order uchun ko'p marta `order.recheck`; R28: zanjir qayta ochilgach "Tegishli kasblarga qayta ochilgan task bo'yicha **notification** (R3)" -> bitta task uchun takroriy `task.available`; R30 qamrovi (b) bitta `work_id` uchun UCH xil hodisani sanaydi: `work.submitted` / `work.rejected` / `work.confirmed`. (b) Spec dedup kalitining DOIRASINI belgilamagan. R30 faqat shuni aytadi: "dedup kaliti **`{entity}:{id}`** (mas. `work:1024`)". Spec (i) `event_type` kalit tarkibiga kiradimi — aytmaydi; (ii) noyoblik oynasini — aytmaydi; (iii) UNIQUE indeks enforcement mexanizmi ekanini ham aytmaydi. R30 ning idempotentlik jumlasi "**takroriy bajarish (retry)** ... bo'yicha aniqlanadi" — bu IJRO (worker) tomoni, INSERT tomoni emas. UNIQUE indeks talabi faqat board mezoni 3186 + technical_notes dan keladi; postgresql skill §8 outbox bo'limida dedup UNIQUE umuman yo'q. KONKRET XAVF (hozirgi qisman indeks bilan ham qoladi, chunki kalitda event_type yo'q): spec kaliti `work:1024` uchala hodisa uchun BIR XIL. Agar `work.submitted` hali pending/processing bo'lsa, nazoratchi tasdig'idagi `work.confirmed` inserti uq_production_outbox_dedup_key ni buzadi. R8 bo'yicha tasdiq BITTA tranzaksiyada va "biror qadam xato bersa **butun tranzaksiya rollback**" — natija yo'qolgan notification emas, YIQILGAN TASDIQ (na `wage_entries` accrual, na FIFO `production_out`). R25 da ham xuddi shu: bitta buyurtmaga ikki work ketma-ket tasdiqlansa, ikkinchi `order.recheck` (`order:77`) to'qnashadi. TEST QAMROVI BU HOLATNI YASHIRADI: har test qatori dedup_key ga sun'iy suffiks beradi ("order:900:duplicate-test", "work:1024:resubmit-test", "task:4242:worker-happy", eventType+":"+counter) — hech biri spec'ning `{entity}:{id}` formatini ishlatmaydi. Shuning uchun sameDedupKeyIsAllowedAgainOnceEarlierRowIsTerminal R11/R25 ni ISBOTLAMAYDI, va "bitta entity uchun ikki xil hodisa bir vaqtda pending" holati umuman testlanmagan. Coder migratsiya izohida buni o'zi tan olgan: "dedup_key ning aniq matn formatini (mas. event_type bilan birga qo'shilishi kerakmi) ... worker T05-S04 tanlaydi" — ya'ni UNIQUE indeks semantikasi hozir aniqlanmagan. === PM/spec dan kerak bo'lgan QAROR (07_tasks §5 R30 ga aniqlik) === 1. Dedup kaliti tarkibi: `{event_type}:{entity}:{id}` mi yoki `{entity}:{id}` mi? 2. Noyoblik oynasi: butun jadval bo'ylab abadiy mi, yoki faqat yakunlanmagan (pending/processing) qatorlar orasida mi? 3. To'qnashuvda yozuvchi xizmat xatti-harakati: `ON CONFLICT DO NOTHING` (hodisani jim tashlab ketish) mi, yoki xato -> R8 bo'yicha butun tranzaksiya rollback mi? 3-savol javobi to'g'ridan-to'g'ri R8 tasdiq oqimining ishonchliligiga tegadi. Javob kelgach 3186 bir necha qatorlik o'zgarish bilan yopiladi (indeks ustunlari + ON CONFLICT semantikasini isbotlovchi test). Qolgan hammasi (jadval strukturasi, 3 ta CHECK, claim indeksi, worker moslik testlari) tayyor va sifatli — faqat 3186 ochiq.
-
✓
qa-ep-07-t01-s05 qabul mezonini belgiladi
✗ Indeks: (`status`, `next_attempt_at`) — claim so'rovi uchun; UNIQUE indeks dedup kaliti bo'yicha
-
✓
qa-ep-07-t01-s05 qabul mezonini belgiladi
✓ `event_type` CHECK ro'yxatida 07 hodisalari bor: `production_run.create_from_order`, `task.available`, `work.submitted`, `work.rejected`, `work.confirmed`, `chain.reopened`, `order.recheck`
-
✓
qa-ep-07-t01-s05 qabul mezonini belgiladi
✓ `AbstractOutboxWorker` kutadigan barcha ustunlar mavjud (worker testi jadvalga qarshi ishlaydi)
-
✓
qa-ep-07-t01-s05 qabul mezonini belgiladi
✓ `status` CHECK: `pending` | `processing` | `sent` | `failed`, default `pending`
-
⇄
coder-ep-07-t01-s05 statusni o'zgartirdi Ishlanyapti → Review
-
💬
coder-ep-07-t01-s05 izoh qoldirdi
Dizayn qarori (blokerga aylanmasin uchun yozib qo‘yildi): R30dagi "dedup kaliti {entity}:{id}" ni LITERAL bo‘lgan holda (event_type siz) BUTUN jadval bo‘yicha abadiy UNIQUE qilib qo‘ysak, R11 (rework — bitta work_id ustida work.submitted qayta kelishi), R25 (order.recheck har work.confirmed da, bitta order_id uchun ko‘p marta) va R28 (chain.reopened) dagi tabiiy takroriy hodisalarni doim bloklab qo‘yardi — bu texnik ziddiyat. Shu sabab dedup_key UNIQUE indeksini FAQAT status IN (pending, processing) uchun QISMAN qildim: navbatda hali turgan bir xil hodisa ikkilanmaydi, lekin avvalgi hodisa sent/failed bo‘lgach xuddi shu entity uchun yangi hodisa yozilishi ochiq qoladi. dedup_key qatorining aniq matn formatini (event_type qo‘shilsinmi) haqiqiy yozuvchi xizmat (worker, T05-S04) tanlaydi — bu migratsiya faqat ustun/indeks strukturasini beradi. Batafsil izoh V28 fayli boshida.
-
✎
coder-ep-07-t01-s05 yangiladi
Yangilandi: branch, commit_sha
-
✓
coder-ep-07-t01-s05 qabul mezonini belgiladi
✓ `event_type` CHECK ro'yxatida 07 hodisalari bor: `production_run.create_from_order`, `task.available`, `work.submitted`, `work.rejected`, `work.confirmed`, `chain.reopened`, `order.recheck`
-
✓
coder-ep-07-t01-s05 qabul mezonini belgiladi
✓ Indeks: (`status`, `next_attempt_at`) — claim so'rovi uchun; UNIQUE indeks dedup kaliti bo'yicha
-
✓
coder-ep-07-t01-s05 qabul mezonini belgiladi
✓ `AbstractOutboxWorker` kutadigan barcha ustunlar mavjud (worker testi jadvalga qarshi ishlaydi)
-
✓
coder-ep-07-t01-s05 qabul mezonini belgiladi
✓ `status` CHECK: `pending` | `processing` | `sent` | `failed`, default `pending`
-
📄
coder-ep-07-t01-s05 fayllarni qayd etdi
2 ta fayl qayd etildi
-
⇄
coder-ep-07-t01-s05 statusni o'zgartirdi Backlog → Ishlanyapti
Agent ishni boshladi
-
⚑
coder-ep-07-t01-s05 ishga oldi
-
✦
pm-agent yaratdi
V28 — `production_outbox` jadvali (R30)
Ma'lumot
- Agent
- coder-ep-07-t01-s05
- Olingan
- 1 о аввал
- Boshlandi
- 25.08.2026 09:43
- Tugadi
- 25.08.2026 11:07
- Baho
- 2 soat
- Spec
- erp/docs/modules/07_tasks.md#5
- Branch
- feat/EP-07-erpbom-backend
- Commit
- 0568070887c1
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-T01-S05/claim \ -H "X-Agent: backend-dev-1"
Tugatgach:
curl -s -X POST https://pmboard.ferp.uz/api/items/EP-07-T01-S05/status \
-H "X-Agent: backend-dev-1" \
-H "Content-Type: application/json" \
-d '{"status":"review","note":"..."}'