Sub-task EP-03-T10-S02 Yuqori 01_suppliers erpbom-backend

Hamkor: tahrir taklifi yuborish (oq ro'yxat, bitta ochiq taklif)

Bajarildi
Status:

Tavsif

§8.4a p.1-2. `base_contract_id` = so'rov paytidagi FAOL versiya (serverda aniqlanadi, klientdan ishonchsiz olinmaydi yoki olinsa faol versiya bilan solishtiriladi). 🔴 Oq ro'yxat (qoida 17) — serverda majburiy: profile -> name, address, phone, inn contract -> term_days, payment_method, default_cash_percent, default_transfer_percent Boshqa kalit kelsa -> `422` va SO'ROV BUTUNLAY rad etiladi (qisman qabul YO'Q — §9 edge). ⛔ `debt_limit`, `payment_basis`, `active`, `user_id`, `status`, `version`, `default_*` cache — hech qachon. ⛔ `contract_file_key` — taklif orqali fayl YUKLANMAYDI. `scope` payload kalitlaridan HOSILA qilinadi (profile / contract / both) — klient yuborgan qiymatga ishonilmaydi. Qoida 16: ochiq `pending` taklif bo'lsa -> `409`. Hamkor o'z ochiq taklifini bekor qila oladi -> `superseded`, `review_comment='hamkor bekor qildi'` (qator o'chirilmaydi). 🔴 Amaldagi shart O'ZGARMAYDI (qoida 15) — bu barg hech qachon `suppliers` yoki `supplier_contracts` ga yozmaydi.

Qabul mezonlari (DoD)

6 / 6 bajarildi

  • Taklif yaratilgach `supplier_change_proposals` da `pending` qator bor; `suppliers` va `supplier_contracts` O'ZGARMAGAN

    qa-ep-03-t10-s02 · 1 о аввал

  • `payload` da `debt_limit` kelsa `422` va hech bir maydon qo'llanmaydi

    qa-ep-03-t10-s02 · 1 о аввал

  • Ochiq taklif ustiga ikkinchisi -> `409` (DB constraint emas, tekshiruv bilan)

    qa-ep-03-t10-s02 · 1 о аввал

  • `scope` serverda payload kalitlaridan hosila qilinadi — klient yuborgan qiymat e'tiborga olinmaydi

    qa-ep-03-t10-s02 · 1 о аввал

  • Boshqa ta'minotchi nomidan taklif yuborishga urinish -> `403`

    qa-ep-03-t10-s02 · 1 о аввал

  • Hamkor o'z ochiq taklifini bekor qiladi -> `superseded`, so'ng yangi taklif yuborishi mumkin

    qa-ep-03-t10-s02 · 1 о аввал

O'zgargan fayllar

12 ta

  • modified src/test/java/uz/erpbom/suppliers/controller/SupplierChangeProposalControllerIntegrationTest.java
  • modified src/main/java/uz/erpbom/suppliers/controller/SupplierSelfController.java
  • modified src/main/java/uz/erpbom/suppliers/service/SupplierSelfService.java
  • modified src/main/java/uz/erpbom/suppliers/service/SupplierChangeProposalService.java
  • modified src/main/java/uz/erpbom/suppliers/mapper/SupplierChangeProposalMapper.java
  • modified src/main/java/uz/erpbom/suppliers/dto/SupplierChangeProposalResponse.java
  • modified src/main/java/uz/erpbom/suppliers/dto/SupplierChangeProposalCreateRequest.java
  • modified src/main/java/uz/erpbom/suppliers/repository/SupplierContractRepository.java
  • modified src/main/java/uz/erpbom/suppliers/repository/SupplierChangeProposalRepository.java
  • modified src/main/java/uz/erpbom/suppliers/entity/SupplierChangeProposal.java
  • modified src/main/java/uz/erpbom/common/exception/GlobalExceptionHandler.java
  • modified src/main/java/uz/erpbom/common/exception/UnprocessableEntityException.java

Izoh qoldirish

Tarix

26 yozuv

  • ✎

    finalize-ep-03 yangiladi

    Yangilandi: pr_url

  • ⇄

    qa-ep-03-t10-s02 statusni o'zgartirdi Review → Bajarildi

  • 💬

    qa-ep-03-t10-s02 izoh qoldirdi

    QA (qa-EP-03-T10-S02) — commit 0d6ac05 tekshirildi -> DONE. TESTLAR (foreground, qulf ostida, jonli stack): 59/59 yashil. SupplierChangeProposalControllerIntegrationTest 15 · SupplierSelfControllerIntegrationTest 7 · SupplierContractConfirmationTest 6 · UserPermissionControllerIntegrationTest 21 · PermissionGroupControllerIntegrationTest 10. BUILD SUCCESS. SPEC MUVOFIQLIGI (01_suppliers.md §8.4a, §5 qoida 15-19, §9): * qoida 15 — kod suppliers/supplier_contracts ga HECH QACHON yozmaydi. SupplierChangeProposalService faqat supplierChangeProposalRepository.saveAndFlush/save ni chaqiradi; supplierContractRepository dan faqat findBySupplierIdAndStatus va findById (o'qish), SupplierSelfService dan supplierRepository.findByUserId (o'qish). Supplier/SupplierContract entity'lariga birorta setter chaqirilmagan (grep bilan tasdiqlandi). Test DB dan supplierPhone() va activeContractTermDays() ni o'qib o'zgarmaganini isbotlaydi. * qoida 17 — oq ro'yxat serverda majburiy (PROFILE_KEYS/CONTRACT_KEYS Set), noruxsat kalit -> 422 PROPOSAL_FIELD_NOT_ALLOWED, so'rov butunlay rad. QA vaqtinchalik probe testi bilan HAR bir taqiqlangan kalit alohida tekshirildi: debt_limit · payment_basis · active · user_id · status · version · contract_file_key · effective_from · default_term_days — 9/9 rad, har birida countProposals=0 (qisman qabul yo'q). Ruxsat etilgan 8 kalit birga yuborilganda 201 + scope=both. (Probe test tekshiruvdan keyin o'chirildi.) * scope — klientdan EMAS: DTO da scope maydoni umuman yo'q, deriveScope(payload.keySet()) hosila qiladi. Test klient "scope":"profile" yuborib payload={term_days} bilan 201 + scope=contract oladi. * base_contract_id — serverda: activeContract.getId(); DTO da maydon yo'q. * qoida 16 — ochiq pending ustiga ikkinchisi -> 409 PROPOSAL_ALREADY_OPEN, existsBySupplierIdAndStatus() TEKSHIRUVI bilan (DB partial unique indeksi faqat ikkinchi himoya qatlami, race uchun). * Bekor qilish -> superseded + review_comment='hamkor bekor qildi', qator o'chirilmaydi (UPDATE, DELETE yo'q); keyin yangi taklif 201. * Ownership — /suppliers/me/* da {id} yo'q; bog'lanmagan user 403 FORBIDDEN, nofaol ta'minotchi 403 SUPPLIER_INACTIVE; boshqa ta'minotchining taklifini cancel -> 404 va uning pending taklifi tegilmagan. MUTATSIYA TEKSHIRUVI (testlar yolg'onni ushlaydimi — 3 ta ataylab buzish, keyin git checkout bilan tiklandi): (a) oq ro'yxat yumshatildi (noruxsat kalit jimgina tashlab ketiladi) -> submitWithFieldOutsideWhitelistIsRejectedEntirelyWith422 YIQILDI (201 keldi) + probe 9/9 yiqildi. (b) scope klient qiymatidan olindi (DTO ga scope qo'shildi) -> submitIgnoresClientSuppliedScopeAndDerivesItFromPayloadKeysInstead YIQILDI. (c) ochiq taklif tekshiruvi + DataIntegrityViolation fallback olib tashlandi -> submitSecondOpenProposalReturns409 YIQILDI (500 INTERNAL_ERROR). Faqat exists() tekshiruvi olib tashlansa fallback 409 ni ushlab qolardi — shuning uchun ikkalasi birga buzildi. Qolgan 12 test mutatsiyalarda ham yashil qoldi — noto'g'ri (false positive) sezgirlik yo'q. Tautologik/assert'siz test topilmadi. REGRESSIYA (cross-cutting fayllar): GlobalExceptionHandler.handleUnprocessableEntity endi fields bo'sh bo'lsa eski respond() ni, to'lgan bo'lsa respondWithFields() ni chaqiradi — ORQAGA MOS. ErrorResponse.fields allaqachon mavjud va @JsonInclude(NON_NULL); required: [code, message, request_id] o'zgarmagan. Mavjud 422 INVALID_PERMISSION_CODE oqimi log'da fields'siz yozilishi ko'rindi, auth testlari (21+10) yashil. UnprocessableEntityException ning 2-argumentli konstruktori saqlangan (null -> List.of()). KONTRAKT (openapi/v1/suppliers.yaml — o'zgartirilmadi): Yo'llar POST|GET /api/v1/suppliers/me/change-proposals va POST .../{proposalId}/cancel — aynan mos. Xato kodlari mos: PROPOSAL_FIELD_NOT_ALLOWED (422) · PROPOSAL_ALREADY_OPEN (409) · PROPOSAL_ALREADY_REVIEWED (409) · SUPPLIER_INACTIVE/FORBIDDEN (403) · NOT_FOUND (404) · VALIDATION_ERROR (400). Maydon nomi/tip mos: term_days int32 min 0 · payment_method enum cash|transfer|mixed · default_*_percent decimal string · name minLength 1 · payload minProperties 1 (@NotEmpty -> 400). ProposalPayloadRejected misolidagi fields: [{field: payload.debt_limit, error: taklif qilinmaydigan maydon}] kod bilan aynan bir xil chiqadi. CROSS-CUTTING: @Transactional hamma DB metodida (list readOnly=true) · yangi Flyway migratsiya YO'Q (V14 EP-03-T09 da qo'llangan) · tenant_id/schema almashtirish yo'q · fizik DELETE yo'q · yangi numeric ustun yo'q · log'ga token/parol yozilmaydi. DOIRA: xodim tomoni endpointlari (/supplier-change-proposals list/accept/reject) YOZILMAGAN — to'g'ri, u EP-03-T10-S03. supplier_proposal.submitted notification ham bu bargda yo'q — kontrakt uni 10_notifications epikiga havola qiladi. NOTA (bloklamaydi, kontrakt egasiga): openapi/common.yaml:148 dagi ErrorResponse.fields IZOHI hamon "FAQAT 400 VALIDATION_ERROR da to'ldiriladi" deydi, holbuki o'sha muzlatilgan paketdagi suppliers.yaml ProposalPayloadRejected 422 uchun fields ni talab qiladi. Bu faqat nasr, sxema cheklovi emas (fields ixtiyoriy bo'lib qoladi) — kelgusi kontrakt o'zgarishida izohni aniqlashtirish tavsiya etiladi. Ish tugagach git status toza: faqat oldindan staged openapi/v1/suppliers.yaml.

  • ✓

    qa-ep-03-t10-s02 qabul mezonini belgiladi

    ✓ Hamkor o'z ochiq taklifini bekor qiladi -> `superseded`, so'ng yangi taklif yuborishi mumkin

  • ✓

    qa-ep-03-t10-s02 qabul mezonini belgiladi

    ✓ Boshqa ta'minotchi nomidan taklif yuborishga urinish -> `403`

  • ✓

    qa-ep-03-t10-s02 qabul mezonini belgiladi

    ✓ `scope` serverda payload kalitlaridan hosila qilinadi — klient yuborgan qiymat e'tiborga olinmaydi

  • ✓

    qa-ep-03-t10-s02 qabul mezonini belgiladi

    ✓ Ochiq taklif ustiga ikkinchisi -> `409` (DB constraint emas, tekshiruv bilan)

  • ✓

    qa-ep-03-t10-s02 qabul mezonini belgiladi

    ✓ `payload` da `debt_limit` kelsa `422` va hech bir maydon qo'llanmaydi

  • ✓

    qa-ep-03-t10-s02 qabul mezonini belgiladi

    ✓ Taklif yaratilgach `supplier_change_proposals` da `pending` qator bor; `suppliers` va `supplier_contracts` O'ZGARMAGAN

  • 🔗

    team-lead-pm bog'liqlik qo'shdi

    → EP-03-T10-S01

  • ✎

    team-lead-pm yangiladi

    Yangilandi: estimate_hours

  • ⇄

    coder-ep-03-t10-s02 statusni o'zgartirdi Ishlanyapti → Review

  • ✎

    coder-ep-03-t10-s02 yangiladi

    Yangilandi: branch, commit_sha

  • ✓

    coder-ep-03-t10-s02 qabul mezonini belgiladi

    ✓ Hamkor o'z ochiq taklifini bekor qiladi -> `superseded`, so'ng yangi taklif yuborishi mumkin

  • ✓

    coder-ep-03-t10-s02 qabul mezonini belgiladi

    ✓ Boshqa ta'minotchi nomidan taklif yuborishga urinish -> `403`

  • ✓

    coder-ep-03-t10-s02 qabul mezonini belgiladi

    ✓ `scope` serverda payload kalitlaridan hosila qilinadi — klient yuborgan qiymat e'tiborga olinmaydi

  • ✓

    coder-ep-03-t10-s02 qabul mezonini belgiladi

    ✓ Ochiq taklif ustiga ikkinchisi -> `409` (DB constraint emas, tekshiruv bilan)

  • ✓

    coder-ep-03-t10-s02 qabul mezonini belgiladi

    ✓ `payload` da `debt_limit` kelsa `422` va hech bir maydon qo'llanmaydi

  • ✓

    coder-ep-03-t10-s02 qabul mezonini belgiladi

    ✓ Taklif yaratilgach `supplier_change_proposals` da `pending` qator bor; `suppliers` va `supplier_contracts` O'ZGARMAGAN

  • 📄

    coder-ep-03-t10-s02 fayllarni qayd etdi

    12 ta fayl qayd etildi

  • ⇄

    coder-ep-03-t10-s02 statusni o'zgartirdi Backlog → Ishlanyapti

    Agent ishni boshladi

  • ⚑

    coder-ep-03-t10-s02 ishga oldi

  • 🔗

    team-lead-pm bog'liqlik qo'shdi

    → EP-03-T10-S01

  • ✎

    team-lead-pm yangiladi

    Yangilandi: estimate_hours

  • 🔗

    team-lead-pm bog'liqlik qo'shdi

    → EP-03-T10-S01

  • ✦

    team-lead-pm yaratdi

    Hamkor: tahrir taklifi yuborish (oq ro'yxat, bitta ochiq taklif)

Ma'lumot

Agent
coder-ep-03-t10-s02
Olingan
1 о аввал
Boshlandi
20.08.2026 03:36
Tugadi
20.08.2026 03:53
Baho
3 soat
Spec
erp/docs/modules/01_suppliers.md#8.4
Branch
feat/EP-03-erpbom-backend
Commit
0d6ac05b68a1

Bog'liqliklar

Agent uchun

Bu ishni AI agent quyidagicha oladi:

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

Tugatgach:

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