Files
nick-doc/02 - Data Models/SellerOffer.md
Siavash Sameni 9698ec5809 docs: align API reference and data model docs with code reality
API Reference (9 files updated):
- Marketplace API: corrected offer endpoints (scoped under /purchase-requests/:id/offers),
  marked phantom /search /stats /seller/:sellerId /withdraw routes as NOT IMPLEMENTED,
  documented PUT→PATCH mismatches, removed invalid SellerOffer 'active' status
- Dispute API: corrected resolve schema (action enum), categories (no 'fraud'),
  removed 'under_review' status, added security callouts (3 unguarded endpoints),
  route shadowing documented, all socket events marked as TODO stubs
- Notification API: corrected mark-all-read method+path, fixed broken GET /:id,
  added unread-count-update event, 90-day TTL documented
- Payment API: /create→/save, removed 10+ phantom endpoints, fixed release/refund
  paths (no /shkeeper/ segment), added 3 unauthenticated endpoint security warnings,
  stats undercounting documented, export privilege gap documented
- Authentication API: 8-digit→6-digit code, no-complexity warning on reset-with-code,
  rate limiter counts all attempts, passkey stub claims removed, deleteAccount bug noted
- Admin API: PUT→PATCH bug documented, wrong status values documented, hard vs soft
  delete clarified, scanner no-auth security bug, 3 NOT IMPLEMENTED endpoints
- Chat API: file upload wrong endpoint bug, archive PUT→PATCH bug, rate limits added
- Points API: corrected redeem schema, referral triggers on 'completed' only,
  leaderboard period ignored, removed 'refund' PointTransaction type
- Socket Events: removed request-cancelled, notification-read; added unread-count-update;
  dispute events all stubs; referral-signup is auth-domain not points-domain

Data Models (3 files updated):
- SellerOffer: removed 'active' from status enum, withdrawOffer() is dead code
- PurchaseRequest: added pending_payment/active statuses, added 'urgent' urgency,
  corrected description minimum (5 chars), removed finalized/archived
- Dispute: corrected action enum, categories (no fraud), removed under_review,
  security callout on unguarded status/resolve endpoints

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 14:57:47 +04:00

4.0 KiB

title, tags, aliases
title tags aliases
SellerOffer
data-model
mongoose
Seller Offer
Bid
ISellerOffer

SellerOffer

Last updated: 2026-05-29 — aligned with code (see Doc vs Code Audit Report)

A seller's bid against a PurchaseRequest. Stores the proposed price, the delivery time commitment, optional notes/attachments, and a small status machine (pending / accepted / rejected / withdrawn). The parent PurchaseRequest keeps the array of offer ids in offers[] and the chosen one in selectedOfferId.

[!note] Source backend/src/models/SellerOffer.ts:24 — schema definition backend/src/models/SellerOffer.ts:100 — model export

Schema

Field Type Required Default Validation Index Description
sellerId ObjectId → User yes yes Seller submitting the bid.
purchaseRequestId ObjectId → PurchaseRequest yes yes Parent request.
title String yes trim, maxlength 200 Offer headline.
description String yes trim, maxlength 1000 Pitch and details.
price.amount Number yes min 0 Quoted amount.
price.currency String yes USDT enum: USD / EUR / IRR / USDT / USDC Quote currency.
deliveryTime.amount Number yes min 1 Numeric ETA.
deliveryTime.unit String yes enum: hours / days / weeks ETA unit.
status String no pending enum: pending / accepted / rejected / withdrawn yes Offer status.
attachments[] String[] no URLs of supporting files.
notes String no trim Internal/private notes.
validUntil Date no Expiration.
createdAt Date auto yes (desc) Mongoose timestamp.
updatedAt Date auto Mongoose timestamp.

Status enum note: Valid values are pending | accepted | rejected | withdrawn only. 'active' is not a valid status and would throw a Mongoose ValidationError if passed.

Virtuals

None defined.

Indexes

Defined at backend/src/models/SellerOffer.ts:95-98:

  • { sellerId: 1 }
  • { purchaseRequestId: 1 }
  • { status: 1 }
  • { createdAt: -1 }

Pre/Post Hooks

None declared.

Instance Methods

None defined.

Static Methods

None defined.

Service notes

createOffer — eligible parent request statuses

createOffer in SellerOfferService permits offers against a PurchaseRequest whose status is pending, received_offers, or active. Attempts against any other status are rejected.

withdrawOffer() — dead code

SellerOfferService.withdrawOffer() exists in the source but is not exposed via any HTTP route. It cannot be called through the API. Any frontend references to a withdraw endpoint will receive a 404.

Relationships

State Transitions

stateDiagram-v2
    [*] --> pending
    pending --> accepted : buyer accepts
    pending --> rejected : buyer rejects
    pending --> withdrawn : seller cancels
    accepted --> [*]
    rejected --> [*]
    withdrawn --> [*]

Common Queries

// Offers for a request
SellerOffer.find({ purchaseRequestId }).sort({ createdAt: -1 });

// Seller's active offers
SellerOffer.find({ sellerId, status: 'pending' });

// Reject siblings on accept
SellerOffer.updateMany(
  { purchaseRequestId, _id: { $ne: acceptedId }, status: 'pending' },
  { status: 'rejected' }
);

// Cleanup expired offers
SellerOffer.find({ validUntil: { $lt: new Date() }, status: 'pending' });

Related: PurchaseRequest, Payment, User.