First template code generated from replit.com
This commit is contained in:
258
server/routes.ts
Normal file
258
server/routes.ts
Normal file
@@ -0,0 +1,258 @@
|
||||
import type { Express } from "express";
|
||||
import { createServer, type Server } from "http";
|
||||
import { storage } from "./storage";
|
||||
import { insertProductSchema, insertStockMovementSchema, insertDocumentSchema } from "@shared/schema";
|
||||
import { z } from "zod";
|
||||
|
||||
export async function registerRoutes(app: Express): Promise<Server> {
|
||||
// Products
|
||||
app.get("/api/products", async (req, res) => {
|
||||
try {
|
||||
const products = await storage.getProducts();
|
||||
res.json(products);
|
||||
} catch (error) {
|
||||
res.status(500).json({ message: "Failed to fetch products" });
|
||||
}
|
||||
});
|
||||
|
||||
app.get("/api/products/search", async (req, res) => {
|
||||
try {
|
||||
const query = req.query.q as string;
|
||||
if (!query) {
|
||||
return res.status(400).json({ message: "Search query is required" });
|
||||
}
|
||||
const products = await storage.searchProducts(query);
|
||||
res.json(products);
|
||||
} catch (error) {
|
||||
res.status(500).json({ message: "Failed to search products" });
|
||||
}
|
||||
});
|
||||
|
||||
app.get("/api/products/low-stock", async (req, res) => {
|
||||
try {
|
||||
const products = await storage.getLowStockProducts();
|
||||
res.json(products);
|
||||
} catch (error) {
|
||||
res.status(500).json({ message: "Failed to fetch low stock products" });
|
||||
}
|
||||
});
|
||||
|
||||
app.get("/api/products/out-of-stock", async (req, res) => {
|
||||
try {
|
||||
const products = await storage.getOutOfStockProducts();
|
||||
res.json(products);
|
||||
} catch (error) {
|
||||
res.status(500).json({ message: "Failed to fetch out of stock products" });
|
||||
}
|
||||
});
|
||||
|
||||
app.get("/api/products/:id", async (req, res) => {
|
||||
try {
|
||||
const product = await storage.getProduct(req.params.id);
|
||||
if (!product) {
|
||||
return res.status(404).json({ message: "Product not found" });
|
||||
}
|
||||
res.json(product);
|
||||
} catch (error) {
|
||||
res.status(500).json({ message: "Failed to fetch product" });
|
||||
}
|
||||
});
|
||||
|
||||
app.post("/api/products", async (req, res) => {
|
||||
try {
|
||||
const productData = insertProductSchema.parse(req.body);
|
||||
const product = await storage.createProduct(productData);
|
||||
res.status(201).json(product);
|
||||
} catch (error) {
|
||||
if (error instanceof z.ZodError) {
|
||||
return res.status(400).json({ message: "Invalid product data", errors: error.errors });
|
||||
}
|
||||
res.status(500).json({ message: "Failed to create product" });
|
||||
}
|
||||
});
|
||||
|
||||
app.patch("/api/products/:id", async (req, res) => {
|
||||
try {
|
||||
const updates = insertProductSchema.partial().parse(req.body);
|
||||
const product = await storage.updateProduct(req.params.id, updates);
|
||||
if (!product) {
|
||||
return res.status(404).json({ message: "Product not found" });
|
||||
}
|
||||
res.json(product);
|
||||
} catch (error) {
|
||||
if (error instanceof z.ZodError) {
|
||||
return res.status(400).json({ message: "Invalid product data", errors: error.errors });
|
||||
}
|
||||
res.status(500).json({ message: "Failed to update product" });
|
||||
}
|
||||
});
|
||||
|
||||
app.delete("/api/products/:id", async (req, res) => {
|
||||
try {
|
||||
const deleted = await storage.deleteProduct(req.params.id);
|
||||
if (!deleted) {
|
||||
return res.status(404).json({ message: "Product not found" });
|
||||
}
|
||||
res.status(204).send();
|
||||
} catch (error) {
|
||||
res.status(500).json({ message: "Failed to delete product" });
|
||||
}
|
||||
});
|
||||
|
||||
// Stock movements
|
||||
app.get("/api/stock-movements", async (req, res) => {
|
||||
try {
|
||||
const productId = req.query.productId as string;
|
||||
const movements = await storage.getStockMovements(productId);
|
||||
res.json(movements);
|
||||
} catch (error) {
|
||||
res.status(500).json({ message: "Failed to fetch stock movements" });
|
||||
}
|
||||
});
|
||||
|
||||
app.post("/api/stock-movements", async (req, res) => {
|
||||
try {
|
||||
const movementData = insertStockMovementSchema.parse(req.body);
|
||||
const movement = await storage.createStockMovement(movementData);
|
||||
res.status(201).json(movement);
|
||||
} catch (error) {
|
||||
if (error instanceof z.ZodError) {
|
||||
return res.status(400).json({ message: "Invalid stock movement data", errors: error.errors });
|
||||
}
|
||||
res.status(500).json({ message: "Failed to create stock movement" });
|
||||
}
|
||||
});
|
||||
|
||||
// Documents
|
||||
app.get("/api/documents", async (req, res) => {
|
||||
try {
|
||||
const documents = await storage.getDocuments();
|
||||
res.json(documents);
|
||||
} catch (error) {
|
||||
res.status(500).json({ message: "Failed to fetch documents" });
|
||||
}
|
||||
});
|
||||
|
||||
app.get("/api/documents/:id", async (req, res) => {
|
||||
try {
|
||||
const document = await storage.getDocument(req.params.id);
|
||||
if (!document) {
|
||||
return res.status(404).json({ message: "Document not found" });
|
||||
}
|
||||
res.json(document);
|
||||
} catch (error) {
|
||||
res.status(500).json({ message: "Failed to fetch document" });
|
||||
}
|
||||
});
|
||||
|
||||
app.post("/api/documents", async (req, res) => {
|
||||
try {
|
||||
const documentData = insertDocumentSchema.parse(req.body);
|
||||
const document = await storage.createDocument(documentData);
|
||||
res.status(201).json(document);
|
||||
} catch (error) {
|
||||
if (error instanceof z.ZodError) {
|
||||
return res.status(400).json({ message: "Invalid document data", errors: error.errors });
|
||||
}
|
||||
res.status(500).json({ message: "Failed to create document" });
|
||||
}
|
||||
});
|
||||
|
||||
app.patch("/api/documents/:id", async (req, res) => {
|
||||
try {
|
||||
const updates = insertDocumentSchema.partial().parse(req.body);
|
||||
const document = await storage.updateDocument(req.params.id, updates);
|
||||
if (!document) {
|
||||
return res.status(404).json({ message: "Document not found" });
|
||||
}
|
||||
res.json(document);
|
||||
} catch (error) {
|
||||
if (error instanceof z.ZodError) {
|
||||
return res.status(400).json({ message: "Invalid document data", errors: error.errors });
|
||||
}
|
||||
res.status(500).json({ message: "Failed to update document" });
|
||||
}
|
||||
});
|
||||
|
||||
// Generate PDF document
|
||||
app.get("/api/documents/:id/pdf", async (req, res) => {
|
||||
try {
|
||||
const document = await storage.getDocument(req.params.id);
|
||||
if (!document) {
|
||||
return res.status(404).json({ message: "Document not found" });
|
||||
}
|
||||
|
||||
// Simple PDF generation for now - in production would use proper PDF library
|
||||
const pdfContent = `
|
||||
Document: ${document.title}
|
||||
Type: ${document.type}
|
||||
Number: ${document.documentNumber}
|
||||
Status: ${document.status}
|
||||
Created: ${document.createdAt}
|
||||
|
||||
Content:
|
||||
${JSON.stringify(document.content, null, 2)}
|
||||
`;
|
||||
|
||||
res.setHeader('Content-Type', 'application/pdf');
|
||||
res.setHeader('Content-Disposition', `attachment; filename="${document.documentNumber}.pdf"`);
|
||||
res.send(pdfContent);
|
||||
} catch (error) {
|
||||
res.status(500).json({ message: "Failed to generate PDF" });
|
||||
}
|
||||
});
|
||||
|
||||
// Notifications
|
||||
app.get("/api/notifications", async (req, res) => {
|
||||
try {
|
||||
const notifications = await storage.getNotifications();
|
||||
res.json(notifications);
|
||||
} catch (error) {
|
||||
res.status(500).json({ message: "Failed to fetch notifications" });
|
||||
}
|
||||
});
|
||||
|
||||
app.get("/api/notifications/unread-count", async (req, res) => {
|
||||
try {
|
||||
const count = await storage.getUnreadNotificationCount();
|
||||
res.json({ count });
|
||||
} catch (error) {
|
||||
res.status(500).json({ message: "Failed to fetch notification count" });
|
||||
}
|
||||
});
|
||||
|
||||
app.patch("/api/notifications/:id/read", async (req, res) => {
|
||||
try {
|
||||
const success = await storage.markNotificationAsRead(req.params.id);
|
||||
if (!success) {
|
||||
return res.status(404).json({ message: "Notification not found" });
|
||||
}
|
||||
res.status(204).send();
|
||||
} catch (error) {
|
||||
res.status(500).json({ message: "Failed to mark notification as read" });
|
||||
}
|
||||
});
|
||||
|
||||
// Dashboard stats
|
||||
app.get("/api/dashboard/stats", async (req, res) => {
|
||||
try {
|
||||
const products = await storage.getProducts();
|
||||
const lowStockProducts = await storage.getLowStockProducts();
|
||||
const outOfStockProducts = await storage.getOutOfStockProducts();
|
||||
|
||||
const stats = {
|
||||
totalItems: products.length,
|
||||
inStockItems: products.filter(p => p.currentStock > p.minThreshold).length,
|
||||
lowStockItems: lowStockProducts.length,
|
||||
outOfStockItems: outOfStockProducts.length,
|
||||
};
|
||||
|
||||
res.json(stats);
|
||||
} catch (error) {
|
||||
res.status(500).json({ message: "Failed to fetch dashboard stats" });
|
||||
}
|
||||
});
|
||||
|
||||
const httpServer = createServer(app);
|
||||
return httpServer;
|
||||
}
|
||||
Reference in New Issue
Block a user