Admin User v1
This commit is contained in:
222
backend/src/features/admin/api/admin.routes.ts
Normal file
222
backend/src/features/admin/api/admin.routes.ts
Normal file
@@ -0,0 +1,222 @@
|
||||
/**
|
||||
* @ai-summary Admin feature routes
|
||||
* @ai-context Registers admin API endpoints with proper guards
|
||||
*/
|
||||
|
||||
import { FastifyPluginAsync } from 'fastify';
|
||||
import { AdminController } from './admin.controller';
|
||||
import {
|
||||
CreateAdminInput,
|
||||
AdminAuth0SubInput,
|
||||
AuditLogsQueryInput
|
||||
} from './admin.validation';
|
||||
import { AdminRepository } from '../data/admin.repository';
|
||||
import { StationOversightService } from '../domain/station-oversight.service';
|
||||
import { StationsController } from './stations.controller';
|
||||
import { CatalogController } from './catalog.controller';
|
||||
import { VehicleCatalogService } from '../domain/vehicle-catalog.service';
|
||||
import { PlatformCacheService } from '../../platform/domain/platform-cache.service';
|
||||
import { cacheService } from '../../../core/config/redis';
|
||||
import { pool } from '../../../core/config/database';
|
||||
|
||||
export const adminRoutes: FastifyPluginAsync = async (fastify) => {
|
||||
const adminController = new AdminController();
|
||||
|
||||
// Initialize station oversight dependencies
|
||||
const adminRepository = new AdminRepository(pool);
|
||||
const stationOversightService = new StationOversightService(pool, adminRepository);
|
||||
const stationsController = new StationsController(stationOversightService);
|
||||
|
||||
// Initialize catalog dependencies
|
||||
const platformCacheService = new PlatformCacheService(cacheService);
|
||||
const catalogService = new VehicleCatalogService(pool, platformCacheService);
|
||||
const catalogController = new CatalogController(catalogService);
|
||||
|
||||
// Admin access verification (used by frontend auth checks)
|
||||
fastify.get('/admin/verify', {
|
||||
preHandler: [fastify.authenticate] // Requires JWT, does NOT require admin role
|
||||
}, adminController.verifyAccess.bind(adminController));
|
||||
|
||||
// Phase 2: Admin management endpoints
|
||||
|
||||
// GET /api/admin/admins - List all admin users
|
||||
fastify.get('/admin/admins', {
|
||||
preHandler: [fastify.requireAdmin],
|
||||
handler: adminController.listAdmins.bind(adminController)
|
||||
});
|
||||
|
||||
// POST /api/admin/admins - Create new admin
|
||||
fastify.post<{ Body: CreateAdminInput }>('/admin/admins', {
|
||||
preHandler: [fastify.requireAdmin],
|
||||
handler: adminController.createAdmin.bind(adminController)
|
||||
});
|
||||
|
||||
// PATCH /api/admin/admins/:auth0Sub/revoke - Revoke admin access
|
||||
fastify.patch<{ Params: AdminAuth0SubInput }>('/admin/admins/:auth0Sub/revoke', {
|
||||
preHandler: [fastify.requireAdmin],
|
||||
handler: adminController.revokeAdmin.bind(adminController)
|
||||
});
|
||||
|
||||
// PATCH /api/admin/admins/:auth0Sub/reinstate - Restore revoked admin
|
||||
fastify.patch<{ Params: AdminAuth0SubInput }>('/admin/admins/:auth0Sub/reinstate', {
|
||||
preHandler: [fastify.requireAdmin],
|
||||
handler: adminController.reinstateAdmin.bind(adminController)
|
||||
});
|
||||
|
||||
// GET /api/admin/audit-logs - Fetch audit trail
|
||||
fastify.get<{ Querystring: AuditLogsQueryInput }>('/admin/audit-logs', {
|
||||
preHandler: [fastify.requireAdmin],
|
||||
handler: adminController.getAuditLogs.bind(adminController)
|
||||
});
|
||||
|
||||
// Phase 3: Catalog CRUD endpoints
|
||||
|
||||
// Makes endpoints
|
||||
fastify.get('/admin/catalog/makes', {
|
||||
preHandler: [fastify.requireAdmin],
|
||||
handler: catalogController.getMakes.bind(catalogController)
|
||||
});
|
||||
|
||||
fastify.post('/admin/catalog/makes', {
|
||||
preHandler: [fastify.requireAdmin],
|
||||
handler: catalogController.createMake.bind(catalogController)
|
||||
});
|
||||
|
||||
fastify.put('/admin/catalog/makes/:makeId', {
|
||||
preHandler: [fastify.requireAdmin],
|
||||
handler: catalogController.updateMake.bind(catalogController)
|
||||
});
|
||||
|
||||
fastify.delete('/admin/catalog/makes/:makeId', {
|
||||
preHandler: [fastify.requireAdmin],
|
||||
handler: catalogController.deleteMake.bind(catalogController)
|
||||
});
|
||||
|
||||
// Models endpoints
|
||||
fastify.get('/admin/catalog/makes/:makeId/models', {
|
||||
preHandler: [fastify.requireAdmin],
|
||||
handler: catalogController.getModels.bind(catalogController)
|
||||
});
|
||||
|
||||
fastify.post('/admin/catalog/models', {
|
||||
preHandler: [fastify.requireAdmin],
|
||||
handler: catalogController.createModel.bind(catalogController)
|
||||
});
|
||||
|
||||
fastify.put('/admin/catalog/models/:modelId', {
|
||||
preHandler: [fastify.requireAdmin],
|
||||
handler: catalogController.updateModel.bind(catalogController)
|
||||
});
|
||||
|
||||
fastify.delete('/admin/catalog/models/:modelId', {
|
||||
preHandler: [fastify.requireAdmin],
|
||||
handler: catalogController.deleteModel.bind(catalogController)
|
||||
});
|
||||
|
||||
// Years endpoints
|
||||
fastify.get('/admin/catalog/models/:modelId/years', {
|
||||
preHandler: [fastify.requireAdmin],
|
||||
handler: catalogController.getYears.bind(catalogController)
|
||||
});
|
||||
|
||||
fastify.post('/admin/catalog/years', {
|
||||
preHandler: [fastify.requireAdmin],
|
||||
handler: catalogController.createYear.bind(catalogController)
|
||||
});
|
||||
|
||||
fastify.put('/admin/catalog/years/:yearId', {
|
||||
preHandler: [fastify.requireAdmin],
|
||||
handler: catalogController.updateYear.bind(catalogController)
|
||||
});
|
||||
|
||||
fastify.delete('/admin/catalog/years/:yearId', {
|
||||
preHandler: [fastify.requireAdmin],
|
||||
handler: catalogController.deleteYear.bind(catalogController)
|
||||
});
|
||||
|
||||
// Trims endpoints
|
||||
fastify.get('/admin/catalog/years/:yearId/trims', {
|
||||
preHandler: [fastify.requireAdmin],
|
||||
handler: catalogController.getTrims.bind(catalogController)
|
||||
});
|
||||
|
||||
fastify.post('/admin/catalog/trims', {
|
||||
preHandler: [fastify.requireAdmin],
|
||||
handler: catalogController.createTrim.bind(catalogController)
|
||||
});
|
||||
|
||||
fastify.put('/admin/catalog/trims/:trimId', {
|
||||
preHandler: [fastify.requireAdmin],
|
||||
handler: catalogController.updateTrim.bind(catalogController)
|
||||
});
|
||||
|
||||
fastify.delete('/admin/catalog/trims/:trimId', {
|
||||
preHandler: [fastify.requireAdmin],
|
||||
handler: catalogController.deleteTrim.bind(catalogController)
|
||||
});
|
||||
|
||||
// Engines endpoints
|
||||
fastify.get('/admin/catalog/trims/:trimId/engines', {
|
||||
preHandler: [fastify.requireAdmin],
|
||||
handler: catalogController.getEngines.bind(catalogController)
|
||||
});
|
||||
|
||||
fastify.post('/admin/catalog/engines', {
|
||||
preHandler: [fastify.requireAdmin],
|
||||
handler: catalogController.createEngine.bind(catalogController)
|
||||
});
|
||||
|
||||
fastify.put('/admin/catalog/engines/:engineId', {
|
||||
preHandler: [fastify.requireAdmin],
|
||||
handler: catalogController.updateEngine.bind(catalogController)
|
||||
});
|
||||
|
||||
fastify.delete('/admin/catalog/engines/:engineId', {
|
||||
preHandler: [fastify.requireAdmin],
|
||||
handler: catalogController.deleteEngine.bind(catalogController)
|
||||
});
|
||||
|
||||
// Change logs endpoint
|
||||
fastify.get('/admin/catalog/change-logs', {
|
||||
preHandler: [fastify.requireAdmin],
|
||||
handler: catalogController.getChangeLogs.bind(catalogController)
|
||||
});
|
||||
|
||||
// Phase 4: Station oversight endpoints
|
||||
|
||||
// GET /api/admin/stations - List all stations globally
|
||||
fastify.get('/admin/stations', {
|
||||
preHandler: [fastify.requireAdmin],
|
||||
handler: stationsController.listAllStations.bind(stationsController)
|
||||
});
|
||||
|
||||
// POST /api/admin/stations - Create new station
|
||||
fastify.post('/admin/stations', {
|
||||
preHandler: [fastify.requireAdmin],
|
||||
handler: stationsController.createStation.bind(stationsController)
|
||||
});
|
||||
|
||||
// PUT /api/admin/stations/:stationId - Update station
|
||||
fastify.put('/admin/stations/:stationId', {
|
||||
preHandler: [fastify.requireAdmin],
|
||||
handler: stationsController.updateStation.bind(stationsController)
|
||||
});
|
||||
|
||||
// DELETE /api/admin/stations/:stationId - Delete station (soft delete by default, ?force=true for hard delete)
|
||||
fastify.delete('/admin/stations/:stationId', {
|
||||
preHandler: [fastify.requireAdmin],
|
||||
handler: stationsController.deleteStation.bind(stationsController)
|
||||
});
|
||||
|
||||
// GET /api/admin/users/:userId/stations - Get user's saved stations
|
||||
fastify.get('/admin/users/:userId/stations', {
|
||||
preHandler: [fastify.requireAdmin],
|
||||
handler: stationsController.getUserSavedStations.bind(stationsController)
|
||||
});
|
||||
|
||||
// DELETE /api/admin/users/:userId/stations/:stationId - Remove user's saved station (soft delete by default, ?force=true for hard delete)
|
||||
fastify.delete('/admin/users/:userId/stations/:stationId', {
|
||||
preHandler: [fastify.requireAdmin],
|
||||
handler: stationsController.removeUserSavedStation.bind(stationsController)
|
||||
});
|
||||
};
|
||||
Reference in New Issue
Block a user