feat(charge-points): add pricing mode for charge points with validation

feat(pricing): implement tariff management with peak, valley, and flat pricing
feat(api): add tariff API for fetching and updating pricing configurations
feat(tariff-schema): create database schema for tariff configuration
feat(pricing-page): create UI for displaying and managing pricing tiers
fix(sidebar): update sidebar to include pricing settings link
This commit is contained in:
2026-03-12 17:23:06 +08:00
parent 2638af3f7f
commit f7ee298060
17 changed files with 2729 additions and 89 deletions

View File

@@ -69,6 +69,7 @@ app.post("/", async (c) => {
chargePointModel?: string;
registrationStatus?: "Accepted" | "Pending" | "Rejected";
feePerKwh?: number;
pricingMode?: "fixed" | "tou";
}>();
if (!body.chargePointIdentifier?.trim()) {
@@ -77,6 +78,9 @@ app.post("/", async (c) => {
if (body.feePerKwh !== undefined && (!Number.isInteger(body.feePerKwh) || body.feePerKwh < 0)) {
return c.json({ error: "feePerKwh must be a non-negative integer" }, 400);
}
if (body.pricingMode !== undefined && !['fixed', 'tou'].includes(body.pricingMode)) {
return c.json({ error: "pricingMode must be 'fixed' or 'tou'" }, 400);
}
const [created] = await db
.insert(chargePoint)
@@ -87,6 +91,7 @@ app.post("/", async (c) => {
chargePointModel: body.chargePointModel?.trim() || "Unknown",
registrationStatus: body.registrationStatus ?? "Pending",
feePerKwh: body.feePerKwh ?? 0,
pricingMode: body.pricingMode ?? "fixed",
})
.returning()
.catch((err: Error) => {
@@ -125,6 +130,7 @@ app.patch("/:id", async (c) => {
const id = c.req.param("id");
const body = await c.req.json<{
feePerKwh?: number;
pricingMode?: "fixed" | "tou";
registrationStatus?: string;
chargePointVendor?: string;
chargePointModel?: string;
@@ -132,6 +138,7 @@ app.patch("/:id", async (c) => {
const set: {
feePerKwh?: number;
pricingMode?: "fixed" | "tou";
registrationStatus?: "Accepted" | "Pending" | "Rejected";
chargePointVendor?: string;
chargePointModel?: string;
@@ -152,6 +159,12 @@ app.patch("/:id", async (c) => {
}
if (body.chargePointVendor !== undefined) set.chargePointVendor = body.chargePointVendor.trim() || "Unknown";
if (body.chargePointModel !== undefined) set.chargePointModel = body.chargePointModel.trim() || "Unknown";
if (body.pricingMode !== undefined) {
if (!['fixed', 'tou'].includes(body.pricingMode)) {
return c.json({ error: "pricingMode must be 'fixed' or 'tou'" }, 400);
}
set.pricingMode = body.pricingMode;
}
const [updated] = await db
.update(chargePoint)