Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 23 additions & 12 deletions bin/metron-cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -661,8 +661,12 @@ class MetronCLI {

for (const dbIssue of dbIssues) {
try {
// Try to find the issue in Metron API by gcd_id
const metronIssue = await this.findMetronIssueByGcdId(apiClient, dbIssue.gcd_id);
// Try to find the issue in Metron API by both gcd_id and metron_id (if available)
const metronIssue = await this.findMetronIssueByGcdId(
apiClient,
dbIssue.gcd_id,
dbIssue.metron_id // Pass metron_id if available for better matching
);

if (!metronIssue) {
// No matching issue found in Metron API - mark as scanned but skip processing
Expand All @@ -679,7 +683,7 @@ class MetronCLI {

skipped++;
if (options.verbose) {
console.log(`⚠️ No Metron issue found for gcd_id: ${dbIssue.gcd_id} (DB ID: ${dbIssue.id}) - marked as scanned`);
console.log(`⚠️ No Metron issue found for gcd_id: ${dbIssue.gcd_id}${dbIssue.metron_id ? `, metron_id: ${dbIssue.metron_id}` : ''} (DB ID: ${dbIssue.id}) - marked as scanned`);
}
continue;
}
Expand Down Expand Up @@ -743,18 +747,25 @@ class MetronCLI {
}

/**
* Find a Metron issue by gcd_id using search
* Find a Metron issue by gcd_id and/or metron_id using merged search
* This method searches by both IDs and returns the best match
*/
private async findMetronIssueByGcdId(apiClient: any, gcdId: number): Promise<any | null> {
private async findMetronIssueByGcdId(apiClient: any, gcdId: number, metronId?: number): Promise<any | null> {
try {
// Search for issues with the specific gcd_id
// Note: This assumes the Metron API supports searching by gcd_id
// If not, we might need to use a different approach
const searchResponse = await apiClient.searchIssuesByGcdId(gcdId);

if (searchResponse && searchResponse.results && searchResponse.results.length > 0) {
// Use the new merged search that checks both GCD ID and Metron ID
const results = await apiClient.searchIssuesByBothIds(gcdId, metronId);

if (results && results.length > 0) {
// If we have multiple results, prefer the one that matches the metron_id (if provided)
if (metronId && results.length > 1) {
const metronMatch = results.find((issue: any) => issue.id === metronId);
if (metronMatch) {
return metronMatch;
}
}

// Return the first matching issue
return searchResponse.results[0];
return results[0];
}

return null;
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@
"db:audit:data-quality": "npx tsx scripts/audit-data-quality.ts",
"db:audit:comprehensive": "npx tsx scripts/run-comprehensive-audit.ts",
"db:audit:cleanup-files": "npx tsx scripts/cleanup-audit-files.ts",
"cleanup-negative-gcd-ids": "npx tsx scripts/cleanup-negative-gcd-ids.ts",
"migrate-variant-gcd-ids": "npx tsx scripts/migrate-variant-gcd-ids.ts",
"metron": "npx tsx bin/metron-cli.ts"
},
"dependencies": {
Expand Down
45 changes: 45 additions & 0 deletions scripts/check-metron-variant-ids.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/usr/bin/env npx tsx

import dotenv from 'dotenv';
dotenv.config({ path: '.env.local' });

import { MetronApiClient } from '../src/lib/metron-api-client';

async function checkVariantIds() {
const client = new MetronApiClient();

// Check issue 954250 which has variants
console.log('Fetching issue 954250 from Metron API...\n');

const issue = await client.fetchIssueById(954250);

if (!issue) {
console.log('Issue not found');
return;
}

console.log(`Issue: ${issue.series.name} #${issue.number}`);
console.log(`Metron ID: ${issue.id}`);
console.log(`Variants: ${issue.variants?.length || 0}\n`);

if (issue.variants && issue.variants.length > 0) {
console.log('Variant details from Metron API:');
issue.variants.forEach((v, i) => {
console.log(`\n${i + 1}. ${v.name}`);
console.log(` SKU: ${v.sku || 'N/A'}`);
console.log(` UPC: ${v.upc || 'N/A'}`);
console.log(` Image: ${v.image ? 'Yes' : 'No'}`);
console.log(` Note: Variants don't have separate Metron IDs or GCD IDs in the API`);
});
}

console.log('\n\n📝 Conclusion:');
console.log('Metron API variants are just metadata (name, image, sku, upc)');
console.log('They do NOT have their own Metron IDs or GCD IDs');
console.log('\nFor our database, variants should:');
console.log('1. Use formula: gcd_id = 1000000 + parent_metron_id + variant_index');
console.log('2. Set variant_of_id to parent issue ID');
console.log('3. Set metron_id to NULL (they don\'t have separate Metron IDs)');
}

checkVariantIds();
81 changes: 81 additions & 0 deletions scripts/check-variant-gcd-ids.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#!/usr/bin/env npx tsx

/**
* Check Variant GCD IDs
*
* This script checks that variant issues have proper deterministic negative GCD IDs
*/

import dotenv from 'dotenv';
dotenv.config({ path: '.env.local' });

import { adminDbService } from '../src/lib/supabase';

async function checkVariantGcdIds() {
console.log('🔍 Checking variant GCD IDs...\n');

// Get variants for issue 954250
const { data: variants, error } = await adminDbService.client
.from('issues')
.select('id, gcd_id, metron_id, variant_of_id, variant_name, title')
.eq('variant_of_id', 954250)
.order('id');

if (error) {
console.error('❌ Error:', error);
return;
}

if (!variants || variants.length === 0) {
console.log('⚠️ No variants found for issue 954250');
return;
}

console.log(`Found ${variants.length} variants for issue 954250:\n`);

variants.forEach((variant: any, index: number) => {
const expectedGcdId = -(954250 * 1000 + index + 1);
const isCorrect = variant.gcd_id === expectedGcdId;
const status = isCorrect ? '✅' : '❌';

console.log(`${status} Variant ${index + 1}:`);
console.log(` DB ID: ${variant.id}`);
console.log(` GCD ID: ${variant.gcd_id} ${isCorrect ? '(correct)' : `(expected: ${expectedGcdId})`}`);
console.log(` Metron ID: ${variant.metron_id || 'NULL'}`);
console.log(` Variant Name: ${variant.variant_name || 'N/A'}`);
console.log(` Title: ${variant.title || 'N/A'}`);
console.log('');
});

// Check for any negative GCD IDs that don't follow the pattern
const { data: negativeGcdIds, error: negError } = await adminDbService.client
.from('issues')
.select('id, gcd_id, metron_id, variant_of_id, variant_name')
.lt('gcd_id', 0)
.order('gcd_id', { ascending: false })
.limit(10);

if (negError) {
console.error('❌ Error checking negative GCD IDs:', negError);
return;
}

if (negativeGcdIds && negativeGcdIds.length > 0) {
console.log(`\n📊 Sample of issues with negative GCD IDs (${negativeGcdIds.length} shown):\n`);

negativeGcdIds.forEach((issue: any) => {
const parentId = issue.variant_of_id;
if (parentId) {
const expectedGcdId = -(parentId * 1000 + 1); // Approximate check
const isPattern = issue.gcd_id <= expectedGcdId && issue.gcd_id > (expectedGcdId - 1000);
console.log(`${isPattern ? '✅' : '⚠️ '} ID: ${issue.id}, GCD ID: ${issue.gcd_id}, Parent: ${parentId || 'N/A'}, Variant: ${issue.variant_name || 'N/A'}`);
} else {
console.log(`❌ ID: ${issue.id}, GCD ID: ${issue.gcd_id}, Parent: NONE (not a variant!)`);
}
});
}

console.log('\n✅ Check complete!');
}

checkVariantGcdIds();
Loading
Loading