Skip to content

Conversation

@mikeallisonJS
Copy link
Collaborator

@mikeallisonJS mikeallisonJS commented Jan 20, 2026

Summary by CodeRabbit

  • New Features
    • Google OAuth reconnection flow with stale credential detection and warning alerts
    • "Reconnect with Google" button to re-authenticate expired Google accounts
    • Email notifications when Google authorization expires
    • Google Sheets sync management UI with active sync tracking, history, and deletion capabilities
    • Localization support for Google integration workflows and user messages

✏️ Tip: You can customize this high-level summary in your review settings.

Added mutation for updating Google integration settings, including handling OAuth redirects and displaying success/error notifications. Enhanced UI with a reconnect button and improved state management for loading and error handling.
…ect functionality

Added `oauthStale` field to the GraphQL schema and updated related components to manage OAuth token expiration. Implemented reconnect URL in email templates and service logic, along with UI alerts for stale OAuth status in the integration details view. Updated mocks and types to reflect these changes.
@mikeallisonJS mikeallisonJS requested a review from tanflem January 20, 2026 00:56
@mikeallisonJS mikeallisonJS self-assigned this Jan 20, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 20, 2026

Walkthrough

This PR introduces Google OAuth staleness detection and reconnection workflow across multiple layers. It adds an oauthStale boolean field to Google integration schemas, creates a reconnection email template, implements backend logic to detect stale tokens and queue reconnection notifications, and updates the admin UI to display staleness status with a reconnection button.

Changes

Cohort / File(s) Summary
Schema Updates (GraphQL & Prisma)
apis/api-gateway/schema.graphql, apis/api-journeys-modern/schema.graphql, apis/api-journeys/src/app/modules/.../google.graphql, apis/api-journeys-modern/src/schema/.../google.ts
Added oauthStale: Boolean! field to IntegrationGoogle type across GraphQL and Prisma schemas to track OAuth credential staleness.
Email Template
apis/api-journeys-modern/src/emails/templates/GoogleReconnect/...
New GoogleReconnect email template component (135 lines) with structured layout, reconnection button, and support for both story preview and production rendering modes. Exports GoogleReconnectEmail, GoogleReconnectEmailProps, and preview data.
Backend OAuth Detection & Notification
apis/api-journeys-modern/src/lib/google/googleAuth.ts
Adds handleStaleOAuth() function to detect failed token refreshes, mark integration as stale, and queue reconnection emails. Integrates conditional emailQueue initialization and extends integration lookup to include teamId.
Email Job Types & Worker
apis/api-journeys-modern/src/workers/email/service/prisma.types.ts, apis/api-journeys-modern/src/workers/email/service/service.ts
Introduces GoogleReconnectJob union member with userId, teamId, teamName, integrationId, and optional accountEmail. Adds googleReconnectEmail() worker function that queries user preferences, builds reconnection URL, renders email, and sends with recipient validation.
Frontend UI & Queries
apps/journeys-admin/src/components/Google/GoogleIntegrationDetails/GoogleIntegrationDetails.tsx, apps/journeys-admin/src/libs/useIntegrationQuery/...
Updates component to display stale OAuth warning alert, adds INTEGRATION_GOOGLE_UPDATE mutation for reconnection, includes Reconnect button with loading state, and tracks auth code/redirectUri. Extends GraphQL query to fetch oauthStale field. Provides mock fixtures for testing.
Localization & Tests
libs/locales/en/apps-journeys-admin.json, apis/api-journeys-modern/src/lib/google/googleAuth.spec.ts, apps/journeys-admin/src/.../GoogleIntegrationDetails.spec.tsx
Added 20+ new translation keys for reconnection prompts, Google Sheets sync UI labels, and status messages. Updated test mocks to include oauthStale field, teamId in integration data, and ownership differentiation scenarios.

Sequence Diagram

sequenceDiagram
    participant Client as Client (Admin UI)
    participant Backend as Backend (Google Auth)
    participant Database as Database
    participant EmailWorker as Email Worker
    participant User as User (Email)

    Backend->>Backend: Token refresh fails
    Backend->>Database: Mark integration.oauthStale = true
    Backend->>Backend: handleStaleOAuth()
    Backend->>Backend: Queue google-reconnect email job
    
    EmailWorker->>Database: Fetch user by ID
    EmailWorker->>Database: Check email preferences (accountNotifications, unsubscribeAll)
    EmailWorker->>Backend: Build reconnect URL (teamId, integrationId)
    EmailWorker->>EmailWorker: Render GoogleReconnectEmail template (HTML + plain text)
    EmailWorker->>User: Send reconnection email
    
    Client->>Database: Query integration (fetch oauthStale)
    Client->>Client: Display stale OAuth warning alert
    Client->>Client: Show "Reconnect with Google" button
    User->>Client: Click Reconnect button
    Client->>Backend: INTEGRATION_GOOGLE_UPDATE mutation
    Backend->>Database: Update integration with new OAuth token
    Backend->>Database: Mark integration.oauthStale = false
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Suggested reviewers

  • tanflem
  • mikeallisonJS
🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 10.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: handle google stale oauth' accurately summarizes the main objective of this pull request, which is to implement handling for stale Google OAuth credentials across multiple files and systems.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 00-00-MA-feat-google-stale

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@nx-cloud
Copy link

nx-cloud bot commented Jan 20, 2026

View your CI Pipeline Execution ↗ for commit f829bf0

Command Status Duration Result
nx run journeys-admin-e2e:e2e ✅ Succeeded 33s View ↗
nx run watch-e2e:e2e ✅ Succeeded 21s View ↗
nx run journeys-e2e:e2e ✅ Succeeded 24s View ↗
nx run watch-modern-e2e:e2e ✅ Succeeded 4s View ↗
nx run videos-admin-e2e:e2e ✅ Succeeded 4s View ↗
nx run player-e2e:e2e ✅ Succeeded 3s View ↗
nx run resources-e2e:e2e ✅ Succeeded 12s View ↗
nx run short-links-e2e:e2e ✅ Succeeded 3s View ↗
Additional runs (24) ✅ Succeeded ... View ↗

☁️ Nx Cloud last updated this comment at 2026-01-28 07:08:09 UTC

@nx-cloud
Copy link

nx-cloud bot commented Jan 20, 2026

View your CI Pipeline Execution ↗ for commit a2ee020

Command Status Duration Result
nx run-many --target=vercel-alias --projects=jo... ✅ Succeeded 2s View ↗
nx run-many --target=deploy --projects=videos-a... ✅ Succeeded 1m 27s View ↗
nx run-many --target=upload-sourcemaps --projec... ✅ Succeeded 6s View ↗
nx run-many --target=deploy --projects=journeys ✅ Succeeded 1m 12s View ↗
nx run-many --target=vercel-alias --projects=pl... ✅ Succeeded 2s View ↗
nx run-many --target=upload-sourcemaps --projec... ✅ Succeeded 8s View ↗
nx run-many --target=vercel-alias --projects=sh... ✅ Succeeded 2s View ↗
nx run-many --target=vercel-alias --projects=wa... ✅ Succeeded 2s View ↗
Additional runs (5) ✅ Succeeded ... View ↗

☁️ Nx Cloud last updated this comment at 2026-01-20 01:07:16 UTC

@github-actions github-actions bot requested a deployment to Preview - resources January 20, 2026 00:58 Pending
@github-actions github-actions bot requested a deployment to Preview - journeys-admin January 20, 2026 00:58 Pending
@github-actions github-actions bot requested a deployment to Preview - videos-admin January 20, 2026 00:58 Pending
@github-actions github-actions bot requested a deployment to Preview - short-links January 20, 2026 00:58 Pending
@github-actions github-actions bot requested a deployment to Preview - resources January 20, 2026 01:00 Pending
@github-actions github-actions bot temporarily deployed to Preview - journeys January 20, 2026 01:00 Inactive
@github-actions github-actions bot requested a deployment to Preview - journeys-admin January 20, 2026 01:00 Pending
@github-actions github-actions bot temporarily deployed to Preview - short-links January 20, 2026 01:00 Inactive
@github-actions github-actions bot temporarily deployed to Preview - videos-admin January 20, 2026 01:00 Inactive
@blacksmith-sh

This comment has been minimized.

@github-actions
Copy link
Contributor

github-actions bot commented Jan 20, 2026

The latest updates on your projects.

Name Status Preview Updated (UTC)
journeys ✅ Ready journeys preview Wed Jan 28 20:02:47 NZDT 2026

@github-actions
Copy link
Contributor

github-actions bot commented Jan 20, 2026

The latest updates on your projects.

Name Status Preview Updated (UTC)
videos-admin ✅ Ready videos-admin preview Wed Jan 28 20:03:32 NZDT 2026

@github-actions
Copy link
Contributor

github-actions bot commented Jan 20, 2026

The latest updates on your projects.

Name Status Preview Updated (UTC)
player ✅ Ready player preview Wed Jan 28 20:02:56 NZDT 2026

@github-actions
Copy link
Contributor

github-actions bot commented Jan 20, 2026

The latest updates on your projects.

Name Status Preview Updated (UTC)
short-links ✅ Ready short-links preview Wed Jan 28 20:02:48 NZDT 2026

@github-actions github-actions bot temporarily deployed to Preview - journeys-admin January 20, 2026 01:04 Inactive
@github-actions
Copy link
Contributor

github-actions bot commented Jan 20, 2026

The latest updates on your projects.

Name Status Preview Updated (UTC)
resources ✅ Ready resources preview Wed Jan 28 20:04:25 NZDT 2026

@github-actions
Copy link
Contributor

github-actions bot commented Jan 20, 2026

The latest updates on your projects.

Name Status Preview Updated (UTC)
journeys-admin ✅ Ready journeys-admin preview Wed Jan 28 20:04:45 NZDT 2026

Enhanced Google integration tests by including the teamId field in mock data and added oauthStale field to the integration update mutation. Updated related components to reflect these changes, ensuring better handling of OAuth token states and integration details.
@github-actions github-actions bot temporarily deployed to Preview - resources January 20, 2026 03:58 Inactive
@github-actions github-actions bot temporarily deployed to Preview - videos-admin January 20, 2026 03:58 Inactive
@github-actions github-actions bot temporarily deployed to Preview - journeys-admin January 20, 2026 03:58 Inactive
@github-actions github-actions bot temporarily deployed to Preview - short-links January 20, 2026 03:58 Inactive
@github-actions github-actions bot temporarily deployed to Preview - journeys January 20, 2026 03:58 Inactive
@github-actions github-actions bot temporarily deployed to Preview - watch-modern January 20, 2026 03:58 Inactive
@github-actions github-actions bot requested a deployment to Preview - resources January 28, 2026 06:56 Pending
@github-actions github-actions bot temporarily deployed to Preview - journeys January 28, 2026 06:56 Inactive
@github-actions github-actions bot requested a deployment to Preview - videos-admin January 28, 2026 06:56 Pending
@github-actions github-actions bot temporarily deployed to Preview - watch-modern January 28, 2026 06:56 Inactive
@github-actions github-actions bot temporarily deployed to Preview - short-links January 28, 2026 06:56 Inactive
@github-actions github-actions bot requested a deployment to Preview - journeys-admin January 28, 2026 06:56 Pending
@github-actions github-actions bot temporarily deployed to Preview - watch-modern January 28, 2026 07:00 Inactive
@github-actions github-actions bot temporarily deployed to Preview - resources January 28, 2026 07:00 Inactive
@github-actions github-actions bot temporarily deployed to Preview - videos-admin January 28, 2026 07:00 Inactive
@github-actions github-actions bot temporarily deployed to Preview - short-links January 28, 2026 07:00 Inactive
@github-actions github-actions bot temporarily deployed to Preview - journeys January 28, 2026 07:00 Inactive
@github-actions github-actions bot temporarily deployed to Preview - journeys-admin January 28, 2026 07:01 Inactive
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@apis/api-gateway/schema.graphql`:
- Around line 1769-1771: The gateway schema declares the oauthStale field with
`@join__field`(graph: API_JOURNEYS) and `@join__field`(graph: API_JOURNEYS_MODERN)
which will route queries to the legacy subgraph incorrectly; update the
oauthStale field declaration so it is routed to the modern subgraph only by
keeping the `@join__field`(graph: API_JOURNEYS_MODERN) and add `@override`(from:
"api-journeys") to indicate the modern subgraph owns the field (locate the
oauthStale field declaration in the schema and replace the dual join__field
directives with the single modern join__field plus the `@override`(from:
"api-journeys") directive).

Comment on lines 1769 to 1771
accountEmail: String
oauthStale: Boolean! @join__field(graph: API_JOURNEYS) @join__field(graph: API_JOURNEYS_MODERN)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for oauthStale in legacy and modern schemas
echo "=== Searching in api-journeys schema ==="
rg -n "oauthStale" apis/api-journeys/schema.graphql

echo ""
echo "=== Searching in api-journeys-modern schema ==="
rg -n "oauthStale" apis/api-journeys-modern/schema.graphql

echo ""
echo "=== Searching in api-journeys resolvers ==="
fd -e ts -e js . apis/api-journeys --type f | head -20 | xargs -I {} rg -l "oauthStale" {}

echo ""
echo "=== Searching in api-journeys-modern resolvers ==="
fd -e ts -e js . apis/api-journeys-modern --type f | head -20 | xargs -I {} rg -l "oauthStale" {}

Repository: JesusFilm/core

Length of output: 425


🏁 Script executed:

#!/bin/bash
# Get context around oauthStale in modern schema
echo "=== Context around oauthStale in api-journeys-modern ==="
sed -n '695,705p' apis/api-journeys-modern/schema.graphql

echo ""
echo "=== Check if this is in a type that appears in both schemas ==="
sed -n '690,705p' apis/api-journeys-modern/schema.graphql

echo ""
echo "=== Look for override directive examples in gateway schema ==="
rg -n "@override" apis/api-gateway/schema.graphql | head -10

echo ""
echo "=== Check what type oauthStale is part of in gateway ==="
sed -n '1760,1775p' apis/api-gateway/schema.graphql

Repository: JesusFilm/core

Length of output: 1486


Add @override directive to route oauthStale to the modern subgraph.

The oauthStale field exists only in api-journeys-modern but is declared in the gateway with @join__field(graph: API_JOURNEYS) @join__field(graph: API_JOURNEYS_MODERN). This will cause supergraph composition or runtime failures when querying the field through the legacy subgraph. Route it to the modern service using:

oauthStale: Boolean! `@join__field`(graph: API_JOURNEYS_MODERN) `@override`(from: "api-journeys")
🤖 Prompt for AI Agents
In `@apis/api-gateway/schema.graphql` around lines 1769 - 1771, The gateway schema
declares the oauthStale field with `@join__field`(graph: API_JOURNEYS) and
`@join__field`(graph: API_JOURNEYS_MODERN) which will route queries to the legacy
subgraph incorrectly; update the oauthStale field declaration so it is routed to
the modern subgraph only by keeping the `@join__field`(graph: API_JOURNEYS_MODERN)
and add `@override`(from: "api-journeys") to indicate the modern subgraph owns the
field (locate the oauthStale field declaration in the schema and replace the
dual join__field directives with the single modern join__field plus the
`@override`(from: "api-journeys") directive).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants