I would like to ask about the concept, so pseudo-code or example in your preferred language should be enough.
Problem:
Let's say, I have two entities. Order and OrderItem. Order has many OrderItems. Let's say, customer calls to helpdesk to change their order for them - maybe they want to change shipping address or add/delete few items. So helpdesk worker needs to be able to change order in the system.
I recently came up with a solution, which solves the problem, but is quite verbouse, hard to debug and silly.
class UpdateOrderDto {
id: int
shippingAddress: Address
items: UpdateOrderItemDto[]
updatedAt: string // Timestamp
}
class UpdateOrderItemDto {
id?: int // optional - in case of creating a new item
productId: int
quantity: int
// Flags:
wasCreated: boolean
wasUpdated: boolean
wasDeleted: boolean
}
This data comes in API request. UpdatedAt is used to check optimistic lock. Flags in OrderItem object indicates the action, which happened on item during update.
Then I run something like this on route:
updateOrder(dto: UpdateOrderDto) {
const orderEntity = this.db.get(dto.id)
if (orderEntity.updatedAt !== dto.updatedAt)
throw "Timestamps don't match"
this.db.startTransaction()
orderEntity.shippingAddress = dto.shippingAddress
// ...
orderEntity.save()
const itemsToDelete = dto.items.filter(...)
const itemsToUpdate = dto.items.filter(...)
const itemsToCreate = dto.items.filter(...)
for (const item of itemsToDelete) {
...
}
// ... cycles for each case.
this.db.endTransaction()
}
Real implementation is much more complex. Would like to ask then, if you know a simpler solution or if I'm missing something. Thank you very much.