The storefront runs in the visitor's browser, and anything that runs there can be changed. With the browser's dev tools, curl or a short script, anyone can send POST /api/checkout with any JSON they like, even "total": 1. So the server never takes a price or a total from req.body. It takes them from its own database.
The given cartOf(userId) already does that: it joins cart_items with products, so every item's price and the cart's total come from shop.db. Now checkout turns that cart into an order: one row in orders, and one row per product in order_items with the unit_price paid. Ending an INSERT with RETURNING id and running it with .get() gives back the new row's id. Here it is on another table:
app.post("/api/reviews", requireLogin, (req, res) => {
const review = db.prepare("INSERT INTO reviews (user_id, text) VALUES (?, ?) RETURNING id").get(req.user.id, req.body.text);
res.status(201).json({ id: review.id });
});
The author comes from the session (req.user.id), not from the request body. The check logs in as Ana on the page, adds the Mug ($12) and the Lamp ($29) and places the order. Then Ben sends his own request with a total of 1:
> click "Place order" → POST /api/checkout -> 201
status: Order 8 placed: $41
link: Cart (0) -> /cart
POST /api/checkout {"name": "Ben Ortiz", …, "total": 1} → 201 {"id": 9, "total": 41}
the new orders in shop.db: 8 | ana@example.com | pending | 41
9 | ben@example.com | pending | 41
their items: order 8 and order 9: Mug at 12, Lamp at 29
Your task: in server/app.js, below the form checks of POST /api/checkout, find the customer, insert a pending order, insert an order_items row for each cart item at the database's price, then empty the user's cart.
Assignment
Follow the Coding Tutorial to save the order in POST /api/checkout: the customer, a pending order, one order_items row per cart item priced from the database, and then an empty cart.
Hint
Use item.price (read by cartOf from the products table) as unit_price, and never anything from req.body. INSERT … RETURNING id with .get() gives you order.id.
Free plan: 30 tutor messages. PRO is unlimited.
