vault backup: 2026-04-29 21:46:53

This commit is contained in:
Vadym Samoilenko 2026-04-29 21:46:53 +01:00
parent a96bf6c3d6
commit 49cddca16a
5 changed files with 143 additions and 1 deletions

View file

@ -23,7 +23,7 @@ This 3-hop pattern works for hundreds of articles without vector search.
| [[wiki/tech-patterns/_index\|tech-patterns/]] | Recurring tech stacks: FastAPI, React/Vite, Next.js, Azure AD, AI, Box, One2Edit, Redis/Celery, cost-tracker | 15 |
| [[wiki/architecture/_index\|architecture/]] | Cross-cutting architectural patterns: Docker Compose, multi-agent AI, GCP timeout, RAG, hotfolder, optical-dev deploy, cost-tracker, new-project checklist, troubleshooting playbooks, ADR log | 10 |
| [[wiki/client-knowledge/_index\|client-knowledge/]] | Per-client notes for Ford, H&M, L'Oréal, Barclays, Ferrero, 3M | 6 |
| [[wiki/concepts/_index\|concepts/]] | Atomic knowledge extracted from Claude Code sessions | 61 |
| [[wiki/concepts/_index\|concepts/]] | Atomic knowledge extracted from Claude Code sessions | 62 |
| [[wiki/connections/_index\|connections/]] | Cross-cutting insights linking 2+ concepts: FastAPI+Azure AD+Docker trinity, AI→cost-tracker, Apache+Vite basePath, GCP→REST polling, Box+hotfolder, Docker DNS+AdGuard | 9 |
| [[wiki/qa/_index\|qa/]] | Filed answers to queries (saved with `--file-back`) | 0 |
| [[wiki/homelab/_index\|homelab/]] | Self-hosted infra: Proxmox install, IOMMU/PCI passthrough, hypervisor setup, budget builds, HP Elitedesk G3, Homarr API + Apps + Boards + Certificates + Integrations + Settings + Tasks + AdGuard + Clock + Docker Stats + Docker Integration + Download Client + Firewall + Proxmox Integration + Radarr + Readarr + Sonarr + Bookmarks + Calendar + Icons + App Widget + Weather + GitHub + Nextcloud + qBittorrent + RSS Feed + Speedtest Tracker + System Health Monitoring + System Resources + Services Map + Media Stack | 39 |

View file

@ -91,6 +91,23 @@ DISABLE_AUTH=true
---
## Banner Builder UI Rebrand (2026-04-28)
The banner builder UI was rebranded from the Barclays design system to the **Oliver Modcomms design system**. Visual layer changed; core functionality unchanged.
**What changed:**
- Tailwind tokens renamed from `barclays-*``oliver-*`
- Layout: horizontal nav → dark vertical sidebar (`w-[220px]`), matching the Modcomms pattern
- Theme colour picker added to both `BannerEditor` and `VariantsGrid` views; variants have a `theme` enum: `navy | sky-blue | yellow | lime | teal`
- Logo: placeholder `CopyGenBannerAgent_RFA.png` generated via `sips` (PIL not available on macOS); real CopyGen/Oliver asset needed
**What did NOT change (by design):**
- Internal localStorage key names (`barclays-*`) intentionally kept to avoid invalidating in-flight user sessions — see [[wiki/concepts/localstorage-key-migration-rebrand|localstorage-key-migration-rebrand]] for why and how to handle this in a future release
- AI Refine/Improve box only mutates copy text fields — cannot change visual theme/colours (by architecture)
- Barclays brand hex codes (`#00AEEF`, `#00395D`, etc.) remain correct in `tailwind.config.ts` as of commit `47b3f12`
---
---
## Lessons from banner-builder (2026-04-28)
@ -144,3 +161,4 @@ See [[wiki/concepts/pydantic-model-dict-interface]] for full pattern.
- [[wiki/concepts/export-endpoint-filter-pattern|export-endpoint-filter-pattern]] — variant_ids in exports
- [[wiki/concepts/zustand-async-hydration]] — Zustand hydration timing bug (Banner Builder)
- [[wiki/concepts/pydantic-model-dict-interface]] — Pydantic vs dict silent failure (Banner Builder tasks.py)
- [[wiki/concepts/localstorage-key-migration-rebrand]] — localStorage key migration after rebrand (Banner Builder 2026-04-28)

View file

@ -69,5 +69,7 @@
| [[wiki/concepts/zustand-async-hydration]] | Zustand persist hydrates localStorage asynchronously — components must gate API calls behind hasHydrated or token will be null on first render | daily/2026-04-28.md | 2026-04-28 |
| [[wiki/concepts/pydantic-model-dict-interface]] | Pydantic model passed where dict expected — .get() returns None silently instead of raising; use isinstance check or model_dump() at boundary | daily/2026-04-28.md | 2026-04-28 |
| [[wiki/concepts/localstorage-key-migration-rebrand]] | localStorage key migration after renaming storage keys in a rebrand — session loss, Zustand persist name, migration script pattern | daily/2026-04-28.md | 2026-04-28 |
<!-- Articles added automatically by compile.py -->
<!-- Format: | [[concepts/slug]] | One-line summary | daily/YYYY-MM-DD.md | date | -->

View file

@ -0,0 +1,117 @@
---
title: "Frontend — localStorage Key Migration When Rebranding"
aliases: [localstorage-key-migration, storage-key-rename, rebrand-session-loss, zustand-persist-rename]
tags: [frontend, localstorage, zustand, react, rebrand, auth, migration]
sources:
- "daily/2026-04-28.md"
created: 2026-04-28
updated: 2026-04-28
---
# Frontend — localStorage Key Migration When Rebranding
When a frontend app is rebranded and its localStorage key names are changed (e.g., from `barclays-auth-storage` to `oliver-auth-storage`), all existing user sessions are silently invalidated. The old keys remain in the browser's localStorage but are no longer read — on next load, the app finds no data under the new key name and treats the user as unauthenticated.
## Key Points
- **Old localStorage keys persist forever** — renaming the key in code does not migrate existing browser data; the old key sits orphaned, the new key is empty
- **All users are effectively logged out** after a key rename deploy — no error, no warning; the app simply starts fresh as if the user never logged in
- **Zustand `persist` middleware uses a `name` option as the localStorage key** — changing this name causes the same session loss
- **Fix: migration script at app entry point** — on load, check for old key, copy data to new key, delete old key; runs once per user, transparent
- **Decision to keep internal keys**: in barclays-banner-builder, internal session keys (`barclays-*`) were intentionally NOT renamed to avoid invalidating in-flight sessions during the rebrand; only UI-visible branding strings were changed
## Details
### Why This Happens
Browsers store localStorage data keyed by the exact string used in `localStorage.setItem(key, value)`. When a Zustand `persist` store has `name: "barclays-auth-storage"`, Zustand writes to and reads from that exact string. When the name is changed to `"oliver-auth-storage"`, Zustand looks for the new key — finds nothing — initialises with the default (unauthenticated) state. The old `barclays-auth-storage` entry remains in the browser forever.
This is not a bug in Zustand or localStorage — it's the expected behavior of key-value storage. The same problem occurs with any keyed storage: sessionStorage, IndexedDB, cookie names, etc.
### Symptom
After a rebrand deploy:
- Users who were logged in are suddenly redirected to the login page
- No error in the console or network tab
- `Application → Local Storage` in DevTools shows both old and new keys: old with data, new empty
- Logging in again works fine (new key is populated); old key remains as clutter
### The Migration Script
Add to `main.tsx` (or the app's entry point), before the React tree mounts:
```typescript
// main.tsx — runs once before React mounts
function migrateStorage() {
const OLD_KEY = "barclays-auth-storage";
const NEW_KEY = "oliver-auth-storage";
const oldData = localStorage.getItem(OLD_KEY);
if (oldData && !localStorage.getItem(NEW_KEY)) {
// Copy old data to new key
localStorage.setItem(NEW_KEY, oldData);
// Clean up old key
localStorage.removeItem(OLD_KEY);
console.log("[migration] Migrated localStorage from", OLD_KEY, "to", NEW_KEY);
}
}
migrateStorage();
ReactDOM.createRoot(document.getElementById("root")!).render(<App />);
```
This migration is safe to ship before or alongside the key rename: if old data exists and new key is empty, migrate; otherwise no-op.
### When to Keep Old Keys (No Migration)
In some cases, deliberately not migrating is the right choice:
- **During a deploy with in-flight user sessions**: renaming now would log everyone out immediately; decide whether a one-time logout is acceptable
- **When the stored data format changed** during the rebrand: migrating old-format data into a new-format key would corrupt state; better to let users re-login with a clean slate
- **Internal-only keys** (e.g., cache keys, feature flags): user impact is minimal, no migration needed
barclays-banner-builder 2026-04-28 decision: `barclays-*` session keys kept unchanged because the rebrand was cosmetic (visual redesign only), and invalidating active work sessions mid-project was unacceptable.
### Zustand-Specific Pattern
For Zustand `persist` stores, the migration can also be done inside the store's `onRehydrateStorage` callback:
```typescript
// Alternative: migrate inside Zustand store initialisation
export const useAuthStore = create<AuthState>()(
persist(
(set) => ({ /* ... */ }),
{
name: "oliver-auth-storage", // ← new key
onRehydrateStorage: () => {
// Check for old key and migrate if needed
const old = localStorage.getItem("barclays-auth-storage");
if (old) {
localStorage.setItem("oliver-auth-storage", old);
localStorage.removeItem("barclays-auth-storage");
}
},
}
)
);
```
This is neater for Zustand stores but couples the migration to the store initialisation rather than the app entry point.
### Other Storage Types
The same pattern applies to:
- `sessionStorage` — same API, same key-rename problem (though sessions are cleared on tab close anyway)
- Cookie names — renaming a session cookie name logs all users out; same migration approach applies server-side
- IndexedDB database names — renaming requires schema migration via `onupgradeneeded`
## Related Concepts
- [[wiki/concepts/zustand-async-hydration]] — Zustand persist hydration timing; keys are the configuration point where naming matters
- [[wiki/concepts/memory-compiler-mac-migration]] — similar "config key mismatch" pattern: hooks reference paths/identifiers that break when the environment changes
- [[wiki/client-knowledge/barclays]] — barclays-banner-builder rebrand context where this was encountered
## Sources
- [[daily/2026-04-28.md]] — barclays-banner-builder UI rebrand from Barclays design tokens to Oliver Modcomms design system; `barclays-*` localStorage keys intentionally kept to avoid session invalidation; decision documented as tech debt item (migrate to `oliver-*` in a future release with migration script)

View file

@ -3,6 +3,11 @@
<!-- Append-only chronological record of compile, query, and lint operations -->
## [2026-04-29T21:00:00+01:00] compile | 2026-04-28.md (pass 3)
- Source: daily/2026-04-28.md
- Articles created: [[wiki/concepts/localstorage-key-migration-rebrand]]
- Articles updated: [[wiki/client-knowledge/barclays]] (added Banner Builder UI rebrand section: Oliver Modcomms design system, vertical sidebar, theme picker, localStorage key intentionally kept)
## [2026-04-28T23:15:00+01:00] compile | 2026-04-28.md (pass 2)
- Source: daily/2026-04-28.md
- Articles created: (none — all primary knowledge captured in pass 1)