# Data Format Versioning

pyPhotoAlbum uses a comprehensive versioning system to manage data format changes and ensure compatibility across versions.

## Current Version

**Data Format Version: 2.0**

## Version History

### Version 2.0 (Released: 2025-01-11)

**Description:** Fixed asset path handling - paths now stored relative to project folder

**Breaking Changes:**
- Asset paths changed from absolute/full-project-relative to project-relative
- Added automatic path normalization for legacy projects

**Compatibility:** Can read and migrate v1.0 files automatically

**Key Improvements:**
- Asset paths now stored as `assets/image.jpg` instead of `./projects/ProjectName/assets/image.jpg`
- Automatic path normalization when loading old projects
- Added search path system for finding assets in multiple locations
- ZIP file directory automatically added as a search path
- New "Heal Assets" feature to reconnect missing images

### Version 1.0 (Released: 2024-01-01)

**Description:** Initial format with basic serialization

**Features:**
- Basic project structure
- Page layouts and elements
- Asset management with reference counting
- ZIP-based `.ppz` project format

## How Versioning Works

### File Format

Each `.ppz` file contains a `project.json` with version information:

```json
{
  "name": "My Project",
  "data_version": "2.0",
  "serialization_version": "2.0",
  ...
}
```

- `data_version`: Current versioning system (introduced in v2.0)
- `serialization_version`: Legacy version field (for backward compatibility)

### Loading Process

When loading a project file:

1. **Version Detection:** The system reads both `data_version` (new) and `serialization_version` (legacy) fields
2. **Compatibility Check:** Verifies if the file version is compatible with the current version
3. **Migration (if needed):** Automatically migrates data from old versions to current format
4. **Path Normalization:** Fixes asset paths to work with current project location
5. **Asset Resolution:** Sets up search paths for finding images

### Compatibility Levels

The system supports multiple compatibility levels:

- **Full Compatibility:** Same version, no migration needed
- **Backward Compatibility:** Older version can be read with automatic migration
- **Incompatible:** Version cannot be loaded (future versions or corrupted files)

## For Developers

### Adding a New Version

When making breaking changes to the data format:

1. **Update version_manager.py:**
   ```python
   CURRENT_DATA_VERSION = "3.0"  # Increment major version

   VERSION_HISTORY["3.0"] = {
       "description": "Description of changes",
       "released": "2025-XX-XX",
       "breaking_changes": [
           "List of breaking changes"
       ],
       "compatible_with": ["2.0", "3.0"],
   }
   ```

2. **Create a migration function:**
   ```python
   @DataMigration.register_migration("2.0", "3.0")
   def migrate_2_0_to_3_0(data: Dict[str, Any]) -> Dict[str, Any]:
       # Perform data transformations
       data['data_version'] = "3.0"
       return data
   ```

3. **Test the migration:**
   - Create test files with old format
   - Verify they load correctly with migration
   - Verify no migration needed for new files

### Version Compatibility Guidelines

**When to increment version:**

- **Major version (1.0 → 2.0):** Breaking changes to data structure
  - Field renames or removals
  - Changed data types
  - New required fields
  - Incompatible serialization changes

- **Minor version (2.0 → 2.1):** Backward-compatible additions
  - New optional fields
  - New features that don't break old data
  - Performance improvements

**Migration Best Practices:**

1. Always test migrations with real user data
2. Log migration steps for debugging
3. Preserve user data even if it can't be fully migrated
4. Provide clear error messages for incompatible versions
5. Document all breaking changes in VERSION_HISTORY

## For Users

### What You Need to Know

- **Automatic Updates:** Old project files are automatically updated when opened
- **No Data Loss:** Your original `.ppz` file remains unchanged
- **Backward Compatibility:** Newer versions can read older files
- **Version Info:** Use File → About to see current version information

### Troubleshooting

**"Incompatible file version" error:**
- The file was created with a much newer or incompatible version
- Solution: Use the version of pyPhotoAlbum that created the file, or upgrade

**Missing assets after loading:**
- Use File → "Heal Assets" to add search paths
- The directory containing the `.ppz` file is automatically searched
- You can add additional locations where images might be found

**Want to ensure future compatibility:**
- Keep your `.ppz` files
- When upgrading, test opening your projects
- Report any migration issues on GitHub

## Implementation Details

### Files Involved

- `version_manager.py`: Core versioning system and migrations
- `project_serializer.py`: Handles loading/saving with version checks
- `models.py`: Asset path resolution with search paths
- `asset_heal_dialog.py`: UI for reconnecting missing assets

### Key Classes

- `VersionCompatibility`: Checks version compatibility
- `DataMigration`: Manages migration functions
- `AssetManager`: Handles asset storage and reference counting

### Search Path Priority

When resolving asset paths (in order):

1. Project folder (primary location)
2. Additional search paths (from Heal Assets)
3. Directory containing the `.ppz` file
4. Current working directory (fallback)
5. Parent of working directory (fallback)
