Modernization Project Complete. Updated to latest versions of frameworks.

This commit is contained in:
Eric Gullickson
2025-08-24 09:49:21 -05:00
parent 673fe7ce91
commit b534e92636
46 changed files with 2341 additions and 5267 deletions

View File

@@ -1,105 +1,125 @@
/**
* @ai-summary HTTP request handlers for stations
* @ai-summary Fastify route handlers for stations API
* @ai-context HTTP request/response handling with Fastify reply methods
*/
import { Request, Response, NextFunction } from 'express';
import { FastifyRequest, FastifyReply } from 'fastify';
import { StationsService } from '../domain/stations.service';
import { StationsRepository } from '../data/stations.repository';
import { pool } from '../../../core/config/database';
import { logger } from '../../../core/logging/logger';
import { StationSearchBody, SaveStationBody, StationParams } from '../domain/stations.types';
export class StationsController {
constructor(private service: StationsService) {}
private stationsService: StationsService;
constructor() {
const repository = new StationsRepository(pool);
this.stationsService = new StationsService(repository);
}
search = async (req: Request, res: Response, next: NextFunction) => {
async searchStations(request: FastifyRequest<{ Body: StationSearchBody }>, reply: FastifyReply) {
try {
const userId = req.user?.sub;
if (!userId) {
return res.status(401).json({ error: 'Unauthorized' });
}
const { latitude, longitude, radius, fuelType } = req.body;
const userId = (request as any).user.sub;
const { latitude, longitude, radius, fuelType } = request.body;
if (!latitude || !longitude) {
return res.status(400).json({ error: 'Latitude and longitude are required' });
return reply.code(400).send({
error: 'Bad Request',
message: 'Latitude and longitude are required'
});
}
const result = await this.service.searchNearbyStations({
const result = await this.stationsService.searchNearbyStations({
latitude,
longitude,
radius,
fuelType
}, userId);
res.json(result);
return reply.code(200).send(result);
} catch (error: any) {
logger.error('Error searching stations', { error: error.message });
return next(error);
logger.error('Error searching stations', { error, userId: (request as any).user?.sub });
return reply.code(500).send({
error: 'Internal server error',
message: 'Failed to search stations'
});
}
}
save = async (req: Request, res: Response, next: NextFunction) => {
async saveStation(request: FastifyRequest<{ Body: SaveStationBody }>, reply: FastifyReply) {
try {
const userId = req.user?.sub;
if (!userId) {
return res.status(401).json({ error: 'Unauthorized' });
}
const { placeId, nickname, notes, isFavorite } = req.body;
const userId = (request as any).user.sub;
const { placeId, nickname, notes, isFavorite } = request.body;
if (!placeId) {
return res.status(400).json({ error: 'Place ID is required' });
return reply.code(400).send({
error: 'Bad Request',
message: 'Place ID is required'
});
}
const result = await this.service.saveStation(placeId, userId, {
const result = await this.stationsService.saveStation(placeId, userId, {
nickname,
notes,
isFavorite
});
res.status(201).json(result);
return reply.code(201).send(result);
} catch (error: any) {
logger.error('Error saving station', { error: error.message });
logger.error('Error saving station', { error, userId: (request as any).user?.sub });
if (error.message.includes('not found')) {
return res.status(404).json({ error: error.message });
return reply.code(404).send({
error: 'Not Found',
message: error.message
});
}
return next(error);
return reply.code(500).send({
error: 'Internal server error',
message: 'Failed to save station'
});
}
}
getSaved = async (req: Request, res: Response, next: NextFunction) => {
async getSavedStations(request: FastifyRequest, reply: FastifyReply) {
try {
const userId = req.user?.sub;
if (!userId) {
return res.status(401).json({ error: 'Unauthorized' });
}
const userId = (request as any).user.sub;
const result = await this.stationsService.getUserSavedStations(userId);
const result = await this.service.getUserSavedStations(userId);
res.json(result);
return reply.code(200).send(result);
} catch (error: any) {
logger.error('Error getting saved stations', { error: error.message });
return next(error);
logger.error('Error getting saved stations', { error, userId: (request as any).user?.sub });
return reply.code(500).send({
error: 'Internal server error',
message: 'Failed to get saved stations'
});
}
}
removeSaved = async (req: Request, res: Response, next: NextFunction) => {
async removeSavedStation(request: FastifyRequest<{ Params: StationParams }>, reply: FastifyReply) {
try {
const userId = req.user?.sub;
if (!userId) {
return res.status(401).json({ error: 'Unauthorized' });
}
const userId = (request as any).user.sub;
const { placeId } = request.params;
const { placeId } = req.params;
await this.service.removeSavedStation(placeId, userId);
res.status(204).send();
await this.stationsService.removeSavedStation(placeId, userId);
return reply.code(204).send();
} catch (error: any) {
logger.error('Error removing saved station', { error: error.message });
logger.error('Error removing saved station', { error, placeId: request.params.placeId, userId: (request as any).user?.sub });
if (error.message.includes('not found')) {
return res.status(404).json({ error: error.message });
return reply.code(404).send({
error: 'Not Found',
message: error.message
});
}
return next(error);
return reply.code(500).send({
error: 'Internal server error',
message: 'Failed to remove saved station'
});
}
}
}