# At a Glance A schema, a migration, and the queries that read and write it. ```ts import { sql, tx, session } from "@elements/app"; interface User { id: string; name: string; email: string; createdAt: Date; } interface Order { id: string; userId: string; total: number; } /** @rpc */ export function placeOrder(items: { sku: string; qty: number }[]): Order { session.isLoggedInOrThrow(); let userId = session.getOrThrow("userId"); return tx(() => { let order = sql(` insert into orders (userId, total) values (${userId}, ${total(items)}) returning * `).firstOrThrow(); for (let item of items) { sql(` insert into orderItems (orderId, sku, qty) values (${order.id}, ${item.sku}, ${item.qty}) `); } return order; }); } function total(items: { sku: string; qty: number }[]): number { let result = 0; for (let row of sql<{ sku: string; price: number }>( `select sku, price from products where sku = any(${items.map(i => i.sku)})` )) { let item = items.find(i => i.sku === row.sku); if (item) { result += row.price * item.qty; } } return result; } ``` The code reads as a sequence of statements with no `await` keywords. Column names stay camelCase throughout. Each `${value}` is extracted to a positional parameter at build time, so the query is parameterized at runtime. The entire body runs inside a Postgres transaction because of the surrounding `tx()`.