97 lines
3.0 KiB
JavaScript
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();
|
|
|