Files
ridebus-admin/backend/src/routes/api.js
Zakhar Timoshenko d13cc92d82 feat: implement multi-city support with city management features
- Added a new cities table to the database to manage multiple cities independently.
- Created a middleware to resolve city context based on X-City-Id header.
- Updated routes and services to handle city-specific data for routes, stops, and alerts.
- Implemented a CityContext in the frontend to manage active city state and provide city data across the application.
- Added a CitySelector component for users to switch between cities.
- Created a CitiesPage for admins to manage cities, including adding new cities with validation.
- Updated various components and pages to reflect the active city context, ensuring data is displayed correctly based on the selected city.
- Enhanced the schedule import functionality to restrict imports based on the active city.
2026-09-17 19:41:17 +03:00

97 lines
5.5 KiB
JavaScript

const express = require('express');
const router = express.Router();
// Controllers
const routesController = require('../controllers/routesController');
const stopsController = require('../controllers/stopsController');
const routeStopsController = require('../controllers/routeStopsController');
const schedulesController = require('../controllers/schedulesController');
const holidaysController = require('../controllers/holidaysController');
const etaController = require('../controllers/etaController');
const syncController = require('../controllers/syncController');
const telemetryController = require('../controllers/telemetryController');
const passengerTelemetryController = require('../controllers/passengerTelemetryController');
const { createPassengerTelemetryRateLimiter } = require('../middleware/passengerTelemetryRateLimiter');
const { authenticateToken, requireAdmin } = require('../middleware/auth');
const { resolveCity } = require('../middleware/city');
const qualityController = require('../controllers/qualityController');
// City catalogue is global. Every transport-data endpoint below receives a
// verified city context from X-City-Id (or falls back to the legacy Polotsk city).
router.use('/cities', require('./cities'));
router.use(resolveCity);
router.use('/schedule-import', require('./scheduleImport'));
router.get('/quality', authenticateToken, requireAdmin, qualityController.getReport.bind(qualityController));
// Routes
router.get('/routes', routesController.getAllRoutes.bind(routesController));
router.get('/routes/:id', routesController.getRouteById.bind(routesController));
router.post('/routes', routesController.createRoute.bind(routesController));
router.put('/routes/:id', routesController.updateRoute.bind(routesController));
router.delete('/routes/:id', routesController.deleteRoute.bind(routesController));
// Route Stops (привязка остановок к маршрутам)
router.get('/routes/:routeId/stops', routeStopsController.getRouteStops.bind(routeStopsController));
router.get('/routes/:routeId/available-stops', routeStopsController.getAvailableStops.bind(routeStopsController));
router.post('/routes/:routeId/stops', routeStopsController.addStopToRoute.bind(routeStopsController));
router.put('/routes/:routeId/stops/:routeStopId', routeStopsController.updateRouteStop.bind(routeStopsController));
router.delete('/routes/:routeId/stops/:routeStopId', routeStopsController.removeStopFromRoute.bind(routeStopsController));
router.put('/routes/:routeId/stops-reorder', routeStopsController.reorderRouteStops.bind(routeStopsController));
// Route Schedules (расписания маршрутов)
router.get('/routes/:routeId/schedules', schedulesController.getRouteSchedules.bind(schedulesController));
router.get('/routes/:routeId/schedule/today', schedulesController.getTodaySchedule.bind(schedulesController));
router.post('/routes/:routeId/schedules/copy', schedulesController.copySchedule.bind(schedulesController));
// Schedules (общие)
router.get('/schedules/:id', schedulesController.getScheduleById.bind(schedulesController));
router.post('/schedules', schedulesController.createSchedule.bind(schedulesController));
router.put('/schedules/:id', schedulesController.updateSchedule.bind(schedulesController));
router.delete('/schedules/:id', schedulesController.deleteSchedule.bind(schedulesController));
// Holidays (праздничные дни)
router.get('/holidays', holidaysController.getAllHolidays.bind(holidaysController));
router.get('/holidays/upcoming', holidaysController.getUpcomingHolidays.bind(holidaysController));
router.get('/holidays/year/:year', holidaysController.getHolidaysForYear.bind(holidaysController));
router.get('/holidays/check/:date', holidaysController.checkHoliday.bind(holidaysController));
router.post('/holidays', holidaysController.createHoliday.bind(holidaysController));
router.put('/holidays/:id', holidaysController.updateHoliday.bind(holidaysController));
router.delete('/holidays/:id', holidaysController.deleteHoliday.bind(holidaysController));
// Stops
router.get('/stops', stopsController.getAllStops.bind(stopsController));
router.get('/stops/nearby', stopsController.getNearbyStops.bind(stopsController));
router.get('/stops/:id', stopsController.getStopById.bind(stopsController));
router.post('/stops', stopsController.createStop.bind(stopsController));
router.put('/stops/:id', stopsController.updateStop.bind(stopsController));
router.delete('/stops/:id', stopsController.deleteStop.bind(stopsController));
// ETA
router.post('/eta/calculate', etaController.calculateEta.bind(etaController));
router.get('/eta/stop/:stopId', etaController.getStopEtas.bind(etaController));
// Realtime GPS / Telemetry
router.post('/telemetry/ingest', telemetryController.ingest.bind(telemetryController));
router.post(
'/passenger-telemetry/ingest',
createPassengerTelemetryRateLimiter(),
passengerTelemetryController.ingest.bind(passengerTelemetryController)
);
router.get('/realtime/routes/:routeId/vehicles', telemetryController.getRouteLiveVehicles.bind(telemetryController));
router.get('/realtime/vehicles/:vehicleId', telemetryController.getVehicleLiveState.bind(telemetryController));
// Sync
router.get('/sync', syncController.sync.bind(syncController));
router.get('/sync/status', syncController.getSyncStatus.bind(syncController));
// Alerts
const alertsRouter = require('./alerts');
router.use('/alerts', alertsRouter);
// Users management (requires JWT auth, handled in routes/users.js)
const usersRouter = require('./users');
router.use('/users', usersRouter);
module.exports = router;