docs: sync from backend 957c356 — H16-H18 transaction closeout
This commit is contained in:
@@ -87,6 +87,9 @@ updated: 2026-06-07
|
||||
| C2/M26: `DrizzleChatRepo.findRows` unbounded chat fetch + JS pagination → bounded row scans, SQL pagination for SQL-pushable predicates, `findOne` `LIMIT 1`/id fast path, type pushdown, and archived-chat index | `8835068` v2.9.35 |
|
||||
| H10: `sweepDerivedDestinations` sequential token-balance RPC probes → bounded parallel balance probe phase before sequential sweep/broadcast handling | `5d7d2af` v2.9.36 |
|
||||
| H19-H21: login, Google sign-in, and Telegram auth duplicate user saves → token helper save bypass plus one final user persistence after audited mutations | `259f3fb` v2.9.37 |
|
||||
| H16: batch template conversion request/offer/status writes split across service calls → proposal conversions use one serializable vital transaction; template usage remains explicitly non-vital | `957c356` v2.9.38 |
|
||||
| H17: template payment completion per-request status loop → one serializable bulk status update with an all-rows-updated guard | `957c356` v2.9.38 |
|
||||
| H18: email-code registration split referrer/user/temp writes → one serializable auth-store registration transaction, with referral bonus left post-commit best-effort | `957c356` v2.9.38 |
|
||||
|
||||
---
|
||||
|
||||
@@ -336,33 +339,33 @@ The AML fee ledger entry (lines 441-471) is written after `db.transaction()` com
|
||||
|
||||
---
|
||||
|
||||
### 16. batchConvertTemplates creates purchase-requests, offers, and status updates without a transaction
|
||||
### 16. batchConvertTemplates creates purchase-requests, offers, and status updates without a transaction | **FIXED** `957c356` v2.9.38
|
||||
|
||||
> **Category:** Missing Transaction | **File:** `src/services/marketplace/RequestTemplateService.ts:521-598`
|
||||
|
||||
The per-item loop calls `createPurchaseRequest`, `createTemplateOffer`, `updateOfferStatus`, `updatePurchaseRequest`, `incrementUsageCount`, and `findPurchaseRequestById` as separate non-transactional operations. A crash after `createPurchaseRequest` but before `incrementUsageCount` leaves an orphaned request with the usage counter un-bumped; a crash after `createTemplateOffer` but before `updatePurchaseRequest` leaves the offer unlinked from the request.
|
||||
|
||||
**Fix:** Wrap each item's write sequence in a Drizzle `db.transaction()`. At minimum wrap `(createPurchaseRequest + createTemplateOffer + updatePurchaseRequest.selectedOfferId + incrementUsageCount)` for each item.
|
||||
**Fix:** Implemented in `957c356`: proposal-backed batch conversions now route through `createTemplatePurchaseRequest`, creating the purchase request, template offer, accepted offer state, and selected-offer link inside one serializable vital-db transaction. Template usage accounting remains in the intentionally non-vital `request_templates` store and stays explicit outside the vital money transaction.
|
||||
|
||||
---
|
||||
|
||||
### 17. completeTemplateRequestsPayment updates multiple purchase-request rows without a transaction
|
||||
### 17. completeTemplateRequestsPayment updates multiple purchase-request rows without a transaction | **FIXED** `957c356` v2.9.38
|
||||
|
||||
> **Category:** Missing Transaction | **File:** `src/services/marketplace/RequestTemplateService.ts:634-641`
|
||||
|
||||
The method reads all requests with `Promise.all` (line 622) and then updates them one-by-one in a `for` loop (lines 634-639) with no surrounding transaction. A crash mid-loop leaves some requests updated and others not, creating inconsistent payment state across cart items.
|
||||
|
||||
**Fix:** Wrap the entire update sequence in a single database transaction, or issue a single `UPDATE … WHERE id = ANY($1)` bulk statement.
|
||||
**Fix:** Implemented in `957c356`: validated template payment requests are updated through `updatePurchaseRequestStatuses`, a single serializable bulk `UPDATE` over the resolved request ids. The service now fails the completion path if the bulk update returns fewer rows than the validated request set.
|
||||
|
||||
---
|
||||
|
||||
### 18. verifyEmailWithCode: user save, referrer stat update, and temp-verification delete are not transactional
|
||||
### 18. verifyEmailWithCode: user save, referrer stat update, and temp-verification delete are not transactional | **FIXED** `957c356` v2.9.38
|
||||
|
||||
> **Category:** Missing Transaction | **File:** `src/services/auth/authController.ts:756-868`
|
||||
|
||||
Registration completes in separate writes: (1) `referrer.save()` increments referralStats, (2) `user.save()` creates the account, (3) `TempVerification.findByIdAndDelete` removes the pending record — all independent. A crash between any two leaves the email address stuck in `temp_verification` (user cannot re-register) or the referrer's count incremented without the user existing.
|
||||
|
||||
**Fix:** Wrap steps 1-3 in a single Postgres transaction. Perform the token-generation and second `user.save()` inside the same transaction before responding.
|
||||
**Fix:** Implemented in `957c356`: `verifyEmailWithCode` stages refresh-token issuance, then `completeEmailVerificationRegistration` deletes the temp verification, atomically increments referrer signup count, persists the verified user and refresh token, and commits in one serializable auth-store transaction. Referral signup bonus points remain post-commit best-effort.
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user