Draft
Conversation
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.
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
- 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).
…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.
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
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