diff --git a/DATABASE_MIGRATIONS.md b/DATABASE_MIGRATIONS.md new file mode 100644 index 0000000..28642ee --- /dev/null +++ b/DATABASE_MIGRATIONS.md @@ -0,0 +1,345 @@ +# BREEDR Database Migrations + +## Automatic Migration System + +BREEDR now includes an **automatic migration system** that runs on every startup to ensure your database schema is always correct and up-to-date. + +## How It Works + +### On Every Startup + +1. **Initialize Database** - Creates tables if they don't exist +2. **Run Migrations** - Automatically fixes schema issues +3. **Validate Schema** - Verifies everything is correct +4. **Start Application** - Server begins accepting requests + +You don't need to do anything manually! + +--- + +## Migrations Included + +### Migration 001: Remove Old Parent Columns + +**Problem**: Old schema had `sire` and `dam` columns in the `dogs` table causing "no such column: sire" errors. + +**Solution**: +- Creates `parents` table for relationships +- Migrates existing sire/dam data to `parents` table +- Recreates `dogs` table without sire/dam columns +- Preserves all existing dog data + +**Automatic**: Runs only if old schema detected + +### Migration 002: Add Litter ID Column + +**Problem**: Dogs table missing `litter_id` column for linking puppies to litters. + +**Solution**: +- Adds `litter_id` column to `dogs` table +- Creates foreign key to `litters` table + +**Automatic**: Runs only if column is missing + +--- + +## Schema Version Tracking + +The migration system uses a `schema_version` table to track which migrations have been applied: + +```sql +CREATE TABLE schema_version ( + version INTEGER PRIMARY KEY, + applied_at DATETIME DEFAULT CURRENT_TIMESTAMP, + description TEXT +); +``` + +Each migration runs only once, even if you restart the server multiple times. + +--- + +## Correct Schema (Current) + +### Dogs Table (No sire/dam columns!) + +```sql +CREATE TABLE dogs ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name TEXT NOT NULL, + registration_number TEXT, + microchip TEXT, + sex TEXT CHECK(sex IN ('male', 'female')), + birth_date DATE, + breed TEXT, + color TEXT, + weight REAL, + height REAL, + notes TEXT, + litter_id INTEGER, + photo_urls TEXT, + is_active INTEGER DEFAULT 1, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (litter_id) REFERENCES litters(id) ON DELETE SET NULL +); +``` + +### Parents Table (Relationships) + +```sql +CREATE TABLE parents ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + dog_id INTEGER NOT NULL, + parent_id INTEGER NOT NULL, + parent_type TEXT NOT NULL CHECK(parent_type IN ('sire', 'dam')), + FOREIGN KEY (dog_id) REFERENCES dogs(id) ON DELETE CASCADE, + FOREIGN KEY (parent_id) REFERENCES dogs(id) ON DELETE CASCADE, + UNIQUE(dog_id, parent_type) +); +``` + +--- + +## How to Use + +### Normal Startup (Automatic) + +Just start your application normally: + +```bash +# With Docker +docker-compose up -d + +# Without Docker +cd server && npm start +``` + +Migrations run automatically! + +### Check Migration Logs + +Look at the server console output: + +``` +============================================================ +BREEDR Database Migration System +============================================================ +Database: /app/data/breedr.db + +Current schema version: 0 + +[Migration 001] Checking for old sire/dam columns... +[Migration 001] Found old schema with sire/dam columns +[Migration 001] Migrating to parents table... +[Migration 001] Backed up 15 dogs +[Migration 001] Migrated 8 sire relationships +[Migration 001] Migrated 8 dam relationships +[Migration 001] Dropped old dogs table +[Migration 001] Created new dogs table +[Migration 001] Restored 15 dogs +[Migration 001] ✓ Migration complete! + +[Migration 002] Checking for litter_id column... +[Migration 002] litter_id column already exists, skipping + +[Validation] ✓ Dogs table exists +[Validation] ✓ Dogs table has no sire/dam columns +[Validation] ✓ Parents table exists +[Validation] ✓ Litter_id column exists +[Validation] ✓ Litters table exists +[Validation] ✓ All schema checks passed! + +============================================================ +Schema version: 0 → 2 +Migration system complete! +============================================================ +``` + +### Manual Migration (If Needed) + +You can also run migrations manually: + +```bash +node server/db/migrations.js +``` + +--- + +## Fresh Install + +For a fresh installation: + +1. **No database file exists** → `init.js` creates correct schema +2. **Migrations check schema** → Everything already correct, no migration needed +3. **Application starts** → Ready to use! + +**Result**: Fresh installs automatically have the correct schema. + +--- + +## Upgrading from Old Version + +For existing installations with old schema: + +1. **Old database detected** → Migration system kicks in +2. **Data is backed up** → Safety first! +3. **Schema is updated** → Sire/dam data moved to parents table +4. **Data is restored** → All your dogs are preserved +5. **Application starts** → Now using correct schema! + +**Result**: Existing data is preserved and schema is fixed automatically. + +--- + +## Docker Integration + +### Dockerfile + +No changes needed! Migrations run automatically when the container starts. + +### docker-compose.yml + +No changes needed! Just restart: + +```bash +docker-compose restart +``` + +Or rebuild: + +```bash +docker-compose down +docker-compose up --build -d +``` + +--- + +## Troubleshooting + +### Migration Failed + +If you see an error: + +``` +⚠️ Database migration failed! +Error: [error message] +``` + +1. **Check the error message** - It will tell you what went wrong +2. **Check database file permissions** - Make sure the file is writable +3. **Check disk space** - Ensure you have enough space +4. **Try manual migration**: + ```bash + node server/db/migrations.js + ``` + +### Database is Locked + +If migrations fail with "database is locked": + +1. Stop all running instances of BREEDR +2. Check for zombie processes: `ps aux | grep node` +3. Kill any old processes: `kill ` +4. Restart BREEDR + +### Migration Keeps Running + +If the same migration runs every time: + +1. Check `schema_version` table: + ```sql + SELECT * FROM schema_version; + ``` +2. If empty, migration isn't being recorded +3. Check for database transaction issues +4. Manually add version: + ```sql + INSERT INTO schema_version (version, description) VALUES (1, 'Manual fix'); + ``` + +### Want to Start Fresh + +To completely reset the database: + +1. **Stop BREEDR** +2. **Backup your data** (optional): + ```bash + cp data/breedr.db data/breedr.db.backup + ``` +3. **Delete database**: + ```bash + rm data/breedr.db + ``` +4. **Restart BREEDR** - Fresh database will be created + +--- + +## Validation Checks + +The migration system validates your schema: + +- ✓ Dogs table exists +- ✓ Dogs table has no sire/dam columns +- ✓ Parents table exists +- ✓ Litter_id column exists +- ✓ Litters table exists + +If any check fails, you'll see a warning. + +--- + +## Adding New Migrations + +If you need to add a new migration: + +1. **Edit `server/db/migrations.js`** +2. **Add new migration function**: + ```javascript + migration003_yourNewMigration() { + console.log('[Migration 003] Doing something...'); + // Your migration code here + } + ``` +3. **Add to runMigrations()**: + ```javascript + if (currentVersion < 3) { + this.migration003_yourNewMigration(); + this.recordMigration(3, 'Description of migration'); + } + ``` +4. **Test thoroughly** before deploying + +--- + +## Best Practices + +1. **Let migrations run automatically** - Don't skip them +2. **Check logs on startup** - Verify migrations succeeded +3. **Backup before major updates** - Safety first +4. **Test in development** - Before deploying to production +5. **Monitor schema_version** - Know what version you're on + +--- + +## Schema Version History + +| Version | Description | Date | +|---------|-------------|------| +| 0 | Initial schema (may have sire/dam columns) | - | +| 1 | Migrated to parents table | March 2026 | +| 2 | Added litter_id column | March 2026 | + +--- + +## Summary + +✅ **Migrations run automatically on every startup** +✅ **No manual intervention needed** +✅ **Data is preserved during migrations** +✅ **Schema is validated after migrations** +✅ **Works with Docker and standalone** +✅ **Fresh installs get correct schema** +✅ **Old installs are automatically upgraded** + +**The "no such column: sire" error is now fixed automatically!** 🎉