Push-token endpointlari (UC4/UC5) — upsert va o'chirish
Tavsif
Texnik ko'rsatma
Agent uchun
Qabul mezonlari (DoD)
4 / 4 bajarildi
-
A user token bilan ro'yxatdan o'tgan qurilmada B user kirsa token B ga o'tadi va A ning qatori qolmaydi (AC11)
qa-ep-13-t04-s02 · 1 о аввал
-
`audience` body'da yuborilsa e'tiborga olinmaydi — server JWT `aud` ni ishlatadi
qa-ep-13-t04-s02 · 1 о аввал
-
`aud=web` bilan token yozib bo'lmaydi
qa-ep-13-t04-s02 · 1 о аввал
-
DELETE dan keyin qator darhol yo'q (kechiktirilmaydi)
qa-ep-13-t04-s02 · 1 о аввал
O'zgargan fayllar
8 ta
-
modified
src/test/java/uz/erpbom/notifications/controller/PushTokensControllerIntegrationTest.java -
modified
src/main/java/uz/erpbom/notifications/service/PushTokenService.java -
modified
src/main/java/uz/erpbom/notifications/repository/PushTokenRepository.java -
modified
src/main/java/uz/erpbom/notifications/mapper/PushTokenMapper.java -
modified
src/main/java/uz/erpbom/notifications/entity/PushToken.java -
modified
src/main/java/uz/erpbom/notifications/dto/PushTokenResponse.java -
modified
src/main/java/uz/erpbom/notifications/dto/PushTokenRegisterRequest.java -
modified
src/main/java/uz/erpbom/notifications/controller/PushTokenController.java
Izoh qoldirish
Tarix
17 yozuv
-
⇄
qa-ep-13-t04-s02 statusni o'zgartirdi Review → Bajarildi
-
💬
qa-ep-13-t04-s02 izoh qoldirdi
QA (qa-EP-13-T04-S02, commit 16c1053, izolyatsiyalangan worktree) — 4/4 mezon tasdiqlandi, done. TEST: 168 test / 0 xato / 0 skip (21 klass, surefire XML dan qayta o'lchandi — coder o'lchovi tasdiqlandi). Filtr `PushTokens*Test` haqiqatan PushTokensControllerIntegrationTest ni qamradi (surefire hisobotida 5 test: 5578/5579/5580/5581 + upsert). MUTATSIYA — 6 mutant, HAMMASI O'LDI (worktree'da, cp bilan tiklandi). Harness avval ataylab sintaktik buzib tekshirildi (build yiqildi = mutant klasspathga tushadi): - M1 deleteByTokenAndUserIdNot() olib tashlandi (javap: bytecode'da chaqiruv 0) -> sameTokenOnSameDeviceMovesToNewUserAndOldRowIsGone O'LDI (500 != 200). AC11 qoplangan. - M2 xatolik kodi WEB_PUSH_NOT_SUPPORTED -> MUTANT_M2 -> webAudienceIsRejected... O'LDI (aynan kod assert qilinadi). - M3 ON CONFLICT dan `delete_after = NULL` olib tashlandi -> secondRegisterIsUpsertNotInsertAndClearsDeleteAfter O'LDI (qoida 23 qoplangan). - M4 DELETE yo'lida qator o'chirish o'rniga delete_after=now+5daq (aynan qoida 23 xatosi, javap tasdiqladi) -> deleteRemovesRowImmediately... O'LDI (satr 170: 'qator DARHOL yo'q'). - M5 qator yo'q bo'lsa 404 -> deleteRemovesRowImmediately... O'LDI (satr 174: ikkinchi DELETE 204). Qoida 22 b qoplangan. - M6 audience JWT o'rniga TANADAN (DTO'ga audience maydoni qo'shildi) -> audienceInBodyIsIgnoredServerUsesJwtAud O'LDI (403 != 200). Test TAUTOLOGIK EMAS: tanada 'web', JWT aud='customer', natija 'customer' deb assert qilinadi. FIXTURE XILMA-XILLIGI — yetarli: 5 xil audience (employee/driver/customer/supplier + web rad etilishi), 2 xil user (5578), 2 xil platform (android/ios), delete_after TO'LGAN va BO'SH holat, device_model/app_version to'lgan va null, qayta upsert DB'dan count(*)=1 + qator id o'zgarmagani bilan tasdiqlangan (satr 202-204), bir xil device_id + farqli audience (5578). KONTRAKT: POST 200 (ResponseStatus yo'q, yangi qatorda ham 200) · javobda `token` YO'Q (PushTokenResponse record'ida maydon yo'q) · DELETE 204 (@ResponseStatus) · maydon nomlari/tiplari/@Size/@Pattern kontrakt sxemasi bilan aynan mos (SNAKE_CASE) · aud=web -> 403 WEB_PUSH_NOT_SUPPORTED va countRowsForToken=0 (jadval tekshirilgan). CROSS-CUTTING: (1) ikki servis metodi ham @Transactional; (2) tenant_id/schema almashtirish izi yo'q (AR-1); (3) user_id da haqiqiy FK fk_push_tokens_user, audience — spec §2.3 talab qilgan CHECK; (5) nomlash snake_case, jadval ko'plikda, FK/UQ to'liq nomdan; (7) fizik DELETE bu yerda SPEC TALABI (qoida 22 a 'darhol', §2.3 da deleted_at ustuni yo'q) — buzilish emas; (8) ikkala klassda Logger YO'Q, FCM token log'ga tushmaydi, javobda ham qaytmaydi. @RequirePermission YO'Q — grep bilan emas, STRUKTURAL: anotatsiya RetentionPolicy.RUNTIME, javap -v controller class'ida uni TOPMADI (javadoc matni grep'ni chalg'itadi). §7: 'o'z qurilma tokeni — maxsus huquq yo'q'. BLOKLAMAYDIGAN KUZATUV (spec bo'shligi, PM uchun; bu barg mezonlariga kirmaydi): ayni token AYNI user'ning boshqa audience/device_id qatorida turgan holat qoplanmagan — deleteByTokenAndUserIdNot faqat userId <> :userId ni o'chiradi, shu sababli (A, D, employee, T) qatori bor holda A 'driver' rolida ayni T bilan kelsa ON CONFLICT (user_id, device_id, audience) mos kelmaydi va INSERT uq_push_tokens_token ni buzib 500 beradi. Spec (§2.3 ⚠️, UC4 3-qadam) faqat 'boshqa user'ning qatorida tursa' holatini yozadi; UC5 3-qadamda ilova FCM tokenni qayta oladi, ya'ni happy-path bu holatga tushmaydi. Kod bu qarorni PushTokenRepository.java:100-107 javadocida ochiq yozgan. Spec javob bermagani uchun defekt deb qaytarilmadi.
-
✓
qa-ep-13-t04-s02 qabul mezonini belgiladi
✓ DELETE dan keyin qator darhol yo'q (kechiktirilmaydi)
-
✓
qa-ep-13-t04-s02 qabul mezonini belgiladi
✓ `aud=web` bilan token yozib bo'lmaydi
-
✓
qa-ep-13-t04-s02 qabul mezonini belgiladi
✓ `audience` body'da yuborilsa e'tiborga olinmaydi — server JWT `aud` ni ishlatadi
-
✓
qa-ep-13-t04-s02 qabul mezonini belgiladi
✓ A user token bilan ro'yxatdan o'tgan qurilmada B user kirsa token B ga o'tadi va A ning qatori qolmaydi (AC11)
-
⇄
coder-ep-13-t04-s02 statusni o'zgartirdi Ishlanyapti → Review
-
💬
coder-ep-13-t04-s02 izoh qoldirdi
POST /api/v1/push-tokens (UC4 upsert, 200) va DELETE /api/v1/push-tokens/{device_id} (UC5, 204) qo'shildi. audience faqat AuthenticatedUser.audience() (JWT aud) dan olinadi, tanadagi audience e'tiborga olinmaydi (kontraktda additionalProperties:false yo'q, shu sabab jimgina tashlab ketiladi). aud='web' -> 403 WEB_PUSH_NOT_SUPPORTED, hech qanday qator yozilmaydi. UC4 3-qadam: PushTokenRepository#deleteByTokenAndUserIdNot upsertdan OLDIN chaqiriladi (aks holda UNIQUE(token) tranzaksiyani rollback-only qiladi); upsert - native INSERT...ON CONFLICT(user_id,device_id,audience) DO UPDATE (token/last_seen_at/delete_after=NULL, spec qat'iy shu 3 ustunni sanaydi - platform/device_model/app_version konfliktda o'zgarmaydi). DELETE - PushTokenRepository#deleteByUserIdAndDeviceIdAndAudience, delete_after ISHLATILMAYDI, topilmasa ham 204. Test: PushTokensControllerIntegrationTest, 5 test (5578/5579/5580/5581 + upsert-not-insert/delete_after-clear). To'liq notification suite: mvn -Dtest='Notification*Test,PushTokens*Test,AdminSecurityNotification*Test,Fcm*Test' -> 168/168 (163 dan +5), 0 xato. PushToken entity/PushTokenRepository - mavjud fayllarga qo'shimcha (S01/S03/S04 metodlariga tegilmadi).
-
✓
coder-ep-13-t04-s02 qabul mezonini belgiladi
✓ DELETE dan keyin qator darhol yo'q (kechiktirilmaydi)
-
✓
coder-ep-13-t04-s02 qabul mezonini belgiladi
✓ `aud=web` bilan token yozib bo'lmaydi
-
✓
coder-ep-13-t04-s02 qabul mezonini belgiladi
✓ `audience` body'da yuborilsa e'tiborga olinmaydi — server JWT `aud` ni ishlatadi
-
✓
coder-ep-13-t04-s02 qabul mezonini belgiladi
✓ A user token bilan ro'yxatdan o'tgan qurilmada B user kirsa token B ga o'tadi va A ning qatori qolmaydi (AC11)
-
✎
coder-ep-13-t04-s02 yangiladi
Yangilandi: branch, commit_sha
-
📄
coder-ep-13-t04-s02 fayllarni qayd etdi
8 ta fayl qayd etildi
-
⇄
coder-ep-13-t04-s02 statusni o'zgartirdi Backlog → Ishlanyapti
Agent ishni boshladi
-
⚑
coder-ep-13-t04-s02 ishga oldi
-
✦
pm-agent yaratdi
Push-token endpointlari (UC4/UC5) — upsert va o'chirish
Ma'lumot
- Agent
- coder-ep-13-t04-s02
- Olingan
- 1 о аввал
- Boshlandi
- 10.09.2026 07:06
- Tugadi
- 10.09.2026 08:20
- Baho
- 5 soat
- Spec
- erp/docs/modules/10_notifications.md#8
- Branch
- feat/EP-13-erpbom-backend
- Commit
- 16c105345dce
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-13-T04-S02/claim \ -H "X-Agent: backend-dev-1"
Tugatgach:
curl -s -X POST https://pmboard.ferp.uz/api/items/EP-13-T04-S02/status \
-H "X-Agent: backend-dev-1" \
-H "Content-Type: application/json" \
-d '{"status":"review","note":"..."}'