npm package: @growflowstudio/growflowbooking-client
Description: Node.js/TypeScript client for GrowFlow Booking API - appointments, availability, customers
Author: GrowFlow
Latest version: 1.0.0

# GrowFlow Booking SDK (Node.js/TypeScript)

TypeScript/JavaScript SDK for the GrowFlow Booking API. Provides a type-safe client for managing bookings, availability, customers, and quotas.

## Installation

```bash
npm install @growflow/booking-client
# or
pnpm add @growflow/booking-client
# or
yarn add @growflow/booking-client
```

## Quick Start

```typescript
import { GrowFlowBookingClient } from '@growflow/booking-client';

const client = new GrowFlowBookingClient({
  apiKey: 'bk_live_xxx',
});

// Get available slots
const slots = await client.getAvailableSlots({
  tenantSlug: 'my-business',
  date: '2024-03-15',
  serviceId: 'service-uuid-here',
});

// Find an available slot
const available = slots.slots.filter(s => s.available);
if (available.length > 0) {
  // Create a booking
  const result = await client.createSimpleBooking({
    tenantSlug: 'my-business',
    serviceId: 'service-uuid-here',
    date: '2024-03-15',
    slot: available[0].time,
    customerName: 'Mario Rossi',
    customerEmail: 'mario@example.com',
  });

  if (result.success) {
    console.log(`Booking created! Code: ${result.booking?.bookingCode}`);
  }
}
```

## Configuration

### Environment Variables

```bash
export GROWFLOW_BOOKING_API_KEY="bk_live_xxx"
export GROWFLOW_BOOKING_URL="https://booking.growflow.studio/api/v1"  # optional
```

### Direct Configuration

```typescript
const client = new GrowFlowBookingClient({
  apiKey: 'bk_live_xxx',
  baseUrl: 'https://booking.growflow.studio/api/v1',
  timeout: 30000,
  maxRetries: 3,
});
```

## API Reference

### Tenants

```typescript
// Get public tenant info (for widget)
const tenant = await client.getTenantPublic('my-business');

// Get tenant services
const services = await client.getTenantServices('my-business');

// Get full tenant details (authenticated)
const tenant = await client.getTenantDetail('my-business');
```

### Availability

```typescript
// Get available dates in a range
const dates = await client.getAvailableDates({
  tenantSlug: 'my-business',
  startDate: '2024-03-01',
  endDate: '2024-03-31',
  serviceId: 'service-uuid', // optional
});

// Get available time slots for a date
const slots = await client.getAvailableSlots({
  tenantSlug: 'my-business',
  date: '2024-03-15',
  serviceId: 'service-uuid',
});
```

### Bookings

```typescript
// Create a simple booking
const result = await client.createSimpleBooking({
  tenantSlug: 'my-business',
  serviceId: 'service-uuid',
  date: '2024-03-15',
  slot: '10:00',
  customerName: 'Mario Rossi',
  customerEmail: 'mario@example.com',
  customerPhone: '+39123456789', // optional
  notes: 'Special request', // optional
});

// Create an experience booking
const result = await client.createExperienceBooking({
  tenantSlug: 'my-business',
  experienceTypeId: 'experience-uuid',
  date: '2024-03-15',
  slot: '14:00',
  participants: 4,
  customerName: 'Mario Rossi',
  customerEmail: 'mario@example.com',
});

// Get booking by ID (with email verification)
const booking = await client.getBooking('booking-uuid', 'mario@example.com');

// List bookings (authenticated)
const bookings = await client.listBookings({
  dateFrom: '2024-03-01',
  dateTo: '2024-03-31',
  status: BookingStatus.Confirmed,
});

// Update booking status
const booking = await client.updateBookingStatus('booking-uuid', BookingStatus.Completed);

// Cancel booking
await client.cancelBooking('booking-uuid', 'Customer request');
```

### Customers

```typescript
// List customers
const customers = await client.listCustomers({ search: 'mario' });

// Create customer
const customer = await client.createCustomer({
  name: 'Mario Rossi',
  email: 'mario@example.com',
  phone: '+39123456789',
});

// Update customer
const customer = await client.updateCustomer('customer-uuid', {
  phone: '+39987654321',
});
```

### Quotas (for external integrations like SweatMate)

```typescript
// Create quota for a customer
const quota = await client.createQuota({
  customerExternalId: 'user_123',
  totalCredits: 10,
  source: 'sweatmate',
  sourceReference: 'subscription_abc',
});

// Get customer credits
const credits = await client.getCustomerCredits('user_123');
console.log(`Remaining: ${credits.remainingCredits}`);

// Use quota credit
const usage = await client.useQuota({
  quotaId: 'quota-uuid',
  credits: 1,
  bookingId: 'booking-uuid',
});
```

## Error Handling

```typescript
import {
  GrowFlowBookingError,
  AuthenticationError,
  NotFoundError,
  ValidationError,
  SlotUnavailableError,
  QuotaExhaustedError,
} from '@growflow/booking-client';

try {
  const result = await client.createSimpleBooking({ ... });
} catch (error) {
  if (error instanceof AuthenticationError) {
    console.error('Invalid API key');
  } else if (error instanceof NotFoundError) {
    console.error('Tenant or service not found');
  } else if (error instanceof ValidationError) {
    console.error('Invalid data:', error.message);
  } else if (error instanceof SlotUnavailableError) {
    console.error('Time slot is no longer available');
  } else if (error instanceof QuotaExhaustedError) {
    console.error('No credits remaining');
  } else if (error instanceof GrowFlowBookingError) {
    console.error('API error:', error.message);
  }
}
```

## TypeScript Support

This SDK is written in TypeScript and provides full type definitions:

```typescript
import type {
  Booking,
  BookingResult,
  BookingStatus,
  TimeSlot,
  AvailableSlots,
  Customer,
  Quota,
  TenantPublic,
} from '@growflow/booking-client';
```

## License

MIT