This guide covers database management operations for the Ashfolio application, including migrations, seeding, backups, and data replication strategies.
# Database operations
just migrate # Run pending migrations
just reset # Reset database with Ecto (drops and recreates)
just reseed # Truncate tables and re-seed with fresh sample data
just db-status # Show table counts and database status
# Backup operations
just backup # Create timestamped database backup
just backups # List available backup files
just restore <file> # Restore from backup fileThe application uses a database-as-user architecture with a single comprehensive migration:
- 20250818052238_create_database_as_user_schema.exs - Complete schema with all tables and relationships
# Run all pending migrations
just migrate
# Check migration status
mix ecto.migrations
# Generate new migration (if needed)
mix ecto.gen.migration migration_nameThe database-as-user architecture eliminates traditional user tables in favor of user settings:
Core Tables:
user_settings- Single-user configuration (currency, locale, preferences)accounts- Investment accounts with balances and metadatasymbols- Financial instruments (stocks, ETFs, crypto)transactions- Transaction history with account/symbol relationshipstransaction_categories- Categorization system for transactions
Key Relationships:
- Transactions → Accounts (required foreign key)
- Transactions → Symbols (required foreign key)
- Transactions → Transaction Categories (optional foreign key)
- Transaction Categories → Parent Categories (hierarchical structure)
The application includes comprehensive sample data for development:
Default User Settings:
- Name: "Local User"
- Currency: "USD"
- Locale: "en-US"
Sample Accounts:
- Schwab Brokerage ($50,000 balance)
- Fidelity 401k ($25,000 balance)
- Crypto Wallet ($5,000 balance)
Sample Symbols:
- AAPL (Apple Inc.) - Stock
- MSFT (Microsoft Corporation) - Stock
- GOOGL (Alphabet Inc.) - Stock
- SPY (SPDR S&P 500 ETF) - ETF
- VTI (Vanguard Total Stock Market ETF) - ETF
- BTC-USD (Bitcoin) - Crypto
Sample Transactions:
- 7 transactions across different accounts and symbols
- Mix of buy, sell, dividend, and fee transactions
- Realistic dates and amounts
# Full database reset with Ecto (recommended for clean start)
just reset
# Truncate and re-seed only (preserves schema)
just reseed
# Check seeded data
just db-status# Create timestamped backup
just backup
# Example output:
# data/backups/ashfolio_backup_20250730T055228.795801Z.db# List all available backups
just backups# Restore from specific backup file
just restore data/backups/ashfolio_backup_20250730T055228.795801Z.db- Backups are stored in
data/backups/ - Filenames include ISO 8601 timestamps for easy identification
- Backups are complete SQLite database copies
- No automatic cleanup - manage backup retention manually
# Start with fresh data
just reseed
# Run tests to ensure stability
just test
# Make changes to code/schema
# ... development work ...
# Run tests after changes
just test
# Create backup before major changes
just backup
# Check data status
just db-status# Generate new migration
mix ecto.gen.migration add_new_feature
# Edit migration file
# ... add migration code ...
# Run migration
just migrate
# Update sample data if needed
# Edit lib/ashfolio/database_manager.ex
just reseed# Create backup of current state
just backup
# Run tests to ensure current state is stable
just test
# Modify data for testing
# ... manual data changes ...
# Run specific tests
just test-file test/ashfolio/seeding_test.exs
# Restore to known state
just restore data/backups/backup_file.db
# Verify restoration with tests
just testThe application currently supports single-user local development only. Data replication features are planned for future implementation:
# Placeholder functions in DatabaseManager
Ashfolio.DatabaseManager.replicate_prod_to_staging() # Not implemented
Ashfolio.DatabaseManager.replicate_staging_to_dev() # Not implementedWhen production and staging environments are available:
-
Production → Staging
- Automated daily replication
- Sanitized data (remove PII)
- Schema and data sync
-
Staging → Development
- On-demand replication
- Subset of data for performance
- Developer-initiated sync
-
Implementation Approach
- SQLite database file copying
- Data transformation scripts
- Backup verification
- Rollback capabilities
# When implemented
just sync-from-staging # Pull staging data to dev
just sync-from-prod # Pull production data to staging
just sanitize-data # Remove PII from copied data-- User settings (single user configuration)
user_settings (id, name, currency, locale, timestamps)
-- Investment accounts
accounts (id, name, platform, currency, account_type, is_excluded, balance,
balance_updated_at, interest_rate, minimum_balance, timestamps)
-- Financial symbols
symbols (id, symbol, name, asset_class, currency, isin, sectors, countries,
data_source, current_price, price_updated_at, timestamps)
-- Transaction categories
transaction_categories (id, name, color, is_system, parent_category_id, timestamps)
-- Transactions
transactions (id, account_id, symbol_id, category_id, type, quantity, price,
total_amount, fee, date, notes, timestamps)- Accounts → Transactions (1:many)
- Symbols → Transactions (1:many)
- Transaction Categories → Transactions (1:many, optional)
- Transaction Categories → Parent Categories (self-referencing hierarchy)
The project maintains a 100% passing test suite (383/383 tests) to ensure stability during development.
# Basic test commands
just test # Run full test suite
just test-file <path> # Run specific test file
# Advanced test commands
just test-coverage # Run tests with coverage report
just test-watch # Run tests in watch mode (re-runs on changes)
just test-failed # Run only failed tests from last run
just test-verbose # Run tests with detailed output# Before making changes
just test # Ensure starting from stable state
# During development
just test-watch # Continuous testing during development
# After changes
just test # Verify all tests still pass
just test-coverage # Check test coverage
# For debugging failures
just test-failed # Focus on failed tests
just test-verbose # Get detailed output for debuggingMigration Errors:
# Check migration status
mix ecto.migrations
# Reset if needed
just resetSeeding Failures:
# Check for constraint violations
just db-status
# Reset and try again
just resetBackup/Restore Issues:
# Verify file exists
ls -la data/backups/
# Check file permissions
chmod 644 data/backups/*.dbIf you encounter persistent issues:
# Nuclear option - complete reset
rm -rf data/ashfolio.db*
rm -rf data/backups/*
just reset- All common query patterns have dedicated indexes
- Use
EXPLAIN QUERY PLANfor complex queries - Monitor query performance in development
- SQLite database grows with transaction history
- Regular backup cleanup recommended
- Consider archiving old transactions in production
- ETS cache separate from database storage
- Database file size typically < 100MB for normal usage
- Backup storage scales with retention policy
- Database files stored in
data/directory - No encryption at rest (local development only)
- Backup files contain full data - secure storage recommended
- Database encryption for sensitive financial data
- Backup encryption and secure storage
- Access logging and audit trails
- Data retention and privacy compliance