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
66 lines
1.8 KiB
JavaScript
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 };
|