chore: upload parte 1 - logica
DevSecOps Enterprise Pipeline / security-gate-and-deploy (push) Failing after 41s

This commit is contained in:
2026-06-01 15:35:53 +01:00
parent a63625d228
commit 9c14a19a87
127 changed files with 22255 additions and 0 deletions
+89
View File
@@ -0,0 +1,89 @@
import { NextRequest, NextResponse } from "next/server";
import { getDb } from "@/lib/db";
export async function GET(
_request: NextRequest,
{ params }: { params: Promise<{ id: string }> }
) {
try {
const sql = getDb();
const { id } = await params;
const rows = await sql(`SELECT * FROM customers WHERE id = $1`, [Number(id)]);
if (rows.length === 0) {
return NextResponse.json({ error: "Customer not found" }, { status: 404 });
}
return NextResponse.json(rows[0]);
} catch (error) {
console.error("[v0] Customer GET error:", error);
return NextResponse.json(
{ error: error instanceof Error ? error.message : "Failed to fetch customer" },
{ status: 500 }
);
}
}
export async function PUT(
request: NextRequest,
{ params }: { params: Promise<{ id: string }> }
) {
try {
const sql = getDb();
const { id } = await params;
const body = await request.json();
const { name, code, email, phone, address, contact_person, notes } = body;
const rows = await sql(
`UPDATE customers SET
name = $1, code = $2, email = $3, phone = $4,
address = $5, contact_person = $6, notes = $7, updated_at = NOW()
WHERE id = $8
RETURNING *`,
[name, code, email || null, phone || null, address || null, contact_person || null, notes || null, Number(id)]
);
if (rows.length === 0) {
return NextResponse.json({ error: "Customer not found" }, { status: 404 });
}
return NextResponse.json(rows[0]);
} catch (error) {
console.error("[v0] Customer PUT error:", error);
return NextResponse.json(
{ error: error instanceof Error ? error.message : "Failed to update customer" },
{ status: 500 }
);
}
}
export async function DELETE(
_request: NextRequest,
{ params }: { params: Promise<{ id: string }> }
) {
try {
const sql = getDb();
const { id } = await params;
const orderCheck = await sql(
`SELECT COUNT(*) as count FROM purchase_orders WHERE customer_id = $1`,
[Number(id)]
);
if (Number(orderCheck[0].count) > 0) {
return NextResponse.json(
{ error: "Cannot delete customer with existing orders. Delete orders first." },
{ status: 400 }
);
}
await sql(`DELETE FROM customers WHERE id = $1`, [Number(id)]);
return NextResponse.json({ success: true });
} catch (error) {
console.error("[v0] Customer DELETE error:", error);
return NextResponse.json(
{ error: error instanceof Error ? error.message : "Failed to delete customer" },
{ status: 500 }
);
}
}
+84
View File
@@ -0,0 +1,84 @@
import { NextRequest, NextResponse } from "next/server";
import { getDb } from "@/lib/db";
export async function GET(
request: NextRequest,
{ params }: { params: Promise<{ id: string }> }
) {
try {
const sql = getDb();
const { id } = await params;
const { searchParams } = new URL(request.url);
const period = searchParams.get("period") || "month"; // week | month | year
// --- On Order by product (not completed/cancelled) ---
const onOrder = await sql(
`SELECT p.id AS product_id, p.name AS product_name, p.sku,
SUM(poi.quantity) AS total_ordered,
SUM(COALESCE(poi.shipped_quantity, 0)) AS total_shipped,
SUM(poi.quantity - COALESCE(poi.shipped_quantity, 0)) AS on_order
FROM purchase_order_items poi
JOIN purchase_orders po ON po.id = poi.purchase_order_id
JOIN products p ON p.id = poi.product_id
WHERE po.customer_id = $1
AND po.status NOT IN ('completed', 'cancelled')
AND poi.quantity > COALESCE(poi.shipped_quantity, 0)
GROUP BY p.id, p.name, p.sku
ORDER BY on_order DESC`,
[Number(id)]
);
// --- Produced/shipped by product over time ---
let dateFilter = "";
if (period === "week") {
dateFilter = "AND pl.created_at >= NOW() - INTERVAL '7 days'";
} else if (period === "month") {
dateFilter = "AND pl.created_at >= NOW() - INTERVAL '30 days'";
} else if (period === "year") {
dateFilter = "AND pl.created_at >= NOW() - INTERVAL '365 days'";
}
// Aggregate shipped quantities by product (from packing lists)
const produced = await sql(
`SELECT p.id AS product_id, p.name AS product_name, p.sku,
SUM(pl.quantity) AS total_produced
FROM packing_lists pl
JOIN purchase_orders po ON po.id = pl.purchase_order_id
JOIN purchase_order_items poi ON poi.id = pl.po_item_id
JOIN products p ON p.id = poi.product_id
WHERE po.customer_id = $1
${dateFilter}
GROUP BY p.id, p.name, p.sku
ORDER BY total_produced DESC`,
[Number(id)]
);
// Produced over time bucketed by date for chart
let dateTrunc = "day";
if (period === "year") dateTrunc = "month";
const producedTimeline = await sql(
`SELECT DATE_TRUNC('${dateTrunc}', pl.created_at) AS bucket,
p.name AS product_name,
p.sku,
SUM(pl.quantity) AS quantity
FROM packing_lists pl
JOIN purchase_orders po ON po.id = pl.purchase_order_id
JOIN purchase_order_items poi ON poi.id = pl.po_item_id
JOIN products p ON p.id = poi.product_id
WHERE po.customer_id = $1
${dateFilter}
GROUP BY bucket, p.id, p.name, p.sku
ORDER BY bucket ASC`,
[Number(id)]
);
return NextResponse.json({ onOrder, produced, producedTimeline });
} catch (error) {
console.error("[v0] Customer stats GET error:", error);
return NextResponse.json(
{ error: error instanceof Error ? error.message : "Failed to fetch customer stats" },
{ status: 500 }
);
}
}