Dashboard Endpoints
Detailed API reference for the dashboard endpoints — aggregate statistics and trend analytics for system monitoring.
Dashboard Endpoints
Base path: /api/v1/dashboard
Authentication: Requires a valid JWT token.
GET /dashboard/stats
Returns aggregate system statistics used to populate the admin dashboard overview cards.
Access Control
- Allowed roles: Any authenticated user
Request
GET /api/v1/dashboard/stats
Authorization: Bearer <token>Response — 200 OK
{
"totalBooks": 1247,
"activeLoans": 89,
"totalUsers": 432,
"totalFines": 12,
"totalRevenue": 1540.00
}Metric Definitions
| Metric | Query | Description |
|---|---|---|
totalBooks | BookCopy.countDocuments() | Total number of physical book copies in the system (not unique titles) |
activeLoans | Transaction.countDocuments({ returnedAt: null }) | Number of currently checked-out books (unreturned transactions) |
totalUsers | User.countDocuments({ isActive: true }) | Number of active user accounts (excludes deactivated) |
totalFines | Fine.countDocuments({ status: 'UNPAID' }) | Number of outstanding unpaid fines |
totalRevenue | Fine.aggregate([{ $match: { status: 'PAID' } }, { $group: { _id: null, total: { $sum: '$amount' } } }]) | Total dollar amount collected from paid fines |
Performance Notes
Each metric executes a countDocuments() query independently. The totalRevenue metric uses a MongoDB aggregation pipeline. For high-traffic deployments, consider:
- Caching these values with a TTL (e.g., Redis)
- Using
Promise.all()to parallelize the queries - Adding MongoDB indexes on
returnedAt,isActive, andstatusfields
GET /dashboard/analytics
Returns time-series trend data for the last 6 months. Used to render charts on the dashboard.
Access Control
- Allowed roles: Any authenticated user
Request
GET /api/v1/dashboard/analytics
Authorization: Bearer <token>Response — 200 OK
{
"loansTrend": [
{ "month": "2026-02", "count": 45 },
{ "month": "2026-03", "count": 67 },
{ "month": "2026-04", "count": 52 },
{ "month": "2026-05", "count": 78 },
{ "month": "2026-06", "count": 61 },
{ "month": "2026-07", "count": 34 }
],
"revenueTrend": [
{ "month": "2026-02", "revenue": 120.00 },
{ "month": "2026-03", "revenue": 245.50 },
{ "month": "2026-04", "revenue": 180.00 },
{ "month": "2026-05", "revenue": 310.00 },
{ "month": "2026-06", "revenue": 195.00 },
{ "month": "2026-07", "revenue": 85.00 }
]
}Data Definitions
| Dataset | Aggregation | Description |
|---|---|---|
loansTrend | Groups Transaction.issuedAt by year/month for the last 6 months | Monthly count of new book checkouts |
revenueTrend | Groups Fine.updatedAt by year/month where status === 'PAID' | Monthly sum of paid fine amounts |
Aggregation Pipeline
Loans Over Time:
Transaction.aggregate([
{ $match: { issuedAt: { $gte: sixMonthsAgo } } },
{ $group: {
_id: { year: { $year: "$issuedAt" }, month: { $month: "$issuedAt" } },
count: { $sum: 1 }
}},
{ $sort: { "_id.year": 1, "_id.month": 1 } }
]);Revenue Over Time:
Fine.aggregate([
{ $match: { status: 'PAID', updatedAt: { $gte: sixMonthsAgo } } },
{ $group: {
_id: { year: { $year: "$updatedAt" }, month: { $month: "$updatedAt" } },
revenue: { $sum: "$amount" }
}},
{ $sort: { "_id.year": 1, "_id.month": 1 } }
]);Frontend Usage
The analytics data feeds into Recharts line/bar charts on the dashboard:
const res = await api.get('/dashboard/analytics');
const { loansTrend, revenueTrend } = res.data;Health Check (Non-API)
While not under the /api/v1/ prefix, the server also exposes a health check:
GET /health
GET /healthResponse — 200 OK
{
"status": "ok",
"message": "SLMS API is running"
}This endpoint requires no authentication and is intended for infrastructure monitoring (load balancers, uptime checks, CI/CD pipelines).
Route Summary
| Method | Path | Auth | Description |
|---|---|---|---|
GET | /dashboard/stats | ✅ | Aggregate stat cards |
GET | /dashboard/analytics | ✅ | 6-month trend data |
GET | /health | — | Server health check |