Refactor Media Manager sync logic and fix duplication bugs
This major refactor addresses improper image matching and duplication: - Implemented strict ID-based matching in 'MediaService', removing the greedy filename matching fallback. - Redesigned synchronization pipeline to treat Google Drive as the Source of Truth, supporting orphan adoption (Shopify -> Drive) and secure uploads. - Implemented 'gallery_order' using Drive file properties (supporting both v2 and v3 APIs) for stable, drag-and-drop global ordering. - Added conditional file renaming using timestamps to enforce '_' naming convention without unnecessary renames. - Fixed runtime errors in 'MediaService' loops and updated 'ShopifyMediaService' GraphQL mutations to match correctly schema. - Rewrote 'MediaService.test.ts' with robust test cases for strict matching, adoption, sorting, and reordering.
This commit is contained in:
@ -12,11 +12,29 @@ export class MockDriveService implements IDriveService {
|
||||
// Mock implementation finding by name "under" parent
|
||||
const key = `${parentFolderId}/${folderName}`
|
||||
if (!this.folders.has(key)) {
|
||||
const id = `mock_folder_${folderName}_id`
|
||||
const newFolder = {
|
||||
getId: () => `mock_folder_${folderName}_id`,
|
||||
getId: () => id,
|
||||
getName: () => folderName,
|
||||
getUrl: () => `https://mock.drive/folders/${folderName}`,
|
||||
createFile: (blob) => this.saveFile(blob, `mock_folder_${folderName}_id`)
|
||||
createFile: (blob) => this.saveFile(blob, id),
|
||||
addFile: (file) => {
|
||||
console.log(`[MockDrive] addFile: Adding ${file.getId()} to ${id}`)
|
||||
// Remove from all other folders (simplification) or just 'root'
|
||||
for (const [fId, files] of this.files.entries()) {
|
||||
const idx = files.findIndex(f => f.getId() === file.getId())
|
||||
if (idx !== -1) {
|
||||
console.log(`[MockDrive] Removed ${file.getId()} from ${fId}`)
|
||||
files.splice(idx, 1)
|
||||
}
|
||||
}
|
||||
// Add to this folder
|
||||
if (!this.files.has(id)) {
|
||||
this.files.set(id, [])
|
||||
}
|
||||
this.files.get(id).push(file)
|
||||
return newFolder
|
||||
}
|
||||
} as unknown as GoogleAppsScript.Drive.Folder;
|
||||
this.folders.set(key, newFolder)
|
||||
}
|
||||
@ -24,20 +42,26 @@ export class MockDriveService implements IDriveService {
|
||||
}
|
||||
|
||||
saveFile(blob: GoogleAppsScript.Base.Blob, folderId: string): GoogleAppsScript.Drive.File {
|
||||
const id = `mock_file_${Date.now()}_${Math.floor(Math.random() * 1000)}`
|
||||
const newFile = {
|
||||
getId: () => `mock_file_${Date.now()}`,
|
||||
getId: () => id,
|
||||
getName: () => blob.getName(),
|
||||
getBlob: () => blob,
|
||||
getUrl: () => `https://mock.drive/files/${blob.getName()}`,
|
||||
getLastUpdated: () => new Date(),
|
||||
getThumbnail: () => ({ getBytes: () => [] })
|
||||
getThumbnail: () => ({ getBytes: () => [] }),
|
||||
getAppProperty: (key) => {
|
||||
return (newFile as any)._properties?.[key]
|
||||
}
|
||||
} as unknown as GoogleAppsScript.Drive.File
|
||||
|
||||
// Initialize properties container
|
||||
;(newFile as any)._properties = {}
|
||||
|
||||
if (!this.files.has(folderId)) {
|
||||
this.files.set(folderId, [])
|
||||
}
|
||||
this.files.get(folderId).push(newFile)
|
||||
console.log(`[MockDrive] Saved file ${newFile.getName()} to ${folderId}. Total files: ${this.files.get(folderId).length}`)
|
||||
return newFile
|
||||
}
|
||||
|
||||
@ -69,10 +93,25 @@ export class MockDriveService implements IDriveService {
|
||||
|
||||
updateFileProperties(fileId: string, properties: any): void {
|
||||
console.log(`[MockDrive] Updating properties for ${fileId}`, properties)
|
||||
const file = this.getFileById(fileId)
|
||||
const mockFile = file as any
|
||||
if (!mockFile._properties) {
|
||||
mockFile._properties = {}
|
||||
}
|
||||
Object.assign(mockFile._properties, properties)
|
||||
}
|
||||
|
||||
createFile(blob: GoogleAppsScript.Base.Blob): GoogleAppsScript.Drive.File {
|
||||
// Create in "root" or similar
|
||||
return this.saveFile(blob, "root")
|
||||
}
|
||||
|
||||
getFileProperties(fileId: string): {[key: string]: string} {
|
||||
try {
|
||||
const file = this.getFileById(fileId)
|
||||
return (file as any)._properties || {}
|
||||
} catch (e) {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user