Notification updates

This commit is contained in:
Eric Gullickson
2025-12-21 19:56:52 -06:00
parent 144f1d5bb0
commit 719c80ecd8
80 changed files with 7552 additions and 678 deletions

View File

@@ -0,0 +1,124 @@
/**
* @ai-summary Fastify route handlers for user profile API
* @ai-context HTTP request/response handling with user authentication
*/
import { FastifyRequest, FastifyReply } from 'fastify';
import { UserProfileService } from '../domain/user-profile.service';
import { UserProfileRepository } from '../data/user-profile.repository';
import { pool } from '../../../core/config/database';
import { logger } from '../../../core/logging/logger';
import { UpdateProfileInput, updateProfileSchema } from './user-profile.validation';
export class UserProfileController {
private userProfileService: UserProfileService;
constructor() {
const repository = new UserProfileRepository(pool);
this.userProfileService = new UserProfileService(repository);
}
/**
* GET /api/user/profile - Get current user's profile
*/
async getProfile(request: FastifyRequest, reply: FastifyReply) {
try {
const auth0Sub = request.userContext?.userId;
if (!auth0Sub) {
return reply.code(401).send({
error: 'Unauthorized',
message: 'User context missing',
});
}
// Get user data from Auth0 token
const auth0User = {
sub: auth0Sub,
email: (request as any).user?.email || request.userContext?.email || '',
name: (request as any).user?.name,
};
// Get or create profile
const profile = await this.userProfileService.getOrCreateProfile(
auth0Sub,
auth0User
);
return reply.code(200).send(profile);
} catch (error: any) {
logger.error('Error getting user profile', {
error: error.message,
userId: request.userContext?.userId,
});
return reply.code(500).send({
error: 'Internal server error',
message: 'Failed to retrieve user profile',
});
}
}
/**
* PUT /api/user/profile - Update user profile
*/
async updateProfile(
request: FastifyRequest<{ Body: UpdateProfileInput }>,
reply: FastifyReply
) {
try {
const auth0Sub = request.userContext?.userId;
if (!auth0Sub) {
return reply.code(401).send({
error: 'Unauthorized',
message: 'User context missing',
});
}
// Validate request body
const validation = updateProfileSchema.safeParse(request.body);
if (!validation.success) {
return reply.code(400).send({
error: 'Bad Request',
message: 'Invalid request body',
details: validation.error.errors,
});
}
const updates = validation.data;
// Update profile
const profile = await this.userProfileService.updateProfile(
auth0Sub,
updates
);
return reply.code(200).send(profile);
} catch (error: any) {
logger.error('Error updating user profile', {
error: error.message,
userId: request.userContext?.userId,
});
if (error.message.includes('not found')) {
return reply.code(404).send({
error: 'Not Found',
message: 'User profile not found',
});
}
if (error.message.includes('At least one field')) {
return reply.code(400).send({
error: 'Bad Request',
message: error.message,
});
}
return reply.code(500).send({
error: 'Internal server error',
message: 'Failed to update user profile',
});
}
}
}