feat(stats): enhance admin and user statistics with additional metrics for revenue and user count
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { Hono } from "hono";
|
||||
import { eq, isNull, sql } from "drizzle-orm";
|
||||
import { useDrizzle } from "@/lib/db.js";
|
||||
import { chargePoint, transaction, idTag } from "@/db/schema.js";
|
||||
import { chargePoint, transaction, idTag, user } from "@/db/schema.js";
|
||||
import type { HonoEnv } from "@/types/hono.ts";
|
||||
|
||||
const app = new Hono<HonoEnv>();
|
||||
@@ -12,25 +12,42 @@ app.get("/", async (c) => {
|
||||
const isAdmin = currentUser?.role === "admin";
|
||||
|
||||
if (isAdmin) {
|
||||
const [totalChargePoints, onlineChargePoints, activeTransactions, totalIdTags, todayEnergy] =
|
||||
await Promise.all([
|
||||
db.select({ count: sql<number>`count(*)::int` }).from(chargePoint),
|
||||
db
|
||||
.select({ count: sql<number>`count(*)::int` })
|
||||
.from(chargePoint)
|
||||
.where(sql`${chargePoint.lastHeartbeatAt} > now() - interval '120 seconds'`),
|
||||
db
|
||||
.select({ count: sql<number>`count(*)::int` })
|
||||
.from(transaction)
|
||||
.where(isNull(transaction.stopTimestamp)),
|
||||
db.select({ count: sql<number>`count(*)::int` }).from(idTag),
|
||||
db
|
||||
.select({
|
||||
total: sql<number>`coalesce(sum(${transaction.stopMeterValue} - ${transaction.startMeterValue}), 0)::int`,
|
||||
})
|
||||
.from(transaction)
|
||||
.where(sql`${transaction.stopTimestamp} >= date_trunc('day', now())`),
|
||||
]);
|
||||
const [
|
||||
totalChargePoints,
|
||||
onlineChargePoints,
|
||||
activeTransactions,
|
||||
totalIdTags,
|
||||
todayEnergy,
|
||||
todayRevenue,
|
||||
totalUsers,
|
||||
todayTransactions,
|
||||
] = await Promise.all([
|
||||
db.select({ count: sql<number>`count(*)::int` }).from(chargePoint),
|
||||
db
|
||||
.select({ count: sql<number>`count(*)::int` })
|
||||
.from(chargePoint)
|
||||
.where(sql`${chargePoint.lastHeartbeatAt} > now() - interval '120 seconds'`),
|
||||
db
|
||||
.select({ count: sql<number>`count(*)::int` })
|
||||
.from(transaction)
|
||||
.where(isNull(transaction.stopTimestamp)),
|
||||
db.select({ count: sql<number>`count(*)::int` }).from(idTag),
|
||||
db
|
||||
.select({
|
||||
total: sql<number>`coalesce(sum(${transaction.stopMeterValue} - ${transaction.startMeterValue}), 0)::int`,
|
||||
})
|
||||
.from(transaction)
|
||||
.where(sql`${transaction.stopTimestamp} >= date_trunc('day', now())`),
|
||||
db
|
||||
.select({ total: sql<number>`coalesce(sum(${transaction.chargeAmount}), 0)::int` })
|
||||
.from(transaction)
|
||||
.where(sql`${transaction.stopTimestamp} >= date_trunc('day', now())`),
|
||||
db.select({ count: sql<number>`count(*)::int` }).from(user),
|
||||
db
|
||||
.select({ count: sql<number>`count(*)::int` })
|
||||
.from(transaction)
|
||||
.where(sql`${transaction.stopTimestamp} >= date_trunc('day', now())`),
|
||||
]);
|
||||
|
||||
return c.json({
|
||||
totalChargePoints: totalChargePoints[0].count,
|
||||
@@ -38,6 +55,9 @@ app.get("/", async (c) => {
|
||||
activeTransactions: activeTransactions[0].count,
|
||||
totalIdTags: totalIdTags[0].count,
|
||||
todayEnergyWh: todayEnergy[0].total,
|
||||
todayRevenue: todayRevenue[0].total,
|
||||
totalUsers: totalUsers[0].count,
|
||||
todayTransactions: todayTransactions[0].count,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -46,7 +66,7 @@ app.get("/", async (c) => {
|
||||
|
||||
const userId = currentUser.id;
|
||||
|
||||
const [userIdTags, totalBalance, activeCount, totalTxCount] = await Promise.all([
|
||||
const [userIdTags, totalBalance, activeCount, totalTxCount, todayEnergy, todayTxCount] = await Promise.all([
|
||||
// Cards belonging to this user
|
||||
db
|
||||
.select({ count: sql<number>`count(*)::int` })
|
||||
@@ -69,6 +89,24 @@ app.get("/", async (c) => {
|
||||
.from(transaction)
|
||||
.innerJoin(idTag, eq(transaction.idTag, idTag.idTag))
|
||||
.where(eq(idTag.userId, userId)),
|
||||
// Today's energy for user's cards
|
||||
db
|
||||
.select({
|
||||
total: sql<number>`coalesce(sum(${transaction.stopMeterValue} - ${transaction.startMeterValue}), 0)::int`,
|
||||
})
|
||||
.from(transaction)
|
||||
.innerJoin(idTag, eq(transaction.idTag, idTag.idTag))
|
||||
.where(
|
||||
sql`${transaction.stopTimestamp} >= date_trunc('day', now()) and ${idTag.userId} = ${userId}`,
|
||||
),
|
||||
// Today's completed transactions for user's cards
|
||||
db
|
||||
.select({ count: sql<number>`count(*)::int` })
|
||||
.from(transaction)
|
||||
.innerJoin(idTag, eq(transaction.idTag, idTag.idTag))
|
||||
.where(
|
||||
sql`${transaction.stopTimestamp} >= date_trunc('day', now()) and ${idTag.userId} = ${userId}`,
|
||||
),
|
||||
]);
|
||||
|
||||
return c.json({
|
||||
@@ -76,6 +114,8 @@ app.get("/", async (c) => {
|
||||
totalBalance: totalBalance[0].total,
|
||||
activeTransactions: activeCount[0].count,
|
||||
totalTransactions: totalTxCount[0].count,
|
||||
todayEnergyWh: todayEnergy[0].total,
|
||||
todayTransactions: todayTxCount[0].count,
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user