Files
website-enchun-mgr/apps/backend/scripts/migration/update-hero-images-inline.ts
pkupuk be7fc902fb feat(backend): update collections, config and migration tools
Update Payload CMS configuration, collections (Audit, Posts), and add migration scripts/reports.
2026-02-11 11:50:23 +08:00

79 lines
2.4 KiB
TypeScript

#!/usr/bin/env tsx
import('dotenv/config')
import('payload').then(async ({getPayload})=>{
const cfg = await import('../../src/payload.config.ts')
const p = await getPayload({config: cfg.default})
console.log('Loading media...')
const media = await p.find({collection:'media', limit:100, depth:0})
const filenameToId = new Map<string, string>()
media.docs.forEach((m: any) => {
filenameToId.set(m.filename, m.id)
})
console.log(`Found ${filenameToId.size} media files`)
const { parseWebflowCSV } = await import('./csvParser.ts')
const { transformPosts } = await import('./transformers.ts')
const data = await parseWebflowCSV('/Users/pukpuk/Dev/website-enchun-mgr/恩群數位行銷 - 行銷放大鏡集.csv')
const posts = await p.find({collection:'posts', limit:100, depth:0})
const postsBySlug = new Map<string, any>()
posts.docs.forEach((post: any) => {
postsBySlug.set(post.slug, post)
})
console.log('\nMatching hero images...\n')
let matched = 0
let updated = 0
let notFound = 0
for (const webflowPost of data.posts) {
const featuredImage = webflowPost.featuredImage
if (!featuredImage) continue
const urlParts = featuredImage.split('/')
const webflowFilename = urlParts[urlParts.length - 1]
let mediaId: string | null = null
for (const [filename, id] of filenameToId.entries()) {
// Match by checking if both contain the same hash (first 15 chars)
const webflowHash = webflowFilename.split('.')[0].substring(0, 15)
const payloadHash = filename.split('.')[0].substring(0, 15)
if (filename.includes(webflowHash) || webflowFilename.includes(payloadHash)) {
mediaId = id
matched++
break
}
}
if (!mediaId) {
notFound++
console.log(`No match: ${webflowPost.title?.substring(0, 40)}`)
console.log(` URL: ${webflowFilename.substring(0, 80)}`)
continue
}
const transformed = transformPosts([webflowPost])[0]
const post = postsBySlug.get(transformed.slug)
if (post && !post.heroImage) {
await p.update({
collection:'posts',
id: post.id,
data:{ heroImage: mediaId }
})
updated++
console.log(`Updated: ${webflowPost.title?.substring(0, 40)}`)
}
}
console.log('\n=== SUMMARY ===')
console.log(`Matched: ${matched}`)
console.log(`Updated: ${updated}`)
console.log(`Not found: ${notFound}`)
}).catch(e=>console.error('Error:', e))