11 KiB
11 KiB
trigger
| trigger |
|---|
| always_on |
Architecture
src/noteflow/
├── domain/ # Entities + ports (see Domain Package Structure below)
├── application/ # Use-cases/services (Meeting, Recovery, Export, Summarization, Trigger, Webhook, Calendar, Retention, NER)
├── infrastructure/ # Implementations
│ ├── audio/ # sounddevice capture, ring buffer, VU levels, playback, buffered writer
│ ├── asr/ # faster-whisper engine, VAD segmenter, streaming
│ ├── diarization/ # Speaker diarization (streaming: diart, offline: pyannote.audio)
│ ├── summarization/# Multi-provider summarization (CloudProvider, OllamaProvider) + citation verification
│ ├── triggers/ # Auto-start signal providers (calendar, audio activity, foreground app)
│ ├── persistence/ # SQLAlchemy + asyncpg + pgvector, Alembic migrations
│ ├── security/ # keyring keystore, AES-GCM encryption
│ ├── crypto/ # Cryptographic utilities
│ ├── export/ # Markdown/HTML/PDF export
│ ├── webhooks/ # Webhook executor with retry logic and HMAC signing
│ ├── converters/ # ORM ↔ domain entity converters (including webhook, NER, calendar, integration)
│ ├── calendar/ # OAuth manager, Google/Outlook calendar adapters
│ ├── ner/ # Named entity recognition engine (spaCy)
│ ├── observability/# OpenTelemetry tracing, usage event tracking
│ ├── metrics/ # Metric collection utilities
│ ├── logging/ # Log buffer and utilities
│ └── platform/ # Platform-specific code
├── grpc/ # Proto definitions, server, client, meeting store, modular mixins
├── cli/ # CLI tools (retention management, model commands)
└── config/ # Pydantic settings (NOTEFLOW_ env vars) + feature flags
Frontend (Tauri + React) lives outside the Python package:
client/
├── src/ # React UI, state, and view components
├── src-tauri/ # Rust/Tauri shell, IPC commands, gRPC client
├── e2e/ # Playwright tests
├── package.json # Vite + test/lint scripts
└── vite.config.ts # Vite configuration
Key patterns:
- Hexagonal architecture: domain → application → infrastructure
- Repository pattern with Unit of Work (
SQLAlchemyUnitOfWork) - gRPC bidirectional streaming for audio → transcript flow
- Protocol-based DI (see
domain/ports/and infrastructureprotocols.pyfiles) - Modular gRPC mixins for separation of concerns (see below)
Domain Package Structure
domain/
├── entities/ # Core domain entities
│ ├── meeting.py # Meeting, MeetingId, MeetingState
│ ├── segment.py # Segment, WordTiming
│ ├── summary.py # Summary, KeyPoint, ActionItem
│ ├── annotation.py # Annotation
│ ├── named_entity.py # NamedEntity for NER results
│ └── integration.py# Integration, IntegrationType, IntegrationStatus
├── identity/ # User/workspace identity (Sprint 16)
│ ├── roles.py # WorkspaceRole enum with permission checks
│ ├── context.py # UserContext, WorkspaceContext, ProjectContext, OperationContext
│ └── entities.py # User, Workspace, WorkspaceMembership domain entities
├── webhooks/ # Webhook domain
│ ├── events.py # WebhookEventType, WebhookConfig, WebhookDelivery, payload classes
│ └── constants.py # Webhook-related constants
├── triggers/ # Trigger detection domain
│ ├── entities.py # Trigger, TriggerAction, TriggerSignal
│ └── ports.py # TriggerProvider protocol
├── summarization/ # Summarization domain
│ └── ports.py # SummarizationProvider protocol
├── ports/ # Repository protocols
│ ├── repositories/ # Organized by concern
│ │ ├── transcript.py # MeetingRepository, SegmentRepository, SummaryRepository
│ │ ├── asset.py # AssetRepository for file management
│ │ ├── background.py # DiarizationJobRepository, EntityRepository
│ │ ├── external.py # WebhookRepository, IntegrationRepository, PreferencesRepository
│ │ └── identity.py # UserRepository, WorkspaceRepository protocols
│ ├── unit_of_work.py # UnitOfWork protocol with supports_* capability checks
│ ├── diarization.py # DiarizationEngine protocol
│ ├── ner.py # NEREngine protocol
│ └── calendar.py # CalendarProvider protocol
├── utils/ # Domain utilities
│ └── time.py # utc_now() helper
├── errors.py # Domain-specific exceptions
└── value_objects.py # Shared value objects
gRPC Mixin Architecture
The gRPC server uses modular mixins for maintainability:
grpc/_mixins/
├── streaming/ # ASR streaming (package)
│ ├── _mixin.py # Main StreamingMixin class
│ ├── _session.py # Session management
│ ├── _asr.py # ASR processing
│ ├── _processing.py# Audio processing pipeline
│ ├── _partials.py # Partial transcript handling
│ ├── _cleanup.py # Resource cleanup
│ └── _types.py # Type definitions
├── diarization/ # Speaker diarization (package)
│ ├── _mixin.py # Main DiarizationMixin class
│ ├── _jobs.py # Background job management
│ ├── _refinement.py# Offline refinement
│ ├── _streaming.py # Real-time diarization
│ ├── _speaker.py # Speaker assignment
│ ├── _status.py # Job status tracking
│ └── _types.py # Type definitions
├── summarization.py # Summary generation (separates LLM inference from DB transactions)
├── meeting.py # Meeting lifecycle (create, get, list, delete, stop)
├── annotation.py # Segment annotations CRUD
├── export.py # Markdown/HTML/PDF document export
├── entities.py # Named entity extraction operations
├── calendar.py # Calendar sync operations
├── webhooks.py # Webhook management operations
├── preferences.py # User preferences operations
├── observability.py # Usage tracking, metrics operations
├── sync.py # State synchronization operations
├── diarization_job.py# Diarization job status/management
├── converters.py # Protobuf ↔ domain entity converters
├── errors.py # gRPC error helpers (abort_not_found, abort_invalid_argument)
├── protocols.py # ServicerHost protocol for mixin composition
└── _audio_helpers.py # Audio utility functions
grpc/interceptors/ # gRPC server interceptors (Sprint 16)
└── identity.py # Identity context propagation (request_id, user_id, workspace_id)
Client-side mixins for the Python gRPC client:
grpc/_client_mixins/
├── streaming.py # Client streaming operations
├── meeting.py # Meeting CRUD operations
├── diarization.py # Diarization requests
├── export.py # Export requests
├── annotation.py # Annotation operations
├── converters.py # Response converters
└── protocols.py # ClientHost protocol
Each mixin operates on ServicerHost protocol, enabling clean composition in NoteFlowServicer.
Service Injection Pattern
Services are injected through a three-tier pattern:
- ServicerHost Protocol (
protocols.py) — declares required service attributes - NoteFlowServicer (
service.py) — accepts services via__init__and stores as instance attributes - NoteFlowServer (
server.py) — creates/initializes services and passes to servicer
Example: _webhook_service, _summarization_service, _ner_service all follow this pattern.
Client Architecture (Tauri + React)
client/src/
├── api/ # API layer with adapters and connection management
│ ├── tauri-adapter.ts # Main Tauri IPC adapter
│ ├── mock-adapter.ts # Mock adapter for testing
│ ├── cached-adapter.ts # Caching layer
│ ├── connection-state.ts # Connection state machine
│ ├── reconnection.ts # Auto-reconnection logic
│ ├── interface.ts # Adapter interface definition
│ └── types/ # API type definitions
├── hooks/ # Custom React hooks
│ ├── use-diarization.ts # Speaker diarization state
│ ├── use-cloud-consent.ts# Cloud provider consent
│ ├── use-webhooks.ts # Webhook management
│ ├── use-oauth-flow.ts # OAuth authentication
│ ├── use-calendar-sync.ts# Calendar synchronization
│ ├── use-entity-extraction.ts # NER operations
│ └── ... # Additional hooks
├── contexts/ # React contexts
│ └── connection-context.tsx # gRPC connection context
├── components/ # React components
│ ├── ui/ # Reusable UI components (shadcn/ui)
│ ├── recording/ # Recording-specific components
│ ├── settings/ # Settings panel components
│ └── analytics/ # Analytics visualizations
├── pages/ # Route pages
├── lib/ # Utilities
│ ├── tauri-helpers.ts # Tauri utility functions
│ ├── tauri-events.ts # Tauri event handling
│ ├── cache/ # Client-side caching
│ ├── config/ # Configuration management
│ └── ... # Format, crypto, utils
└── types/ # Shared TypeScript types
Rust/Tauri backend:
client/src-tauri/src/
├── commands/ # Tauri IPC command handlers
│ ├── recording/ # Recording commands (capture, device, audio)
│ ├── triggers/ # Trigger detection commands
│ ├── meeting.rs # Meeting CRUD
│ ├── diarization.rs# Diarization operations
│ ├── calendar.rs # Calendar sync
│ ├── webhooks.rs # Webhook management
│ └── ... # Export, annotation, preferences, etc.
├── grpc/ # gRPC client
│ ├── client/ # Client implementations by domain
│ └── types/ # Rust type definitions
├── state/ # Runtime state management
│ ├── app_state.rs # Main application state
│ ├── preferences.rs# User preferences
│ ├── playback.rs # Audio playback state
│ └── types.rs # State type definitions
├── audio/ # Audio capture and playback
├── cache/ # Memory caching
├── crypto/ # Cryptographic operations
├── events/ # Tauri event emission
├── triggers/ # Trigger detection
├── main.rs # Application entry point
└── lib.rs # Library exports