Files
noteflow/.rag/07-typescript-api-layer.md
Travis Vasceannie 1ce24cdf7b feat: reorganize Claude hooks and add RAG documentation structure with error handling policies
- Moved all hookify configuration files from `.claude/` to `.claude/hooks/` subdirectory for better organization
- Added four new blocking hooks to prevent common error handling anti-patterns:
  - `block-broad-exception-handler`: Prevents catching generic `Exception` with only logging
  - `block-datetime-now-fallback`: Blocks returning `datetime.now()` as fallback on parse failures to prevent data corruption
  - `block-default
2026-01-15 15:58:06 +00:00

4.9 KiB

NoteFlow TypeScript API Layer

Location

client/src/api/

Architecture

Multi-adapter design with fallback chain:

  1. TauriAdapter (tauri-adapter.ts) — Primary: Rust IPC to gRPC
  2. CachedAdapter (cached-adapter.ts) — Fallback: Read-only cache
  3. MockAdapter (mock-adapter.ts) — Development: Simulated responses

API Interface (interface.ts)

interface NoteFlowAPI {
  // Connection
  connect(): Promise<ConnectionResult>;
  disconnect(): Promise<void>;
  isConnected(): boolean;
  getEffectiveServerUrl(): Promise<string>;

  // Meetings
  createMeeting(request: CreateMeetingRequest): Promise<Meeting>;
  getMeeting(request: GetMeetingRequest): Promise<Meeting>;
  listMeetings(request: ListMeetingsRequest): Promise<ListMeetingsResponse>;
  stopMeeting(request: StopMeetingRequest): Promise<Meeting>;
  deleteMeeting(request: DeleteMeetingRequest): Promise<void>;

  // Streaming
  startTranscription(meetingId: string): TranscriptionStream;

  // Diarization
  refineSpeakerDiarization(request: RefineDiarizationRequest): Promise<DiarizationJob>;
  getDiarizationJobStatus(request: GetJobStatusRequest): Promise<DiarizationJobStatus>;
  renameSpeaker(request: RenameSpeakerRequest): Promise<void>;

  // Summaries
  generateSummary(request: GenerateSummaryRequest): Promise<Summary>;
  listSummarizationTemplates(): Promise<SummarizationTemplate[]>;
  createSummarizationTemplate(request: CreateTemplateRequest): Promise<SummarizationTemplate>;

  // Annotations
  addAnnotation(request: AddAnnotationRequest): Promise<Annotation>;
  listAnnotations(request: ListAnnotationsRequest): Promise<Annotation[]>;
  updateAnnotation(request: UpdateAnnotationRequest): Promise<Annotation>;
  deleteAnnotation(request: DeleteAnnotationRequest): Promise<void>;

  // Export
  exportTranscript(request: ExportRequest): Promise<ExportResult>;

  // ... 50+ more methods
}

Transcription Streaming

interface TranscriptionStream {
  send(chunk: AudioChunk): void;
  onUpdate(callback: (update: TranscriptUpdate) => void): Promise<void> | void;
  onError?(callback: (error: StreamError) => void): void;
  onCongestion?(callback: (state: CongestionState) => void): void;
  close(): void;
}

Connection State (connection-state.ts)

type ConnectionMode = 'connected' | 'disconnected' | 'cached' | 'mock' | 'reconnecting';

interface ConnectionState {
  mode: ConnectionMode;
  lastConnectedAt: Date | null;
  disconnectedAt: Date | null;
  reconnectAttempts: number;
  error: string | null;
  serverUrl: string | null;
}

Type Definitions (types/)

Core Types (core.ts)

  • Meeting, FinalSegment, WordTiming, Summary, Annotation
  • KeyPoint, ActionItem, Speaker

Enums (enums.ts)

  • UpdateType: partial | final | vad_start | vad_end
  • MeetingState: created | recording | stopped | completed | error
  • JobStatus: queued | running | completed | failed | cancelled
  • AnnotationType: action_item | decision | note | risk
  • ExportFormat: markdown | html | pdf

Feature Types (features/)

  • webhooks.ts — WebhookConfig, WebhookDelivery
  • calendar.ts — CalendarProvider, CalendarEvent, OAuthConfig
  • ner.ts — Entity extraction types
  • identity.ts — User, Workspace
  • oidc.ts — OIDCProvider, OIDCConfig
  • sync.ts — SyncStatus, SyncHistory
  • observability.ts — LogEntry, MetricPoint

Projects (projects.ts)

  • Project, ProjectMember, ProjectMembership

Cached Adapter (cached/)

Provides offline read-only access:

// cached/readonly.ts
export function rejectReadOnly(): never {
  throw new Error('This action requires an active connection');
}

// Pattern in cached adapters
export const cachedMeetings = {
  async getMeeting(id: string): Promise<Meeting> {
    return meetingCache.get(id) ?? rejectReadOnly();
  },
  async createMeeting(): Promise<Meeting> {
    return rejectReadOnly();  // Mutations blocked
  },
};

Cache Modules

  • meetings.ts — Meeting cache with TTL
  • projects.ts — Project cache
  • diarization.ts — Job status cache
  • annotations.ts — Annotation cache
  • templates.ts — Template cache
  • preferences.ts — Preferences cache

API Initialization

// api/index.ts
export async function initializeAPI(): Promise<NoteFlowAPI> {
  try {
    const tauriAdapter = await createTauriAdapter();
    return tauriAdapter;
  } catch {
    console.warn('Falling back to mock adapter');
    return createMockAdapter();
  }
}

export function getAPI(): NoteFlowAPI {
  return window.__NOTEFLOW_API__ ?? mockAdapter;
}

Usage Pattern

import { getAPI } from '@/api';

const api = getAPI();
const meeting = await api.createMeeting({ title: 'Sprint Planning' });
const stream = api.startTranscription(meeting.id);

stream.onUpdate((update) => {
  if (update.update_type === 'final') {
    console.log('New segment:', update.segment);
  }
});

// Send audio chunks
stream.send({ audio_data: audioBuffer });