# DSS Export/Import System - Complete Implementation Guide ## Overview The DSS (Design System Studio) Export/Import system enables complete project archival, distribution, and restoration with round-trip fidelity. Projects can be exported to versioned `.dss` archive files and imported back with full metadata, relationships, and audit information preserved. **Key Features:** - ✅ Round-trip fidelity (export → import = identical state) - ✅ Complete metadata preservation (source attribution, deprecation, timestamps) - ✅ Multiple import strategies (Replace, Merge, Fork) - ✅ UUID-based smart merging with conflict detection - ✅ Schema versioning with automatic migrations - ✅ Referential integrity validation - ✅ Backward compatible (no breaking changes) --- ## Architecture Overview ### Shadow UUID Strategy Instead of replacing existing integer IDs, we introduce UUIDs as a **transport-layer identity**: ``` Database (Runtime): Archive Format (Transport): ┌──────────────────┐ ┌──────────────────┐ │ id (integer/str) │ │ UUID references │ │ projects │────────▶│ .dss archive │ │ components │ │ (ZIP) │ │ tokens │ │ │ └──────────────────┘ └──────────────────┘ (unchanged) (new, export-only) ``` **Benefits:** - No database schema breaking changes - Backward compatible with existing code - Clean separation of export/import logic from runtime logic - Supports distributed collaboration --- ## Implementation Details ### Phase 1: Model Extensions (UUID Fields) All models now include optional UUID fields with auto-generation: ```python from dss.models.project import Project from dss.models.component import Component from dss.models.theme import DesignToken, Theme # UUIDs are auto-generated if not provided project = Project( id="my-project", # Keep existing ID for runtime uuid="...", # Auto-generated UUID name="My Design System" ) token = DesignToken( uuid="...", # Auto-generated name="primary", value="#3B82F6" ) component = Component( uuid="...", # Auto-generated name="Button" ) ``` **Database Schema Changes:** - Added `uuid TEXT UNIQUE` columns to: `projects`, `components`, `styles` - UUIDs nullable for backward compatibility - Indexed for fast lookups ### Phase 2: Export (Archive Creation) Creates versioned `.dss` ZIP archives with complete project state: ``` project.dss (ZIP Archive) ├── manifest.json # Metadata, version, contents ├── config.json # Project configuration ├── tokens.json # All tokens with metadata ├── components.json # Components with variants ├── themes.json # Theme definitions └── history/ # Future: audit logs └── audit-trail.json ``` **Example Export:** ```python from pathlib import Path from dss.export_import import DSSArchiveExporter project = Project(...) # Your DSS project exporter = DSSArchiveExporter(project) archive_path = exporter.export_to_file(Path("my-design-system.dss")) print(f"Exported to: {archive_path}") # Output: Exported to: my-design-system.dss (2.3 MB) ``` **Exported Token Format (W3C-compatible):** ```json { "tokens": { "colors": { "primary": { "uuid": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "$value": "#3B82F6", "$type": "color", "$category": "color", "$description": "Primary brand color", "$source": "figma:abc123", "$deprecated": false, "$createdAt": "2025-01-15T10:00:00Z", "$updatedAt": "2025-12-01T14:30:00Z" } } } } ``` ### Phase 3: Import (Archive Loading) Loads `.dss` archives with three strategies: #### 3a. REPLACE Strategy (Backup Restore) Complete project replacement - ideal for backup restoration and cloning: ```python from dss.export_import import DSSArchiveImporter importer = DSSArchiveImporter(Path("backup.dss")) # Analyze before importing (no modifications) analysis = importer.analyze() print(f"Valid: {analysis.is_valid}") print(f"Errors: {[e.message for e in analysis.errors]}") # Import with REPLACE (wipes all existing data) imported_project = importer.import_replace() ``` **Validation Pipeline:** 1. Archive integrity check (valid ZIP, required files present) 2. Manifest validation (required fields, version format) 3. Schema version compatibility (migrations if needed) 4. Structural validation (JSON format, required keys) 5. Referential integrity (all UUIDs resolve, no dangling references) #### 3b. MERGE Strategy (Smart Update) UUID-based intelligent merging for team collaboration: ```python from dss.export_import import DSSArchiveImporter from dss.export_import.merger import SmartMerger, ConflictResolutionMode # Load imported project importer = DSSArchiveImporter(Path("updated.dss")) imported_project = importer.import_replace() # Create merger local_project = Project(...) # Your current project merger = SmartMerger(local_project, imported_project) # Analyze merge analysis = merger.analyze_merge() print(f"New tokens: {len(analysis.new_items['tokens'])}") print(f"Updated: {len(analysis.updated_items['tokens'])}") print(f"Conflicts: {len(analysis.conflicted_items)}") # Perform merge with strategy merged = merger.merge_with_strategy( ConflictResolutionMode.OVERWRITE # Import wins ) ``` **Merge Detection:** - New items: Exist in import, not in local → Add - Updated items: Same UUID, same hash → Skip - Updated items: Same UUID, different hash, not modified locally → Update - Conflicts: Same UUID, different hash, modified both → Detect **Conflict Strategies:** - `OVERWRITE`: Import version wins (timestamp-based guidance) - `KEEP_LOCAL`: Keep local version (safest for local work) - `FORK`: Create duplicate with new UUID (no data loss) **Example Conflict Resolution:** ```python from dss.export_import.merger import ConflictItem analysis = merger.analyze_merge() for conflict in analysis.conflicted_items: print(f"Conflict: {conflict.entity_name}") print(f" Local updated: {conflict.local_updated_at}") print(f" Imported updated: {conflict.imported_updated_at}") print(f" Local is newer: {conflict.local_is_newer}") print(f" Imported is newer: {conflict.imported_is_newer}") # Apply strategy if analysis.has_conflicts: merged = merger.merge_with_strategy( ConflictResolutionMode.MANUAL # Handled elsewhere ) ``` ### Phase 4: Schema Versioning & Migrations Automatic schema evolution handling: ```python from dss.export_import.migrations import MigrationManager # Current schema version current = MigrationManager.get_latest_version() print(f"Current schema: {current}") # "1.0.1" # Automatic migration on import archive_version = "1.0.0" # Old archive target_version = current if archive_version < target_version: migrated_data = MigrationManager.migrate( archive_data, from_version=archive_version, to_version=target_version ) ``` **Version Compatibility:** - Old archives (v1.0.0) → Auto-migrated to latest - Current archives (v1.0.1) → No migration needed - Newer archives (v1.0.2) → Error: Please update DSS **Defining New Migrations:** ```python from dss.export_import.migrations import SchemaMigration, MigrationManager class MigrationV1_0_1_to_V1_0_2(SchemaMigration): source_version = "1.0.1" target_version = "1.0.2" def up(self, data): """Upgrade v1.0.1 → v1.0.2""" # Add new fields, transform structure, etc. if 'components' in data: for comp in data['components']: if 'deprecationMessage' not in comp: comp['deprecationMessage'] = "" return data def down(self, data): """Rollback v1.0.2 → v1.0.1""" # Remove new fields if 'components' in data: for comp in data['components']: comp.pop('deprecationMessage', None) return data # Register migration MigrationManager.MIGRATIONS[("1.0.1", "1.0.2")] = MigrationV1_0_1_to_V1_0_2 MigrationManager.VERSIONS.append("1.0.2") ``` --- ## Usage Examples ### 1. Backup & Restore Workflow ```python from pathlib import Path from datetime import datetime from dss.export_import import DSSArchiveExporter, DSSArchiveImporter # BACKUP def backup_project(project, backup_dir="./backups"): timestamp = datetime.utcnow().strftime("%Y%m%d_%H%M%S") backup_path = Path(backup_dir) / f"backup_{project.name}_{timestamp}.dss" exporter = DSSArchiveExporter(project) saved_path = exporter.export_to_file(backup_path) print(f"✓ Backed up to {saved_path}") return saved_path # RESTORE def restore_from_backup(backup_path): importer = DSSArchiveImporter(backup_path) # Validate before restoring analysis = importer.analyze() if not analysis.is_valid: errors = "\n".join([e.message for e in analysis.errors]) raise ValueError(f"Cannot restore: {errors}") # Restore project = importer.import_replace() print(f"✓ Restored project: {project.name}") return project # Usage project = Project(...) backup_path = backup_project(project) restored = restore_from_backup(backup_path) ``` ### 2. Project Export for Distribution ```python # Export complete project exporter = DSSArchiveExporter(project) exporter.export_to_file(Path("design-system-v2.0.dss")) # Share with team, other projects, or documentation # File contains everything needed to reconstruct the system ``` ### 3. Collaborative Merging ```python from dss.export_import.merger import SmartMerger, ConflictResolutionMode # Team member A has local version local_project = Project(...) # Team member B shares updated version importer = DSSArchiveImporter(Path("shared-updates.dss")) remote_updates = importer.import_replace() # Merge intelligently merger = SmartMerger(local_project, remote_updates) analysis = merger.analyze_merge() # Show merge summary to user print(f"New tokens: {len(analysis.new_items['tokens'])}") print(f"Updated: {len(analysis.updated_items['components'])}") print(f"Conflicts to resolve: {len(analysis.conflicted_items)}") # Apply merge merged_project = merger.merge_with_strategy( ConflictResolutionMode.KEEP_LOCAL # Prefer local changes ) ``` ### 4. Archive Analysis Without Import ```python # Inspect archive before importing importer = DSSArchiveImporter(Path("mysterious-update.dss")) analysis = importer.analyze() if analysis.is_valid: print(f"Project: {analysis.project_name}") print(f"Tokens: {analysis.content_summary['tokens']['count']}") print(f"Components: {analysis.content_summary['components']['count']}") print(f"Schema: {analysis.schema_version}") print(f"Migration needed: {analysis.migration_needed}") if analysis.migration_needed: print(f"Will be upgraded from {analysis.schema_version} to {analysis.target_version}") else: for error in analysis.errors: print(f"✗ [{error.stage}] {error.message}") ``` --- ## Database Integration The export/import system integrates with the existing DSS database layer: ### Adding UUIDs to Existing Projects Existing projects need UUID generation. A migration utility handles this: ```python from dss.storage.database import get_connection from uuid import uuid4 def backfill_uuids(): """Generate UUIDs for all existing records""" with get_connection() as conn: cursor = conn.cursor() # Projects cursor.execute("SELECT id FROM projects WHERE uuid IS NULL") for row in cursor.fetchall(): project_id = row[0] new_uuid = str(uuid4()) conn.execute( "UPDATE projects SET uuid = ? WHERE id = ?", (new_uuid, project_id) ) # Components cursor.execute("SELECT id FROM components WHERE uuid IS NULL") for row in cursor.fetchall(): comp_id = row[0] new_uuid = str(uuid4()) conn.execute( "UPDATE components SET uuid = ? WHERE id = ?", (new_uuid, comp_id) ) # Run once to initialize backfill_uuids() ``` --- ## API Reference ### DSSArchiveExporter ```python class DSSArchiveExporter: def __init__(self, project: Project): """Initialize exporter with project""" def export_to_file(self, output_path: Path) -> Path: """Export to .dss file, returns path""" ``` ### DSSArchiveImporter ```python class DSSArchiveImporter: def __init__(self, archive_path: Path): """Initialize importer with archive path""" def analyze(self) -> ImportAnalysis: """Analyze archive without importing""" def import_replace(self) -> Project: """Import with REPLACE strategy""" ``` ### SmartMerger ```python class SmartMerger: def __init__(self, local_project: Project, imported_project: Project): """Initialize merger""" def analyze_merge(self) -> MergeAnalysis: """Analyze merge without modifying""" def merge_with_strategy( self, conflict_handler: ConflictResolutionMode ) -> Project: """Perform merge with strategy""" ``` ### MigrationManager ```python class MigrationManager: @classmethod def migrate( cls, data: Dict, from_version: str, to_version: str ) -> Dict: """Apply migrations from source to target""" @classmethod def get_latest_version(cls) -> str: """Get latest schema version""" ``` --- ## File Structure ``` dss-mvp1/dss/ ├── models/ │ ├── project.py # Project + uuid field │ ├── component.py # Component + uuid field │ └── theme.py # Theme + DesignToken with uuid │ ├── export_import/ # NEW PACKAGE │ ├── __init__.py # Package exports │ ├── exporter.py # Archive creation │ ├── importer.py # Archive loading + validation │ ├── merger.py # Smart merge logic │ └── migrations.py # Schema versioning │ └── storage/ └── database.py # Updated with uuid columns ``` --- ## Backward Compatibility ✅ **No breaking changes** - Existing code continues to work unchanged - UUIDs are optional (auto-generated if missing) - Database schema is backward compatible (uuid columns nullable) - Export/import is opt-in feature - Runtime code doesn't use UUIDs (transport-layer only) --- ## Security Considerations 1. **Archive Integrity**: Validate before importing 2. **Referential Integrity**: All UUID references checked 3. **Schema Validation**: JSON schemas enforced 4. **Conflict Detection**: No silent overwrites 5. **Audit Trail**: Import operations logged --- ## Performance Notes - Export: O(n) where n = total tokens + components (single pass) - Import: O(n) validation + O(m) for merge where m = local items - Archive size: Gzipped, typically 10-50% of token count in KB - Memory: Entire archive loaded in memory (can be optimized with streaming) --- ## Future Enhancements 1. **Selective Export**: Choose what to export (tokens only, components only, etc.) 2. **Streaming Import**: Process large archives without full memory load 3. **Audit Trail Export**: Include sync history and activity logs 4. **Figma Sync**: Direct sync with Figma without manual export 5. **Cloud Storage**: Native upload/download to cloud services 6. **Compression**: Optional additional compression 7. **Encryption**: Encrypted archives for sensitive projects --- ## Troubleshooting ### "Archive validation failed" Check the detailed error messages in `analysis.errors`. Ensure: - Archive is valid ZIP file - manifest.json exists and is valid JSON - All referenced files exist in archive ### "Schema version too new" Update DSS application to latest version. Archives can only be migrated forward, not backward. ### "Referential integrity error" Ensure all token/component references are valid. Check if: - Referenced UUIDs exist in archive - No circular dependencies - All dependencies are included in export ### "Merge conflicts detected" Review conflicts in `analysis.conflicted_items`. Decide on resolution strategy: - `OVERWRITE`: Trust imported version - `KEEP_LOCAL`: Trust local version - `FORK`: Create separate copy of imported version --- ## Support For issues or questions: 1. Check ImportAnalysis errors 2. Review migration compatibility 3. Validate archive structure 4. Check referential integrity --- Generated with DSS Export/Import System v1.0.0