Skip to content

260 feature milestone 1 google sso gmeet#219

Draft
calebbourg wants to merge 63 commits intomainfrom
260-feature-milestone-1---google-sso-gmeet
Draft

260 feature milestone 1 google sso gmeet#219
calebbourg wants to merge 63 commits intomainfrom
260-feature-milestone-1---google-sso-gmeet

Conversation

@calebbourg
Copy link
Collaborator

Description

describe the intent of your changes here

GitHub Issue: [Closes|Fixes|Resolves] #your GitHub issue number here

Changes

  • ...
  • ...
  • ...

Testing Strategy

describe how you or someone else can test and verify the changes

Concerns

describe any concerns that might be worth mentioning or discussing

jhodapp and others added 30 commits December 20, 2025 15:34
Add database schema, entities, and CRUD operations for the AI meeting
recording and transcription integration:

Database Migrations:
- Add user_integrations table for encrypted API credentials
- Add ai_privacy_level enum and meeting_url to coaching_relationships
- Add meeting_recordings, transcriptions, transcript_segments tables
- Add ai_suggested_items table for AI-detected actions/agreements

Entity Definitions:
- user_integrations (Google OAuth, Recall.ai, AssemblyAI credentials)
- meeting_recordings (Recall.ai bot tracking)
- transcriptions (AssemblyAI transcript data)
- transcript_segments (speaker-diarized utterances)
- ai_suggested_items (pending AI suggestions)
- Enums: ai_privacy_level, meeting_recording_status, transcription_status,
  sentiment, ai_suggestion_type, ai_suggestion_status

Entity API:
- CRUD operations for user_integration, meeting_recording, transcription,
  and ai_suggested_item modules

Other:
- AES-256-GCM encryption utilities for API key storage
- Config additions for external service credentials
- Update coaching_relationships with meeting_url and ai_privacy_level

Relates to: refactor-group/refactor-platform-fe#146
…se 3)

Add gateway clients for Recall.ai, AssemblyAI, and Google OAuth with
configurable base URLs. Create integration controller endpoints for
API key verification and OAuth flow handling.
Add start/stop recording endpoints that integrate with Recall.ai bot
for meeting capture. Add webhook handler for receiving recording
status updates from Recall.ai.
- Add transcript_segment entity_api module with CRUD operations
- Add AssemblyAI webhook handler for transcription callbacks
- Create transcription controller with transcript/segments/summary endpoints
- Update router with transcription routes
- Export transcript_segment and transcription modules from domain
- Add ai_suggestion_controller with endpoints for suggestion management
- Implement accept flow that creates Actions or Agreements from suggestions
- Implement dismiss flow to mark suggestions as dismissed
- Export ai_suggested_item module from domain
- Add routes for GET /coaching_sessions/:id/ai-suggestions
- Add routes for POST /ai-suggestions/:id/accept and /dismiss
- Add nested response structures for Recall.ai video URL extraction
  (recordings[0].media_shortcuts.video_mixed.data.download_url)
- Add backend polling for Recall.ai bot status when frontend requests
- Fix AssemblyAI webhook field name mismatch (id vs transcript_id)
- Fetch full transcript from AssemblyAI API on webhook notification
  (webhooks are notifications only, don't include transcript data)
- Add comprehensive debug logging for troubleshooting
- Add serde(rename_all = "snake_case") to AiPrivacyLevel enum
- Add serde(default) to UpdateParams fields for optional deserialization
- Add Default derive to UpdateParams struct
- Add action item extraction after transcription completes
- Create AI suggestion records for each detected action item
- Use keyword-based extraction (will, going to, need to, should, etc.)
- Log extraction results for debugging
- Add LeMUR API client for extracting actions/agreements from transcripts
- Implement dual AI privacy levels (coach + coachee must both consent)
- Add manual extraction endpoints for actions and agreements
- Fix Recall.ai JSON deserialization for null values
- Fix serde serialization to use lowercase enum variants
- Upgrade API error logs from WARN to ERROR level
- Silence verbose SQLx/SeaORM query logs
- Add auto_approve_ai_suggestions field to user integrations
- Add stated_by, assigned_to, source_segment fields to AI suggestions
- Add POST /coaching_relationships/:id/create-google-meet endpoint
- Automatically refresh expired Google OAuth tokens
- Update relationship with new meeting URL after creation
- Remove x-version header requirement from OAuth endpoints (browser redirects can't set headers)
- Add GOOGLE_OAUTH_SUCCESS_REDIRECT_URI config option
- Update OAuth callback to use full frontend URL instead of relative path
- Fixes redirect going to backend port instead of frontend
- Add WebhookConfig and WebhookEvents structs to CreateBotRequest
- Configure bot to send bot.status_change, bot.done, and recording.done events
- This enables receiving webhooks when recording completes instead of only polling
- Replace speaker labels (A, B) with actual coach/coachee names in
  transcript segments using word-count heuristic for speaker identification
- Add speaker context to LeMUR summary prompt for accurate attribution
- Extract due dates from natural language phrases in action items
- Prepend assignee name as [Name] prefix when it matches coach/coachee
- Run action extraction as background task (HTTP 202) to prevent timeouts
- Add pre-calculated date lookup table for relative date accuracy
- Strip markdown code blocks from LeMUR JSON responses
Log filtering with Trace-level bypass is now implemented in PR #216
with additional unit tests and improved architecture.
Update trait naming in abstraction layer design document to better
reflect that these bots serve multiple purposes beyond just recording
(transcription, note-taking, etc.). Changes include:

- Rename trait from RecordingBotProvider to MeetingBotProvider
- Update MeetingWorkflow field from recording_provider to bot_provider
- Update controller examples to use bot_provider naming
- Update mock test examples to use BotProvider naming
Update crate naming in abstraction layer design document. The term
"SDK" typically refers to vendor-specific libraries, whereas this is
a trait-based abstraction layer. Changes include:

- Rename crate from meeting-ai-sdk to meeting-ai
- Update Cargo.toml package name
- Update directory structure references
- Update import statements in code examples
- Change "SDK" to "abstraction layer" in open questions section
Add comprehensive inline documentation (3-5 lines each) to all traits,
types, and methods in the meeting-ai-abstraction-layer implementation plan.

Enhanced documentation covers:
- SdkError variants with handling guidance and use cases
- MeetingPlatformProvider OAuth flow and token management
- MeetingBotProvider lifecycle, artifacts, and monitoring strategies
- TranscriptionProvider features, status tracking, and cost considerations
- AiAnalysisProvider capabilities, token usage, and confidence scoring
- WebhookEvent types with security and idempotency requirements
- WorkflowOrchestrator state machine and resumption patterns

Each comment now includes:
- Purpose and functionality
- When and how to use
- Important considerations and edge cases
- Relationships to other system components

This improves developer experience by making design decisions explicit
and reducing ambiguity during implementation of the abstraction layer.
Replace "SDK" references with more accurate terminology:
- Title: "Meeting AI SDK" → "Meeting AI Abstraction Layer"
- Error type: Describe as "universal error type" abstracting providers
- Code comments: Use "trait types" instead of "SDK types"

This clarifies that we're building an abstraction layer with traits,
not a standalone SDK, which better reflects the hybrid architecture
approach (standalone crate + domain implementations).
Remove all SDK-specific type aliases in favor of standard Rust types:
- SdkError → Error
- SdkResult<T> → Result<T, Error>
- Remove SdkResult type alias entirely

This simplifies the API by using idiomatic Rust error handling patterns
and removes unnecessary abstraction layers. All trait methods now return
standard Result types, making the interface more familiar to Rust developers.

Changes applied to:
- Core error type definition
- All trait method signatures (5 traits, 25+ methods)
- Implementation examples (RecallAiProvider, SkribbyProvider)
- Test mock examples
- Documentation references

Updated 32 locations across the implementation plan.
jhodapp and others added 20 commits January 30, 2026 17:43
Remove concepts already handled by meeting-auth and meeting-manager
crates to eliminate duplication between implementation plans.

Changes:
- Remove MeetingPlatformProvider trait (replaced by OAuthProvider
  and MeetingClient in meeting-auth/meeting-manager)
- Remove OAuth types: OAuthConfig, OAuthTokens, PlatformUser
- Remove MeetingSpace/MeetingSpaceConfig types (now in meeting-manager)
- Rename MeetingBotProvider to RecordingBotProvider for clarity
- Remove verify_webhook() from WebhookHandler trait (use
  meeting-auth's WebhookValidator instead)
- Update MeetingWorkflow to remove meeting creation responsibilities
- Remove MeetingCreated state from WorkflowState enum
- Update directory structure to remove meeting_platform.rs
- Add dependencies on meeting-auth and meeting-manager crates
- Update implementation examples to use meeting-auth utilities
  (ApiKeyAuth, AuthenticatedClientBuilder, RetryAfterPolicy)
- Add scope notes clarifying this plan focuses on AI operations only
- Add cross-reference to meeting-and-auth-abstraction-layers.md

The meeting-ai crate now focuses exclusively on:
- RecordingBotProvider (bot deployment and recording)
- TranscriptionProvider (speech-to-text)
- AiAnalysisProvider (LLM-powered analysis)
- WebhookHandler (event processing)
- ExtractedResource system (domain-agnostic resource extraction)
…ase patterns

Per Caleb's suggestion, reorganize token types into oauth/token/ module:
- token::Storage, token::Manager, token::Tokens (no redundant Token prefix)

Align error handling with existing codebase patterns:
- Crate-level errors (ManagerError, StorageError) stay simple
- Domain layer provides From impls to convert to domain::Error
- Web layer handles HTTP status code mapping automatically

This follows the established flow: crate error → domain::Error → web::Error → HTTP response
Replace stringly-typed provider_id() method with type-safe provider()
method returning OAuthProviderKind enum, matching the pattern already
used for ApiKeyProvider in the ProviderAuth trait.
Add implementation notes to Storage and CredentialStorage traits
explaining they will be implemented in the domain crate using SeaORM
entities mapped to oauth_connections and api_credentials tables,
with encryption at rest via domain::encryption.
- Rename MeetingSpace/MeetingConfig to Space/Config (DRY principle:
  module path provides context)
- Add import examples showing aliasing for external code clarity
- Move hardcoded API URLs to module-level constants
- Use const_format::concatcp! for compile-time URL construction
- Define contextual error types for both meeting-auth and meeting-manager
- Add new ExternalErrorKind variants: Authentication, RateLimited
- Show complete From implementations mapping crate errors to domain::Error
- Add error flow summary tables showing HTTP status mappings
- Follow existing pattern: crate error → domain::Error → web::Error → HTTP

Error types follow codebase naming conventions and map to appropriate
HTTP status codes via the existing web layer error handling.
- Add Cargo.toml with authentication dependencies
- Define library structure with module organization
- Implement error types following domain error pattern
- Add helper functions for creating contextual errors
- Add ProviderAuth trait for request authentication
- Implement ApiKeyAuth for custom header patterns (Recall.ai, AssemblyAI)
- Implement BearerTokenAuth for standard Bearer tokens
- Support provider-specific authentication methods
- Add Provider trait for OAuth flows (authorization, token exchange, refresh)
- Implement PKCE (Proof Key for Code Exchange) with SHA256
- Add StateManager for CSRF protection with expiration
- Support provider identification and rotating refresh tokens
- Add Tokens struct with expiration checking
- Define Storage trait for token persistence with atomic updates
- Implement Manager with per-user refresh locking
- Support Zoom's rotating refresh tokens with race condition handling
- Add comprehensive tests for token operations
- Create Provider implementation for Google OAuth
- Add placeholder methods for authorization, token exchange, and refresh
- Mark Google as non-rotating refresh token provider
- Reference existing implementation for future migration
- Add AuthenticatedClientBuilder with middleware composition
- Implement RetryAfterPolicy with Retry-After header parsing
- Support exponential backoff with configurable limits
- Parse both seconds and HTTP-date formats for rate limits
- Add comprehensive tests for retry logic
- Add WebhookValidator trait for signature verification
- Implement HmacWebhookValidator using HMAC-SHA256
- Support provider-specific signature headers
- Prevent webhook spoofing attacks with cryptographic validation
- Define CredentialStorage trait for API key persistence
- Add pre-configured settings for Recall.ai and AssemblyAI
- Support region-specific configurations and rate limits
- Enable encrypted credential storage with provider-specific options
- Document rule against redundant type prefixes
- Provide examples of correct module-based naming
- Show proper import patterns with aliases
- Ensure consistency across all new crates
- Lock meeting-auth dependencies for reproducible builds
- Include all transitive dependencies with exact versions
- Ensure consistent builds across environments
@calebbourg calebbourg requested a review from jhodapp February 5, 2026 14:17
@calebbourg calebbourg self-assigned this Feb 5, 2026
- Implement all OAuth 2.0 flow methods in GoogleProvider:
  * authorization_url() with PKCE support
  * exchange_code() for token retrieval
  * refresh_token() for token renewal
  * revoke_token() for authorization cleanup
  * get_user_info() for profile data
- Add urlencoding dependency for proper URL encoding
- Simplify RetryAfterPolicy to only supported exponential backoff
- Fix SecretString::from() usage in tests (use .to_string())
- Add missing async_trait import in token manager tests

All 32 meeting-auth tests passing.
- Create gateway/oauth module to provide provider-agnostic OAuth access
- Re-export meeting-auth OAuth types (AuthorizationRequest, Tokens, UserInfo, Provider trait)
- Add google::new_provider() constructor for Google OAuth
- Add meeting-auth dependency to domain

Follows existing gateway pattern (RecallAiClient, AssemblyAiClient).
Controllers instantiate providers on-demand from config.
- Create google_meet::Client for Google Meet Space creation
- Follows RecallAiClient pattern (instantiated on-demand with access token)
- Supports creating OPEN access meeting spaces
- Properly handles Bearer token authentication

Extracted from old google_oauth.rs to separate concerns.
- oauth_controller: Use oauth::google::new_provider() instead of direct GoogleProvider
- coaching_relationship_controller: Use new gateway for token refresh and Google Meet
- Add secrecy dependency to web for ExposeSecret trait
- Import Provider trait to access OAuth methods

Controllers are now decoupled from meeting-auth implementation details.
All OAuth operations go through domain gateway layer.
- Delete domain/src/gateway/google_oauth.rs (replaced by oauth/ and google_meet.rs)
- Update Cargo.lock with new dependencies (meeting-auth in domain, secrecy in web)

Old implementation mixed OAuth and Google Meet concerns.
New structure separates OAuth authentication (gateway/oauth) from
Meet API operations (gateway/google_meet).
@jhodapp jhodapp removed their request for review February 11, 2026 15:01
…ng fields

- Replace user_integrations table with provider enum + oauth_connections table
  for generic, provider-agnostic OAuth credential storage
- Move meeting_url from coaching_relationships to coaching_sessions with
  provider column so each session can have its own meeting link
- Remove AI-related migrations (privacy levels, recording tables, lemur fields)
  to be re-added when the AI/recording milestone is implemented
- Update DBML schema documentation to reflect current state
Document migration design decisions and outline remaining steps
for the milestone: entity definitions, entity API, domain layer,
OAuth controller, session/meeting endpoints, and cleanup.
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