Files
TimeTracker/docs/features/ALEMBIC_MIGRATION_README.md
2025-10-09 13:48:03 +02:00

7.1 KiB

Alembic Migration for Project Costs - README

Migration is Ready!

The Alembic migration for the Project Costs feature has been properly configured and is ready to run.

Migration Details

File: migrations/versions/018_add_project_costs_table.py

Revision: 018
Previous Revision: 017
Status: Ready to execute

Quick Start

Step 1: Backup Database (CRITICAL!)

# PostgreSQL
pg_dump -U timetracker timetracker > backup_$(date +%Y%m%d).sql

# Or if using Docker
docker-compose exec db pg_dump -U timetracker timetracker > backup_$(date +%Y%m%d).sql

Step 2: Check Current Migration Status

# Using Flask-Migrate
flask db current

# Expected output: 017 (or similar)

Step 3: Run the Migration

# Using Flask-Migrate (recommended)
flask db upgrade

# Or using Alembic directly
alembic upgrade head

Step 4: Verify Success

# Check migration status
flask db current
# Expected output: 018 (head)

# Verify table was created
psql -U timetracker -d timetracker -c "\d project_costs"

Step 5: Restart Application

# Docker
docker-compose restart app

# Or restart your Flask application server

What the Migration Does

Creates Table: project_costs

Columns:

  • id - Primary key (Integer)
  • project_id - Foreign key to projects (Integer, NOT NULL)
  • user_id - Foreign key to users (Integer, NOT NULL)
  • description - Cost description (String 500, NOT NULL)
  • category - Cost category (String 50, NOT NULL)
  • amount - Cost amount (Numeric 10,2, NOT NULL)
  • currency_code - Currency (String 3, default 'EUR')
  • billable - Whether billable (Boolean, default TRUE)
  • invoiced - Whether invoiced (Boolean, default FALSE)
  • invoice_id - Foreign key to invoices (Integer, NULL)
  • cost_date - Date of cost (Date, NOT NULL)
  • notes - Additional notes (Text, NULL)
  • receipt_path - Path to receipt (String 500, NULL)
  • created_at - Creation timestamp (DateTime)
  • updated_at - Update timestamp (DateTime)

Indexes:

  • ix_project_costs_project_id on project_id
  • ix_project_costs_user_id on user_id
  • ix_project_costs_cost_date on cost_date
  • ix_project_costs_invoice_id on invoice_id

Foreign Keys:

  • fk_project_costs_project_idprojects(id) ON DELETE CASCADE
  • fk_project_costs_user_idusers(id) ON DELETE CASCADE
  • fk_project_costs_invoice_idinvoices(id) ON DELETE SET NULL

Safety Features

The migration includes:

  • Table existence check (won't fail if table exists)
  • Proper foreign key constraints
  • Indexes for performance
  • Safe rollback capability
  • Follows existing migration chain (017 → 018)

Alternative Migration Methods

If Alembic/Flask-Migrate is not available:

Method 1: Direct SQL

psql -U timetracker -d timetracker -f migrations/add_project_costs.sql

Method 2: Python Script (Docker)

python docker/migrate-add-project-costs.py

Rollback (If Needed)

To rollback the migration:

# Using Flask-Migrate
flask db downgrade

# Or to specific revision
flask db downgrade 017

# Using Alembic
alembic downgrade -1
# or
alembic downgrade 017

⚠️ WARNING: Rollback will delete the project_costs table and all data!

Verification Checklist

After migration, verify:

  • Migration status shows 018
  • Table project_costs exists
  • All columns are present
  • Indexes are created
  • Foreign keys are in place
  • Application starts without errors
  • Can view project page
  • Can add a test cost
  • Can edit the test cost
  • Can delete the test cost

Expected Output

Successful Migration

INFO  [alembic.runtime.migration] Context impl PostgresqlImpl.
INFO  [alembic.runtime.migration] Will assume transactional DDL.
INFO  [alembic.runtime.migration] Running upgrade 017 -> 018, Add project costs table for tracking expenses

Verification Query

-- Run this to verify table structure
\d project_costs

-- Expected output shows:
-- Table "public.project_costs"
-- Column, Type, Collation, Nullable, Default
-- (all columns listed)
-- Indexes: (4 indexes listed)
-- Foreign-key constraints: (3 constraints listed)

Troubleshooting

"Table already exists"

The migration has safety checks. If you see this error:

# Mark migration as complete
alembic stamp 018

"Cannot find revision 017"

Ensure previous migrations are run:

flask db upgrade 017

"Foreign key constraint violation"

Ensure tables projects, users, and invoices exist:

psql -U timetracker -d timetracker -c "\dt"

"Permission denied"

Grant necessary permissions:

GRANT CREATE ON DATABASE timetracker TO timetracker;

Post-Migration Steps

  1. Restart Application

    docker-compose restart app
    
  2. Clear Cache (if applicable)

    redis-cli FLUSHALL  # if using Redis
    
  3. Test in Browser

    • Navigate to a project
    • Look for "Project Costs & Expenses" section
    • Add a test cost
  4. Monitor Logs

    tail -f logs/timetracker.log
    

Migration Files Structure

TimeTracker/
├── migrations/
│   ├── versions/
│   │   ├── 001_initial_schema.py
│   │   ├── ...
│   │   ├── 017_reporting_invoicing_extensions.py
│   │   └── 018_add_project_costs_table.py  ← NEW
│   ├── add_project_costs.sql               ← Alternative
│   └── alembic.ini
├── docker/
│   └── migrate-add-project-costs.py        ← Alternative
└── MIGRATION_INSTRUCTIONS.md               ← Detailed guide

Support & Documentation

  • Detailed Instructions: MIGRATION_INSTRUCTIONS.md
  • Feature Documentation: PROJECT_COSTS_FEATURE.md
  • Implementation Details: PROJECT_COSTS_IMPLEMENTATION_SUMMARY.md
  • Quick Start: QUICK_START_PROJECT_COSTS.md

Migration Revision Chain

... → 016 → 017 → 018 (head)
              ↑      ↑
          Previous  Current
                   (project_costs)

Testing the Migration

If you want to test before running on production:

  1. Create test database:

    CREATE DATABASE timetracker_test;
    
  2. Restore backup to test database:

    pg_restore -U timetracker -d timetracker_test backup.sql
    
  3. Run migration on test:

    DB_NAME=timetracker_test flask db upgrade
    
  4. Verify on test:

    psql -U timetracker -d timetracker_test -c "\d project_costs"
    
  5. If successful, run on production

Success Criteria

Migration is successful when:

  • No error messages during upgrade
  • Current revision is 018
  • Table project_costs exists with all columns
  • All 4 indexes are created
  • All 3 foreign keys are in place
  • Application starts without errors
  • Project page shows costs section
  • Can perform CRUD operations on costs

Questions?

If you encounter issues:

  1. Check logs: logs/timetracker.log
  2. Verify database connection
  3. Review MIGRATION_INSTRUCTIONS.md
  4. Check database state: \d project_costs

Ready to migrate? Follow the Quick Start steps above!