fix(entry-point-discovery): Self-healing duplicate detection

When resolving platform_dispensary_id, check if it already exists on
another dispensary. If so, mark current dispensary as duplicate instead
of failing with unique constraint violation.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Kelly
2025-12-13 00:46:10 -07:00
parent b69d03c02f
commit 291a8279bd

View File

@@ -501,6 +501,35 @@ async function updateDispensaryWithPlatformId(
source: string,
slug: string
): Promise<void> {
// Self-healing: Check if platform_dispensary_id already exists on another dispensary
const existingResult = await pool.query(`
SELECT id, name FROM dispensaries
WHERE platform_dispensary_id = $1 AND id != $2
`, [platformId, dispensaryId]);
if (existingResult.rows.length > 0) {
const existing = existingResult.rows[0];
console.log(`[EntryPointDiscovery] Platform ID ${platformId} already exists on dispensary ${existing.id} (${existing.name})`);
console.log(`[EntryPointDiscovery] Marking dispensary ${dispensaryId} as duplicate of ${existing.id}`);
// Mark current dispensary as duplicate and disable it
await pool.query(`
UPDATE dispensaries
SET
id_resolution_status = 'duplicate',
id_resolution_error = $2,
crawl_enabled = false,
stage = 'duplicate',
updated_at = NOW(),
last_modified_at = NOW(),
last_modified_by_task = $3,
last_modified_task_id = $4
WHERE id = $1
`, [dispensaryId, `Duplicate of dispensary ${existing.id} (${existing.name})`, task.role, task.id]);
return; // Don't queue product_discovery for duplicates
}
// Update dispensary with platform ID and stage checkpoint
// Stage transitions: discovered/validated → promoted (ready for crawling)
await pool.query(`