docs: sync from backend 99ae2db — delivery confirmation id seam
This commit is contained in:
@@ -7,7 +7,7 @@ related_apis: ["POST /api/marketplace/purchase-requests/:id/delivery-code/genera
|
|||||||
|
|
||||||
# Delivery Confirmation Flow
|
# Delivery Confirmation Flow
|
||||||
|
|
||||||
> **Last updated:** 2026-05-29 — aligned with code (see [Doc vs Code Audit Report](../09%20-%20Audits/Doc%20vs%20Code%20Audit%20Report%20-%202026-05-29.md))
|
> **Last updated:** 2026-06-06 — buyer fast-track confirmation is buyer/admin-only and uses cross-store id matching.
|
||||||
|
|
||||||
After the escrow is funded ([[PRD - Request Network In-House Checkout]] / [[Escrow Flow]]) and the seller has prepared the item, the seller **marks shipped**, the buyer **generates and reads out the delivery code**, the seller **verifies the code** to confirm receipt, and the escrow becomes eligible for release ([[Payout Flow]]).
|
After the escrow is funded ([[PRD - Request Network In-House Checkout]] / [[Escrow Flow]]) and the seller has prepared the item, the seller **marks shipped**, the buyer **generates and reads out the delivery code**, the seller **verifies the code** to confirm receipt, and the escrow becomes eligible for release ([[Payout Flow]]).
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ After the escrow is funded ([[PRD - Request Network In-House Checkout]] / [[Escr
|
|||||||
- On success: `deliveryInfo.deliveryCodeUsed = true; deliveryCodeUsedAt = now`. Status flips `delivery → delivered`.
|
- On success: `deliveryInfo.deliveryCodeUsed = true; deliveryCodeUsedAt = now`. Status flips `delivery → delivered`.
|
||||||
- Emits `purchase-request-update` `status-changed`.
|
- Emits `purchase-request-update` `status-changed`.
|
||||||
- Sends delivery-confirmed notifications to both buyer and seller directly within `DeliveryService.verifyDeliveryCode`.
|
- Sends delivery-confirmed notifications to both buyer and seller directly within `DeliveryService.verifyDeliveryCode`.
|
||||||
6. **Alternative path — buyer fast-track** — the buyer can also call `PATCH .../confirm-delivery` to set status to `delivered` without any code (used when the code path fails, e.g. code expired or lost). This endpoint emits only `purchase-request-update` with `status-changed` — it does **not** send delivery-specific notifications to either party. **⚠️ Authorization gap:** this endpoint currently has no authorization check; any authenticated user can call it.
|
6. **Alternative path — buyer fast-track** — the buyer can also call `PATCH .../confirm-delivery` to set status to `delivered` without any code (used when the code path fails, e.g. code expired or lost). The endpoint is buyer/admin-only and uses the same cross-store `sameUser()` id comparison as the seller delivery gates, so legacy ObjectId sessions and Postgres UUID request rows compare correctly. It emits only `purchase-request-update` with `status-changed` — it does **not** send delivery-specific notifications to either party.
|
||||||
7. **Optional auto-release timer** — once `status === 'delivered'`, a scheduled job can flip the request to `confirming` and then to `seller_paid` after a grace period (e.g. 48h). The auto-release worker is not yet implemented; today an admin completes the chain via [[Payout Flow]].
|
7. **Optional auto-release timer** — once `status === 'delivered'`, a scheduled job can flip the request to `confirming` and then to `seller_paid` after a grace period (e.g. 48h). The auto-release worker is not yet implemented; today an admin completes the chain via [[Payout Flow]].
|
||||||
|
|
||||||
## Sequence diagram
|
## Sequence diagram
|
||||||
@@ -87,7 +87,7 @@ sequenceDiagram
|
|||||||
| `POST` | `/api/marketplace/purchase-requests/:id/delivery-code/generate` | Buyer generates delivery code (buyer only) |
|
| `POST` | `/api/marketplace/purchase-requests/:id/delivery-code/generate` | Buyer generates delivery code (buyer only) |
|
||||||
| `POST` | `/api/marketplace/purchase-requests/:id/delivery-code/verify` | Seller verifies code (seller only) |
|
| `POST` | `/api/marketplace/purchase-requests/:id/delivery-code/verify` | Seller verifies code (seller only) |
|
||||||
| `GET` | `/api/marketplace/purchase-requests/:id/delivery-code/status` | Check code status (buyer + seller) |
|
| `GET` | `/api/marketplace/purchase-requests/:id/delivery-code/status` | Check code status (buyer + seller) |
|
||||||
| `PATCH` | `/api/marketplace/purchase-requests/:id/confirm-delivery` | Buyer fast-track confirm (no code) — ⚠️ no auth check, no delivery notifications |
|
| `PATCH` | `/api/marketplace/purchase-requests/:id/confirm-delivery` | Buyer/admin fast-track confirm (no code); no delivery-specific notifications |
|
||||||
|
|
||||||
### Phantom frontend actions (routes do NOT exist on backend)
|
### Phantom frontend actions (routes do NOT exist on backend)
|
||||||
|
|
||||||
@@ -102,7 +102,7 @@ These Redux/API actions exist in the frontend but call endpoints that return 404
|
|||||||
## Two paths to `delivered` status
|
## Two paths to `delivered` status
|
||||||
|
|
||||||
1. **Code path** — seller calls `POST .../delivery-code/verify` with the correct, unexpired code → status becomes `delivered`. Both buyer and seller receive delivery-confirmed notifications (sent by `DeliveryService.verifyDeliveryCode`).
|
1. **Code path** — seller calls `POST .../delivery-code/verify` with the correct, unexpired code → status becomes `delivered`. Both buyer and seller receive delivery-confirmed notifications (sent by `DeliveryService.verifyDeliveryCode`).
|
||||||
2. **Fast-track path** — buyer calls `PATCH .../confirm-delivery` (no code required) → also becomes `delivered`. ⚠️ Currently no authorization check on this endpoint, and no delivery-specific notifications are sent to either party.
|
2. **Fast-track path** — buyer calls `PATCH .../confirm-delivery` (no code required) → also becomes `delivered`. Authorization is buyer/admin-only, with cross-store id matching for legacy ObjectId/PG UUID seams. No delivery-specific notifications are sent to either party.
|
||||||
|
|
||||||
## Database writes
|
## Database writes
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,16 @@ entries on top. Maintained by agents per the rule in `../AGENTS.md`.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
### 2026-06-06 — backend@99ae2db, frontend@94a99a1 — buyer delivery confirmation id-seam fix
|
||||||
|
|
||||||
|
**Commits:** `99ae2db` `94a99a1`
|
||||||
|
**Touched:** backend `src/services/marketplace/marketplaceController.ts`, backend version files; frontend `package.json`.
|
||||||
|
**Why:** Live BSC Testnet E2E rounds funded escrow and seller delivery successfully, but buyer `PATCH /api/marketplace/purchase-requests/:id/confirm-delivery` returned 403 because the route compared the buyer's session legacy ObjectId directly to the purchase request buyer id. The route now uses the same cross-store `sameUser()` helper already used by seller delivery/code gates.
|
||||||
|
**Verification:** backend `npm run typecheck`, `npm test -- --runTestsByPath __tests__/rn-in-house-checkout.test.ts __tests__/decentralized-payment-verifier.test.ts __tests__/amn-pay-adapter-intent.test.ts --runInBand`, `BASE_URL=https://dev.amn.gg bash scripts/smoke/bsc-testnet-payment-registry.sh`, `git diff --check`; frontend package version sanity check. Post-deploy retry of the two live E2E delivery confirmations pending.
|
||||||
|
**Linked docs updated:** [[04 - Flows/Delivery Confirmation Flow]]
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
### 2026-06-06 — backend@3e9a2f2, frontend@e4fa4de, scanner@1911c3a — BSC Testnet tUSDT contract corrected
|
### 2026-06-06 — backend@3e9a2f2, frontend@e4fa4de, scanner@1911c3a — BSC Testnet tUSDT contract corrected
|
||||||
|
|
||||||
**Commits:** `3e9a2f2` `e4fa4de` `e235286` `1911c3a`
|
**Commits:** `3e9a2f2` `e4fa4de` `e235286` `1911c3a`
|
||||||
|
|||||||
Reference in New Issue
Block a user