Implements persistent flag tracking to ensure default client and project are only created on fresh installations and never recreated after user deletion during updates or restarts. - Added initial_data_seeded flag to InstallationConfig - Updated all 3 database initialization scripts to check flag - Added 3 unit tests (all passing) - Created comprehensive documentation Fixes issue where defaults were recreated after deletion during updates.
5.7 KiB
Default Data Seeding Behavior
Overview
TimeTracker's database initialization has been updated to ensure that default client and project data is only created during a fresh database installation, and never re-injected during subsequent updates or restarts.
Previous Behavior (Before v3.2.3)
Previously, the database initialization scripts would check if specific default entities existed by name:
- If "Default Client" didn't exist, it would be recreated
- If "General" project didn't exist, it would be recreated
This meant that if a user deleted these default entities, they would be re-created on the next container restart or update.
New Behavior (v3.2.3+)
The system now tracks whether initial data has been seeded using a flag in data/installation.json:
{
"initial_data_seeded": true,
"initial_data_seeded_at": "2025-10-23 12:34:56.789"
}
Seeding Logic
-
Fresh Installation (no existing projects):
- Default client "Default Client" is created
- Default project "General" is created
- Flag
initial_data_seededis set totrue
-
Existing Database (projects already exist):
- Default data is NOT created
- Flag
initial_data_seededis set totrueto prevent future attempts
-
Already Seeded (flag is
true):- Default data is NEVER created again
- This persists across updates, restarts, and migrations
Benefits
- User Control: Users can delete default entities without them being recreated
- Clean Updates: Updates won't re-inject deleted default data
- Predictable Behavior: Once deleted, defaults stay deleted
- Migration Safety: Database migrations don't re-seed data
Implementation Details
Configuration Tracking
The InstallationConfig class (app/utils/installation.py) provides methods to track seeding:
from app.utils.installation import get_installation_config
config = get_installation_config()
# Check if initial data has been seeded
if not config.is_initial_data_seeded():
# Create default data...
config.mark_initial_data_seeded()
Affected Scripts
The following database initialization scripts have been updated:
docker/init-database.py- Flask-based initializationdocker/init-database-enhanced.py- Enhanced SQL-based initializationdocker/init-database-sql.py- SQL script-based initialization
All scripts now check the initial_data_seeded flag before creating default entities.
Testing
Unit tests have been added to verify the behavior:
# Run installation config tests
pytest tests/test_installation_config.py -v
# Specific tests for seeding behavior
pytest tests/test_installation_config.py::TestInstallationConfig::test_initial_data_seeding_tracking -v
pytest tests/test_installation_config.py::TestInstallationConfig::test_initial_data_seeding_persistence -v
Resetting Default Data
If you need to reset the system to create default data again:
Option 1: Delete the Flag (Recommended)
Edit data/installation.json and remove the initial_data_seeded flag:
# Linux/Mac
sed -i '/"initial_data_seeded"/d' data/installation.json
# Windows (PowerShell)
(Get-Content data/installation.json) | Where-Object { $_ -notmatch 'initial_data_seeded' } | Set-Content data/installation.json
Then restart the container or application.
Option 2: Manual Deletion
Delete all projects from the database, then remove the flag:
-- Connect to your database
DELETE FROM time_entries; -- Remove time entries first
DELETE FROM projects; -- Remove all projects
DELETE FROM clients; -- Remove all clients
Then remove the initial_data_seeded flag from data/installation.json and restart.
Option 3: Fresh Installation
For a completely fresh start:
# Stop the application
docker-compose down
# Remove the database volume
docker volume rm timetracker_postgres_data
# Remove installation config
rm data/installation.json
# Start fresh
docker-compose up -d
Troubleshooting
Default Data Not Being Created
Symptom: Fresh installation but no default client/project created
Possible Causes:
- The
initial_data_seededflag is already set totrue - Projects already exist in the database
Solution:
- Check
data/installation.jsonfor the flag - Check database for existing projects:
SELECT COUNT(*) FROM projects; - Remove the flag if needed and restart
Default Data Being Recreated (Shouldn't Happen)
Symptom: Deleted default data reappears after restart
This should NOT happen with v3.2.3+. If it does:
- Check your version: The fix is in v3.2.3 and later
- Verify
data/installation.jsonexists and is writable - Check container logs for errors writing to installation.json
- Report as a bug if issue persists
Migration Notes
Upgrading from v3.2.2 to v3.2.3
If you already deleted default entities in v3.2.2:
- Upgrade to v3.2.3
- The flag will be automatically set on first startup (if projects exist)
- Your deleted defaults will NOT be recreated
- No manual intervention needed
Fresh Installation
On a fresh installation:
- Default client and project will be created
- Flag will be set automatically
- You can safely delete these defaults
- They won't be recreated
Related Files
app/utils/installation.py- InstallationConfig classdocker/init-database.py- Flask-based initializationdocker/init-database-enhanced.py- Enhanced initializationdocker/init-database-sql.py- SQL-based initializationtests/test_installation_config.py- Unit tests