Fix Auth Errors

This commit is contained in:
Eric Gullickson
2025-09-22 10:27:10 -05:00
parent 3588372cef
commit 8fd7973656
19 changed files with 1342 additions and 174 deletions

View File

@@ -8,7 +8,7 @@ import { FuelLogsService } from '../domain/fuel-logs.service';
import { FuelLogsRepository } from '../data/fuel-logs.repository';
import { pool } from '../../../core/config/database';
import { logger } from '../../../core/logging/logger';
import { FuelLogParams, VehicleParams, EnhancedCreateFuelLogRequest } from '../domain/fuel-logs.types';
import { FuelLogParams, VehicleParams, EnhancedCreateFuelLogRequest, EnhancedUpdateFuelLogRequest } from '../domain/fuel-logs.types';
export class FuelLogsController {
private fuelLogsService: FuelLogsService;
@@ -124,13 +124,17 @@ export class FuelLogsController {
}
}
async updateFuelLog(_request: FastifyRequest<{ Params: FuelLogParams; Body: any }>, reply: FastifyReply) {
async updateFuelLog(request: FastifyRequest<{ Params: FuelLogParams; Body: EnhancedUpdateFuelLogRequest }>, reply: FastifyReply) {
try {
// Update not implemented in enhanced flow
return reply.code(501).send({ error: 'Not Implemented', message: 'Update fuel log not implemented' });
const userId = (request as any).user.sub;
const { id } = request.params;
const updatedFuelLog = await this.fuelLogsService.updateFuelLog(id, request.body, userId);
return reply.code(200).send(updatedFuelLog);
} catch (error: any) {
logger.error('Error updating fuel log', { error });
logger.error('Error updating fuel log', { error, fuelLogId: request.params.id, userId: (request as any).user?.sub });
if (error.message.includes('not found')) {
return reply.code(404).send({
error: 'Not Found',
@@ -143,7 +147,13 @@ export class FuelLogsController {
message: error.message
});
}
if (error.message.includes('No fields provided')) {
return reply.code(400).send({
error: 'Bad Request',
message: error.message
});
}
return reply.code(500).send({
error: 'Internal server error',
message: 'Failed to update fuel log'

View File

@@ -286,4 +286,90 @@ export class FuelLogsRepository {
);
return res.rows[0] || null;
}
async updateEnhanced(id: string, data: {
dateTime?: Date;
odometerReading?: number;
tripDistance?: number;
fuelType?: string;
fuelGrade?: string | null;
fuelUnits?: number;
costPerUnit?: number;
locationData?: any;
notes?: string;
}): Promise<any | null> {
const fields = [];
const values = [];
let paramCount = 1;
// Build dynamic update query for enhanced schema
if (data.dateTime !== undefined) {
fields.push(`date_time = $${paramCount++}`);
fields.push(`date = $${paramCount++}`);
values.push(data.dateTime);
values.push(data.dateTime.toISOString().slice(0, 10));
}
if (data.odometerReading !== undefined) {
fields.push(`odometer = $${paramCount++}`);
values.push(data.odometerReading);
}
if (data.tripDistance !== undefined) {
fields.push(`trip_distance = $${paramCount++}`);
values.push(data.tripDistance);
}
if (data.fuelType !== undefined) {
fields.push(`fuel_type = $${paramCount++}`);
values.push(data.fuelType);
}
if (data.fuelGrade !== undefined) {
fields.push(`fuel_grade = $${paramCount++}`);
values.push(data.fuelGrade);
}
if (data.fuelUnits !== undefined) {
fields.push(`fuel_units = $${paramCount++}`);
fields.push(`gallons = $${paramCount++}`); // legacy support
values.push(data.fuelUnits);
values.push(data.fuelUnits);
}
if (data.costPerUnit !== undefined) {
fields.push(`cost_per_unit = $${paramCount++}`);
fields.push(`price_per_gallon = $${paramCount++}`); // legacy support
values.push(data.costPerUnit);
values.push(data.costPerUnit);
}
if (data.locationData !== undefined) {
fields.push(`location_data = $${paramCount++}`);
values.push(data.locationData);
}
if (data.notes !== undefined) {
fields.push(`notes = $${paramCount++}`);
values.push(data.notes);
}
// Recalculate total cost if both fuelUnits and costPerUnit are present
if (data.fuelUnits !== undefined && data.costPerUnit !== undefined) {
fields.push(`total_cost = $${paramCount++}`);
values.push(data.fuelUnits * data.costPerUnit);
}
if (fields.length === 0) {
return this.findByIdEnhanced(id);
}
values.push(id);
const query = `
UPDATE fuel_logs
SET ${fields.join(', ')}, updated_at = NOW()
WHERE id = $${paramCount}
RETURNING *
`;
const result = await this.pool.query(query, values);
if (result.rows.length === 0) {
return null;
}
return result.rows[0];
}
}

View File

@@ -4,7 +4,7 @@
*/
import { FuelLogsRepository } from '../data/fuel-logs.repository';
import { EnhancedCreateFuelLogRequest, EnhancedFuelLogResponse, FuelType } from './fuel-logs.types';
import { EnhancedCreateFuelLogRequest, EnhancedUpdateFuelLogRequest, EnhancedFuelLogResponse, FuelType } from './fuel-logs.types';
import { logger } from '../../../core/logging/logger';
import { cacheService } from '../../../core/config/redis';
import pool from '../../../core/config/database';
@@ -109,7 +109,81 @@ export class FuelLogsService {
return this.toEnhancedResponse(row, undefined, unitSystem);
}
async updateFuelLog(): Promise<any> { throw new Error('Not Implemented'); }
async updateFuelLog(id: string, data: EnhancedUpdateFuelLogRequest, userId: string): Promise<EnhancedFuelLogResponse> {
logger.info('Updating enhanced fuel log', { id, userId });
// Verify the fuel log exists and belongs to the user
const existing = await this.repository.findByIdEnhanced(id);
if (!existing) throw new Error('Fuel log not found');
if (existing.user_id !== userId) throw new Error('Unauthorized');
// Get user settings for unit conversion
const userSettings = await UserSettingsService.getUserSettings(userId);
// Validate the update data
if (Object.keys(data).length === 0) {
throw new Error('No fields provided for update');
}
// Prepare update data with proper type conversion
const updateData: any = {};
if (data.dateTime !== undefined) {
updateData.dateTime = new Date(data.dateTime);
}
if (data.odometerReading !== undefined) {
updateData.odometerReading = data.odometerReading;
}
if (data.tripDistance !== undefined) {
updateData.tripDistance = data.tripDistance;
}
if (data.fuelType !== undefined) {
updateData.fuelType = data.fuelType;
}
if (data.fuelGrade !== undefined) {
updateData.fuelGrade = data.fuelGrade;
}
if (data.fuelUnits !== undefined) {
updateData.fuelUnits = data.fuelUnits;
}
if (data.costPerUnit !== undefined) {
updateData.costPerUnit = data.costPerUnit;
}
if (data.locationData !== undefined) {
updateData.locationData = data.locationData;
}
if (data.notes !== undefined) {
updateData.notes = data.notes;
}
// Update the fuel log
const updated = await this.repository.updateEnhanced(id, updateData);
if (!updated) throw new Error('Failed to update fuel log');
// Update vehicle odometer if changed
if (data.odometerReading !== undefined) {
await pool.query(
'UPDATE vehicles SET odometer_reading = $1 WHERE id = $2 AND user_id = $3 AND (odometer_reading IS NULL OR odometer_reading < $1)',
[data.odometerReading, existing.vehicle_id, userId]
);
}
// Invalidate caches
await this.invalidateCaches(userId, existing.vehicle_id, userSettings.unitSystem);
// Calculate efficiency for response
const efficiency = EfficiencyCalculationService.calculateEfficiency(
{
odometerReading: updated.odometer ?? undefined,
tripDistance: updated.trip_distance ?? undefined,
fuelUnits: updated.fuel_units ?? undefined
},
null, // Previous log efficiency calculation would require more complex logic for updates
userSettings.unitSystem
);
return this.toEnhancedResponse(updated, efficiency?.value ?? undefined, userSettings.unitSystem);
}
async deleteFuelLog(id: string, userId: string): Promise<void> {
const existing = await this.repository.findByIdEnhanced(id);

View File

@@ -87,6 +87,18 @@ export interface EnhancedCreateFuelLogRequest {
notes?: string;
}
export interface EnhancedUpdateFuelLogRequest {
dateTime?: string;
odometerReading?: number;
tripDistance?: number;
fuelType?: FuelType;
fuelGrade?: FuelGrade;
fuelUnits?: number;
costPerUnit?: number;
locationData?: LocationData;
notes?: string;
}
export interface EnhancedFuelLogResponse {
id: string;
userId: string;