Files
2026-07-12 10:17:17 -04:00

72 lines
3.1 KiB
Markdown

# Cross-Page Settings Desync: Missing initializeSettings
## Diagnostic Signal
User toggles a setting (desktop notifications, sound alerts, dark mode) on **page A**, saves — it sticks. Navigates to **page B** — the same toggle shows its **default/off state**. Toggling+saving on page B works on page B but page A reverts. Each page "remembers" only its own saves.
## Root Cause
A shared settings module (`settings.js`) exports `initializeSettings()`, which:
1. Calls `loadSettings()` — fetches saved settings from PocketBase/localStorage
2. Calls `populateSiteSettingsForm()` — sets checkbox/select values from loaded settings
3. Calls `setupUnifiedSiteSettingsModalHandlers()` — wires close/save/cancel buttons
4. Calls `subscribeToRealtimeSettings()` — sets up change listeners
If **any page** in the app loads `settings.js` as a `<script type="module">` but **never calls `initializeSettings()`**, that page runs with module defaults. The form controls show their raw HTML state (unchecked for `input[type=checkbox]` without a `checked` attribute).
## Common Pattern
```
repair-orders.js: import { initializeSettings } from './settings.js'
await initializeSettings(...); // ✅ called
customers.js: import { initializeSettings } from './settings.js'
await initializeSettings(...); // ✅ called
main.js: import { initializeSettings } from './settings.js'
initializeSettings(...); // ✅ called
dashboard.js: settingsModule.initializeSettings(...); // ✅ called
appointments.js: // ❌ imports settings.js? Yes (loaded as module)
// ❌ calls initializeSettings()? NO
// → settings desync on appointments page
```
## Fix
Add the import and call to every page that has a site settings modal:
```javascript
// At top of page's JS file:
import { initializeSettings } from './settings.js';
// Inside the page's init function (after auth check):
initializeSettings();
```
## Verification
```bash
# Check every page's JS for the initializeSettings call
for js in repair-orders.js appointments.js customers.js main.js dashboard.js; do
echo -n "$js: "
grep -c 'initializeSettings' "$js"
done
# Every result should be ≥ 2 (import + call site). A result of 0 or 1 = bug.
```
## PocketBase Pitfall: onSnapshot is One-Shot
The `onSnapshot` function in PocketBase adapter (`pocketbase.js`) is a **one-shot fetch**, not a realtime listener. It fires once when called, then never again:
```javascript
function onSnapshot(queryOrDocRef, callback) {
// Simple one-shot onSnapshot compatibility shim
getDoc(queryOrDocRef).then(doc => callback(doc));
return () => {}; // Unsubscribe is a no-op
}
```
This means `subscribeToRealtimeSettings()` does NOT provide realtime cross-page sync. Settings saved on page A are persisted to PocketBase, but page B won't see the change until it **reloads** (calling `loadSettings()` fresh). This is fine for navigation-based sync (each page loads settings on init), but means two open tabs won't stay in sync without a manual refresh.