# Coding Conventions

**Analysis Date:** 2026-04-02

## Naming Patterns

**Functions:**
- PascalCase for public functions: `Write-Log`, `Get-ProfilesFilePath`, `Load-Profiles`, `Save-Profiles`, `Show-InputDialog`
- Verb-Noun format using standard PowerShell verbs: Get-, Load-, Save-, Show-, Export-, Apply-, Validate-, Merge-, Refresh-, Switch-
- Private/internal functions prefixed with underscore: `_Pkl-FormatMB`, `_Pkl-Sort`, `_Pkl-Repopulate`, `_Tpl-Repopulate`, `_Tpl-Log`
- Descriptive names reflecting operation scope: `Get-SiteStorageMetrics`, `Collect-FolderStorage`, `Collect-WebStorage`, `Export-PermissionsToHTML`

**Variables:**
- camelCase for local variables: `$message`, `$color`, `$data`, `$index`, `$siteSrl`
- PascalCase for control variables and form elements: `$form`, `$LogBox`, `$ClientId`, `$SiteURL`
- Prefixed script-scope variables with `$script:` for shared state: `$script:LogBox`, `$script:Profiles`, `$script:SelectedSites`, `$script:_pkl`, `$script:_tpl`
- Abbreviated but meaningful names in tight loops: `$s` (site), `$e` (event), `$i` (index), `$m` (message), `$c` (color)
- Hashtable keys use camelCase: `@{ name = "...", clientId = "...", tenantUrl = "..." }`

**Parameters:**
- Type hints included in function signatures: `[string]$Message`, `[array]$Data`, `[switch]$IncludeSubsites`, `[int]$CurrentDepth`
- Optional parameters use `= $null` or `= $false` defaults: `[string]$Color = "LightGreen"`, `[System.Windows.Forms.Form]$Owner = $null`
- Single-letter abbreviated parameters in nested functions: `param($s, $e)` for event handlers

**File/Directory Names:**
- Single main script file: `Sharepoint_ToolBox.ps1`
- Settings/profile files: `Sharepoint_Settings.json`, `Sharepoint_Export_profiles.json`, `Sharepoint_Templates.json`
- Generated report files use pattern: `{ReportType}_{site/date}_{timestamp}.{csv|html}`

## Code Style

**Formatting:**
- No explicit formatter configured
- Indentation: 4 spaces (PowerShell default)
- Line length: practical limit around 120 characters (some HTML generation lines exceed this)
- Braces on same line for blocks: `function Name { ... }`, `if ($condition) { ... }`
- Region markers used for file organization: `#region ===== Section Name =====` and `#endregion`

**Regions Organization (in `Sharepoint_ToolBox.ps1`):**
- Shared Helpers (utility functions)
- Profile Management (profile CRUD, loading/saving)
- Settings (configuration handling)
- Site Picker (dialog and list management)
- Template Management (capture, apply, storage)
- HTML Export: Permissions and Storage (report generation)
- PnP: Permissions and Storage Metrics (SharePoint API operations)
- File Search (advanced file search functionality)
- Transfer (file/folder transfer operations)
- Bulk Site Creation (site creation from templates)
- Internationalization (multi-language support)
- GUI (main form and controls definition)
- Event Handlers (button clicks, selections, menu actions)
- Structure (folder tree CSV parsing)

**Comments:**
- Inline comments explain non-obvious logic: `# Groups rows that share the same Users + Permissions`
- Block comments precede major sections: `# -- Top bar --`, `# -- Site list (ListView with columns) --`
- Section separators use dashes: `# ── Profile Management ─────────────────────────────────`
- Descriptive comments in complex functions explain algorithm: `# Recursively collects subfolders up to $MaxDepth levels deep`
- No JSDoc/TSDoc style - pure text comments

## Import Organization

**Module Imports:**
- `Add-Type -AssemblyName` for .NET assemblies at script start:
  - `System.Windows.Forms` for UI controls
  - `System.Drawing` for colors and fonts
- `Import-Module PnP.PowerShell` dynamically when needed in background runspace blocks
- No explicit order beyond UI assemblies first

## Error Handling

**Patterns:**
- Broad `try-catch` blocks with minimal logging: `try { ... } catch {}`
- Silent error suppression common: empty catch blocks swallow exceptions
- Explicit error capture in key operations: `catch { $Sync.Error = $_.Exception.Message }`
- Error logging via `Write-Log` with color coding:
  - Red for critical failures: `Write-Log "Erreur: $message" "Red"`
  - Yellow for informational messages: `Write-Log "Processing..." "Yellow"`
  - DarkGray for skipped items: `Write-Log "Skipped: $reason" "DarkGray"`
- Exception messages extracted and logged: `$_.Exception.Message`
- Validation checks return boolean: `if ([string]::IsNullOrWhiteSpace(...)) { return $false }`

## Logging

**Framework:** Native `Write-Log` function + UI RichTextBox display

**Patterns:**
```powershell
function Write-Log {
    param([string]$Message, [string]$Color = "LightGreen")
    if ($script:LogBox -and !$script:LogBox.IsDisposed) {
        # Append to UI with timestamp and color
        $script:LogBox.AppendText("$(Get-Date -Format 'HH:mm:ss') - $Message`n")
    }
    Write-Host $Message  # Also output to console
}
```

**Logging locations:**
- Long-running operations log to RichTextBox in real-time via background runspace queue
- Background functions use custom `BgLog` helper that queues messages: `function BgLog([string]$m, [string]$c="LightGreen")`
- Colors indicate message type: LightGreen (success), Yellow (info), Cyan (detail), DarkGray (skip), Red (error)
- Timestamps added automatically: `HH:mm:ss` format

## Validation

**Input Validation:**
- Null/whitespace checks: `[string]::IsNullOrWhiteSpace($variable)`
- Array/collection size checks: `$array.Count -gt 0`, `$items -and $items.Count -gt 0`
- Index bounds validation: `if ($idx -lt 0 -or $idx -ge $array.Count) { return }`
- UI MessageBox dialogs for user-facing errors: `[System.Windows.Forms.MessageBox]::Show(...)`
- Function-level validation via `Validate-Inputs` pattern

## String Handling

**HTML Escaping:**
- Custom `EscHtml` function escapes special characters for HTML generation:
  ```powershell
  function EscHtml([string]$s) {
      return $s -replace '&','&amp;' -replace '<','&lt;' -replace '>','&gt;' -replace '"','&quot;'
  }
  ```
- Applied to all user-supplied data rendered in HTML reports

**String Interpolation:**
- Double-quoted strings with `$variable` expansion: `"URL: $url"`
- Format operator for complex strings: `"Template '{0}' saved" -f $name`
- Localization helper function `T` for i18n strings: `T "profile"`, `T "btn.save"`

## Function Design

**Size:** Functions range from 5-50 lines for utilities, 100+ lines for complex operations

**Parameters:**
- Explicit type declarations required
- Optional parameters use default values
- Switch parameters for boolean flags: `[switch]$IncludeSubsites`
- Complex objects passed as reference (arrays, hashtables)

**Return Values:**
- Functions return results or arrays: `return @()`, `return $data`
- Boolean results for validation: `return $true` / `return $false`
- PSCustomObject for structured data: `[PSCustomObject]@{ Name = ...; Value = ... }`
- Void operations often silent or logged

## Object/Struct Patterns

**PSCustomObject for Data:**
```powershell
[PSCustomObject]@{
    name              = "value"
    clientId          = "value"
    capturedAt        = (Get-Date -Format 'dd/MM/yyyy HH:mm')
    options           = @{ structure = $true; permissions = $true }
}
```

**Hashtable for Mutable State:**
```powershell
$script:_pkl = @{
    AllSites      = @()
    CheckedUrls   = [System.Collections.Generic.HashSet[string]]::new()
    SortCol       = 0
    SortAsc       = $true
}
```

**Synchronized Hashtable for Thread-Safe State:**
```powershell
$sync = [hashtable]::Synchronized(@{
    Done  = $false
    Error = $null
    Queue = [System.Collections.Generic.Queue[object]]::new()
})
```

## Class/Type Usage

- Minimal custom classes; primarily uses `[PSCustomObject]`
- Extensive use of .NET types:
  - `[System.Windows.Forms.*]` for UI controls
  - `[System.Drawing.Color]` for colors
  - `[System.Drawing.Font]` for typography
  - `[System.Drawing.Point]`, `[System.Drawing.Size]` for positioning
  - `[System.Collections.Generic.HashSet[string]]` for efficient lookups
  - `[System.Collections.Generic.Queue[object]]` for message queues
  - `[System.Management.Automation.Runspaces.*]` for background execution

## Date/Time Formatting

**Consistent format:** `dd/MM/yyyy HH:mm` (European format)
- Used for timestamps in reports and logs
- Timestamps in logs: `HH:mm:ss`
- Storage/file metrics: `dd/MM/yyyy HH:mm`

## Performance Patterns

**Batch Operations:**
- Form updates wrapped in `BeginUpdate()` / `EndUpdate()` to prevent flickering
- ListView population optimized: clear, populate, sort in batch

**Threading:**
- Long-running PnP operations execute in separate runspace
- Main UI thread communicates via synchronized hashtable + timer polling
- Async UI updates via `Timer` with `DoEvents()` for responsiveness

---

*Convention analysis: 2026-04-02*
