docs: add Claude development guidelines for database migrations

- Create CLAUDE.md with comprehensive migration guidelines
- Emphasize MUST create migrations for all schema changes
- Provide complete migration template and workflow
- Include naming conventions and best practices
- Document current database schema reference
- Add integration examples for dev/Docker/production

This ensures future AI assistants and developers follow
proper migration practices to prevent schema inconsistencies.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-08-08 00:07:23 -04:00
parent ed896a2bdf
commit 6c4acf438d

201
CLAUDE.md Normal file
View File

@@ -0,0 +1,201 @@
# Claude Development Guidelines
## Database Migrations
**⚠️ IMPORTANT: When making changes to database models or schema, you MUST create migration files.**
### When to Create Migrations
**ALWAYS create a migration when:**
- Adding new columns to existing tables
- Creating new tables
- Modifying column types or constraints
- Adding or removing indexes
- Changing default values
- Adding foreign keys or relationships
**Examples that require migrations:**
```python
# Adding a new field to PetPicture model
class PetPicture:
# ... existing fields ...
tags = models.TextField() # ❌ Requires migration!
```
```python
# Changing database schema in init_db()
def init_db():
db.execute("""
CREATE TABLE users ( -- ❌ New table requires migration!
id INTEGER PRIMARY KEY,
username TEXT NOT NULL
)
""")
```
### How to Create Migrations
1. **Navigate to migrations directory:**
```bash
cd migrations/
```
2. **Create new migration file:**
```bash
# Use next sequential number (002, 003, etc.)
touch XXX_descriptive_name.py
```
3. **Use the migration template:**
```python
#!/usr/bin/env python3
"""
Migration XXX: Brief description of changes
Date: YYYY-MM-DD
Description: Detailed explanation of what this migration does
"""
import sqlite3
import sys
from datetime import datetime
def check_column_exists(cursor, table_name, column_name):
"""Check if a column exists in a table"""
cursor.execute(f"PRAGMA table_info({table_name})")
columns = [column[1] for column in cursor.fetchall()]
return column_name in columns
def migrate_up(cursor):
"""Apply the migration"""
# Check if already applied
if check_column_exists(cursor, 'pet_pictures', 'new_column'):
print("Migration already applied, skipping...")
return False
# Apply the migration
print("Adding new_column to pet_pictures table...")
cursor.execute("ALTER TABLE pet_pictures ADD COLUMN new_column TEXT")
return True
def migrate_down(cursor):
"""Rollback the migration (optional)"""
print("Rollback not implemented for SQLite column drops")
return False
def main():
"""Run migration standalone"""
# Standard migration execution code
pass
if __name__ == "__main__":
sys.exit(main())
```
4. **Test the migration:**
```bash
# Test individual migration
python migrations/XXX_descriptive_name.py
# Or run all pending migrations
python migrations/migrate.py
```
5. **Commit the migration file:**
```bash
git add migrations/XXX_descriptive_name.py
git commit -m "feat: add migration for [description]"
```
### Migration Naming Convention
- **Sequential numbering**: `001_`, `002_`, `003_`, etc.
- **Descriptive names**: Explain what the migration does
- **Examples**:
- `002_add_user_table.py`
- `003_add_tags_column_to_pictures.py`
- `004_create_comments_table.py`
### DO NOT Modify Database Schema Without Migrations
**❌ NEVER do this:**
```python
# Directly modifying init_db() or model schema
def init_db():
db.execute("""
CREATE TABLE pet_pictures (
id INTEGER PRIMARY KEY,
filename TEXT NOT NULL,
new_field TEXT -- ❌ Added without migration!
)
""")
```
**✅ ALWAYS do this:**
1. Create migration file first
2. Run migration to update schema
3. Then update model code if needed
### Model Changes Workflow
1. **Identify needed schema change**
2. **Create migration file**
3. **Test migration locally**
4. **Update model/application code** (if needed)
5. **Test full application**
6. **Commit migration + code changes together**
### Migration Best Practices
- **One logical change per migration**
- **Make migrations idempotent** (safe to run multiple times)
- **Test on development data first**
- **Include rollback logic when possible**
- **Document breaking changes clearly**
- **Never edit applied migrations**
### Integration Points
**Development:**
```bash
# Apply migrations before starting app
python migrations/migrate.py && python main.py
```
**Docker:**
```bash
# Migrations run automatically via docker-compose
docker compose --profile migrate up migrate
```
**Production Deployment:**
```bash
# Run migrations as part of deployment
python migrations/migrate.py
systemctl restart pet-picture-queue
```
---
## Database Schema Reference
**Current Schema (after migrations):**
### `pet_pictures` table:
- `id` - INTEGER PRIMARY KEY AUTOINCREMENT
- `filename` - TEXT NOT NULL
- `subscriber_name` - TEXT NOT NULL
- `description` - TEXT NULL (added via migration 001)
- `uploaded_at` - TIMESTAMP NOT NULL
- `posted` - BOOLEAN DEFAULT 0
- `likes` - INTEGER DEFAULT 0
### `migrations` table (auto-created):
- `id` - INTEGER PRIMARY KEY AUTOINCREMENT
- `migration_name` - TEXT NOT NULL UNIQUE
- `applied_at` - TIMESTAMP NOT NULL
---
**Remember: Schema changes without migrations will cause deployment issues and data inconsistencies!**
Always follow the migration workflow for database changes.