feat: Update AI service to use new Google Generative AI SDK
Some checks are pending
Deploy to Test Environment / deploy-to-test (push) Has started running
Some checks are pending
Deploy to Test Environment / deploy-to-test (push) Has started running
- Refactored AIService to integrate with the latest GoogleGenAI SDK, updating the generateContent method signature and response handling. - Adjusted error handling and logging for improved clarity and consistency. - Enhanced mock implementations in tests to align with the new SDK structure. refactor: Modify Admin DB service to use Profile type - Updated AdminRepository to replace User type with Profile in relevant methods. - Enhanced test cases to utilize mock factories for creating Profile and AdminUserView objects. fix: Improve error handling in BudgetRepository - Implemented type-safe checks for PostgreSQL error codes to enhance error handling in createBudget method. test: Refactor Deals DB tests for type safety - Updated DealsRepository tests to use Pool type for mock instances, ensuring type safety. chore: Add new mock factories for testing - Introduced mock factories for UserWithPasswordHash, Profile, WatchedItemDeal, LeaderboardUser, and UnmatchedFlyerItem to streamline test data creation. style: Clean up queue service tests - Refactored queue service tests to improve readability and maintainability, including better handling of mock worker instances. docs: Update types to include UserWithPasswordHash - Added UserWithPasswordHash interface to types for better clarity on user authentication data structure. chore: Remove deprecated Google AI SDK references - Updated code and documentation to reflect the migration to the new Google Generative AI SDK, removing references to the deprecated SDK.
This commit is contained in:
@@ -149,10 +149,10 @@ router.get('/stats/daily', async (req, res, next: NextFunction) => {
|
||||
});
|
||||
|
||||
router.post('/corrections/:id/approve', validateRequest(numericIdParamSchema('id')), async (req: Request, res: Response, next: NextFunction) => {
|
||||
type ApproveCorrectionRequest = z.infer<typeof updateCorrectionSchema>;
|
||||
const { params } = req as unknown as ApproveCorrectionRequest;
|
||||
// Apply ADR-003 pattern for type safety
|
||||
const { params } = req as unknown as z.infer<ReturnType<typeof numericIdParamSchema>>;
|
||||
try {
|
||||
await db.adminRepo.approveCorrection(params.id, req.log);
|
||||
await db.adminRepo.approveCorrection(params.id, req.log); // params.id is now safely typed as number
|
||||
res.status(200).json({ message: 'Correction approved successfully.' });
|
||||
} catch (error) {
|
||||
next(error);
|
||||
@@ -160,10 +160,10 @@ router.post('/corrections/:id/approve', validateRequest(numericIdParamSchema('id
|
||||
});
|
||||
|
||||
router.post('/corrections/:id/reject', validateRequest(numericIdParamSchema('id')), async (req: Request, res: Response, next: NextFunction) => {
|
||||
type RejectCorrectionRequest = z.infer<typeof updateCorrectionSchema>;
|
||||
const { params } = req as unknown as RejectCorrectionRequest;
|
||||
// Apply ADR-003 pattern for type safety
|
||||
const { params } = req as unknown as z.infer<ReturnType<typeof numericIdParamSchema>>;
|
||||
try {
|
||||
await db.adminRepo.rejectCorrection(params.id, req.log);
|
||||
await db.adminRepo.rejectCorrection(params.id, req.log); // params.id is now safely typed as number
|
||||
res.status(200).json({ message: 'Correction rejected successfully.' });
|
||||
} catch (error) {
|
||||
next(error);
|
||||
@@ -171,8 +171,8 @@ router.post('/corrections/:id/reject', validateRequest(numericIdParamSchema('id'
|
||||
});
|
||||
|
||||
router.put('/corrections/:id', validateRequest(updateCorrectionSchema), async (req: Request, res: Response, next: NextFunction) => {
|
||||
type UpdateCorrectionRequest = z.infer<typeof updateCorrectionSchema>;
|
||||
const { params, body } = req as unknown as UpdateCorrectionRequest;
|
||||
// Apply ADR-003 pattern for type safety
|
||||
const { params, body } = req as unknown as z.infer<typeof updateCorrectionSchema>;
|
||||
try {
|
||||
const updatedCorrection = await db.adminRepo.updateSuggestedCorrection(params.id, body.suggested_value, req.log);
|
||||
res.status(200).json(updatedCorrection);
|
||||
@@ -182,8 +182,8 @@ router.put('/corrections/:id', validateRequest(updateCorrectionSchema), async (r
|
||||
});
|
||||
|
||||
router.put('/recipes/:id/status', validateRequest(updateRecipeStatusSchema), async (req: Request, res: Response, next: NextFunction) => {
|
||||
type UpdateRecipeStatusRequest = z.infer<typeof updateRecipeStatusSchema>;
|
||||
const { params, body } = req as unknown as UpdateRecipeStatusRequest;
|
||||
// Apply ADR-003 pattern for type safety
|
||||
const { params, body } = req as unknown as z.infer<typeof updateRecipeStatusSchema>;
|
||||
try {
|
||||
const updatedRecipe = await db.adminRepo.updateRecipeStatus(params.id, body.status, req.log); // This is still a standalone function in admin.db.ts
|
||||
res.status(200).json(updatedRecipe);
|
||||
@@ -193,6 +193,7 @@ router.put('/recipes/:id/status', validateRequest(updateRecipeStatusSchema), asy
|
||||
});
|
||||
|
||||
router.post('/brands/:id/logo', validateRequest(numericIdParamSchema('id')), upload.single('logoImage'), requireFileUpload('logoImage'), async (req: Request, res: Response, next: NextFunction) => {
|
||||
// Apply ADR-003 pattern for type safety
|
||||
const { params } = req as unknown as z.infer<ReturnType<typeof numericIdParamSchema>>;
|
||||
try {
|
||||
// Although requireFileUpload middleware should ensure the file exists,
|
||||
@@ -223,8 +224,10 @@ router.get('/unmatched-items', async (req, res, next: NextFunction) => {
|
||||
* DELETE /api/admin/recipes/:recipeId - Admin endpoint to delete any recipe.
|
||||
*/
|
||||
router.delete('/recipes/:recipeId', validateRequest(numericIdParamSchema('recipeId')), async (req: Request, res: Response, next: NextFunction) => {
|
||||
// Define schema locally to simplify type inference
|
||||
const schema = numericIdParamSchema('recipeId');
|
||||
const adminUser = req.user as UserProfile;
|
||||
const { params } = req as unknown as z.infer<ReturnType<typeof numericIdParamSchema>>;
|
||||
const { params } = req as unknown as z.infer<typeof schema>;
|
||||
try {
|
||||
// The isAdmin flag bypasses the ownership check in the repository method.
|
||||
await db.recipeRepo.deleteRecipe(params.recipeId, adminUser.user_id, true, req.log);
|
||||
@@ -238,7 +241,9 @@ router.delete('/recipes/:recipeId', validateRequest(numericIdParamSchema('recipe
|
||||
* DELETE /api/admin/flyers/:flyerId - Admin endpoint to delete a flyer and its items.
|
||||
*/
|
||||
router.delete('/flyers/:flyerId', validateRequest(numericIdParamSchema('flyerId')), async (req: Request, res: Response, next: NextFunction) => {
|
||||
const { params } = req as unknown as z.infer<ReturnType<typeof numericIdParamSchema>>;
|
||||
// Define schema locally to simplify type inference
|
||||
const schema = numericIdParamSchema('flyerId');
|
||||
const { params } = req as unknown as z.infer<typeof schema>;
|
||||
try {
|
||||
await db.flyerRepo.deleteFlyer(params.flyerId, req.log);
|
||||
res.status(204).send();
|
||||
@@ -248,8 +253,8 @@ router.delete('/flyers/:flyerId', validateRequest(numericIdParamSchema('flyerId'
|
||||
});
|
||||
|
||||
router.put('/comments/:id/status', validateRequest(updateCommentStatusSchema), async (req: Request, res: Response, next: NextFunction) => {
|
||||
type UpdateCommentStatusRequest = z.infer<typeof updateCommentStatusSchema>;
|
||||
const { params, body } = req as unknown as UpdateCommentStatusRequest;
|
||||
// Apply ADR-003 pattern for type safety
|
||||
const { params, body } = req as unknown as z.infer<typeof updateCommentStatusSchema>;
|
||||
try {
|
||||
const updatedComment = await db.adminRepo.updateRecipeCommentStatus(params.id, body.status, req.log); // This is still a standalone function in admin.db.ts
|
||||
res.status(200).json(updatedComment);
|
||||
@@ -268,8 +273,8 @@ router.get('/users', async (req, res, next: NextFunction) => {
|
||||
});
|
||||
|
||||
router.get('/activity-log', validateRequest(activityLogSchema), async (req: Request, res: Response, next: NextFunction) => {
|
||||
type ActivityLogRequest = z.infer<typeof activityLogSchema>;
|
||||
const { query } = req as unknown as ActivityLogRequest;
|
||||
// Apply ADR-003 pattern for type safety
|
||||
const { query } = req as unknown as z.infer<typeof activityLogSchema>;
|
||||
try {
|
||||
const logs = await db.adminRepo.getActivityLog(query.limit, query.offset, req.log);
|
||||
res.json(logs);
|
||||
@@ -279,7 +284,8 @@ router.get('/activity-log', validateRequest(activityLogSchema), async (req: Requ
|
||||
});
|
||||
|
||||
router.get('/users/:id', validateRequest(uuidParamSchema('id')), async (req: Request, res: Response, next: NextFunction) => {
|
||||
const { params } = req as z.infer<ReturnType<typeof uuidParamSchema>>;
|
||||
// Apply ADR-003 pattern for type safety
|
||||
const { params } = req as unknown as z.infer<ReturnType<typeof uuidParamSchema>>;
|
||||
try {
|
||||
const user = await db.userRepo.findUserProfileById(params.id, req.log);
|
||||
res.json(user);
|
||||
@@ -289,8 +295,8 @@ router.get('/users/:id', validateRequest(uuidParamSchema('id')), async (req: Req
|
||||
});
|
||||
|
||||
router.put('/users/:id', validateRequest(updateUserRoleSchema), async (req: Request, res: Response, next: NextFunction) => {
|
||||
type UpdateUserRoleRequest = z.infer<typeof updateUserRoleSchema>;
|
||||
const { params, body } = req as unknown as UpdateUserRoleRequest;
|
||||
// Apply ADR-003 pattern for type safety
|
||||
const { params, body } = req as unknown as z.infer<typeof updateUserRoleSchema>;
|
||||
try {
|
||||
const updatedUser = await db.adminRepo.updateUserRole(params.id, body.role, req.log);
|
||||
res.json(updatedUser);
|
||||
@@ -302,7 +308,8 @@ router.put('/users/:id', validateRequest(updateUserRoleSchema), async (req: Requ
|
||||
|
||||
router.delete('/users/:id', validateRequest(uuidParamSchema('id')), async (req: Request, res: Response, next: NextFunction) => {
|
||||
const adminUser = req.user as UserProfile;
|
||||
const { params } = req as z.infer<ReturnType<typeof uuidParamSchema>>;
|
||||
// Apply ADR-003 pattern for type safety
|
||||
const { params } = req as unknown as z.infer<ReturnType<typeof uuidParamSchema>>;
|
||||
try {
|
||||
if (adminUser.user.user_id === params.id) {
|
||||
throw new ValidationError([], 'Admins cannot delete their own account.');
|
||||
@@ -360,8 +367,10 @@ router.post('/trigger/analytics-report', async (req: Request, res: Response, nex
|
||||
* This is triggered by an admin after they have verified the flyer processing was successful.
|
||||
*/
|
||||
router.post('/flyers/:flyerId/cleanup', validateRequest(numericIdParamSchema('flyerId')), async (req: Request, res: Response, next: NextFunction) => {
|
||||
// Define schema locally to simplify type inference
|
||||
const schema = numericIdParamSchema('flyerId');
|
||||
const adminUser = req.user as UserProfile;
|
||||
const { params } = req as unknown as z.infer<ReturnType<typeof numericIdParamSchema>>;
|
||||
const { params } = req as unknown as z.infer<typeof schema>;
|
||||
logger.info(`[Admin] Manual trigger for flyer file cleanup received from user: ${adminUser.user_id} for flyer ID: ${params.flyerId}`);
|
||||
|
||||
// Enqueue the cleanup job. The worker will handle the file deletion.
|
||||
|
||||
Reference in New Issue
Block a user