step 6.1: wip (not ticked)

This commit is contained in:
bepis
2026-10-21 00:42:56 +11:00
parent ae8ee02721
commit ffee0efc47
6 changed files with 810 additions and 15 deletions
+63
View File
@@ -0,0 +1,63 @@
// Shop routes: GET /api/shop, POST /api/shop/buy, POST /api/shop/sell.
const zod = require('zod');
const { AppError } = require('../utils/errors');
const { requireAuth } = require('../middleware/session');
const { getCharacterIdForUser } = require('../services/characterService');
const { getStock, buyItem, sellItem } = require('../services/shopService');
function wrap(fn) {
return (req, res, next) => Promise.resolve(fn(req, res, next)).catch(next);
}
/**
* GET /api/shop — list shop stock and materials available for sale.
*/
async function handleListShop(_req, res) {
const characterId = getCharacterIdForUser(_req.session.userId);
const result = getStock(characterId);
res.json({ ok: true, data: result });
}
/**
* POST /api/shop/buy — buy an item from the shop.
*/
async function handleBuy(req, res) {
const parsed = zod.strictObject({
itemId: zod.number().int().positive(),
quantity: zod.number().int().min(1).max(99),
}).safeParse(req.body);
if (!parsed.success) {
throw new AppError('VALIDATION_ERROR', 'Request validation failed.', 400);
}
const { itemId, quantity } = parsed.data;
const characterId = getCharacterIdForUser(req.session.userId);
const result = buyItem(characterId, itemId, quantity);
res.json({ ok: true, data: result });
}
/**
* POST /api/shop/sell — sell a material back to the shop.
*/
async function handleSell(req, res) {
const parsed = zod.strictObject({
itemId: zod.number().int().positive(),
quantity: zod.number().int().min(1).max(99),
}).safeParse(req.body);
if (!parsed.success) {
throw new AppError('VALIDATION_ERROR', 'Request validation failed.', 400);
}
const { itemId, quantity } = parsed.data;
const characterId = getCharacterIdForUser(req.session.userId);
const result = sellItem(characterId, itemId, quantity);
res.json({ ok: true, data: result });
}
module.exports = {
routes: {
getShop: wrap(handleListShop),
postBuy: wrap(handleBuy),
postSell: wrap(handleSell),
},
};