2026-08-24 15:53:06 -04:00
|
|
|
import { sql } from '../../../lib/sql.js';
|
|
|
|
|
import { getUserFromRequest } from '../../../lib/permission-middleware';
|
2026-08-24 17:19:24 -04:00
|
|
|
import { pickDesignFields } from '../../../lib/custom-cards-fields.js';
|
2026-08-24 15:53:06 -04:00
|
|
|
import { syncCatalogCard, ensureOwnedRow } from './index.js';
|
|
|
|
|
|
|
|
|
|
export default async function handler(req, res) {
|
|
|
|
|
try {
|
|
|
|
|
const user = await getUserFromRequest(req);
|
|
|
|
|
if (!user) {
|
|
|
|
|
return res.status(401).json({ error: 'Authentication required' });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const designId = parseInt(req.query.id, 10);
|
|
|
|
|
if (!Number.isInteger(designId)) {
|
|
|
|
|
return res.status(400).json({ error: 'Invalid design id' });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const found = await sql`
|
|
|
|
|
SELECT * FROM custom_cards
|
|
|
|
|
WHERE id = ${designId} AND user_id = ${user.userId}
|
|
|
|
|
`;
|
|
|
|
|
if (found.rows.length === 0) {
|
|
|
|
|
return res.status(404).json({ error: 'Design not found' });
|
|
|
|
|
}
|
|
|
|
|
const existing = found.rows[0];
|
|
|
|
|
|
|
|
|
|
if (req.method === 'GET') {
|
|
|
|
|
return res.status(200).json({ design: existing });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (req.method === 'PUT') {
|
2026-08-24 17:19:24 -04:00
|
|
|
const f = pickDesignFields(req.body);
|
2026-08-24 15:53:06 -04:00
|
|
|
if (!f.name) {
|
|
|
|
|
return res.status(400).json({ error: 'Name is required' });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const updated = await sql`
|
|
|
|
|
UPDATE custom_cards SET
|
|
|
|
|
name = ${f.name}, mana_cost = ${f.manaCost},
|
|
|
|
|
card_type = ${f.cardType}, rarity = ${f.rarity},
|
|
|
|
|
rules_text = ${f.rulesText}, actions = ${f.actions},
|
2026-08-24 17:19:24 -04:00
|
|
|
flavor_quote = ${f.flavorQuote},
|
2026-08-24 15:53:06 -04:00
|
|
|
power = ${f.power}, toughness = ${f.toughness},
|
|
|
|
|
frame_id = ${f.frameId}, artwork_url = ${f.artworkUrl},
|
2026-08-24 17:19:24 -04:00
|
|
|
art_mode = ${f.artMode},
|
2026-08-24 15:53:06 -04:00
|
|
|
updated_at = CURRENT_TIMESTAMP
|
|
|
|
|
WHERE id = ${designId}
|
|
|
|
|
RETURNING *
|
|
|
|
|
`;
|
|
|
|
|
const design = updated.rows[0];
|
|
|
|
|
|
|
|
|
|
const cardId = await syncCatalogCard(design, f);
|
|
|
|
|
if (cardId) {
|
|
|
|
|
await ensureOwnedRow(user.userId, cardId);
|
|
|
|
|
if (!design.card_id) {
|
|
|
|
|
const linked = await sql`
|
|
|
|
|
UPDATE custom_cards SET card_id = ${cardId}
|
|
|
|
|
WHERE id = ${designId} RETURNING *
|
|
|
|
|
`;
|
|
|
|
|
return res.status(200).json({ design: linked.rows[0] });
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return res.status(200).json({ design });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (req.method === 'DELETE') {
|
|
|
|
|
// The catalog twin stays (it may already live in lists/decks);
|
|
|
|
|
// removing the design row simply detaches future edits from it.
|
|
|
|
|
await sql`DELETE FROM custom_cards WHERE id = ${designId}`;
|
|
|
|
|
return res.status(200).json({ message: 'Design deleted' });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return res.status(405).json({ error: 'Method not allowed' });
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error('Custom card API error:', error);
|
|
|
|
|
return res.status(500).json({ error: 'Internal server error' });
|
|
|
|
|
}
|
|
|
|
|
}
|