deckhearth/pages/api/collections/[identifier]/thumbnails.js
Randall Stillwell 6dc97aaae5 🔍 Add Debug Logging to Thumbnails API
Added comprehensive debugging to understand the actual structure of thumbnailsResult from Neon SQL queries. This will help identify whether it's an array, object with rows, or something else entirely.
2025-07-27 14:45:37 -05:00

150 lines
No EOL
4.8 KiB
JavaScript

import { sql } from '@vercel/postgres';
import { getUserFromRequest } from '../../../../lib/permission-middleware';
import { isValidSlug } from '../../../../lib/slug-utils';
export default async function handler(req, res) {
// Set CORS headers
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
// Handle preflight requests
if (req.method === 'OPTIONS') {
res.status(200).end();
return;
}
if (req.method !== 'GET') {
return res.status(405).json({ error: 'Method not allowed' });
}
try {
const { identifier } = req.query;
// Get authenticated user
const user = await getUserFromRequest(req);
if (!user) {
return res.status(401).json({ error: 'Authentication required' });
}
if (!identifier) {
return res.status(400).json({ error: 'Collection identifier is required' });
}
// Determine if identifier is a slug or numeric ID
const isSlug = isValidSlug(identifier) || isNaN(parseInt(identifier));
// Verify user has access to this collection
let collectionResult;
try {
if (isSlug) {
collectionResult = await sql`
SELECT c.*, cp.role as user_role
FROM collections c
LEFT JOIN collection_permissions cp ON c.id = cp.collection_id AND cp.user_id = ${user.userId} AND cp.status = 'active'
WHERE c.slug = ${identifier}
AND (
c.user_id = ${user.userId} OR
cp.id IS NOT NULL OR
c.is_public = true
)
`;
} else {
const numericId = parseInt(identifier);
collectionResult = await sql`
SELECT c.*, cp.role as user_role
FROM collections c
LEFT JOIN collection_permissions cp ON c.id = cp.collection_id AND cp.user_id = ${user.userId} AND cp.status = 'active'
WHERE c.id = ${numericId}
AND (
c.user_id = ${user.userId} OR
cp.id IS NOT NULL OR
c.is_public = true
)
`;
}
} catch (sqlError) {
console.error('🔍 SQL Error:', sqlError);
return res.status(500).json({ error: 'Database query failed' });
}
if (!collectionResult || !collectionResult.rows || collectionResult.rows.length === 0) {
return res.status(404).json({ error: 'Collection not found or access denied' });
}
const collection = collectionResult.rows[0];
// Add debugging and validation
if (!collection || !collection.id) {
console.error('Collection data invalid:', { collection, identifier, isSlug });
return res.status(500).json({ error: 'Collection data invalid' });
}
// Get the top 5 rarest cards from the collection
const thumbnailsResult = await sql`
SELECT
cards.id,
cards.name,
cards.rarity,
cards.image_url,
cards.stock_image_url,
cards.market_price,
cards.game,
cards.set_name,
cc.quantity
FROM collection_cards cc
JOIN cards ON cc.card_id = cards.id
WHERE cc.collection_id = ${collection.id}
AND (cards.image_url IS NOT NULL OR cards.stock_image_url IS NOT NULL)
ORDER BY
CASE cards.rarity
WHEN 'mythic' THEN 8
WHEN 'legendary' THEN 7
WHEN 'rare' THEN 6
WHEN 'uncommon' THEN 5
WHEN 'common' THEN 4
WHEN 'special' THEN 3
WHEN 'promo' THEN 2
WHEN 'token' THEN 1
ELSE 0
END DESC,
cards.market_price DESC NULLS LAST,
cards.name ASC
LIMIT 5
`;
console.log('🔍 thumbnailsResult type:', typeof thumbnailsResult);
console.log('🔍 thumbnailsResult:', thumbnailsResult);
console.log('🔍 thumbnailsResult.rows:', thumbnailsResult?.rows);
console.log('🔍 Array.isArray(thumbnailsResult):', Array.isArray(thumbnailsResult));
// Handle the result properly based on its structure
let thumbnailsArray;
if (Array.isArray(thumbnailsResult)) {
thumbnailsArray = thumbnailsResult;
} else if (thumbnailsResult && thumbnailsResult.rows && Array.isArray(thumbnailsResult.rows)) {
thumbnailsArray = thumbnailsResult.rows;
} else {
thumbnailsArray = [];
}
const thumbnails = thumbnailsArray.map(card => ({
id: card.id,
name: card.name,
rarity: card.rarity,
image_url: card.image_url,
stock_image_url: card.stock_image_url,
market_price: parseFloat(card.market_price) || 0,
game: card.game,
set_name: card.set_name,
quantity: parseInt(card.quantity) || 1
}));
res.status(200).json({ thumbnails });
} catch (error) {
console.error('Error fetching collection thumbnails:', error);
res.status(500).json({ error: 'Internal server error' });
}
}