Files
Momento/scripts/rollback-notebooks.ts
Sepehr Ramezani e4d4e23dc7 chore: clean up repo for public release
- Remove BMAD framework, IDE configs, dev screenshots, test files,
  internal docs, and backup files
- Rename keep-notes/ to memento-note/
- Update all references from keep-notes to memento-note
- Add Apache 2.0 license with Commons Clause (non-commercial restriction)
- Add clean .gitignore and .env.docker.example
2026-04-20 22:48:06 +02:00

168 lines
4.7 KiB
TypeScript
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Rollback Script: Notebooks → Tags
*
* This script rolls back the notebooks migration by:
* 1. Deleting all notebooks
* 2. Removing notebookId from labels (set to empty string)
* 3. Removing notebookId from notes (set to null)
*
* WARNING: This will revert ALL notebook-related changes!
* Make sure you have a database backup before running this.
*
* Usage:
* npx tsx scripts/rollback-notebooks.ts
*
* Confirm by adding --confirm flag:
* npx tsx scripts/rollback-notebooks.ts --confirm
*/
import { prisma } from '../memento-note/lib/prisma'
interface RollbackStats {
notebooksDeleted: number
labelsUpdated: number
notesUpdated: number
errors: string[]
}
/**
* Main rollback function
*/
async function rollbackNotebooks(confirm = false): Promise<RollbackStats> {
console.log('⚠️ NOTEBOOKS ROLLBACK\n')
if (!confirm) {
console.log('❌ ERROR: Rollback requires confirmation.')
console.log('\nTo rollback, run with --confirm flag:')
console.log(' npx tsx scripts/rollback-notebooks.ts --confirm')
console.log('\n⚠ This will:')
console.log(' - Delete ALL notebooks')
console.log(' - Remove notebookId from all labels')
console.log(' - Remove notebookId from all notes')
console.log(' - IRREVERSIBLY delete notebook associations\n')
process.exit(1)
}
console.log('🔄 Starting rollback...\n')
const stats: RollbackStats = {
notebooksDeleted: 0,
labelsUpdated: 0,
notesUpdated: 0,
errors: [],
}
try {
// Step 1: Get count before rollback
console.log('📊 Counting items to rollback...')
const notebookCount = await prisma.notebook.count()
const labelCount = await prisma.label.count({
where: {
notebookId: {
not: '',
},
},
})
const noteCount = await prisma.note.count({
where: {
notebookId: {
not: null,
},
},
})
console.log(` Notebooks to delete: ${notebookCount}`)
console.log(` Labels to update: ${labelCount}`)
console.log(` Notes to update: ${noteCount}\n`)
if (notebookCount === 0 && labelCount === 0 && noteCount === 0) {
console.log(' Nothing to rollback. System is already in pre-migration state.\n')
return stats
}
// Step 2: Update labels (remove notebookId)
if (labelCount > 0) {
console.log('🏷️ Updating labels...')
const labelResult = await prisma.label.updateMany({
where: {
notebookId: {
not: '',
},
},
data: {
notebookId: '',
},
})
stats.labelsUpdated = labelResult.count
console.log(` ✅ Updated ${stats.labelsUpdated} label(s)`)
}
// Step 3: Update notes (remove notebookId)
if (noteCount > 0) {
console.log('📝 Updating notes...')
const noteResult = await prisma.note.updateMany({
where: {
notebookId: {
not: null,
},
},
data: {
notebookId: null,
},
})
stats.notesUpdated = noteResult.count
console.log(` ✅ Updated ${stats.notesUpdated} note(s)`)
}
// Step 4: Delete notebooks (cascade deletes labels, but notes are already updated)
if (notebookCount > 0) {
console.log('📁 Deleting notebooks...')
const notebookResult = await prisma.notebook.deleteMany({})
stats.notebooksDeleted = notebookResult.count
console.log(` ✅ Deleted ${stats.notebooksDeleted} notebook(s)`)
}
// Summary
console.log('\n' + '='.repeat(60))
console.log('✅ Rollback complete!\n')
console.log('📊 Summary:')
console.log(` Notebooks deleted: ${stats.notebooksDeleted}`)
console.log(` Labels updated: ${stats.labelsUpdated}`)
console.log(` Notes updated: ${stats.notesUpdated}`)
if (stats.errors.length > 0) {
console.log(`\n⚠ Errors: ${stats.errors.length}`)
stats.errors.forEach((error) => console.log(`${error}`))
}
console.log('\n' + '='.repeat(60))
console.log('\n✨ Rollback successful!')
console.log('\n📌 System is now back to the flat tags model:')
console.log(' - All notebooks removed')
console.log(' - All labels detached from notebooks')
console.log(' - All notes back in "Notes générales" (Inbox)\n')
return stats
} catch (error) {
console.error('\n❌ Rollback failed:', error)
throw error
} finally {
await prisma.$disconnect()
}
}
// Run rollback
const args = process.argv.slice(2)
const isConfirmed = args.includes('--confirm')
rollbackNotebooks(isConfirmed)
.then(() => {
console.log('✨ All done!')
process.exit(0)
})
.catch((error) => {
console.error('\n💥 Fatal error:', error)
process.exit(1)
})