# mojoPortal Update Methodology

**Framework Version:** 1.0.0  
**Update Script Format:** `SQM_Update_nnn.ps1`  
**Version Mapping:** Ordinal 3-digit to semantic versioning (n.n.n)  

---

## Overview

The update system uses a systematic, sequencable PowerShell script framework that makes it simple to apply incremental updates while maintaining clear version tracking and backup procedures.

### Version Mapping System

The version string `n.n.n` (semantic versioning) maps to a 3-digit ordinal in the script filename:
- Each position in the version corresponds to a digit (0-9)
- No version like 0.0.10 (each position maxes at 9)
- Makes sequencing logical and predictable

**Examples:**
```
Version 1.0.0 → SQM_Update_100.ps1
Version 1.0.1 → SQM_Update_101.ps1
Version 1.0.5 → SQM_Update_105.ps1
Version 1.1.0 → SQM_Update_110.ps1
Version 1.5.3 → SQM_Update_153.ps1
Version 2.1.4 → SQM_Update_214.ps1
Version 9.9.9 → SQM_Update_999.ps1
```

---

## Update Script Structure

### Directory Organization

```
C:\___Work\SqliteMojo\
├── Updates/                          # All update scripts
│   ├── SQM_Update_100.ps1           # v1.0.0 baseline/reference
│   ├── SQM_Update_101.ps1           # v1.0.1 updates
│   ├── SQM_Update_102.ps1           # v1.0.2 updates
│   └── ...
├── Backups/                          # Automatic backups per update
│   ├── 2024-01-15_v100/             # Backup before v1.0.0 update
│   │   ├── Web/
│   │   ├── mojoPortal.*/
│   │   └── VERSION.md
│   ├── 2024-01-20_v101/             # Backup before v1.0.1 update
│   │   ├── Web/
│   │   ├── mojoPortal.*/
│   │   └── VERSION.md
│   └── ...
├── VERSION_HISTORY.md               # Log of all updates applied
└── [source files...]
```

### Update Script Template

Each `SQM_Update_nnn.ps1` script follows this structure:

```powershell
#==============================================================================
# mojoPortal Update Script - Version n.n.n
#==============================================================================
# Script: SQM_Update_nnn.ps1
# Version: n.n.n
# Purpose: [What this update accomplishes]
# Date: [Release date]
#==============================================================================

param(
    [string]$SourcePath = "C:\___Work\SqliteMojo",
    [string]$BackupPath = "C:\___Work\SqliteMojo\Backups",
    [string]$UpdatesPath = "C:\___Work\SqliteMojo\Updates",
    [switch]$DryRun = $false,
    [switch]$SkipBackup = $false
)

#==============================================================================
# CONFIGURATION
#==============================================================================

$CurrentVersion = "n.n.n"           # Update this version number
$UpdateName = "SQM_Update_nnn"      # This script's name
$Timestamp = Get-Date -Format "yyyy-MM-dd"
$BackupDir = Join-Path $BackupPath "$Timestamp`_v{0:d3}" -f $VersionOrdinal

#==============================================================================
# FUNCTIONS
#==============================================================================

function Write-Header {
    param([string]$Message)
    Write-Host "`n" -NoNewline
    Write-Host "=" * 80 -ForegroundColor Cyan
    Write-Host $Message -ForegroundColor Cyan
    Write-Host "=" * 80 -ForegroundColor Cyan
}

function Write-Step {
    param([string]$Message, [int]$Step)
    Write-Host "`n[Step $Step] $Message" -ForegroundColor Yellow
}

function Write-Success {
    param([string]$Message)
    Write-Host "✓ $Message" -ForegroundColor Green
}

function Write-Error-Custom {
    param([string]$Message)
    Write-Host "✗ $Message" -ForegroundColor Red
}

function Test-Prerequisites {
    Write-Step "Validating prerequisites" 1
    
    # Check if source path exists
    if (-not (Test-Path $SourcePath)) {
        throw "Source path not found: $SourcePath"
    }
    Write-Success "Source path exists: $SourcePath"
    
    # Check if running as administrator
    $Admin = [Security.Principal.WindowsIdentity]::GetCurrent()
    $Principal = New-Object Security.Principal.WindowsPrincipal($Admin)
    if (-not $Principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
        throw "This script requires Administrator privileges"
    }
    Write-Success "Running as Administrator"
    
    return $true
}

function Create-Backup {
    Write-Step "Creating backup" 2
    
    if ($SkipBackup) {
        Write-Host "Skipping backup (--SkipBackup flag set)" -ForegroundColor Yellow
        return
    }
    
    # Create backup directory
    if (-not (Test-Path $BackupDir)) {
        New-Item -ItemType Directory -Path $BackupDir -Force | Out-Null
    }
    
    # Copy source files
    Write-Host "Backing up to: $BackupDir"
    Copy-Item -Path "$SourcePath\*" -Destination $BackupDir -Recurse -Force
    
    Write-Success "Backup created successfully"
    Write-Host "Location: $BackupDir"
}

function Get-VersionOrdinal {
    param([string]$Version)
    # Convert n.n.n to nnn
    # e.g., "1.0.0" → 100, "1.2.3" → 123
    $parts = $Version.Split('.')
    return [int]::Parse(("{0}{1}{2}" -f $parts[0], $parts[1], $parts[2]))
}

#==============================================================================
# MAIN EXECUTION
#==============================================================================

Write-Header "mojoPortal Update Script - Version $CurrentVersion"

try {
    # Step 1: Validate prerequisites
    Test-Prerequisites | Out-Null
    
    # Step 2: Create backup
    Create-Backup
    
    # Step 3: Apply updates
    Write-Step "Applying update changes" 3
    
    # [INSERT SPECIFIC UPDATE LOGIC HERE]
    # This is where version-specific changes are implemented
    # Examples: copy files, update configs, run migrations, etc.
    
    Write-Success "Update changes applied"
    
    # Step 4: Update version file
    Write-Step "Updating VERSION.md" 4
    
    $VersionFilePath = Join-Path $SourcePath "VERSION.md"
    # [UPDATE VERSION FILE HERE]
    
    Write-Success "VERSION.md updated to $CurrentVersion"
    
    # Step 5: Update history log
    Write-Step "Logging update to version history" 5
    
    $HistoryFilePath = Join-Path $SourcePath "VERSION_HISTORY.md"
    $HistoryEntry = @"
## Update Applied: $CurrentVersion

**Date:** $(Get-Date -Format "yyyy-MM-dd HH:mm:ss")
**Script:** $UpdateName.ps1
**Backup:** $BackupDir
**Changes:** [See CHANGELOG_$CurrentVersion.md]

"@
    
    Add-Content -Path $HistoryFilePath -Value $HistoryEntry
    Write-Success "Version history updated"
    
    # Step 6: Summary
    Write-Header "Update Complete!"
    Write-Host "Version: $CurrentVersion" -ForegroundColor Green
    Write-Host "Applied: $(Get-Date -Format "yyyy-MM-dd HH:mm:ss")" -ForegroundColor Green
    Write-Host "Backup: $BackupDir" -ForegroundColor Green
    
    if ($DryRun) {
        Write-Host "`nNote: DRY RUN MODE - No actual changes were made" -ForegroundColor Yellow
    }
}
catch {
    Write-Error-Custom "Update failed: $_"
    Write-Host "`nRollback backup available at: $BackupDir" -ForegroundColor Yellow
    exit 1
}
```

---

## Update Workflow

### Before Applying an Update

1. **Review the Update**
   ```powershell
   # Read the changelog for the version
   Get-Content ".\Updates\CHANGELOG_101.md"
   ```

2. **Check Current Version**
   ```powershell
   # View current version
   Get-Content "VERSION.md" | Select-String "^**Version:**"
   ```

3. **Verify Backup Location**
   ```powershell
   # Ensure backup directory exists and has space
   Get-Item ".\Backups" | Select-Object FullName
   ```

### Applying an Update

**Dry Run (Preview Only)**
```powershell
# Preview changes without applying
C:\___Work\SqliteMojo\Updates\SQM_Update_101.ps1 -DryRun
```

**Live Update (With Backup)**
```powershell
# Apply update with automatic backup
C:\___Work\SqliteMojo\Updates\SQM_Update_101.ps1
```

**Update Without Backup (Caution)**
```powershell
# Apply update, skip backup (not recommended)
C:\___Work\SqliteMojo\Updates\SQM_Update_101.ps1 -SkipBackup
```

### Verifying Update Success

```powershell
# Check new version
Get-Content "VERSION.md" | Select-String "^**Version:**"

# View backup created
Get-ChildItem ".\Backups" | Sort-Object LastWriteTime -Descending | Select-Object -First 1

# Review update history
Get-Content "VERSION_HISTORY.md"
```

---

## Version Mapping Reference

### Complete Version Map (0.0.0 to 9.9.9)

```
1.0.0 → 100  | 1.5.0 → 150  | 2.0.0 → 200  | 3.0.0 → 300  | 5.0.0 → 500
1.0.1 → 101  | 1.5.1 → 151  | 2.0.1 → 201  | 3.0.1 → 301  | 5.0.1 → 501
1.0.2 → 102  | 1.5.5 → 155  | 2.1.0 → 210  | 3.5.2 → 352  | 5.2.3 → 523
1.0.5 → 105  | 1.9.9 → 199  | 2.9.9 → 299  | 3.9.9 → 399  | 9.9.9 → 999
```

### Ordinal Calculation Formula

```
Ordinal = (Major × 100) + (Minor × 10) + Patch
```

**Examples:**
- 1.0.0 = (1 × 100) + (0 × 10) + 0 = **100**
- 1.2.3 = (1 × 100) + (2 × 10) + 3 = **123**
- 2.5.7 = (2 × 100) + (5 × 10) + 7 = **257**

---

## Update Lifecycle

### Creating a New Update Script

1. **Plan the update**
   - Document changes needed
   - Test locally first
   - Prepare rollback procedure

2. **Create script file**
   ```powershell
   # Copy template and update version numbers
   Copy-Item ".\Updates\SQM_Update_100.ps1" ".\Updates\SQM_Update_101.ps1"
   
   # Edit SQM_Update_101.ps1:
   # - Change $CurrentVersion = "1.0.1"
   # - Update $UpdateName = "SQM_Update_101"
   # - Add specific changes in Step 3
   ```

3. **Create changelog**
   ```powershell
   # Create CHANGELOG_101.md documenting changes
   New-Item ".\Updates\CHANGELOG_101.md"
   ```

4. **Test the update**
   ```powershell
   # Dry run to verify
   .\Updates\SQM_Update_101.ps1 -DryRun
   ```

5. **Document the update**
   - Update VERSION.md with new version info
   - Add release notes
   - Update README.md if needed

### Managing Update History

The `VERSION_HISTORY.md` file tracks all updates applied:

```markdown
## Version History

### Version 1.0.1 (2024-01-20)
- Applied SQM_Update_101.ps1
- Backup: 2024-01-20_v101
- Changes: [Link to changelog]

### Version 1.0.0 (2024-01-15)
- Initial release
- Backup: 2024-01-15_v100
- Status: Alpha

```

---

## Backup Strategy

### Automatic Backups

Each update script automatically:
1. Creates timestamped backup directory: `Backups/YYYY-MM-DD_vnnn/`
2. Copies entire source tree
3. Logs backup location in VERSION_HISTORY.md
4. Preserves previous backups

### Backup Retention

```powershell
# Keep last 30 days of backups
Get-ChildItem "C:\___Work\SqliteMojo\Backups" -Directory | 
    Where-Object {$_.LastWriteTime -lt (Get-Date).AddDays(-30)} | 
    Remove-Item -Recurse -Force
```

### Rollback Procedure

If an update causes issues:

```powershell
# 1. Stop any running services
Stop-Service "YourService" -Force

# 2. Restore from backup
$BackupDir = "C:\___Work\SqliteMojo\Backups\2024-01-20_v101"
Copy-Item -Path "$BackupDir\*" -Destination "C:\___Work\SqliteMojo" -Recurse -Force

# 3. Restart services
Start-Service "YourService"

# 4. Verify version
Get-Content "C:\___Work\SqliteMojo\VERSION.md" | Select-String "^**Version:**"
```

---

## Semantic Versioning Guide

### Version Format: `MAJOR.MINOR.PATCH`

**MAJOR** (First digit)
- Incremented when making incompatible changes
- Example: 1.0.0 → 2.0.0 (significant architectural change)
- Ordinal: 100 → 200

**MINOR** (Second digit)
- Incremented when adding functionality in backward-compatible manner
- Example: 1.0.0 → 1.1.0 (new features added)
- Ordinal: 100 → 110

**PATCH** (Third digit)
- Incremented for bug fixes and minor updates
- Example: 1.0.0 → 1.0.1 (bug fix)
- Ordinal: 100 → 101

### Update Type Examples

| Type | Version Change | Ordinal | Script |
|------|---|---|---|
| Bug fix | 1.0.0 → 1.0.1 | 100 → 101 | SQM_Update_101.ps1 |
| New features | 1.0.1 → 1.1.0 | 101 → 110 | SQM_Update_110.ps1 |
| Breaking changes | 1.1.0 → 2.0.0 | 110 → 200 | SQM_Update_200.ps1 |
| Performance fix | 1.0.1 → 1.0.2 | 101 → 102 | SQM_Update_102.ps1 |

---

## Example Update Scenario

### Scenario: Fix for Migration Issue (v1.0.0 → v1.0.1)

**Step 1: Create Update Script**
```powershell
# Copy template
Copy-Item ".\Updates\SQM_Update_100.ps1" ".\Updates\SQM_Update_101.ps1"
```

**Step 2: Update Version Info**
```powershell
# Edit SQM_Update_101.ps1
$CurrentVersion = "1.0.1"
$UpdateName = "SQM_Update_101"
```

**Step 3: Add Specific Changes**
```powershell
# In the "Applying update changes" section:
Write-Host "Copying updated migration engine..."
Copy-Item ".\mojoPortal.Data.SQLite\LegacyDataMigrationEngine.cs" `
    -Destination "$SourcePath\mojoPortal.Data.SQLite\" -Force

Write-Host "Updating configuration..."
# Update any config files as needed
```

**Step 4: Create Changelog**
```markdown
# Changelog for Version 1.0.1

## Bug Fixes
- Fixed issue with module type mapping during migration
- Resolved null reference in MigrationHelper analysis
- Corrected permission mapping for inherited roles

## Improvements
- Enhanced error logging for migration failures
- Updated validation rules for legacy database

## Files Changed
- mojoPortal.Data.SQLite/LegacyDataMigrationEngine.cs
- mojoPortal.Data.SQLite/LegacyMigrationHelper.cs
- Web/Data/sqlitedb/MIGRATION_GUIDE.md
```

**Step 5: Apply Update**
```powershell
# Dry run first
.\Updates\SQM_Update_101.ps1 -DryRun

# Then apply
.\Updates\SQM_Update_101.ps1
```

**Step 6: Verify**
```powershell
# Confirm version
Get-Content "VERSION.md" | Select-String "**Version:**"
# Output: **Version:** 1.0.1

# Check backup
Get-ChildItem ".\Backups" | Sort-Object Name -Descending | Select-Object -First 1
# Output: 2024-01-20_v101
```

---

## Best Practices

### ✅ DO

- ✅ Test updates locally before release
- ✅ Create comprehensive changelogs
- ✅ Always backup before applying updates
- ✅ Document breaking changes clearly
- ✅ Use dry-run mode to preview changes
- ✅ Keep version numbers sequential
- ✅ Update all version references
- ✅ Maintain VERSION_HISTORY.md

### ❌ DON'T

- ❌ Skip backups to save time
- ❌ Use non-sequential version numbers
- ❌ Apply updates without testing
- ❌ Ignore rollback procedures
- ❌ Version versions above 9.9.9
- ❌ Make version changes without scripts
- ❌ Update scripts without changelogs
- ❌ Forget to update documentation

---

## Update Distribution

### For Your Team

```powershell
# Package an update for distribution
$UpdateName = "SQM_Update_101"
$DistroDir = "C:\Builds\$UpdateName"

New-Item -ItemType Directory -Path $DistroDir -Force

# Copy essential files
Copy-Item ".\Updates\$UpdateName.ps1" "$DistroDir\"
Copy-Item ".\Updates\CHANGELOG_101.md" "$DistroDir\"
Copy-Item ".\README.md" "$DistroDir\"
Copy-Item ".\VERSION.md" "$DistroDir\"

# Create distribution package
Compress-Archive -Path $DistroDir -DestinationPath "$DistroDir.zip"
```

### Update Notification

When releasing an update, include:

```markdown
# mojoPortal Update Available: v1.0.1

**Release Date:** 2024-01-20  
**Type:** Patch (Bug fixes)  
**Breaking Changes:** None  

## What's Fixed
- Migration engine module type mapping
- Permission inheritance issue
- Error handling in analysis phase

## Installation
1. Download: SQM_Update_101.zip
2. Extract to your mojoPortal directory
3. Run: `.\Updates\SQM_Update_101.ps1`
4. Verify version in `VERSION.md`

## Rollback (if needed)
Automatic backup created at: `Backups/2024-01-20_v101/`

## Support
For issues, refer to MIGRATION_GUIDE.md or contact support
```

---

## Monitoring & Logging

### Update Log Example

```powershell
# View recent updates
Get-Content "VERSION_HISTORY.md" | Select-Object -First 50
```

**Output:**
```
## Version History

### Update Applied: 1.0.1

**Date:** 2024-01-20 14:30:00
**Script:** SQM_Update_101.ps1
**Backup:** C:\___Work\SqliteMojo\Backups\2024-01-20_v101
**Changes:** Migration engine fixes and improvements

---

### Version 1.0.0

**Date:** 2024-01-15 09:00:00
**Status:** Initial Alpha Release
```

### Performance Tracking

```powershell
# Track update duration
$StartTime = Get-Date
.\Updates\SQM_Update_101.ps1
$Duration = (Get-Date) - $StartTime
Write-Host "Update completed in $($Duration.TotalSeconds) seconds"
```

---

## Summary

The **SQM_Update_nnn.ps1** framework provides:

✅ **Clear versioning** — Semantic versioning mapped to 3-digit ordinals  
✅ **Safe updates** — Automatic backups before every change  
✅ **Rollback capability** — Restore from backup if needed  
✅ **Complete history** — Track all updates applied  
✅ **Testable changes** — Dry-run mode to preview  
✅ **Scalable process** — Handles unlimited updates (up to 9.9.9)  
✅ **Comprehensive logging** — Full audit trail of all operations  

This methodology ensures that updates are applied consistently, safely, and with complete visibility into what changed and why.

---

**Next Update: SQM_Update_101.ps1 (Version 1.0.1)**  
*Framework ready for systematic, traceable version management* ✅
