July 25, 2026 — Durable device unlock (no re-prompt every visit)
Shipped in this commit
- Bug: HVAC Lens asked for license on every open / login; registered device often not recognized after online re-check failures.
- Durable unlock: after successful online validate, persist
unlocked: trueon the device (phvac-licenselocalStorage + cookiephvac-license-unlockedwith deviceId). - Gate allow-first:
license-gate.jsunlocks immediately from that flag; online revalidation runs in the background only. - Hard lock only on: no unlock flag, Remove Key, or server-confirmed revoked. Soft errors (
device_limit, network) no longer re-prompt a previously unlocked device. - Settings devices: email backfill from session; clearer “This device”; offline note + Register this device when unlocked locally but missing from server list.
- Homepage CTA:
pwa-entry.jsuses unlock flag (not expiry date). - Help:
app/help/license-auth.htmdocuments stay-unlocked behavior.
Key files
js/license-client.js—isDeviceUnlocked(), unlock flag + cookie mirrorapp/license-gate.js— allow-firstcheckAccess,revalidateInBackgroundjs/settings-devices.js,js/pwa-entry.js,js/config.jsapp/sw.js—phvac-app-v77
⚠ Need to do (carried from July 21 log + new)
From July 21 session — production deploy was still pending (CLI access privileges). Confirm or finish with the account that owns project fzpqenrqzptglpfboerq.
- SQL (if not done): Supabase Dashboard → SQL Editor → run full file
_pwa-build/supabase/migrations/007_no_license_expiry.sql. - Edge functions (if not done):
cd C:\Users\Peter\Documents\consultation.web.site\_pwa-build supabase login supabase functions deploy validate-license --project-ref fzpqenrqzptglpfboerq supabase functions deploy recover-license --project-ref fzpqenrqzptglpfboerq supabase functions deploy renew-license --project-ref fzpqenrqzptglpfboerq supabase functions deploy create-checkout --project-ref fzpqenrqzptglpfboerq # Or: SUPABASE_ACCESS_TOKEN + scripts\deploy-functions.ps1 from repo root
- Smoke test (unlock persistence): unlock once → refresh / reopen app → no license gate; force old
validatedAt→ still open; Remove Key → gate returns; Settings shows This device after online unlock (or use Register this device). - Smoke test (July 21 license product): Settings bar “does not expire”; renew free → norenewal when active; 6th device still blocked.
- Netlify: confirm site auto-deployed from this git push (or trigger deploy). Hard-refresh / reinstall PWA so SW v77 loads.
- New product work: main website should use the same licensing path as the PWA (replace members profile / subscribe gate with license unlock + durable flag) for one simple access model. Not in this commit — plan next.