/** * Sikka ONE API Integration for WORKWAY * * Unified dental practice management integration covering 400+ PMS systems * including Dentrix, Eaglesoft, Open Dental, and more. * * Zuhandenheit: Dentists don't want "API calls" - they want: * - Patients who show up * - Chairs that stay full * - Less time in admin screens * * @example * ```typescript * import { Sikka } from '@workwayco/integrations/sikka'; * * // Initialize with App ID and App Key from Sikka portal * const sikka = new Sikka({ * appId: process.env.SIKKA_APP_ID, * appKey: process.env.SIKKA_APP_KEY, * }); * * // Step 1: Get authorized practices (uses App-Id/App-Key auth) * const practices = await sikka.getAuthorizedPractices(); * console.log(`Found ${practices.data.length} practices`); * * // Step 2: Connect to a practice (obtains temporary request_key) * await sikka.connectToPractice(practices.data[0].office_id); * * // Step 3: Now you can access data (uses request-key auth) * const appointments = await sikka.getAppointments({ * practiceId: practices.data[0].office_id, * startDate: new Date(), * endDate: new Date(), * }); * * // Find patients modified in last 7 days (for incremental sync) * const patients = await sikka.getPatients({ * practiceId: practices.data[0].office_id, * modifiedSince: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000), * }); * ``` */ import { ActionResult } from '@workwayco/sdk'; import { BaseAPIClient } from '../core/index.js'; /** * Sikka integration configuration * * Authentication Model (3-step flow): * 1. Use `appId` + `appKey` to call /authorized_practices * 2. Exchange `officeId` + `secretKey` for a temporary `requestKey` (24h expiration) * 3. Use `requestKey` for all data access * * You can either: * - Provide appId + appKey (will fetch practices and request keys automatically) * - Provide a pre-fetched requestKey directly (for cached/stored keys) */ export interface SikkaConfig { /** Application ID from Sikka portal */ appId: string; /** Application secret key from Sikka portal */ appKey: string; /** Optional: Pre-fetched request key (skips auth flow if provided) */ requestKey?: string; /** Optional: Override API endpoint (for testing) */ apiUrl?: string; /** Request timeout in milliseconds (default: 30000) */ timeout?: number; } /** * Practice authorization info returned from /authorized_practices */ export interface SikkaAuthorizedPractice { office_id: string; secret_key: string; practice_name?: string; pms_type?: string; data_insert_date?: string; } /** * Request key response from POST /request_key */ export interface SikkaRequestKeyInfo { request_key: string; expires_in: string; status: string; scope?: string; issued_to?: string; start_time?: string; end_time?: string; } /** * Sikka practice (dental office) */ export interface SikkaPractice { practice_id: string; practice_name: string; practice_address?: string; practice_city?: string; practice_state?: string; practice_zip?: string; practice_phone?: string; pms_type?: string; timezone?: string; is_active?: boolean; } /** * Sikka patient record */ export interface SikkaPatient { patient_id: string; practice_id: string; first_name: string; last_name: string; middle_name?: string; email?: string; phone_home?: string; phone_cell?: string; phone_work?: string; date_of_birth?: string; gender?: string; address?: string; city?: string; state?: string; zip?: string; insurance_carrier?: string; primary_provider_id?: string; status?: 'active' | 'inactive' | 'archived'; balance?: number; last_visit_date?: string; next_appointment_date?: string; created_at?: string; modified_at?: string; } /** * Sikka appointment */ export interface SikkaAppointment { appointment_id: string; practice_id: string; patient_id: string; provider_id?: string; operatory_id?: string; appointment_date: string; appointment_time: string; duration_minutes?: number; status: 'scheduled' | 'confirmed' | 'checked_in' | 'in_progress' | 'completed' | 'cancelled' | 'no_show'; appointment_type?: string; procedure_codes?: string[]; notes?: string; created_at?: string; modified_at?: string; } /** * Sikka provider (dentist, hygienist, etc.) */ export interface SikkaProvider { provider_id: string; practice_id: string; first_name: string; last_name: string; provider_type?: string; npi?: string; email?: string; is_active?: boolean; } /** * Sikka treatment/procedure */ export interface SikkaTreatment { treatment_id: string; practice_id: string; patient_id: string; provider_id?: string; procedure_code: string; procedure_description?: string; tooth_number?: string; surface?: string; fee?: number; insurance_portion?: number; patient_portion?: number; status: 'planned' | 'scheduled' | 'in_progress' | 'completed'; treatment_date?: string; created_at?: string; modified_at?: string; } /** * Sikka insurance claim */ export interface SikkaClaim { claim_id: string; practice_id: string; patient_id: string; insurance_carrier: string; claim_date: string; amount_billed: number; amount_paid?: number; amount_adjusted?: number; status: 'pending' | 'submitted' | 'accepted' | 'rejected' | 'paid' | 'denied'; procedure_codes: string[]; created_at?: string; modified_at?: string; } /** * Sikka transaction */ export interface SikkaTransaction { transaction_id: string; practice_id: string; patient_id?: string; transaction_type: 'payment' | 'adjustment' | 'charge' | 'refund'; amount: number; payment_method?: string; transaction_date: string; description?: string; created_at?: string; } /** * Sikka webhook event */ export interface SikkaWebhookEvent { event_type: 'appointment.created' | 'appointment.updated' | 'appointment.cancelled' | 'patient.created' | 'patient.updated' | 'treatment.completed' | 'payment.received'; practice_id: string; timestamp: string; data: Record; callback_key?: string; } export interface GetPatientsOptions { practiceId: string; /** Filter by modified date (incremental sync) */ modifiedSince?: Date; modifiedUntil?: Date; /** Maximum records to return (max: 5000) */ limit?: number; /** Offset for pagination */ offset?: number; } export interface GetAppointmentsOptions { practiceId: string; /** Start date for appointment range */ startDate?: Date; /** End date for appointment range */ endDate?: Date; /** Filter by status */ status?: SikkaAppointment['status']; /** Filter by provider */ providerId?: string; limit?: number; offset?: number; } export interface GetTreatmentsOptions { practiceId: string; patientId?: string; /** Filter by status */ status?: SikkaTreatment['status']; modifiedSince?: Date; limit?: number; offset?: number; } export interface GetClaimsOptions { practiceId: string; patientId?: string; status?: SikkaClaim['status']; startDate?: Date; endDate?: Date; limit?: number; offset?: number; } export interface GetTransactionsOptions { practiceId: string; startDate?: Date; endDate?: Date; transactionType?: SikkaTransaction['transaction_type']; limit?: number; offset?: number; } export interface CreateAppointmentOptions { practiceId: string; patientId: string; providerId?: string; appointmentDate: Date; appointmentTime: string; durationMinutes?: number; appointmentType?: string; procedureCodes?: string[]; notes?: string; } export interface UpdateAppointmentOptions { practiceId: string; appointmentId: string; status?: SikkaAppointment['status']; appointmentDate?: Date; appointmentTime?: string; notes?: string; } /** * Sikka ONE API Integration * * Weniger, aber besser: One integration for 400+ dental PMS systems. * * Authentication flow: * 1. App-Id + App-Key → /authorized_practices → office_id + secret_key * 2. POST /request_key → temporary request_key (24h) * 3. request-key header → all data endpoints */ export declare class Sikka extends BaseAPIClient { private readonly appId; private readonly appKey; private requestKey?; private requestKeyExpiry?; private authorizedPracticesCache?; private currentPractice?; constructor(config: SikkaConfig); /** * Make authenticated request using App-Id/App-Key headers * Used for /authorized_practices endpoint */ private requestWithAppAuth; /** * Obtain a request_key for a specific practice */ obtainRequestKey(practice: SikkaAuthorizedPractice): Promise>; /** * Check if current request key is valid */ hasValidRequestKey(): boolean; /** * Override request to use Sikka's request-key authentication * Requires a valid request_key to be set (call obtainRequestKey first) */ protected request(path: string, options?: RequestInit, additionalHeaders?: Record, isRetry?: boolean): Promise; /** * Get all practices you have authorization to access * * Uses App-Id/App-Key authentication (not request-key). * Returns office_id and secret_key which are needed to obtain request_keys. * * @example * ```typescript * const sikka = new Sikka({ appId: '...', appKey: '...' }); * const practices = await sikka.getAuthorizedPractices(); * * // Get request key for first practice * await sikka.obtainRequestKey(practices.data[0]); * * // Now you can access data * const patients = await sikka.getPatients({ practiceId: practices.data[0].office_id }); * ``` */ getAuthorizedPractices(): Promise>; /** * Connect to a practice (get request key and prepare for data access) * * Convenience method that combines getAuthorizedPractices + obtainRequestKey */ connectToPractice(officeId?: string): Promise>; /** * Get practice details */ getPractice(practiceId: string): Promise>; /** * Get patients from a practice * * Supports incremental sync via modifiedSince parameter. */ getPatients(options: GetPatientsOptions): Promise>; /** * Get a single patient by ID */ getPatient(practiceId: string, patientId: string): Promise>; /** * Search patients by name or email */ searchPatients(practiceId: string, searchTerm: string): Promise>; /** * Get appointments for a practice * * Zuhandenheit: "Show me today's schedule" not "GET /appointments?date_range=..." */ getAppointments(options: GetAppointmentsOptions): Promise>; /** * Get today's appointments for a practice * * Convenience method for the most common use case. */ getTodaysAppointments(practiceId: string): Promise>; /** * Get upcoming appointments for a patient */ getPatientAppointments(practiceId: string, patientId: string): Promise>; /** * Get providers (dentists, hygienists) for a practice */ getProviders(practiceId: string): Promise>; /** * Get treatment plans and procedures */ getTreatments(options: GetTreatmentsOptions): Promise>; /** * Get pending treatment plans for a patient * * Useful for treatment acceptance tracking. */ getPendingTreatments(practiceId: string, patientId: string): Promise>; /** * Get insurance claims */ getClaims(options: GetClaimsOptions): Promise>; /** * Get financial transactions */ getTransactions(options: GetTransactionsOptions): Promise>; /** * Create an appointment (requires Enterprise license) * * Note: Write-back is only available with Enterprise API license. */ createAppointment(options: CreateAppointmentOptions): Promise>; /** * Update appointment status (requires Enterprise license) */ updateAppointmentStatus(options: UpdateAppointmentOptions): Promise>; /** * Handle errors consistently */ private handleError; /** * Get capabilities for Sikka actions */ private getCapabilities; } /** * Convert Sikka patient to standard contact format */ export declare function toStandardContact(patient: SikkaPatient): { id: string; firstName: string; lastName: string; email: string | undefined; phone: string | undefined; source: "sikka"; sourceId: string; metadata: { practiceId: string; dateOfBirth: string | undefined; lastVisit: string | undefined; nextAppointment: string | undefined; balance: number | undefined; }; }; /** * Convert Sikka appointment to standard calendar event format */ export declare function toStandardEvent(appointment: SikkaAppointment): { id: string; title: string; start: string; end: string; status: "scheduled" | "completed" | "in_progress" | "cancelled" | "confirmed" | "checked_in" | "no_show"; source: "sikka"; sourceId: string; metadata: { practiceId: string; patientId: string; providerId: string | undefined; procedureCodes: string[] | undefined; notes: string | undefined; }; }; //# sourceMappingURL=index.d.ts.map