gohorsejobs/seeder-api/src/utils/uuid.js
Tiago Yamamoto ae4a3e5e63 feat: migrate from UUID v4 to UUID v7
Migrations:
- Fix 010_seed_super_admin.sql: only use columns from migration 001
- Add 021_create_uuid_v7_function.sql: PostgreSQL uuid_generate_v7() function
- Add 022_migrate_to_uuid_v7.sql: update notifications, tickets, job_payments to use v7

Seeder:
- Create seeder-api/src/utils/uuid.js with uuidv7() function
- Update notifications.js to use uuidv7() instead of randomUUID()

Docs:
- Update DATABASE.md with UUID v7 section and benefits

UUID v7 benefits:
- Time-ordered (sortable by creation time)
- Better index performance than v4
- RFC 9562 compliant
2025-12-24 11:19:26 -03:00

66 lines
1.8 KiB
JavaScript

/**
* UUID v7 Generator for Node.js
* Generates time-ordered UUIDs per RFC 9562
*
* Format: tttttttt-tttt-7xxx-yxxx-xxxxxxxxxxxx
* - t = timestamp (48 bits)
* - 7 = version
* - x = random
* - y = variant (8, 9, a, or b)
*/
import crypto from 'crypto';
/**
* Generate a UUID v7 (time-ordered)
* @returns {string} UUID v7 string
*/
export function uuidv7() {
// Get current timestamp in milliseconds
const timestamp = Date.now();
// Generate random bytes
const randomBytes = crypto.randomBytes(10);
// Build UUID bytes (16 total)
const bytes = Buffer.alloc(16);
// First 6 bytes: timestamp (48 bits, big-endian)
bytes.writeUInt32BE(Math.floor(timestamp / 0x10000), 0);
bytes.writeUInt16BE(timestamp & 0xFFFF, 4);
// Next 2 bytes: version (4 bits = 7) + random (12 bits)
bytes[6] = 0x70 | (randomBytes[0] & 0x0F); // version 7
bytes[7] = randomBytes[1];
// Last 8 bytes: variant (2 bits = 10) + random (62 bits)
bytes[8] = 0x80 | (randomBytes[2] & 0x3F); // variant RFC 4122
randomBytes.copy(bytes, 9, 3, 10);
// Format as UUID string
const hex = bytes.toString('hex');
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
}
/**
* Validate if a string is a valid UUID (any version)
* @param {string} uuid
* @returns {boolean}
*/
export function isValidUUID(uuid) {
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
return uuidRegex.test(uuid);
}
/**
* Get UUID version from a UUID string
* @param {string} uuid
* @returns {number} version (1-7) or 0 if invalid
*/
export function getUUIDVersion(uuid) {
if (!isValidUUID(uuid)) return 0;
return parseInt(uuid.charAt(14), 16);
}
// Export default for convenience
export default { uuidv7, isValidUUID, getUUIDVersion };