chitfund/backend/run-member-number-migration.js

97 lines
3.0 KiB
JavaScript

const { sequelize } = require('./src/config/database');
const { QueryTypes } = require('sequelize');
async function runMigration() {
try {
console.log('🚀 Starting member_number migration...\n');
// Step 1: Add column (if not exists)
console.log('Step 1: Adding member_number column...');
await sequelize.query(`
ALTER TABLE group_members
ADD COLUMN IF NOT EXISTS member_number INTEGER
`);
console.log('✓ Column added\n');
// Step 2: Populate for existing members
console.log('Step 2: Assigning numbers to existing members...');
const [results] = await sequelize.query(`
WITH numbered_members AS (
SELECT
id,
ROW_NUMBER() OVER (
PARTITION BY group_id
ORDER BY joined_date ASC, created_at ASC
) as assigned_number
FROM group_members
WHERE member_number IS NULL
)
UPDATE group_members gm
SET member_number = nm.assigned_number
FROM numbered_members nm
WHERE gm.id = nm.id
RETURNING gm.member_number
`);
console.log(`✓ Assigned numbers to ${results.length} existing members\n`);
// Step 3: Make NOT NULL
console.log('Step 3: Setting NOT NULL constraint...');
await sequelize.query(`
ALTER TABLE group_members
ALTER COLUMN member_number SET NOT NULL
`);
console.log('✓ NOT NULL constraint set\n');
// Step 4: Add unique index
console.log('Step 4: Creating unique index...');
await sequelize.query(`
CREATE UNIQUE INDEX IF NOT EXISTS idx_group_members_member_number
ON group_members(group_id, member_number)
`);
console.log('✓ Unique index created\n');
// Step 5: Verify
console.log('Step 5: Verifying migration...');
const members = await sequelize.query(
`SELECT
gm.member_number,
u.full_name,
cg.name as group_name
FROM group_members gm
JOIN users u ON gm.user_id = u.id
JOIN chit_groups cg ON gm.group_id = cg.id
ORDER BY cg.name, gm.member_number
LIMIT 20`,
{ type: QueryTypes.SELECT }
);
console.log('\n✅ Migration completed successfully!\n');
console.log('Sample members with assigned numbers:');
console.log('─'.repeat(70));
members.forEach(m => {
console.log(`#${m.member_number}\t${m.full_name}\t(${m.group_name})`);
});
console.log('─'.repeat(70));
console.log(`\n✓ Total members checked: ${members.length}`);
console.log('\n🎉 Member numbers are now active!');
console.log(' Restart your backend server to see them in action.');
await sequelize.close();
process.exit(0);
} catch (error) {
console.error('\n❌ Migration failed:', error.message);
console.error('\nFull error:', error);
await sequelize.close();
process.exit(1);
}
}
console.log('═'.repeat(70));
console.log(' MEMBER NUMBER MIGRATION');
console.log(' Adding readable serial numbers (1, 2, 3...) to members');
console.log('═'.repeat(70));
console.log('');
runMigration();