Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions .agents/handoffs/3232.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
schema_version: 1
task_id: "3232"
from: Implementer
to: GitHub
owner: GitHub
status: verifying
artifact:
- path: packages/web/src/auth/providers/provider-copy.util.ts
- path: packages/web/src/auth/providers/ProviderConnectChooser.tsx
- path: packages/web/src/auth/providers/ConnectProviderAction.tsx
- path: packages/web/src/components/Settings/SettingsModal.tsx
- path: packages/web/src/components/Sidebar/CalendarList/CalendarList.tsx
- path: packages/web/src/components/CalendarConnectionBanner/CalendarConnectionBanner.tsx
evidence:
- command: bun run verify --strict
result: "VERDICT: PASS (test:web, type-check, lint, knip, test:a11y, test:e2e)"
assumptions:
- "Microsoft reconnect copy uses Outlook as the product name so banner text matches the WP-08b example."
- "Default calendar optgroups now include (Provider) even for Google."
open_risks: []
next_deadline: 2026-09-05T12:00:00Z
retry: 0
approval: allow
waiting_on: null
escalation: null
---

P0 WP-08b: migrate Settings, sidebar, banners and toasts to the provider layer.
43 changes: 43 additions & 0 deletions .agents/handoffs/3233.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
schema_version: 1
task_id: "3233"
from: Implementer
to: GitHub
owner: GitHub
status: verifying
artifact:
- path: packages/web/src/sse/hooks/useSyncSSE.ts
- path: packages/web/src/sse/hooks/useSyncSSE.factory.ts
- path: packages/web/src/auth/providers/connection-revoked.util.ts
- path: packages/web/src/booking/BookingConnectGooglePrompt.tsx
- path: packages/web/src/calendars/calendar.util.ts
- path: packages/web/src/auth/posthog/track.ts
evidence:
- command: bun run verify --strict
result: "VERDICT: PASS (test:web, type-check, lint, knip, test:a11y, test:e2e)"
assumptions:
- "Booking empty-chooser copy stays Google-identical so BookingSettings tests pass when connectable is empty."
- "WP-08c PR includes WP-08b commits until #3383 merges."
open_risks: []
next_deadline: 2026-09-05T12:00:00Z
retry: 0
approval: human
waiting_on: "human review on PR #3384"
escalation: "Issue #3233 approval boundary is human; label agent-loop-needs-human."
---

P0 WP-08c: migrate SSE, booking, calendars, modals and analytics off the Google connect layer.

Remaining `auth/google/` files (sign-in only, 762 lines):

- `packages/web/src/auth/google/google-auth-config.ts`
- `packages/web/src/auth/google/google-auth-config.test.ts`
- `packages/web/src/auth/google/authorization/complete-google-authorization.ts`
- `packages/web/src/auth/google/authorization/google-authorization.constants.ts`
- `packages/web/src/auth/google/authorization/google-authorization.storage.ts`
- `packages/web/src/auth/google/authorization/google-authorization.storage.test.ts`
- `packages/web/src/auth/google/authorization/google-authorization.util.ts`
- `packages/web/src/auth/google/authorization/google-authorization.util.test.ts`
- `packages/web/src/auth/google/authorization/google-authorization.test.ts`
- `packages/web/src/auth/google/authorization/useStartGoogleAuthorization.ts`
- `packages/web/src/auth/google/authorization/useStartGoogleAuthorization.impl.ts`
4 changes: 1 addition & 3 deletions packages/web/src/__tests__/helpers/web-test-seams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,8 @@ import {
} from "@web/auth/google/authorization/useStartGoogleAuthorization";
import {
resetGoogleAvailabilityForTests,
setGoogleAvailabilityForTests,
} from "@web/auth/google/hooks/useIsGoogleAvailable/useIsGoogleAvailable";
import {
resetProviderAvailabilityForTests,
setGoogleAvailabilityForTests,
setProviderAvailabilityForTests,
} from "@web/auth/providers/useIsProviderAvailable";
import { resetEmbeddedCheckoutForTests } from "@web/billing/embedded-checkout/embedded-checkout.seam";
Expand Down
2 changes: 1 addition & 1 deletion packages/web/src/app.bootstrap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ import { createRoot } from "react-dom/client";
import "react-toastify/dist/ReactToastify.css";
import "./common/styles/toastify-theme.css";
import { sessionInit } from "@web/auth/compass/session/SessionProvider";
import { configureGoogleRevocationApiHandler } from "@web/auth/google/util/google-revocation-api.config";
import {
readConnectStatus,
refreshUserMetadataAfterConnect,
showConnectStatusToast,
} from "@web/auth/providers/connect-status.util";
import { configureGoogleRevocationApiHandler } from "@web/auth/providers/revocation-api.config";
import {
initializeDatabaseWithErrorHandling,
showDbInitErrorToast,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
markUserAsAuthenticated,
} from "@web/auth/compass/state/auth.state.util";
import { refreshUserMetadata } from "@web/auth/compass/user/util/user-metadata.util";
import { syncPendingLocalEvents } from "@web/auth/google/util/google.auth.util";
import { syncPendingLocalEvents } from "@web/auth/providers/connection-revoked.util";
import { eventQueryKeys } from "@web/events/queries/event.query.keys";
import { refreshEventRepositorySource } from "@web/events/repositories/event.repository.source.store";
import { createUseCompleteAuthentication } from "./useCompleteAuthentication.factory";
Expand Down
2 changes: 1 addition & 1 deletion packages/web/src/auth/compass/session/SessionProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ import {
getLastKnownEmail,
markUserAsAuthenticated,
} from "@web/auth/compass/state/auth.state.util";
import { clearGoogleSyncIndicatorOverride } from "@web/auth/providers/sync.indicator.state";
import { userMetadataActions } from "@web/auth/state/user-metadata.store";
import { ENV_WEB } from "@web/common/constants/env.constants";
import { ROOT_ROUTES } from "@web/common/constants/routes";
import { createExternalStore } from "@web/common/utils/external-store.util";
import { refreshEventRepositorySource } from "@web/events/repositories/event.repository.source.store";
import * as sse from "@web/sse/provider/SSEProvider";
import { clearGoogleSyncIndicatorOverride } from "../../google/state/google.sync.state";
import { refreshUserMetadata } from "../user/util/user-metadata.util";
import { SessionContext } from "./session.context";

Expand Down
6 changes: 3 additions & 3 deletions packages/web/src/auth/compass/session/logout.teardown.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const mockDraftActionsDiscard = mock();
// and only intercept what this file asserts on while it runs - the flag flips
// back to the real implementations in afterAll, because many later suites
// exercise these functions for real (draftActions.discard closes event forms,
// clearGoogleSyncIndicatorOverride drives useGcalSSE, and the source store's
// clearGoogleSyncIndicatorOverride drives useSyncSSE, and the source store's
// own tests call refreshEventRepositorySource).
const actualRepositorySource = {
...(await import("@web/events/repositories/event.repository.source.store")),
Expand All @@ -32,7 +32,7 @@ const actualUserMetadata = {
};
const actualSseClient = { ...(await import("@web/sse/client/sse.client")) };
const actualSyncState = {
...(await import("@web/auth/google/state/google.sync.state")),
...(await import("@web/auth/providers/sync.indicator.state")),
};
const actualDraftStore = {
...(await import("@web/events/stores/draft.store")),
Expand Down Expand Up @@ -62,7 +62,7 @@ mock.module("@web/auth/state/user-metadata.store", () => ({
},
}));

mock.module("@web/auth/google/state/google.sync.state", () => ({
mock.module("@web/auth/providers/sync.indicator.state", () => ({
...actualSyncState,
clearGoogleSyncIndicatorOverride: (...args: unknown[]) =>
isTeardownMocked
Expand Down
2 changes: 1 addition & 1 deletion packages/web/src/auth/compass/session/logout.teardown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
*/

import { queryClient } from "@web/api/query-client";
import { clearGoogleSyncIndicatorOverride } from "@web/auth/google/state/google.sync.state";
import { clearGoogleSyncIndicatorOverride } from "@web/auth/providers/sync.indicator.state";
import { userMetadataActions } from "@web/auth/state/user-metadata.store";
import { calendarQueryKeys } from "@web/calendars/calendar.query";
import { eventQueryKeys } from "@web/events/queries/event.query.keys";
Expand Down
2 changes: 1 addition & 1 deletion packages/web/src/auth/compass/state/auth.state.util.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { z } from "zod/v4";
import { clearAllGoogleReconnectRequired } from "@web/auth/providers/reconnect.state";
import { STORAGE_KEYS } from "@web/common/constants/storage.constants";
import { persistentBrowserStore } from "@web/common/storage/browser-key-value.store";
import { subscribeToStorageKey } from "@web/common/utils/external-store.util";
import { clearAllGoogleReconnectRequired } from "../../google/state/google.reconnect.state";

export const AuthStateSchema = z.object({
hasAuthenticated: z.boolean().default(false),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { type UserMetadata } from "@core/types/user.types";
import { createTestToastPort } from "@web/__tests__/helpers/web-test-seams";
import { BaseApi } from "@web/api/base/base.api";
import { resetGoogleReconnectRequiredForTests } from "@web/auth/google/state/google.reconnect.state";
import { resetGoogleReconnectRequiredForTests } from "@web/auth/providers/reconnect.state";
import { GOOGLE_DELAYED_TOAST_ID } from "@web/common/constants/toast.constants";
import { registerToastPort } from "@web/common/utils/toast/toast.port";
import {
Expand Down
8 changes: 6 additions & 2 deletions packages/web/src/auth/compass/user/util/user-metadata.util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ import {
getGoogleReconnectRequiredAccountEmails,
hasGoogleReconnectRequired,
syncReconnectRequiredFromConnections,
} from "@web/auth/google/state/google.reconnect.state";
} from "@web/auth/providers/reconnect.state";
import {
findPrimaryGoogleSyncConnectionFromMetadata,
findSyncConnectionsFromMetadata,
userMetadataActions,
} from "@web/auth/state/user-metadata.store";
import {
Expand All @@ -30,11 +31,14 @@ let metadataFetchEpoch = 0;
* metadata payload, whether it arrived from REST refresh or SSE.
*/
export const applyUserMetadataSideEffects = (metadata: UserMetadata): void => {
const connections = metadata.google?.connections ?? [];
const connections = findSyncConnectionsFromMetadata(metadata);
syncReconnectRequiredFromConnections(connections);

const needsReconnect =
metadata.google?.connectionState === "RECONNECT_REQUIRED" ||
connections.some(
(connection) => connection.connectionState === "RECONNECT_REQUIRED",
) ||
hasGoogleReconnectRequired();

if (needsReconnect) {
Expand Down

This file was deleted.

This file was deleted.

Loading