@trap_stevo/ventry
Version:
The universal engine for creating, tracking, and evolving interactive content — from posts, comments, and likes to offers, auctions, events, and beyond. Define, extend, and analyze content objects in real time. Turn anything into user-driven content.
256 lines (255 loc) • 5.84 kB
JavaScript
"use strict";
const {
newID
} = require("../HUDComponents/ID.cjs");
class OffersManager {
constructor(vaultManager, metricsManager, eventsManager) {
this.metrics = metricsManager;
this.events = eventsManager;
this.vault = vaultManager;
}
proposeOffer(itemID, bidderID, input = {}) {
const item = this.vault.getItem(itemID);
if (!item) {
console.warn("Item not found.");
return null;
}
const accepts = !!(item.data && item.data.acceptsOffers === true);
if (!accepts) {
console.warn("Offers not permitted.");
return null;
}
const rec = {
id: newID(),
itemID,
itemOwnerID: item.data.ownerID,
bidderID,
amount: input.amount,
currency: input.currency || item.data && item.data.price && item.data.price.currency || "credits",
status: "open",
expiresAt: input.expiresAt || null,
metadata: input.metadata || {}
};
const saved = this.vault.createOffer(rec);
this.metrics.track("offer.created", 1, {
offerID: saved.id,
bidderID,
itemID
});
if (this.events) {
this.events.emit("offer.created", {
expiresAt: rec.expiresAt,
currency: rec.currency,
amount: rec.amount,
offerID: saved.id,
bidderID,
itemID
});
}
return {
offerID: saved.id
};
}
acceptOffer(offerID, ownerID) {
const offer = this.vault.getOffer(offerID);
if (!offer) {
console.warn("Offer not found.");
return null;
}
if (offer.data.itemOwnerID !== ownerID) {
console.warn("Unauthorized action.");
return null;
}
this.vault.updateOffer(offerID, {
status: "accepted"
});
this.metrics.track("offer.accepted", 1, {
itemID: offer.data.itemID,
offerID,
ownerID
});
if (this.events) {
this.events.emit("offer.accepted", {
bidderID: offer.data.bidderID,
itemID: offer.data.itemID,
ownerID,
offerID
});
}
return {
ok: true
};
}
rejectOffer(offerID, ownerID, reason) {
const offer = this.vault.getOffer(offerID);
if (!offer) {
console.warn("Offer not found.");
return null;
}
if (offer.data.itemOwnerID !== ownerID) {
console.warn("Unauthorized action.");
return null;
}
this.vault.updateOffer(offerID, {
status: "rejected",
reason: reason || null
});
this.metrics.track("offer.rejected", 1, {
itemID: offer.data.itemID,
offerID,
ownerID,
reason
});
if (this.events) {
this.events.emit("offer.rejected", {
itemID: offer.data.itemID,
offerID,
ownerID,
reason
});
}
return {
ok: true
};
}
withdrawOffer(offerID, bidderID) {
const offer = this.vault.getOffer(offerID);
if (!offer) {
console.warn("Offer not found.");
return null;
}
if (offer.data.bidderID !== bidderID) {
console.warn("Unauthorized action.");
return null;
}
this.vault.updateOffer(offerID, {
status: "withdrawn"
});
this.metrics.track("offer.withdrawn", 1, {
itemID: offer.data.itemID,
bidderID,
offerID
});
if (this.events) {
this.events.emit("offer.withdrawn", {
itemID: offer.data.itemID,
bidderID,
offerID
});
}
return {
ok: true
};
}
listOffers(itemID, filter = {}, page = {}) {
const q = {
itemID
};
if (filter.status) {
q.status = Array.isArray(filter.status) ? filter.status : [filter.status];
}
const qb = this.vault.queryOffers(q, {
timestamp: -1
}, {
limit: page.limit || 50
});
const offers = qb.execute(true);
return {
offers,
nextCursor: undefined
};
}
markItemSold(itemID, ownerID, sale = {}) {
const it = this.vault.getItem(itemID);
if (!it) {
console.warn("Item not found.");
return null;
}
if (it.data.ownerID !== ownerID) {
console.warn("Unauthorized action.");
return null;
}
const data = Object.assign({}, it.data || {}, {
lastSale: sale,
sold: true
});
this.vault.updateItem(itemID, {
data,
status: "archived"
});
this.metrics.track("sale.marked", 1, {
currency: sale.currency,
amount: sale.amount,
ownerID,
itemID
});
if (this.events) {
this.events.emit("item.sold_marked", {
itemID,
ownerID,
sale
});
}
return {
ok: true
};
}
toggleForSale(itemID, ownerID, forSale) {
const it = this.vault.getItem(itemID);
if (!it) {
console.warn("Item not found.");
return null;
}
if (it.data.ownerID !== ownerID) {
console.warn("Unauthorized action.");
return null;
}
const data = Object.assign({}, it.data || {}, {
forSale: !!forSale
});
this.vault.updateItem(itemID, {
data
});
if (this.events) {
this.events.emit("item.for_sale_toggled", {
forSale: !!forSale,
ownerID,
itemID
});
}
return {
ok: true
};
}
updatePrice(itemID, ownerID, price) {
const it = this.vault.getItem(itemID);
if (!it) {
console.warn("Item not found.");
return null;
}
if (it.data.ownerID !== ownerID) {
console.warn("Unauthorized action.");
return null;
}
const data = Object.assign({}, it.data || {}, {
price
});
this.vault.updateItem(itemID, {
data
});
if (this.events) {
this.events.emit("item.price_updated", {
ownerID,
itemID,
price
});
}
return {
ok: true
};
}
}
;
module.exports = {
OffersManager
};