()
| 7 | }); |
| 8 | |
| 9 | async function main() { |
| 10 | const pool = getPool(); |
| 11 | |
| 12 | const result = await pool.query( |
| 13 | `SELECT id, title, category, excerpt FROM perspectives |
| 14 | WHERE status = 'published' AND working_group_id IS NULL AND illustration_id IS NULL |
| 15 | ORDER BY published_at DESC NULLS LAST |
| 16 | LIMIT 6` |
| 17 | ); |
| 18 | |
| 19 | console.log(`Found ${result.rows.length} perspectives to illustrate`); |
| 20 | |
| 21 | for (const art of result.rows) { |
| 22 | console.log(`Generating for: ${art.title.slice(0, 60)}...`); |
| 23 | try { |
| 24 | const { imageBuffer, promptUsed } = await generateIllustration({ |
| 25 | title: art.title, |
| 26 | category: art.category, |
| 27 | excerpt: art.excerpt, |
| 28 | }); |
| 29 | |
| 30 | // Insert with explicit \\x hex encoding for BYTEA |
| 31 | const hexData = '\\x' + imageBuffer.toString('hex'); |
| 32 | |
| 33 | const insertResult = await pool.query( |
| 34 | `INSERT INTO perspective_illustrations (perspective_id, image_data, prompt_used, status, approved_at) |
| 35 | VALUES ($1, decode($2, 'base64'), $3, 'approved', NOW()) |
| 36 | RETURNING id`, |
| 37 | [art.id, imageBuffer.toString('base64'), promptUsed] |
| 38 | ); |
| 39 | const illId = insertResult.rows[0].id; |
| 40 | |
| 41 | await pool.query( |
| 42 | `UPDATE perspectives SET illustration_id = $1 WHERE id = $2`, |
| 43 | [illId, art.id] |
| 44 | ); |
| 45 | |
| 46 | console.log(` OK -> ${illId}`); |
| 47 | } catch (e: any) { |
| 48 | console.log(` ERROR: ${e.message.slice(0, 200)}`); |
| 49 | } |
| 50 | } |
| 51 | process.exit(0); |
| 52 | } |
| 53 | main(); |
no test coverage detected