Rules Hub
Code Ruleset
Rule priority, scope & exceptions
Use this to align rules with the senior-level structure (P0/P1/P2, scope, exceptions/tradeoffs).
Use transactions for multi-step writes
Wrap multi-step write operations in a transaction to prevent partial updates.
Bad example
| 1 | export async function placeOrder(userId: string, items: Item[]) { |
| 2 | const order = await db.order.create({ data: { userId } }); |
| 3 |
|
| 4 | for (const item of items) { |
| 5 | await db.inventory.update({ |
| 6 | where: { id: item.id }, |
| 7 | data: { stock: { decrement: item.qty } }, |
| 8 | }); |
| 9 | } |
| 10 |
|
| 11 | await db.payment.create({ data: { orderId: order.id } }); |
| 12 | return order; |
| 13 | } |
Explanation (EN)
Independent commits can leave a partial order after a later database operation fails.
Objašnjenje (HR)
Odvojeni commitovi mogu ostaviti djelomičnu narudžbu kada kasnija operacija baze ne uspije.
Good example
| 1 | export async function placeOrder(userId: string, items: Item[]) { |
| 2 | return db.$transaction(async (tx) => { |
| 3 | const order = await tx.order.create({ data: { userId } }); |
| 4 |
|
| 5 | for (const item of items) { |
| 6 | await tx.inventory.update({ |
| 7 | where: { id: item.id }, |
| 8 | data: { stock: { decrement: item.qty } }, |
| 9 | }); |
| 10 | } |
| 11 |
|
| 12 | await tx.payment.create({ data: { orderId: order.id } }); |
| 13 | return order; |
| 14 | }); |
| 15 | } |
Explanation (EN)
Transactions make the operation atomic: either everything succeeds or everything rolls back.
Objašnjenje (HR)
Transakcije cine operaciju atomarnom: ili sve uspije ili se sve vrati.
Notes (EN)
Use one transaction-scoped connection for database writes and invariant-dependent reads that must commit or roll back together.
Exceptions / Tradeoffs (EN)
If you intentionally use a saga/outbox with compensating actions, document it and ensure consistency guarantees. A database transaction does not roll back an external payment/API call. Preserve business constraints such as nonnegative inventory separately through conditional writes, locks or constraints.
Iznimke / Tradeoffi (HR)
Saga ili outbox s kompenzacijom mogu biti namjerni uz jasno opisana jamstva. Transakcija baze ne poništava vanjsko plaćanje ili API poziv. Poslovne uvjete, primjerice nenegativnu zalihu, dodatno zaštiti uvjetnim upisom, zaključavanjem ili ograničenjem baze.