From 048184bef042f1afcaa166334660b810e4e937f1 Mon Sep 17 00:00:00 2001 From: Till JS Date: Wed, 8 Apr 2026 22:34:29 +0200 Subject: [PATCH] fix(macmini): auto-rebuild stale sveltekit-base before per-app web builds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Per-app web Dockerfiles do `FROM sveltekit-base:local` and do NOT re-COPY packages/shared-* — those packages are baked into the base image. So a change to packages/shared-utils, packages/shared-ui, etc. only reaches the live web app if the base image is also rebuilt. This bit us THREE times on 2026-04-08 alone: 1. CSP fix in shared-utils ('wasm-unsafe-eval') sat unused in production for over an hour because every `build-app.sh mana-web` cheerfully reused the cached base layer that still contained the old shared-utils. 2. Same problem with the BaseListView export in shared-ui after the ListView consolidation refactor — mana-web's build failed because the Rollup pass couldn't resolve the new symbol from the stale base. 3. Same shape, different package, repeatedly. The pattern is identical every time and the manual workaround (`build-app.sh --base` first) is something you only think to run if you already know how the layering works. Make the script catch it. New `is_base_image_stale` helper compares the base image's `Created` timestamp against the latest git commit touching paths the base image actually depends on: - packages/ (all shared-* packages baked in) - docker/Dockerfile.sveltekit-base - pnpm-lock.yaml (transitive dep changes) When building any *-web service, if the image is stale or missing, the base is rebuilt automatically before the per-app build kicks off, with the triggering commit's oneline printed for transparency. Date parsing notes: - macOS Docker emits the Created field with the local TZ offset ("...+02:00"), not Z. We strip the fractional + offset suffix and parse the literal local clock time with BSD date (no -u), which is what the original timestamp meant on this host. GNU date is the fallback for Linux dev boxes and handles the full ISO directly. - If parsing fails for any reason we conservatively force a rebuild rather than risk shipping stale code. Verified end-to-end against the live Mac Mini's current state earlier today: image 55s newer than the last packages/ commit at the time → "fresh, skip" (correct). When the next packages/ commit lands, the script will see commit_epoch > image_epoch and trigger the base rebuild automatically. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../src/lib/components/PickerOverlay.svelte | 210 ++++++++++++++++++ .../components/workbench/AppPagePicker.svelte | 154 ++----------- .../components/pages/ContactPagePicker.svelte | 178 ++------------- .../todo/components/pages/PagePicker.svelte | 187 ++-------------- 4 files changed, 269 insertions(+), 460 deletions(-) create mode 100644 apps/mana/apps/web/src/lib/components/PickerOverlay.svelte diff --git a/apps/mana/apps/web/src/lib/components/PickerOverlay.svelte b/apps/mana/apps/web/src/lib/components/PickerOverlay.svelte new file mode 100644 index 000000000..0a93ff196 --- /dev/null +++ b/apps/mana/apps/web/src/lib/components/PickerOverlay.svelte @@ -0,0 +1,210 @@ + + + +
+
+

{title}

+ +
+
+ {#each items as entry, i} + {#if i > 0}
{/if} + {@render item(entry, i)} + {/each} + {#if footer} + {#if items.length > 0}
{/if} + {@render footer()} + {:else if items.length === 0} +

{emptyLabel}

+ {/if} +
+
+ + diff --git a/apps/mana/apps/web/src/lib/components/workbench/AppPagePicker.svelte b/apps/mana/apps/web/src/lib/components/workbench/AppPagePicker.svelte index 2b85e6711..e11a18e44 100644 --- a/apps/mana/apps/web/src/lib/components/workbench/AppPagePicker.svelte +++ b/apps/mana/apps/web/src/lib/components/workbench/AppPagePicker.svelte @@ -3,7 +3,7 @@ --> -
-
-

App hinzufügen

- -
-
- {#each availableApps as app, i (app.id)} - {#if i > 0}
{/if} - - {/each} - - {#if availableApps.length === 0} -

Alle Apps sind bereits geöffnet

- {/if} -
-
+ + {#snippet item(app)} + + {/snippet} + diff --git a/apps/mana/apps/web/src/lib/modules/contacts/components/pages/ContactPagePicker.svelte b/apps/mana/apps/web/src/lib/modules/contacts/components/pages/ContactPagePicker.svelte index 5c2ad32ac..87c769ec8 100644 --- a/apps/mana/apps/web/src/lib/modules/contacts/components/pages/ContactPagePicker.svelte +++ b/apps/mana/apps/web/src/lib/modules/contacts/components/pages/ContactPagePicker.svelte @@ -1,5 +1,5 @@ -
-
-

Neue Seite

- -
-
- {#each availableOptions as option, i (option.id)} - {#if i > 0}
{/if} - - {/each} - {#if availableOptions.length === 0} -

Alle Seiten sind bereits geöffnet

- {/if} -
-
- - + + {#snippet item(option)} + + {/snippet} + diff --git a/apps/mana/apps/web/src/lib/modules/todo/components/pages/PagePicker.svelte b/apps/mana/apps/web/src/lib/modules/todo/components/pages/PagePicker.svelte index fb4a566dd..138bf2dbb 100644 --- a/apps/mana/apps/web/src/lib/modules/todo/components/pages/PagePicker.svelte +++ b/apps/mana/apps/web/src/lib/modules/todo/components/pages/PagePicker.svelte @@ -1,5 +1,5 @@ -
-
-

Neue Seite

- -
-
- {#each availableOptions as option, i (option.id)} - {#if i > 0}
{/if} - - {/each} - {#if availableOptions.length > 0 && onCreateCustom}
{/if} + + {#snippet item(option)} + + {/snippet} + + {#snippet footer()} {#if onCreateCustom} - {/if} - {#if availableOptions.length === 0 && !onCreateCustom} -

Alle Seiten sind bereits geöffnet

- {/if} -
-
+ {/snippet} +