Add isNew column for "new until edited" badge; existing rows are not new.
()
| 1756 | ORDER BY LENGTH(thumbnail) DESC |
| 1757 | `).all(THUMBNAIL_MAX_STORED_CHARS); |
| 1758 | |
| 1759 | if (rows.length === 0) return; |
| 1760 | |
| 1761 | const batch = rows.slice(0, THUMBNAIL_MIGRATION_MAX_PER_SESSION); |
| 1762 | const remaining = rows.length - batch.length; |
| 1763 | console.log( |
| 1764 | `Migrating ${batch.length} legacy thumbnail(s) (${reason || 'startup'})` + |
| 1765 | (remaining > 0 ? `; ${remaining} deferred to a later session` : '') + |
| 1766 | '...' |
| 1767 | ); |
| 1768 | |
| 1769 | let updated = 0; |
| 1770 | for (const row of batch) { |
| 1771 | try { |
| 1772 | const allowOversized = row.thumbLen > THUMBNAIL_ABSOLUTE_MAX_LOAD_CHARS; |
| 1773 | const thumbnail = readThumbnailColumn(row.filePath, { allowOversized }); |
| 1774 | if (!thumbnail) continue; |
| 1775 | |
| 1776 | const parts = thumbnail.includes('::') ? thumbnail.split('::').filter(Boolean) : [thumbnail]; |
| 1777 | const needsWork = parts.some((part) => needsCompression(part)); |
| 1778 | if (!needsWork) continue; |
| 1779 |
no outgoing calls
no test coverage detected