Replaces MongoDB support with PostgreSQL (#151)

- All schemas have been rewritten to a relational model
- All services have been rewritten to accommodate the new data model
- Adds idempotency keys to core endpoints allowing you to retry requests with no additional side effects
- Adds staged jobs to avoid putting jobs in the queue when transactions abort
- Adds atomic transactions to all methods with access to the data layer

Co-authored-by: Oliver Windall Juhl <oliver@mrbltech.com>
This commit is contained in:
Sebastian Rindom
2021-01-26 10:26:14 +01:00
co-authored by Oliver Windall Juhl
parent 5f819486fc
commit f1baca3cbd
499 changed files with 25909 additions and 16128 deletions
+25 -68
View File
@@ -1,101 +1,58 @@
class OrderSubscriber {
constructor({
paymentProviderService,
customerService,
manager,
eventBusService,
discountService,
giftCardService,
totalsService,
orderService,
regionService,
}) {
this.manager_ = manager
this.totalsService_ = totalsService
this.paymentProviderService_ = paymentProviderService
this.customerService_ = customerService
this.discountService_ = discountService
this.giftCardService_ = giftCardService
this.orderService_ = orderService
this.regionService_ = regionService
this.eventBus_ = eventBusService
this.eventBus_.subscribe("order.placed", async order => {
await this.customerService_.addOrder(order.customer_id, order._id)
this.eventBus_.subscribe("order.placed", this.handleOrderPlaced)
}
const address = {
...order.shipping_address,
}
delete address._id
await this.customerService_.addAddress(order.customer_id, address)
handleOrderPlaced = async data => {
const order = await this.orderService_.retrieve(data.id, {
select: ["subtotal"],
relations: ["discounts", "items", "gift_cards"],
})
this.eventBus_.subscribe("order.placed", this.handleDiscounts)
this.eventBus_.subscribe("order.placed", this.handleGiftCards)
}
handleDiscounts = async order => {
await Promise.all(
order.discounts.map(async d => {
const subtotal = await this.totalsService_.getSubtotal(order)
if (d.is_giftcard) {
const discountRule = {
...d.discount_rule,
value: Math.max(0, d.discount_rule.value - subtotal),
}
delete discountRule._id
return this.discountService_.update(d._id, {
discount_rule: discountRule,
usage_count: d.usage_count + 1,
disabled: discountRule.value === 0,
})
} else {
return this.discountService_.update(d._id, {
usage_count: d.usage_count + 1,
})
}
})
)
}
handleGiftCards = async order => {
const region = await this.regionService_.retrieve(order.region_id)
const items = await Promise.all(
order.items.map(async i => {
if (i.is_giftcard) {
const giftcard = await this.discountService_
.generateGiftCard(i.content.unit_price, region._id)
.then(result => {
this.eventBus_.emit("order.gift_card_created", {
line_item: i,
currency_code: region.currency_code,
tax_rate: region.tax_rate,
giftcard: result,
email: order.email,
})
return result
for (let qty = 0; qty < i.quantity; qty++) {
await this.giftCardService_.create({
region_id: order.region_id,
order_id: order.id,
value: i.unit_price,
balance: i.unit_price,
metadata: i.metadata,
})
return {
...i,
metadata: {
...i.metadata,
giftcard: giftcard._id,
},
}
}
return i
})
)
return this.orderService_.update(order._id, {
items,
})
await Promise.all(
order.discounts.map(async d => {
return this.discountService_.update(d.id, {
usage_count: d.usage_count + 1,
})
})
)
}
}