Repository navigation
Open shifts follow-up: keep post keys across a reload, clear them on account deletion #3566
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
ac1f6af
Open shifts follow-up: keep post keys across a reload, clear them on …
claude e270353
Seal the Open shifts follow-up migration
claude 5cb9dad
Gitleaks: ignore the migration seal hash for the post keys migration
claude 2444c3b
fix: Index post keys by account
qodo-code-review[bot] 81da70b
Open shifts: forget the post key when the list confirms a lost post
claude d67b83d
Open shifts: tie post keys to the signed-in person
claude f6ef790
Revert "fix: Index post keys by account"
claude 8d5fc36
Merge origin/main into claude/project-thread-sr3mdk
claude 96a88e3
fix: Stop posting when the account changes
qodo-code-review[bot] 433c359
Drop in-memory open-shift post keys on sign-out
claude ef8884a
Keep posted dates when an account switch stops a post
claude 9755975
Stop an open-shift post as soon as the account signs out
claude File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| import { OPEN_SHIFTS_POST_KEYS_STORAGE_KEY } from "@/lib/account-scoped-browser-state"; | ||
|
|
||
| /** | ||
| * The retry key for each shift being posted, kept for this tab so it survives a reload. If a post | ||
| * went live but its answer was lost, reloading the page and posting the same shift again sends the | ||
| * same key, and the server answers with the shift it already saved instead of saving a second one. | ||
| * A key is dropped once its post is confirmed, so a deliberate later post of the same shift gets a | ||
| * new key. Keys older than a day are dropped as stale. Storage can be missing or blocked, so every | ||
| * read and write is guarded and the page still works for this visit without it. | ||
| */ | ||
|
|
||
| const KEY = OPEN_SHIFTS_POST_KEYS_STORAGE_KEY; | ||
| const MAX_AGE_MS = 24 * 60 * 60 * 1000; | ||
| const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i; | ||
|
|
||
| type Stored = Record<string, { key: string; at: number }>; | ||
|
|
||
| function read(now: number): Stored { | ||
| try { | ||
| const raw = window.sessionStorage.getItem(KEY); | ||
| const value = raw ? (JSON.parse(raw) as unknown) : null; | ||
| if (!value || typeof value !== "object" || Array.isArray(value)) return {}; | ||
| const kept: Stored = {}; | ||
| for (const [signature, entry] of Object.entries(value as Record<string, unknown>)) { | ||
| if (!entry || typeof entry !== "object") continue; | ||
| const { key, at } = entry as { key?: unknown; at?: unknown }; | ||
| if (typeof key === "string" && UUID.test(key) && typeof at === "number" && now - at < MAX_AGE_MS) { | ||
| kept[signature] = { key, at }; | ||
| } | ||
| } | ||
| return kept; | ||
| } catch { | ||
| return {}; | ||
| } | ||
| } | ||
|
|
||
| function write(stored: Stored): void { | ||
| try { | ||
| if (Object.keys(stored).length === 0) window.sessionStorage.removeItem(KEY); | ||
| else window.sessionStorage.setItem(KEY, JSON.stringify(stored)); | ||
| } catch { | ||
| // Storage is blocked or full: the key still holds for this visit. | ||
| } | ||
| } | ||
|
|
||
| /** The key for this shift: the one kept from an earlier unanswered attempt, or a new one, kept now. */ | ||
| export function postKeyFor(signature: string, memory: Record<string, string>, now = Date.now()): string { | ||
| const stored = read(now); | ||
| const key = memory[signature] ?? stored[signature]?.key ?? crypto.randomUUID(); | ||
|
BigSimmo marked this conversation as resolved.
Resolved
|
||
| memory[signature] = key; | ||
| if (stored[signature]?.key !== key) write({ ...stored, [signature]: { key, at: now } }); | ||
|
qodo-code-review[bot] marked this conversation as resolved.
Resolved
|
||
| return key; | ||
| } | ||
|
|
||
| /** The post is confirmed, so a later post of the same shift is a new one and gets a new key. */ | ||
| export function forgetPostKey(signature: string, memory: Record<string, string>, now = Date.now()): void { | ||
| delete memory[signature]; | ||
| const stored = read(now); | ||
| if (signature in stored) { | ||
| delete stored[signature]; | ||
| write(stored); | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
17 changes: 17 additions & 0 deletions
17
supabase/migrations/20261015181500_roster_open_post_keys_posted_by_fk.sql
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| -- Never edit an applied migration. Merging this applies it to the live database. | ||
| -- Deleting a doctor's account also clears their id from the open-shift post keys. | ||
| -- roster_open_shifts.posted_by already clears itself when the account goes (on delete set null); | ||
| -- the post keys added in 20261015174500 kept the same id with no link to the account, so it stayed | ||
| -- until the open shift itself was purged. This gives roster_open_post_keys.posted_by the same | ||
| -- link. Any key whose poster's account is already gone is cleared first so the link can be added. | ||
| set local lock_timeout = '5s'; | ||
| set local statement_timeout = '30s'; | ||
|
|
||
| update public.roster_open_post_keys k | ||
|
BigSimmo marked this conversation as resolved.
Resolved
|
||
| set posted_by = null | ||
| where k.posted_by is not null | ||
| and not exists (select 1 from auth.users u where u.id = k.posted_by); | ||
|
|
||
| alter table public.roster_open_post_keys | ||
| add constraint roster_open_post_keys_posted_by_fkey | ||
| foreign key (posted_by) references auth.users (id) on delete set null; | ||
|
qodo-code-review[bot] marked this conversation as resolved.
Resolved
BigSimmo marked this conversation as resolved.
Resolved
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.