diff --git a/GITHUB_ISSUES.md b/GITHUB_ISSUES.md index 1bc539d..cbd04c2 100644 --- a/GITHUB_ISSUES.md +++ b/GITHUB_ISSUES.md @@ -1,5 +1,7 @@ # GitHub Issue Backlog: Secure Commerce Program +**RACE-SIM-001C / #731 — STAGING DEPLOYED, OPEN:** PR734/merge `669e2fb`, exact PR38455181292/main38455775086 six jobs/every step, native v6/downloaded archive/resource/owner/MFA/invoker/unchanged profiles and dependent Hosting/public assets verified. Anonymous 390×844 screen passes, not signed-in lifecycle/security/cleanup. Officer impact: planned supervised fiction remains NOT AVAILABLE YET until that acceptance. Officer documentation: dated STAGING_COMMUNITY/entrypoints/maps/root checkpoint. Deployment evidence: [native receipt](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/731); earlier source-only/not-deployed entries are historical. No production/real payments or broader goal completion. + **RACE-SIM-001C / #731 — CLIENT SOURCE PREPARED, OPEN:** closed staging request/status/ack parsing and `/community/races` screen cover synthetic signup, cancellation/full credit return, private offer/recipient waiver acceptance/revoke, exact retry and context/stale-state clearing. No migration, money/provider action, dependency/service/workflow/IAM/Rules allowance. Officer impact: planned supervised fictional screen, NOT AVAILABLE YET. Officer documentation: STAGING_COMMUNITY, entrypoints, EVENTS_SHOP_MEMBERS and SYSTEM_MAPS. Deployment evidence: local doubles/full checks only at this milestone; genuine native security, exact backend-first Function/Hosting release, actual screens and fenced cleanup remain required. #732's backend source is merged; neither source milestone closes #731 or the full backend goal. **RACE-SIM-001C1 / #732 — SOURCE / DEMO ONLY:** child of open #731. Exact race-prefixed native-context routing, explicit same-project SDK app, current disposable authority/metadata, closed twenty-race manifest and consistent private read-only status. No broad query/Auth roster, other UID/contact/waiver/history/count/capacity/financial total projection; exact incoming offer only and uniform missing/unrelated denial. Fresh post-read time; original credit/index/retry and lost-recipient owner recovery preserved. Deterministic archive includes all necessary relative imports. Officer impact: race screens remain NOT AVAILABLE YET. Officer documentation: staging guide, entrypoints, Events-Shop-Members, maps and root status. Deployment evidence: none from this child; source/double/native-wrapper tests with mocked verifiers and actual demo SDK proof are not genuine hosted identity/App Check/deployment/UI. No production/payment/service/IAM/dependency/workflow/Rules-allowance/migration change. #731 retains typed client/screen, exact backend-first release, genuine security/UI/mobile/failure proof and exact owned hosted cleanup; the full backend goal stays open. diff --git a/IMPLEMENTATION_PLAN.md b/IMPLEMENTATION_PLAN.md index f81ab79..2c4ae74 100644 --- a/IMPLEMENTATION_PLAN.md +++ b/IMPLEMENTATION_PLAN.md @@ -1,5 +1,7 @@ # MPRC Secure Commerce Implementation Plan +**#731 staging deployment checkpoint — 2026-10-13:** exact PR/main checks passed; backend v6/archive was verified before Hosting `669e2fb`. Anonymous phone-width UI/public assets pass, not signed-in acceptance. Continue genuine disposable security/lifecycle/privacy/failure/retry/expiry/mobile and fenced cleanup before closing #731. [Current handoff](./docs/officers/STAGING_COMMUNITY.md#fictional-race-member-screen--731-source-prepared). Earlier source-only/not-deployed notes are historical; full backend goal/production/real payments remain separate. + **#731 client milestone — SOURCE PREPARED:** strict staging client and minimal member screen now have local positive/negative/context/failure/retry/expiry tests. Review and merge this source independently of deployment. Next verify all six exact current-main jobs/every step, deploy/read back the changed backend archive first, then publish staging Hosting and finish genuine security/actual UI/mobile/failure/expiry/owned cleanup. No new service/dependency/workflow/IAM or production/payment work; #731 and the broader backend goal remain open until native acceptance. **#731 review split / #732 — SOURCE / DEMO ONLY:** first review exact callable routing, explicit SDK realm, private bounded read-only status and deterministic archive independently. Current source/double, native-wrapper-with-mocked-verifiers and actual demo transaction/metadata tests qualify only that child. Then #731 adds strict client parsing, context fences and minimal fictional member screens; exact green-main backend archive must deploy/verify before staging Hosting. Genuine native Auth/App Check denials, actual UI/retry/expiry/recipient-loss/mobile proof and exact owned hosted cleanup are still required. No production, real payments, new service/dependency/workflow/IAM, backfill or broader goal completion is implied; earlier #727/#729 nonintegration notes are historical. diff --git a/OFFICER_START_HERE.md b/OFFICER_START_HERE.md index 443d229..e6560ff 100644 --- a/OFFICER_START_HERE.md +++ b/OFFICER_START_HERE.md @@ -1,5 +1,7 @@ # MPRC Website: Officer Start Here +**#731 latest checkpoint — STAGING DEPLOYED 2026-10-13, TESTS STILL OPEN:** the [current handoff](./docs/officers/STAGING_COMMUNITY.md#fictional-race-member-screen--731-source-prepared) separates verified deployment from unfinished signed-in race/cleanup tests. The planned officer flow is NOT AVAILABLE YET; ask Dave/platform specialist for the later acceptance receipt and fresh private fixtures. Older source-only/not-deployed notes below are historical. No real payments or production changes. + **#731 fictional race screen — SOURCE PREPARED, NOT AVAILABLE YET:** the [planned review](./docs/officers/STAGING_COMMUNITY.md#fictional-race-member-screen--731-source-prepared) covers signup, fictional credit return and private recipient-accepted bib transfer. Local screen tests are not hosted proof. Dave/platform specialist must verify staging release, security, real screens and cleanup first; production and real payments remain untouched. **Fictional race boundary — #732, SOURCE / DEMO ONLY:** safe backend routing and private test status are prepared, but there is no new deployed race screen yet. Use the [source review](./docs/officers/STAGING_COMMUNITY.md#fictional-race-boundary--732-source-only) to ask for proof. #731 still needs actual staging release, disposable screens and cleanup. Do not use legacy refund/substitute controls or real member/payment details. diff --git a/OPERATIONS_RUNBOOK.md b/OPERATIONS_RUNBOOK.md index 661522a..cbc26a6 100644 --- a/OPERATIONS_RUNBOOK.md +++ b/OPERATIONS_RUNBOOK.md @@ -1,5 +1,7 @@ # MPRC Platform Operations Runbook +**#731 staging deployment checkpoint — 2026-10-13:** existing community service v6 and Hosting `669e2fb` are verified; no additional Function build is needed for this documentation. Signed-in tests/fixture cleanup and qualified officer use remain pending. Follow the [current handoff](./docs/officers/STAGING_COMMUNITY.md#fictional-race-member-screen--731-source-prepared), not old source-only/not-deployed checkpoints below. Preserve exact current/rollback evidence; fixture supply, native tests/cleanup and rollback remain specialist-only. Production/real payments untouched. + **#731 member screen — SOURCE PREPARED, NOT AVAILABLE YET:** use the [planned no-terminal review](./docs/officers/STAGING_COMMUNITY.md#fictional-race-member-screen--731-source-prepared) only after the specialist supplies native release/security/UI/cleanup proof and fresh private fixtures. Keep the same fixed staging target and resource limits; no new polling, scheduler or financial provider. Account/permission/config supply, backend-first deployment/readback and fenced cleanup/rollback remain specialist-only. Existing v5/Hosting485be670 are historical deployed proof, not race-screen proof; production and real payments stay untouched. **#732 source boundary — NOT DEPLOYED:** race routes/status are now connected in source and included in the prepared archive, not the existing staging v5 runtime or website. `communityConfig/fictionalRaces` must be an exact fictional manifest with no more than twenty IDs; missing/corrupt configuration denies rather than discovering entries. Current caller marker/own-entry permission and verified/enabled Auth are required for status too. Own history and privately supplied named offers only; no officer queries a roster, edits records or enters real details. Status uses consistent reads and fresh time, adds no write/poll or scheduled cleanup. #731's specialist must supply fixtures, exact green reviewed release, genuine security/UI proof and identity/update-time-fenced cleanup before the screen becomes available. Source rollback is a reviewed revert; there is no cloud change from this child to undo. Keep the existing exact staging/rollback proof and six-permission/min0/max2/256MB/30s scope. Historical #727/#729 archive-exclusion notes describe older milestones; production and real payments remain untouched. diff --git a/SECURITY.md b/SECURITY.md index cf5c83b..38578e1 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,5 +1,7 @@ # MPRC Security, Privacy, and Risk Plan +**#731 staging deployment checkpoint — 2026-10-13:** native v6/archive/resources/owner/MFA/invoker/unchanged profiles and website assets are verified at `669e2fb`. Two requests without Auth and with missing/invalid attestation denied; this does not isolate App Check or qualify signed-in caller/grant/privacy tests. Those and disposable cleanup remain open. [Current handoff](./docs/officers/STAGING_COMMUNITY.md#fictional-race-member-screen--731-source-prepared). Earlier source-only/not-deployed notes are historical; no production/payment/IAM authority expansion. + **#731 client — SOURCE PREPARED, NOT DEPLOYED:** closed plain-object/array parsing rejects extra fields, accessors, coercions, malformed bounds and mismatched request acknowledgements before display. UI/transport bind the same verified disposable SDK account/app/default tenant; observed session epochs fence even same-UID renewals. No token extraction/logging, direct database access or runner directory. Failed/uncertain reads and known deadlines remove old controls; exact saved retries never cross account/session/provider changes. These local tests use SDK/service doubles, not genuine hosted Auth/App Check proof; server authority, native release and hosted acceptance remain required. **#732 race routing/status — SOURCE / DEMO ONLY:** clone bounded closed input before inspecting its action; only six exact race-prefixed routes enter the existing native callable wrapper. Platform-verified UID/claims and App Check are required, never browser flags. Status also requires current exact expiring marker/own-entry permission, default-tenant recent verified password context and enabled/verified native caller metadata. A consistent read-only transaction reads at most twenty configured races, caller indexes and necessary exact entry/index records, not a query/roster or broad Auth lookup. Only own state and an exactly named offer to the caller are projected; no other UID/contact/waiver/count/capacity/total is returned. Missing/unrelated incoming IDs share one fixed denial. Fresh post-read time prevents slow reads extending access/availability. SDK/config/state errors are redacted; status writes nothing. The archive now includes these source helpers, with no Rules allowance or runtime permission expansion. Historical #727/#729 integration limits are superseded in source only: native HTTP tests mock verifiers, demo caller context remains synthetic, no deployed native token/App Check/UI qualification exists yet, and Auth metadata is still not locked by a Firestore transaction. diff --git a/STRIPE_COMMERCE_DESIGN.md b/STRIPE_COMMERCE_DESIGN.md index ba28b8d..75a43e9 100644 --- a/STRIPE_COMMERCE_DESIGN.md +++ b/STRIPE_COMMERCE_DESIGN.md @@ -1,5 +1,7 @@ # Stripe, Race Registration, and Merchandise Design +**#731 staging deployment checkpoint — 2026-10-13:** Function v6/website `669e2fb` and their archive/public assets are verified. Fictional credits remain disconnected from Stripe and real money; signed-in race/cleanup acceptance is pending. [Current handoff](./docs/officers/STAGING_COMMUNITY.md#fictional-race-member-screen--731-source-prepared). Earlier source-only/not-deployed notes are historical. No real policy, provider payment or production launch is approved. + **#731 member screen — SOURCE PREPARED, NOT DEPLOYED:** UI labels all amounts and returns fictional credit, never paid/refunded money. It accepts no client price, deadline, finance role or runner profile; transfer keeps the original credit owner. No provider SDK, Checkout, payment/refund object or real rule is added. Hosted staging release/UI/security/cleanup remain open; finance/MFA/provider reconciliation and production gates are unchanged. **#732 boundary — SOURCE / DEMO ONLY:** exact staging race RPC routing and minimal own-entry status now exist in source, without any Checkout, PaymentIntent, Refund, provider state or real-money action. Simulated credits are explicitly fictional integer cents. No client price/deadline/recipient profile or finance-role bypass; original credit/waiver/bib and immutable retry behavior remain #729's rules. Native HTTP tests use verifier doubles; real local Auth metadata/Firestore tests are not hosted identity/App Check proof. #731 still owns client and genuine hosted acceptance. This child does not deploy, establish real club rules, replace finance permission/recent MFA/provider reconciliation, or close real refund/transfer launch blockers. Earlier #727/#729 nonintegration statements are historical milestone boundaries. diff --git a/SYSTEM_DESIGN.md b/SYSTEM_DESIGN.md index ddd0357..84e2de2 100644 --- a/SYSTEM_DESIGN.md +++ b/SYSTEM_DESIGN.md @@ -1,5 +1,7 @@ # MPRC Platform System Design +**#731 staging deployment checkpoint — 2026-10-13:** Function v6 and the staging website use `669e2fb`; exact archive, resource/identity/security settings, unchanged profiles and public assets passed verification. Signed-in race security/lifecycle/cleanup remain unqualified. [Current handoff](./docs/officers/STAGING_COMMUNITY.md#fictional-race-member-screen--731-source-prepared). Earlier source-only/not-deployed notes below are historical checkpoints, not current deployment status. Production and real payments remain untouched. + **#731 member screen — SOURCE PREPARED, NOT DEPLOYED:** a separate `/community/races` route/link uses the same staging service, exact bounded DTOs and server-supplied entry IDs/revisions. Same Auth/Functions app, verified disposable caller, default tenant and session/provider generation fences prevent late cross-context display/retry. Failed reads hide old controls; saved commands retry exactly; acceptance rereads own status without the consumed offer. Conservative deadline timers clear status without polling. No migration, runtime/Rules/IAM/service/dependency change or money action; genuine native security, backend-first release, actual screens and fenced cleanup remain open. **#732 fictional race boundary — SOURCE / DEMO ONLY:** #731 is split for review: this child connects exact race-prefixed routes to the existing callable source and adds read-only `race_status`. Firebase supplies verified caller/App Check context; recent default-tenant password claims, live expiring disposable marker/own-entry permission and current native caller metadata remain mandatory. The explicitly selected app/project has no production fallback. A closed `communityConfig/fictionalRaces` manifest lists at most twenty exact event IDs. One read-only transaction projects validated event policy, own enrollment/entry and only an exactly named incoming offer. It returns no other UID/contact/waiver/history, capacity/count or financial total; missing/unrelated offer IDs deny identically. Fresh time after reads fences access/window/offer expiry; owner status/revoke survives recipient loss. Additive configuration, unchanged browser denial and complete deterministic archive only; no migration, new service/dependency/workflow/IAM or cloud deployment. Historical #727/#729 paragraphs describe their source milestones, not the new connected source. Client screens, genuine hosted security, exact backend-first deployment and cleanup remain #731 gates; #724's deployed service/website are unchanged by this child. diff --git a/docs/officers/EVENTS_SHOP_MEMBERS.md b/docs/officers/EVENTS_SHOP_MEMBERS.md index a1aa5ac..960d397 100644 --- a/docs/officers/EVENTS_SHOP_MEMBERS.md +++ b/docs/officers/EVENTS_SHOP_MEMBERS.md @@ -1,5 +1,7 @@ # Events, Shop, Members, and Money +**#731 latest checkpoint — STAGING DEPLOYED 2026-10-13:** only deployment/archive/public assets and the signed-out page are verified. Signed-in race actions/security/cleanup and qualified officer use remain pending. [Current handoff](./STAGING_COMMUNITY.md#fictional-race-member-screen--731-source-prepared). Older source-only/not-deployed notes are historical; do not use legacy refund/substitute controls or real details. + **#731 member screen — SOURCE PREPARED, NOT AVAILABLE YET:** the [planned screen review](./STAGING_COMMUNITY.md#fictional-race-member-screen--731-source-prepared) covers fictional signup, credit return and privately named bib offers/acceptance/revocation. Native staging release/security/screens/cleanup still require the specialist; local service doubles do not prove hosted behavior. No real refund, payment, club policy or production change is available. **#732 race boundary — SOURCE / DEMO ONLY:** [read the short handoff](./STAGING_COMMUNITY.md#fictional-race-boundary--732-source-only) before any review. Backend source now includes exact fictional race actions and own-entry status, but no new deployed screen or genuine hosted proof. #731 must finish that release and cleanup. No real refund, payment, policy, runner directory or record-edit procedure is available. Earlier #727/#729 paragraphs are historical milestone limits. diff --git a/docs/officers/README.md b/docs/officers/README.md index 5674434..d0e1400 100644 --- a/docs/officers/README.md +++ b/docs/officers/README.md @@ -1,5 +1,7 @@ # Officer Website Handbook +**#731 latest checkpoint — 2026-10-13:** deployment/archive/public assets are verified in staging, but signed-in race security/screens and disposable cleanup remain open. Use the [current handoff](./STAGING_COMMUNITY.md#fictional-race-member-screen--731-source-prepared); its planned procedure is NOT AVAILABLE YET. Older source-only/not-deployed notes are historical. Production and real payments stay untouched. + [#731's fictional race screen](./STAGING_COMMUNITY.md#fictional-race-member-screen--731-source-prepared) is source prepared, **NOT AVAILABLE YET**. A separate dated native release/security/screen/cleanup receipt is required before the planned review. No real payment, policy or production change is supplied. [#732's fictional race backend review](./STAGING_COMMUNITY.md#fictional-race-boundary--732-source-only) is SOURCE / DEMO ONLY. No new race screen or cloud release is supplied by that child. #731 retains genuine staging security, screen, release and cleanup requirements; only the specialist supplies fixtures/provider proof. Production and real payments remain unavailable. diff --git a/docs/officers/STAGING_COMMUNITY.md b/docs/officers/STAGING_COMMUNITY.md index 62b2b18..176b42e 100644 --- a/docs/officers/STAGING_COMMUNITY.md +++ b/docs/officers/STAGING_COMMUNITY.md @@ -29,7 +29,9 @@ ## Fictional race member screen — #731 source prepared -**Status:** SOURCE PREPARED, **NOT AVAILABLE YET**. The staging-only `/community/races` screen has signup, simulated credit return, private bib offers, acceptance and revocation in source. Local screen tests use service doubles, not genuine hosted identities or attestation. The #732 section describes the earlier backend milestone. No race release or hosted cleanup proof is claimed here. +**Status:** STAGING DEPLOYED 2026-10-13; signed-in acceptance remains open, so the planned officer flow is **NOT AVAILABLE YET**. Function v6 and the website use `669e2fb` after PR734's exact six PR/main jobs and every step passed. Fixed release and independent read-only verification both passed: downloaded 101,386-byte archive SHA-256 `94380430f7fb3bbbb1ddbf6ee8fa2a87cd9510d54810fda71ddd010a8da3fc87`; existing owner/MFA, six runtime permissions/zero user keys, min0/max2/256MB/30s, invoker bindings and profiles2/1/2843388 are verified. Hosting followed the backend; marker, actual HTML and main JavaScript bytes match. No second Function build is needed for these documentation-only changes. + +**Actual screen proof so far:** signed-out Chrome shows fictional credits/no real money, sign-in and no mutation buttons. At 390×844 there is no horizontal overflow; viewport restored. Two requests without Auth and with missing/invalid attestation deny, which does not isolate App Check or prove signed-in identity/capability/privacy. Local 78 race tests and CI frontend1,463 pass with doubles; genuine signed-in lifecycle/security/mobile/cleanup remain #731's required gates. No disposable account/record/permission, receiver or network grant was created in this release slice. Synthetic diagnostic output was cleaned; current/rollback evidence retained. See the [dated native receipt](https://github.com/Run-MPRC/Run-MPRC.github.io/issues/731). Earlier source-only/not-deployed paragraphs describe historical review milestones. **Purpose:** review the intended test flow without mistaking fictional credit for money. **Approver/escalation:** Dave, sole staging owner; no backup is appointed. **Prerequisites:** Dave/platform specialist must first supply dated native security, exact backend-first Function/Hosting release, disposable screen and fenced cleanup evidence. Fresh verified disposable accounts, expiring permissions and private test IDs are separate prerequisites. Until then, do not try these steps on a website. @@ -54,7 +56,7 @@ Planned supervised screen review — **NOT AVAILABLE YET**: 17. If a named offer is unavailable, select **Show only my entries**, not another guessed ID. 18. Sign out and ask for the exact disposable cleanup receipt. -**Expected result:** only your own entry or an exactly named offer to you is shown. Transfer preserves the bib and original credit owner; it creates no second place. One enrollment ever and one transfer are test limits, not club policy. Old controls disappear after a failed read or known deadline. An exact saved action may be retried only within the same account/session; fresh successful status restores controls. No polling, email, directory, card or provider payment is added. +**Expected result:** only your own entry or an exactly named offer to you is shown. Transfer preserves the bib and original credit owner; it creates no second place. One enrollment ever and one transfer are test limits, not club policy. Old controls disappear after a failed read or known deadline. Refresh retains the selected private offer ID after a failed lookup, never returning to the previous offer; this small #735 correction needs its own reviewed source/Hosting proof. An exact saved action may be retried only within the same account/session; fresh successful status restores controls. No polling, email, directory, card or provider payment is added. **Stop:** production, real person/payment information, missing permission, uncertain private ID, stale controls, real-money claims, or requests for secrets/record edits. **Success proof:** #731 must separately record source/full checks, merge, native Auth/App Check/security/archive/resource/unchanged profiles, Hosting marker, actual failure/retry/expiry/privacy/mobile screens, and fenced cleanup. This source review was read as an officer without a terminal; hosted steps are not qualified yet. **Undo:** sign out; Dave/specialist handles reviewed staging rollback or fixture cleanup. Setup, provider verification, permission revocation, cleanup and rollback remain specialist-only. Never post passwords, tokens, codes or member records to an issue or AI tool. diff --git a/docs/officers/SYSTEM_MAPS.md b/docs/officers/SYSTEM_MAPS.md index f1adf4c..820cb5a 100644 --- a/docs/officers/SYSTEM_MAPS.md +++ b/docs/officers/SYSTEM_MAPS.md @@ -2,21 +2,23 @@ These diagrams show where pages, information, and deployments go. Each diagram includes a one-sentence text version. -## Fictional race member screen — #731 source prepared, not deployed +## Fictional race member screen — #731 staging deployed, acceptance pending + +**2026-10-13 checkpoint:** native v6/archive/resources/unchanged profiles and dependent Hosting/public assets `669e2fb` are verified. Anonymous screen/phone-width proof only; signed-in security/lifecycle and cleanup remain open. Older source-only/not-deployed maps below are historical milestones. ```mermaid flowchart LR Account["Same verified disposable staging session"] --> Screen["Private race screen; no runner directory"] - Screen --> Read["Strict bounded status or exact saved command"] + Screen --> Read["Strict status for selected ID or exact saved command"] Read --> Server["Existing native Auth/App Check and server authority"] Server --> Fresh["Fresh own status; acceptance consumes incoming offer"] Fresh --> Screen Change["Account/session change, failed read or known deadline"] --> Hide["Clear old controls; never reuse another context's action"] Hide --> Screen - Gate["Exact native release, hosted UI/security and cleanup still required"] -.-> Screen + Gate["Signed-in hosted UI/security and cleanup still required"] -.-> Screen ``` -Text alternative: the source-only staging screen submits bounded private reads and exact saved commands through the existing server boundary, rereads own status after acceptance, and clears old controls on uncertainty or context changes; native release, hosted behavior and cleanup remain unverified. +Text alternative: deployed staging source submits bounded private reads and exact saved commands through the existing server boundary, rereads own status after acceptance, and clears old controls on uncertainty or context changes; deployment is verified, while signed-in hosted behavior and cleanup remain unqualified. ## Fictional race boundary — #732 source and demo only diff --git a/src/pages/community/FictionalRaces.test.tsx b/src/pages/community/FictionalRaces.test.tsx index 3eba3a6..f384260 100644 --- a/src/pages/community/FictionalRaces.test.tsx +++ b/src/pages/community/FictionalRaces.test.tsx @@ -391,6 +391,37 @@ test('failed incoming lookup clears old controls, preserves typed focus and allo await screen.findByText(/Your enrollment: confirmed/); expect(screen.getByLabelText('Private incoming test entry ID')).toHaveValue(''); }); +test('refresh after a failed new offer lookup keeps the selected ID, never the previous offer', async () => { + mockUser = { uid: recipient }; + mockSession.uid = recipient; + await ready(); + fireEvent.change(screen.getByLabelText('Private incoming test entry ID'), { + target: { value: entryId } + }); + read.mockResolvedValue(state('incoming')); + fireEvent.click(screen.getByRole('button', { name: 'Check named offer' })); + await screen.findByRole('button', { name: 'Accept fictional bib transfer' }); + const selected = 'stage_race_other_incoming'; + fireEvent.change(screen.getByLabelText('Private incoming test entry ID'), { + target: { value: selected } + }); + read.mockRejectedValueOnce(Error('synthetic new offer unavailable')); + fireEvent.click(screen.getByRole('button', { name: 'Check named offer' })); + await screen.findByText(/Fictional race status is unavailable/); + expect(screen.getByLabelText('Private incoming test entry ID')).toHaveValue(selected); + const fresh = state('incoming'); + fresh.incoming!.entryId = selected; + read.mockResolvedValue(fresh); + fireEvent.click(screen.getByRole('button', { name: 'Refresh test status' })); + await screen.findByRole('button', { name: 'Accept fictional bib transfer' }); + expect(read).toHaveBeenLastCalledWith( + mockServices.firebaseResources.functions, + mockServices.firebaseResources.auth, + recipient, + selected + ); + expect(send).not.toHaveBeenCalled(); +}); test('native same-UID token/session renewal fences late action and never schedules an old-context reread', async () => { await ready('confirmed'); let resolve!: (value: unknown) => void; diff --git a/src/pages/community/FictionalRaces.tsx b/src/pages/community/FictionalRaces.tsx index dbf7b7d..a04e775 100644 --- a/src/pages/community/FictionalRaces.tsx +++ b/src/pages/community/FictionalRaces.tsx @@ -90,6 +90,8 @@ export default function FictionalRaces() { // The accepted offer is consumed. Reread own entry, never that old offer. if (command.action === 'race_accept') readFocus = null; } + // Preserve the caller's selected lookup even if this read fails. + focus.current = readFocus; const began = clock(); const value = await readFictionalStatus(functions, auth, session.user.uid, readFocus); if (!stillCurrent()) return;