From 67c5d135d914a15fd75ea4379f92137665c342c9 Mon Sep 17 00:00:00 2001 From: Claudio Schaad Date: Tue, 14 Apr 2026 06:31:10 +0200 Subject: [PATCH] docs: add design spec for configurable icons from Docker share Co-Authored-By: Claude Sonnet 4.6 --- .../2026-04-14-configurable-icons-design.md | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 docs/superpowers/specs/2026-04-14-configurable-icons-design.md diff --git a/docs/superpowers/specs/2026-04-14-configurable-icons-design.md b/docs/superpowers/specs/2026-04-14-configurable-icons-design.md new file mode 100644 index 0000000..4379678 --- /dev/null +++ b/docs/superpowers/specs/2026-04-14-configurable-icons-design.md @@ -0,0 +1,59 @@ +# Configurable Icons from Docker Share + +**Date:** 2026-04-14 +**Status:** Approved + +## Problem + +Icons for shifts are currently PNG files bundled in the repository under `Client/wwwroot/icons/`. This means adding or changing an icon requires a code change and a redeployment. The user wants icons to be configurable at runtime, placed on the same Docker-mounted volume as monthly schedule files and other configuration. + +## Solution + +Serve icon files from `config/icons/` (a subfolder of the existing Docker share) using ASP.NET Core's static file middleware with a `PhysicalFileProvider`. No frontend changes are required — the URL path `/icons/filename.png` stays identical. + +## Architecture + +### Server change (`Server/Program.cs`) + +Add a second `UseStaticFiles` call after the existing one: + +```csharp +var iconsPath = Path.Combine(Directory.GetCurrentDirectory(), "config", "icons"); +Directory.CreateDirectory(iconsPath); +app.UseStaticFiles(new StaticFileOptions +{ + FileProvider = new PhysicalFileProvider(iconsPath), + RequestPath = "/icons" +}); +``` + +- `config/icons/` is created automatically on first run if absent. +- Files placed there are served at `/icons/{filename}` immediately, no restart needed. +- Built-in ASP.NET Core static file serving provides ETags, cache headers, and range request support. + +### Cleanup + +- Delete `Client/wwwroot/icons/` and all PNG files within it. +- Remove all `` entries from `Client/ShiftScheduler.Client.csproj`. + +### No changes needed + +- `Shift.IsPngIcon` computed property +- `Shift.Icon` field +- `` in `Index.razor` +- `ConfigurationDialog.razor` +- Any other frontend or shared model code + +## Data Flow + +1. User places `myicon.png` in `config/icons/` on the Docker share. +2. In `appsettings.json` (or `config/shifts.json`), the shift's `Icon` field is set to `myicon.png`. +3. The Blazor client fetches shift config from `GET /api/shift/shifts`. +4. `Shift.IsPngIcon` returns `true`, and the UI renders ``. +5. The browser GETs `/icons/myicon.png` — served by the `PhysicalFileProvider` from `config/icons/myicon.png`. + +## Out of Scope + +- Emoji icons are unaffected. +- No upload UI for icons — files are placed on the share directly (consistent with how schedule files work). +- No fallback to repo-bundled icons (repo icons are removed entirely).