Files
Sharepoint-Toolbox/.planning/phases/09-storage-visualization/09-01-PLAN.md
Dev a63a698282 docs(09-storage-visualization): create phase plan — 4 plans in 4 waves
Wave 1: LiveCharts2 NuGet + FileTypeMetric model + IStorageService extension
Wave 2: StorageService file-type enumeration implementation
Wave 3: ViewModel chart properties + View XAML + localization
Wave 4: Unit tests for chart ViewModel behavior

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 15:16:16 +02:00

8.8 KiB

phase, plan, type, wave, depends_on, files_modified, autonomous, requirements, must_haves
phase plan type wave depends_on files_modified autonomous requirements must_haves
09-storage-visualization 01 execute 1
SharepointToolbox/SharepointToolbox.csproj
SharepointToolbox/Core/Models/FileTypeMetric.cs
SharepointToolbox/Services/IStorageService.cs
true
VIZZ-01
truths artifacts key_links
LiveCharts2 SkiaSharp WPF package is a NuGet dependency and the project compiles
FileTypeMetric record models file extension, total size, and file count
IStorageService declares CollectFileTypeMetricsAsync without breaking existing CollectStorageAsync
path provides contains
SharepointToolbox/SharepointToolbox.csproj LiveChartsCore.SkiaSharpView.WPF package reference LiveChartsCore.SkiaSharpView.WPF
path provides contains
SharepointToolbox/Core/Models/FileTypeMetric.cs Data model for file type breakdown record FileTypeMetric
path provides contains
SharepointToolbox/Services/IStorageService.cs Extended interface with file type metrics method CollectFileTypeMetricsAsync
from to via pattern
SharepointToolbox/Services/IStorageService.cs SharepointToolbox/Core/Models/FileTypeMetric.cs Return type of CollectFileTypeMetricsAsync IReadOnlyList<FileTypeMetric>
Add LiveCharts2 NuGet dependency, create the FileTypeMetric data model, and extend IStorageService with a file-type metrics collection method signature.

Purpose: Establishes the charting library dependency (VIZZ-01) and the data contracts that all subsequent plans depend on. No implementation yet -- just the NuGet, the model, and the interface. Output: Updated csproj, FileTypeMetric.cs, updated IStorageService.cs

<execution_context> @C:/Users/dev/.claude/get-shit-done/workflows/execute-plan.md @C:/Users/dev/.claude/get-shit-done/templates/summary.md </execution_context>

@.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md From SharepointToolbox/Services/IStorageService.cs: ```csharp using Microsoft.SharePoint.Client; using SharepointToolbox.Core.Models;

namespace SharepointToolbox.Services;

public interface IStorageService { Task<IReadOnlyList> CollectStorageAsync( ClientContext ctx, StorageScanOptions options, IProgress progress, CancellationToken ct); }


From SharepointToolbox/Core/Models/StorageScanOptions.cs:
```csharp
public record StorageScanOptions(bool PerLibrary = true, bool IncludeSubsites = false, int FolderDepth = 0);

From SharepointToolbox/Core/Models/OperationProgress.cs:

public record OperationProgress(int Current, int Total, string Message)
{
    public static OperationProgress Indeterminate(string message) => new(0, 0, message);
}
Task 1: Add LiveCharts2 NuGet and create FileTypeMetric model SharepointToolbox/SharepointToolbox.csproj, SharepointToolbox/Core/Models/FileTypeMetric.cs **Step 1:** Add LiveCharts2 WPF NuGet package:
```bash
cd "C:\Users\dev\Documents\projets\Sharepoint"
dotnet add SharepointToolbox/SharepointToolbox.csproj package LiveChartsCore.SkiaSharpView.WPF --version 2.0.0-rc5.4
```

This will add the package reference to the csproj. The `--version 2.0.0-rc5.4` is a pre-release RC, so the command may need `--prerelease` flag if it fails. Try with explicit version first; if that fails, use:
```bash
dotnet add SharepointToolbox/SharepointToolbox.csproj package LiveChartsCore.SkiaSharpView.WPF --prerelease
```

**Step 2:** Create `SharepointToolbox/Core/Models/FileTypeMetric.cs`:

```csharp
namespace SharepointToolbox.Core.Models;

/// <summary>
/// Represents storage consumption for a single file extension across all scanned libraries.
/// Produced by IStorageService.CollectFileTypeMetricsAsync and consumed by chart bindings.
/// </summary>
public record FileTypeMetric(
    /// <summary>File extension including dot, e.g. ".docx", ".pdf". Empty string for extensionless files.</summary>
    string Extension,
    /// <summary>Total size in bytes of all files with this extension.</summary>
    long TotalSizeBytes,
    /// <summary>Number of files with this extension.</summary>
    int FileCount)
{
    /// <summary>
    /// Human-friendly display label: ".docx" becomes "DOCX", empty becomes "No Extension".
    /// </summary>
    public string DisplayLabel => string.IsNullOrEmpty(Extension)
        ? "No Extension"
        : Extension.TrimStart('.').ToUpperInvariant();
}
```

Design notes:
- Record type for value semantics (same as StorageScanOptions, PermissionSummary patterns)
- Extension stored with dot prefix for consistency with Path.GetExtension
- DisplayLabel computed property for chart label binding
- TotalSizeBytes is long to match StorageNode.TotalSizeBytes type
cd "C:\Users\dev\Documents\projets\Sharepoint" && dotnet build SharepointToolbox/SharepointToolbox.csproj --no-incremental 2>&1 | tail -5 LiveChartsCore.SkiaSharpView.WPF appears in csproj PackageReference. FileTypeMetric.cs exists with Extension, TotalSizeBytes, FileCount properties and DisplayLabel computed property. Project compiles with 0 errors. Task 2: Extend IStorageService with CollectFileTypeMetricsAsync SharepointToolbox/Services/IStorageService.cs Update `SharepointToolbox/Services/IStorageService.cs` to add a second method for file-type metrics collection. Do NOT modify the existing CollectStorageAsync signature.
Replace the file contents with:

```csharp
using Microsoft.SharePoint.Client;
using SharepointToolbox.Core.Models;

namespace SharepointToolbox.Services;

public interface IStorageService
{
    /// <summary>
    /// Collects storage metrics per library/folder using SharePoint StorageMetrics API.
    /// Returns a tree of StorageNode objects with aggregate size data.
    /// </summary>
    Task<IReadOnlyList<StorageNode>> CollectStorageAsync(
        ClientContext ctx,
        StorageScanOptions options,
        IProgress<OperationProgress> progress,
        CancellationToken ct);

    /// <summary>
    /// Enumerates files across all non-hidden document libraries in the site
    /// and aggregates storage consumption grouped by file extension.
    /// Uses CSOM CamlQuery to retrieve FileLeafRef and File_x0020_Size per file.
    /// This is a separate operation from CollectStorageAsync -- it provides
    /// file-type breakdown data for chart visualization.
    /// </summary>
    Task<IReadOnlyList<FileTypeMetric>> CollectFileTypeMetricsAsync(
        ClientContext ctx,
        IProgress<OperationProgress> progress,
        CancellationToken ct);
}
```

Design notes:
- CollectFileTypeMetricsAsync does NOT take StorageScanOptions because file-type enumeration scans ALL non-hidden doc libraries (no per-library/subfolder filtering needed for chart aggregation)
- Returns IReadOnlyList<FileTypeMetric> sorted by TotalSizeBytes descending (convention -- implementation will handle sorting)
- Separate from CollectStorageAsync so existing storage scan flow is untouched
cd "C:\Users\dev\Documents\projets\Sharepoint" && dotnet build SharepointToolbox/SharepointToolbox.csproj --no-incremental 2>&1 | tail -5 IStorageService.cs declares both CollectStorageAsync (unchanged) and CollectFileTypeMetricsAsync (new). Build fails with CS0535 in StorageService.cs (expected -- Plan 09-02 implements the method). If build succeeds, even better. Interface contract is established. - `dotnet restore SharepointToolbox/SharepointToolbox.csproj` succeeds and LiveChartsCore.SkiaSharpView.WPF is resolved - FileTypeMetric.cs exists in Core/Models with record definition - IStorageService.cs has both method signatures - Existing CollectStorageAsync signature is byte-identical to original

<success_criteria> LiveCharts2 is a project dependency. FileTypeMetric data model is defined. IStorageService has the new CollectFileTypeMetricsAsync method signature. The project compiles (or fails only because StorageService doesn't implement the new method yet -- that is acceptable and expected). </success_criteria>

After completion, create `.planning/phases/09-storage-visualization/09-01-SUMMARY.md`