Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 24x 2x 24x 2x 2x 2x 2x 2x 2x 24x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 24x 2x 6x 6x 4x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 24x 2x 2x 2x 2x 2x 2x 2x 2x 4x 2x 4x 4x 2x 3x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x | // src/routes/system.routes.ts
// All route handlers now use req.log (request-scoped logger) as per ADR-004
import { Router, Request, Response, NextFunction } from 'express';
// Removed: import { logger } from '../services/logger.server';
// All route handlers now use req.log (request-scoped logger) as per ADR-004
import { geocodingService } from '../services/geocodingService.server';
// All route handlers now use req.log (request-scoped logger) as per ADR-004
import { validateRequest } from '../middleware/validation.middleware';
// All route handlers now use req.log (request-scoped logger) as per ADR-004
import { z } from 'zod';
// All route handlers now use req.log (request-scoped logger) as per ADR-004
import { requiredString } from '../utils/zodUtils';
// All route handlers now use req.log (request-scoped logger) as per ADR-004
import { systemService } from '../services/systemService';
// All route handlers now use req.log (request-scoped logger) as per ADR-004
import { geocodeLimiter } from '../config/rateLimiters';
import { sendSuccess, sendError, ErrorCode } from '../utils/apiResponse';
const router = Router();
const geocodeSchema = z.object({
body: z.object({
address: requiredString('An address string is required.'),
}),
});
// An empty schema for routes that do not expect any input, to maintain a consistent validation pattern.
const emptySchema = z.object({});
/**
* @openapi
* /system/pm2-status:
* get:
* tags: [System]
* summary: Get PM2 process status
* description: Checks the status of the 'flyer-crawler-api' process managed by PM2. For development and diagnostic purposes.
* responses:
* 200:
* description: PM2 process status information
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/SuccessResponse'
*/
router.get(
'/pm2-status',
validateRequest(emptySchema),
async (req: Request, res: Response, next: NextFunction) => {
try {
const status = await systemService.getPm2Status();
sendSuccess(res, status);
} catch (error) {
next(error);
}
},
);
/**
* @openapi
* /system/geocode:
* post:
* tags: [System]
* summary: Geocode an address
* description: Geocodes a given address string. Acts as a secure proxy to the Google Maps Geocoding API.
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required:
* - address
* properties:
* address:
* type: string
* description: Address string to geocode
* responses:
* 200:
* description: Geocoded coordinates
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/SuccessResponse'
* 404:
* description: Could not geocode the provided address
*/
router.post(
'/geocode',
geocodeLimiter,
validateRequest(geocodeSchema),
async (req: Request, res: Response, next: NextFunction) => {
// Infer type and cast request object as per ADR-003
type GeocodeRequest = z.infer<typeof geocodeSchema>;
const {
body: { address },
} = req as unknown as GeocodeRequest;
try {
const coordinates = await geocodingService.geocodeAddress(address, req.log);
if (!coordinates) {
// This check remains, but now it only fails if BOTH services fail.
return sendError(res, ErrorCode.NOT_FOUND, 'Could not geocode the provided address.', 404);
}
sendSuccess(res, coordinates);
} catch (error) {
req.log.error({ error }, 'Error geocoding address');
next(error);
}
},
);
export default router;
|