some minor log in fixes - also new flyer function
All checks were successful
Deploy to Web Server flyer-crawler.projectium.com / deploy (push) Successful in 6m14s
All checks were successful
Deploy to Web Server flyer-crawler.projectium.com / deploy (push) Successful in 6m14s
This commit is contained in:
@@ -532,11 +532,16 @@ export const unfollowUser = async (userIdToUnfollow: string, tokenOverride?: str
|
|||||||
* @returns A promise that resolves to an array of ActivityLogItem objects.
|
* @returns A promise that resolves to an array of ActivityLogItem objects.
|
||||||
*/
|
*/
|
||||||
export const fetchActivityLog = async (limit: number = 20, offset: number = 0, tokenOverride?: string): Promise<Response> => {
|
export const fetchActivityLog = async (limit: number = 20, offset: number = 0, tokenOverride?: string): Promise<Response> => {
|
||||||
return apiFetch(`/activity-log?limit=${limit}&offset=${offset}`, {}, tokenOverride);
|
return apiFetch(`/admin/activity-log?limit=${limit}&offset=${offset}`, {}, tokenOverride);
|
||||||
};
|
};
|
||||||
|
|
||||||
// --- Favorite Recipes API Functions ---
|
// --- Favorite Recipes API Functions ---
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a list of the currently authenticated user's favorite recipes.
|
||||||
|
* @param {string} [tokenOverride] Optional token for testing purposes.
|
||||||
|
* @returns {Promise<Response>} A promise that resolves to the API response.
|
||||||
|
*/
|
||||||
export const getUserFavoriteRecipes = async (tokenOverride?: string): Promise<Response> => {
|
export const getUserFavoriteRecipes = async (tokenOverride?: string): Promise<Response> => {
|
||||||
return apiFetch(`/users/me/favorite-recipes`, {}, tokenOverride);
|
return apiFetch(`/users/me/favorite-recipes`, {}, tokenOverride);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -12,6 +12,35 @@ export class FlyerRepository {
|
|||||||
this.db = db;
|
this.db = db;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async findOrCreateStore(storeName: string): Promise<number> {
|
||||||
|
// Note: This method should be called within a transaction if the caller
|
||||||
|
// needs to ensure atomicity with other operations.
|
||||||
|
try {
|
||||||
|
// First, try to find the store.
|
||||||
|
let result = await this.db.query<{ store_id: number }>('SELECT store_id FROM public.stores WHERE name = $1', [storeName]);
|
||||||
|
|
||||||
|
if (result.rows.length > 0) {
|
||||||
|
return result.rows[0].store_id;
|
||||||
|
} else {
|
||||||
|
// If not found, create it.
|
||||||
|
result = await this.db.query<{ store_id: number }>('INSERT INTO public.stores (name) VALUES ($1) RETURNING store_id', [storeName]);
|
||||||
|
return result.rows[0].store_id;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// Check for a unique constraint violation on name, which could happen in a race condition
|
||||||
|
// if two processes try to create the same store at the same time.
|
||||||
|
if (error instanceof Error && 'code' in error && error.code === '23505') {
|
||||||
|
logger.warn(`Race condition avoided: Store "${storeName}" was created by another process. Refetching.`);
|
||||||
|
const result = await this.db.query<{ store_id: number }>('SELECT store_id FROM public.stores WHERE name = $1', [storeName]);
|
||||||
|
if (result.rows.length > 0) {
|
||||||
|
return result.rows[0].store_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
logger.error('Database error in findOrCreateStore:', { error, storeName });
|
||||||
|
throw new Error('Failed to find or create store in database.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inserts a new flyer into the database.
|
* Inserts a new flyer into the database.
|
||||||
* @param flyerData - The data for the new flyer.
|
* @param flyerData - The data for the new flyer.
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ export class UserRepository {
|
|||||||
profileData: { full_name?: string; avatar_url?: string }
|
profileData: { full_name?: string; avatar_url?: string }
|
||||||
): Promise<UserProfile> {
|
): Promise<UserProfile> {
|
||||||
// This method now manages its own transaction to ensure atomicity.
|
// This method now manages its own transaction to ensure atomicity.
|
||||||
const client = await (this.db as Pool).connect();
|
const client = await getPool().connect();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
logger.debug(`[DB createUser] Starting transaction for email: ${email}`);
|
logger.debug(`[DB createUser] Starting transaction for email: ${email}`);
|
||||||
|
|||||||
Reference in New Issue
Block a user