Initial commit
This commit is contained in:
+143
@@ -0,0 +1,143 @@
|
||||
import cors from "cors";
|
||||
import express from "express";
|
||||
import path from "path";
|
||||
import { fileURLToPath } from "url";
|
||||
import { connectToDatabase } from "./db.js";
|
||||
import { config } from "./config.js";
|
||||
import { MenuItem } from "./models/MenuItem.js";
|
||||
import { Order } from "./models/Order.js";
|
||||
import {
|
||||
computeOrderTotal,
|
||||
ensureSeedMenu,
|
||||
getSettings,
|
||||
nextOrderNumber,
|
||||
resetMenuToDefaults
|
||||
} from "./services.js";
|
||||
|
||||
const app = express();
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
const clientDist = path.resolve(__dirname, "../client/dist");
|
||||
|
||||
app.use(cors());
|
||||
app.use(express.json());
|
||||
|
||||
app.get("/api/health", (_request, response) => {
|
||||
response.json({ ok: true });
|
||||
});
|
||||
|
||||
app.get("/api/bootstrap", async (_request, response, next) => {
|
||||
try {
|
||||
await ensureSeedMenu();
|
||||
const [menu, orders] = await Promise.all([
|
||||
MenuItem.find().sort({ category: 1, name: 1 }),
|
||||
Order.find({ status: { $ne: "completed" } }).sort({ createdAt: -1 })
|
||||
]);
|
||||
response.json({
|
||||
menu,
|
||||
orders,
|
||||
settings: getSettings()
|
||||
});
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
});
|
||||
|
||||
app.post("/api/menu", async (request, response, next) => {
|
||||
try {
|
||||
const { name, category, description = "", basePrice } = request.body;
|
||||
if (!name || !category || typeof basePrice !== "number" || Number.isNaN(basePrice)) {
|
||||
return response.status(400).json({ error: "Invalid menu item payload." });
|
||||
}
|
||||
const menuItem = await MenuItem.create({ name, category, description, basePrice });
|
||||
response.status(201).json({ menuItem });
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
});
|
||||
|
||||
app.delete("/api/menu/:menuItemId", async (request, response, next) => {
|
||||
try {
|
||||
await MenuItem.findByIdAndDelete(request.params.menuItemId);
|
||||
response.json({ ok: true });
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
});
|
||||
|
||||
app.post("/api/menu/reset", async (_request, response, next) => {
|
||||
try {
|
||||
const menu = await resetMenuToDefaults();
|
||||
response.json({ menu });
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
});
|
||||
|
||||
app.post("/api/orders", async (request, response, next) => {
|
||||
try {
|
||||
const { customerName = "", paymentMethod = "cash", lines } = request.body;
|
||||
if (!Array.isArray(lines) || lines.length === 0) {
|
||||
return response.status(400).json({ error: "Orders require at least one line item." });
|
||||
}
|
||||
const total = computeOrderTotal(lines);
|
||||
const order = await Order.create({
|
||||
number: await nextOrderNumber(),
|
||||
customerName,
|
||||
paymentMethod,
|
||||
lines,
|
||||
total
|
||||
});
|
||||
response.status(201).json({ order });
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
});
|
||||
|
||||
app.patch("/api/orders/:orderId/status", async (request, response, next) => {
|
||||
try {
|
||||
const { status } = request.body;
|
||||
const order = await Order.findByIdAndUpdate(
|
||||
request.params.orderId,
|
||||
{ status },
|
||||
{ new: true, runValidators: true }
|
||||
);
|
||||
response.json({ order });
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
});
|
||||
|
||||
app.delete("/api/orders/:orderId", async (request, response, next) => {
|
||||
try {
|
||||
await Order.findByIdAndDelete(request.params.orderId);
|
||||
response.json({ ok: true });
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
});
|
||||
|
||||
app.use(express.static(clientDist));
|
||||
|
||||
app.get("*", (request, response, next) => {
|
||||
if (request.path.startsWith("/api/")) {
|
||||
return next();
|
||||
}
|
||||
response.sendFile(path.join(clientDist, "index.html"));
|
||||
});
|
||||
|
||||
app.use((error, _request, response, _next) => {
|
||||
console.error(error);
|
||||
response.status(500).json({ error: error.message || "Internal server error" });
|
||||
});
|
||||
|
||||
connectToDatabase()
|
||||
.then(() => {
|
||||
app.listen(config.port, () => {
|
||||
console.log(`Ranaze POS server listening on port ${config.port}`);
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Failed to connect to MongoDB", error);
|
||||
process.exit(1);
|
||||
});
|
||||
Reference in New Issue
Block a user