mirror of
https://github.com/clucraft/PriceGhost.git
synced 2026-06-29 15:59:39 +02:00
Add per-product pause/resume checking feature
Users can now pause and resume price checking for individual products or in bulk via the Actions menu. Backend: - Added checking_paused column to products table - Scheduler skips products with checking_paused=true - Added POST /products/bulk/pause endpoint for bulk pause/resume Frontend: - Added Pause Checking and Resume Checking to bulk Actions menu - Added filter dropdown (All/Active/Paused) next to sort controls - Paused products show greyed out with pause icon and "Paused" label - Progress bar hidden when paused Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
1f668239bd
commit
26a802e3d0
6 changed files with 176 additions and 6 deletions
|
|
@ -191,6 +191,10 @@ async function runMigrations() {
|
|||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'products' AND column_name = 'ai_extraction_disabled') THEN
|
||||
ALTER TABLE products ADD COLUMN ai_extraction_disabled BOOLEAN DEFAULT false;
|
||||
END IF;
|
||||
-- Per-product checking pause flag
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'products' AND column_name = 'checking_paused') THEN
|
||||
ALTER TABLE products ADD COLUMN checking_paused BOOLEAN DEFAULT false;
|
||||
END IF;
|
||||
END $$;
|
||||
`);
|
||||
|
||||
|
|
|
|||
|
|
@ -344,6 +344,7 @@ export interface Product {
|
|||
notify_back_in_stock: boolean;
|
||||
ai_verification_disabled: boolean;
|
||||
ai_extraction_disabled: boolean;
|
||||
checking_paused: boolean;
|
||||
created_at: Date;
|
||||
}
|
||||
|
||||
|
|
@ -587,8 +588,8 @@ export const productQueries = {
|
|||
findDueForRefresh: async (): Promise<Product[]> => {
|
||||
const result = await pool.query(
|
||||
`SELECT * FROM products
|
||||
WHERE next_check_at IS NULL
|
||||
OR next_check_at < CURRENT_TIMESTAMP`
|
||||
WHERE (next_check_at IS NULL OR next_check_at < CURRENT_TIMESTAMP)
|
||||
AND (checking_paused IS NULL OR checking_paused = false)`
|
||||
);
|
||||
return result.rows;
|
||||
},
|
||||
|
|
@ -638,6 +639,15 @@ export const productQueries = {
|
|||
);
|
||||
return result.rows[0]?.ai_extraction_disabled === true;
|
||||
},
|
||||
|
||||
bulkSetCheckingPaused: async (ids: number[], userId: number, paused: boolean): Promise<number> => {
|
||||
if (ids.length === 0) return 0;
|
||||
const result = await pool.query(
|
||||
`UPDATE products SET checking_paused = $1 WHERE id = ANY($2) AND user_id = $3`,
|
||||
[paused, ids, userId]
|
||||
);
|
||||
return result.rowCount || 0;
|
||||
},
|
||||
};
|
||||
|
||||
// Price History types and queries
|
||||
|
|
|
|||
|
|
@ -268,4 +268,31 @@ router.delete('/:id', async (req: AuthRequest, res: Response) => {
|
|||
}
|
||||
});
|
||||
|
||||
// Bulk pause/resume checking
|
||||
router.post('/bulk/pause', async (req: AuthRequest, res: Response) => {
|
||||
try {
|
||||
const userId = req.userId!;
|
||||
const { ids, paused } = req.body;
|
||||
|
||||
if (!Array.isArray(ids) || ids.length === 0) {
|
||||
res.status(400).json({ error: 'Product IDs array is required' });
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof paused !== 'boolean') {
|
||||
res.status(400).json({ error: 'Paused status (boolean) is required' });
|
||||
return;
|
||||
}
|
||||
|
||||
const updated = await productQueries.bulkSetCheckingPaused(ids, userId, paused);
|
||||
res.json({
|
||||
message: `${updated} product(s) ${paused ? 'paused' : 'resumed'}`,
|
||||
updated
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error bulk updating pause status:', error);
|
||||
res.status(500).json({ error: 'Failed to update pause status' });
|
||||
}
|
||||
});
|
||||
|
||||
export default router;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue