docs: sync from backend cbc32dc — template delivery rails
This commit is contained in:
@@ -6,7 +6,7 @@ aliases: [Purchase Request, Buy Request, IPurchaseRequest]
|
||||
|
||||
# PurchaseRequest
|
||||
|
||||
> **Last updated:** 2026-05-31 — `budget.currency` aligned with template/Postgres enum (`USD`, `EUR`, `IRR`, `USDT`, `USDC`); `categoryId` added to `IRequestTableItem`
|
||||
> **Last updated:** 2026-05-31 — `budget.currency` aligned with template/Postgres enum (`USD`, `EUR`, `IRR`, `USDT`, `USDC`); template checkout now preserves seller-owned delivery mode and overlays buyer address/email.
|
||||
|
||||
The central buyer-side document. A `PurchaseRequest` captures what a buyer wants to acquire (physical product, digital product, service, or consultation), the budget envelope, urgency, delivery details, and the entire lifecycle from creation through payment, delivery, and completion. Sellers respond by attaching [[SellerOffer]] documents; the buyer accepts one, a [[Payment]] is opened, and delivery is verified by a 6-digit code.
|
||||
|
||||
@@ -39,15 +39,15 @@ The central buyer-side document. A `PurchaseRequest` captures what a buyer wants
|
||||
| `specifications[].key` | String | yes | — | trim | — | Spec key. |
|
||||
| `specifications[].value` | String | yes | — | trim | — | Spec value. |
|
||||
| `specifications[].label` | String | no | — | trim | — | Human label. |
|
||||
| `deliveryInfo.deliveryType` | String | yes | `physical` | enum: `physical` / `online` | — | Delivery channel. |
|
||||
| `deliveryInfo.address` | String | no | — | — | — | Physical address. |
|
||||
| `deliveryInfo.deliveryType` | String | yes | `physical` | enum: `physical` / `online` | — | Delivery channel. Direct requests are buyer-selected; template checkout inherits the seller-selected [[RequestTemplate]] delivery mode. |
|
||||
| `deliveryInfo.address` | String | no | — | — | — | Physical address. In template checkout this is built from the buyer's selected billing address only when the template requires physical delivery. |
|
||||
| `deliveryInfo.preferredDate` | Date | no | — | — | — | Buyer's target date. |
|
||||
| `deliveryInfo.notes` | String | no | — | — | — | Free-form notes. |
|
||||
| `deliveryInfo.deliveryAddress.name` | String | no | — | — | — | Recipient name. |
|
||||
| `deliveryInfo.deliveryAddress.phoneNumber` | String | no | — | — | — | Recipient phone. |
|
||||
| `deliveryInfo.deliveryAddress.fullAddress` | String | no | — | — | — | Full address string. |
|
||||
| `deliveryInfo.deliveryAddress.fullAddress` | String | no | — | — | — | Full address string copied from checkout billing for physical template orders. |
|
||||
| `deliveryInfo.deliveryAddress.addressType` | String | no | — | — | — | e.g. Home / Office. |
|
||||
| `deliveryInfo.email` | String | no | — | email regex | — | For digital delivery. |
|
||||
| `deliveryInfo.email` | String | no | — | email regex | — | Buyer receiving email for digital/online template delivery. |
|
||||
| `deliveryInfo.sellerDeliveryInfo.estimatedDeliveryDate` | Date | no | — | — | — | Seller's ETA date. |
|
||||
| `deliveryInfo.sellerDeliveryInfo.estimatedDeliveryTime` | String | no | — | — | — | Seller's ETA time. |
|
||||
| `deliveryInfo.sellerDeliveryInfo.trackingNumber` | String | no | — | — | — | Carrier tracking. |
|
||||
@@ -129,6 +129,14 @@ None defined.
|
||||
- **References**: [[User]] (`buyerId`, `preferredSellerIds[]`, `deliveryInfo.deliveryCodeUsedBy`, `deliveryInfo.deliveryAttempts[].sellerId`), [[Category]] (`categoryId`), [[SellerOffer]] (`offers[]`, `selectedOfferId`).
|
||||
- **Referenced by**: [[SellerOffer]] (`purchaseRequestId`), [[Payment]] (`purchaseRequestId`), [[Dispute]] (`purchaseRequestId`), [[Chat]] (`relatedTo.id` when `relatedTo.type === 'PurchaseRequest'`), [[Review]] (`purchaseRequestId`).
|
||||
|
||||
## Template Checkout Mapping
|
||||
|
||||
When a buyer converts a [[RequestTemplate]], the seller's template remains authoritative for delivery mode:
|
||||
|
||||
- `physical` templates require a buyer billing/delivery address in checkout. The generated request stores both `deliveryInfo.address` and `deliveryInfo.deliveryAddress`.
|
||||
- `online` templates require a buyer email in checkout. The generated request stores it in `deliveryInfo.email`.
|
||||
- Mixed carts can produce multiple requests with different delivery modes; the checkout UI asks for the union of required buyer details.
|
||||
|
||||
## State Transitions
|
||||
|
||||
```mermaid
|
||||
|
||||
@@ -6,7 +6,9 @@ aliases: [Template, Request Template, IRequestTemplate]
|
||||
|
||||
# RequestTemplate
|
||||
|
||||
A reusable template authored by a seller. When a buyer visits the template's `shareableLink`, the front-end pre-fills a new [[PurchaseRequest]] with the template's category, urgency, specs, delivery info, and an optional default seller `proposal`. The schema mirrors `PurchaseRequest` for fast cloning, plus template-specific bookkeeping (`isActive`, `usageCount`, `maxUsage`, `expiresAt`).
|
||||
> **Last updated:** 2026-05-31 — seller-owned delivery mode and per-template payment rails documented.
|
||||
|
||||
A reusable template authored by a seller. When a buyer visits the template's `shareableLink`, the front-end pre-fills a new [[PurchaseRequest]] with the template's category, urgency, specs, seller-selected delivery mode, payment rail allowlist, and an optional default seller `proposal`. The schema mirrors `PurchaseRequest` for fast cloning, plus template-specific bookkeeping (`isActive`, `usageCount`, `maxUsage`, `expiresAt`).
|
||||
|
||||
> [!note] Source
|
||||
> `backend/src/models/RequestTemplate.ts:65` — schema definition
|
||||
@@ -34,9 +36,12 @@ A reusable template authored by a seller. When a buyer visits the template's `sh
|
||||
| `specifications[].key` | String | yes | — | trim | — | Spec key. |
|
||||
| `specifications[].value` | String | yes | — | trim | — | Spec value. |
|
||||
| `specifications[].label` | String | no | — | trim | — | Human label. |
|
||||
| `deliveryInfo.deliveryType` | String | no | `physical` | enum: `physical` / `online` | — | Delivery channel. |
|
||||
| `deliveryInfo.notes` | String | no | — | — | — | Notes. |
|
||||
| `deliveryInfo.email` | String | no | — | email regex | — | Digital delivery email. |
|
||||
| `deliveryInfo.deliveryType` | String | no | `physical` | enum: `physical` / `online` | — | Seller-selected delivery channel. Buyers cannot override this at checkout. |
|
||||
| `deliveryInfo.notes` | String | no | — | — | — | Seller notes about delivery. |
|
||||
| `deliveryInfo.email` | String | no | — | email regex when non-empty | — | Legacy/optional field. Template checkout now asks the buyer for a receiving email when `deliveryType === "online"`. |
|
||||
| `paymentConfig.useShopDefault` | Boolean | no | `true` | — | — | When `false`, the template's own chain/token allowlist overrides [[ShopSettings]]. New template UI defaults this to `false` so sellers choose rails explicitly. |
|
||||
| `paymentConfig.allowedChains[]` | Number[] | no | `[1, 56]` | must contain at least one positive chain id | — | Chain ids accepted for this template, e.g. `1` Ethereum, `56` BSC. Empty arrays are rejected. |
|
||||
| `paymentConfig.allowedTokens[]` | String[] | no | `["USDC", "USDT"]` | must contain at least one non-empty token symbol | — | Settlement tokens accepted for this template. Empty arrays are rejected. |
|
||||
| `serviceInfo.duration` | Number | no | — | min 0.5 | — | Hours. |
|
||||
| `serviceInfo.sessionType` | String | no | — | enum: `online` / `in_person` / `hybrid` | — | Session type. |
|
||||
| `serviceInfo.location` | String | no | — | trim, maxlength 200 | — | Location. |
|
||||
@@ -95,6 +100,12 @@ None defined.
|
||||
- **References**: [[User]] (`sellerId`), [[Category]] (`categoryId`).
|
||||
- **Referenced by**: [[PurchaseRequest]] (`metadata.templateId` as string), [[Review]] (`subjectId` when `subjectType === 'template'`).
|
||||
|
||||
## Checkout Semantics
|
||||
|
||||
- The seller chooses `deliveryInfo.deliveryType` on the template. The buyer checkout step only collects the required fulfillment details: a physical address for `physical`, a receiving email for `online`, and both when a cart mixes physical and online templates.
|
||||
- `batch-convert` copies the seller's delivery mode into each generated [[PurchaseRequest]] and overlays the buyer-supplied billing/email details.
|
||||
- Payment checkout resolves allowed rails through `paymentConfig`: template override first, then [[ShopSettings]], then the global supported default. A template with an explicit empty chain or token list is invalid.
|
||||
|
||||
## State Transitions
|
||||
|
||||
```mermaid
|
||||
|
||||
@@ -6,7 +6,9 @@ aliases: [Shop, Storefront, IShopSettings]
|
||||
|
||||
# ShopSettings
|
||||
|
||||
One-to-one storefront configuration for a seller. Holds the shop name, description, avatar, cover image, public visibility flag, review toggles (`allowSellerReviews`, `allowTemplateReviews`), and social links. The unique constraint on `sellerId` enforces the one-shop-per-seller invariant.
|
||||
> **Last updated:** 2026-05-31 — store-level payment rail defaults documented.
|
||||
|
||||
One-to-one storefront configuration for a seller. Holds the shop name, description, avatar, cover image, public visibility flag, review toggles (`allowSellerReviews`, `allowTemplateReviews`), social links, and store-level payment rail defaults. The unique constraint on `sellerId` enforces the one-shop-per-seller invariant.
|
||||
|
||||
> [!note] Source
|
||||
> `backend/src/models/ShopSettings.ts:22` — schema definition
|
||||
@@ -28,6 +30,8 @@ One-to-one storefront configuration for a seller. Holds the shop name, descripti
|
||||
| `socialLinks.instagram` | String | no | `""` | — | — | Instagram URL. |
|
||||
| `socialLinks.linkedin` | String | no | `""` | — | — | LinkedIn URL. |
|
||||
| `socialLinks.twitter` | String | no | `""` | — | — | Twitter / X URL. |
|
||||
| `paymentConfig.allowedChains[]` | Number[] | no | `[1, 56]` | update route requires at least one chain when supplied | — | Store-level accepted chain ids used by templates with `paymentConfig.useShopDefault === true`. |
|
||||
| `paymentConfig.allowedTokens[]` | String[] | no | `["USDC", "USDT"]` | update route requires at least one token when supplied | — | Store-level accepted settlement tokens. |
|
||||
| `createdAt` | Date | auto | — | — | — | Mongoose timestamp. |
|
||||
| `updatedAt` | Date | auto | — | — | — | Mongoose timestamp. |
|
||||
|
||||
@@ -82,6 +86,9 @@ ShopSettings.findOneAndUpdate(
|
||||
|
||||
// Public shop directory
|
||||
ShopSettings.find({ isPublic: true }).sort({ createdAt: -1 });
|
||||
|
||||
// Resolve seller-level payment rails for template checkout
|
||||
ShopSettings.findOne({ sellerId }).select('paymentConfig');
|
||||
```
|
||||
|
||||
> [!warning] Creating two shops will fail
|
||||
|
||||
Reference in New Issue
Block a user