Add Node.js/Express backend with PostgreSQL and wire frontend to API

- Server: Express.js with 13 API route files (auth, regulations, contacts,
  calendar, truck stops, bridges, weigh stations, alerts, load board,
  escort locator, orders, documents, contributions)
- Database: PostgreSQL with Prisma ORM, 15 models covering all modules
- Auth: JWT + bcrypt with role-based access control (driver/carrier/escort/admin)
- Geospatial: Haversine distance filtering on truck stops, bridges, escorts
- Seed script: Imports all existing mock data (51 states, contacts, equipment,
  truck stops, bridges, weigh stations, alerts, seasonal restrictions)
- Frontend: All 10 data-driven pages now fetch from /api instead of mock-data.js
- API client (api.js): Compatibility layer that transforms API responses to
  match existing frontend rendering code, minimizing page-level changes

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Daniel Kovalevich
2026-03-30 15:43:27 -04:00
parent 260f7c4928
commit f917fb8014
35 changed files with 4964 additions and 193 deletions

View File

@@ -0,0 +1,34 @@
const express = require('express');
const prisma = require('../config/db');
const router = express.Router();
// GET /api/calendar — all seasonal restrictions
router.get('/', async (req, res, next) => {
try {
const restrictions = await prisma.seasonalRestriction.findMany({
include: { state: { select: { name: true, abbr: true } } },
orderBy: [{ startMonth: 'asc' }, { state: { name: 'asc' } }],
});
res.json(restrictions);
} catch (err) {
next(err);
}
});
// GET /api/calendar/:stateAbbr
router.get('/:stateAbbr', async (req, res, next) => {
try {
const abbr = req.params.stateAbbr.toUpperCase();
const state = await prisma.state.findUnique({
where: { abbr },
include: { seasonalRestrictions: true },
});
if (!state) return res.status(404).json({ error: `State '${abbr}' not found.` });
res.json(state.seasonalRestrictions);
} catch (err) {
next(err);
}
});
module.exports = router;