/**
* Migration: avatar → array
*
* Converts Member.Data.avatar from a single file URL string to an array
* containing just the filename. If the stored URL already contains a `?`
* query string that part is kept; otherwise `?date=<iso-date>` is appended
* using the current wall-clock time so clients can bust their caches.
*
* Before: "avatar.jpg" or "https://…/UID/avatar/avatar.jpg"
* After: ["avatar.jpg?date=2026-03-29"] (filename only, array)
*
* Remove `export const disabled = true` to enable this migration.
*/
export const id = '20260330-avatar-strip-uuid';
export const name = 'Strip UUID from Member.Data.avatar URLs';
/** Set to false (or delete this line) when ready to apply */
export const disabled = false;
/** Set to false to actually write changes */
export const DRY_RUN = false;
/**
* @param {{ query: Function, transaction: Function, UUID2hex: Function, HEX2uuid: Function }} api
*/
const newAvatar=(raw)=>{
// Strip any path prefix — keep only the filename (last path segment, before any '?')
const pathPart = raw.split('?')[0];
const queryPart = raw.includes('?') ? raw.slice(raw.indexOf('?')) : `?t=${Date.now()}`;
const filename = pathPart.split('/').pop().replace(/avatar%2[F,f]/, ''); // Handle URL-encoded slash in some stored URLs
const dateSuffix = queryPart ?? `?date=${new Date().toISOString().slice(0, 10)}`;
return `${filename}${dateSuffix}`;
};
export const migrate = async ({ query }) => {
const rows = await query(
`SELECT UID, Data FROM Member WHERE JSON_VALUE(Data, '$.avatar') LIKE 'UUID-%'`,
[],
{ cast: ['json'] }
);
for (const row of rows) {
const Data = row.Data;
if(Data.avatar && typeof Data.avatar === 'string' && Data.avatar.startsWith('UUID-')) {
Data.avatar = newAvatar(Data.avatar);
}
if (DRY_RUN) {
console.log('[DRY RUN] avatar migration:', { UID: row.UID, before: row.Data, after: Data });
} else {
const updated = { ...row.Data, avatar: Data.avatar, avatar_white: Data.avatar_white, avatar_black: Data.avatar_black };
await query(`UPDATE Member SET Data = ? WHERE UID = ?`, [JSON.stringify(Data), row.UID]);
}
}
if (DRY_RUN) console.log(`[DRY RUN] avatar migration: ${rows.length} row(s) would be updated`);
};